예제 #1
0
fz_bbox
fz_union_bbox(fz_bbox a, fz_bbox b)
{
	fz_bbox r;
	if (fz_is_infinite_rect(a)) return a;
	if (fz_is_infinite_rect(b)) return b;
	if (fz_is_empty_rect(a)) return b;
	if (fz_is_empty_rect(b)) return a;
	r.x0 = MIN(a.x0, b.x0);
	r.y0 = MIN(a.y0, b.y0);
	r.x1 = MAX(a.x1, b.x1);
	r.y1 = MAX(a.y1, b.y1);
	return r;
}
예제 #2
0
fz_rect
fz_intersect_rect(fz_rect a, fz_rect b)
{
	fz_rect r;
	if (fz_is_infinite_rect(a)) return b;
	if (fz_is_infinite_rect(b)) return a;
	if (fz_is_empty_rect(a)) return fz_empty_rect;
	if (fz_is_empty_rect(b)) return fz_empty_rect;
	r.x0 = MAX(a.x0, b.x0);
	r.y0 = MAX(a.y0, b.y0);
	r.x1 = MIN(a.x1, b.x1);
	r.y1 = MIN(a.y1, b.y1);
	return (r.x1 < r.x0 || r.y1 < r.y0) ? fz_empty_rect : r;
}
예제 #3
0
fz_bbox
fz_intersect_bbox(fz_bbox a, fz_bbox b)
{
	fz_bbox r;
	if (fz_is_infinite_rect(a)) return b;
	if (fz_is_infinite_rect(b)) return a;
	if (fz_is_empty_rect(a)) return fz_empty_bbox;
	if (fz_is_empty_rect(b)) return fz_empty_bbox;
	r.x0 = MAX(a.x0, b.x0);
	r.y0 = MAX(a.y0, b.y0);
	r.x1 = MIN(a.x1, b.x1);
	r.y1 = MIN(a.y1, b.y1);
	return (r.x1 < r.x0 || r.y1 < r.y0) ? fz_empty_bbox : r;
}
예제 #4
0
fz_bbox
fz_union_bbox(fz_bbox a, fz_bbox b)
{
    fz_bbox r;
    /* Check for empty box before infinite box */
    if (fz_is_empty_rect(a)) return b;
    if (fz_is_empty_rect(b)) return a;
    if (fz_is_infinite_rect(a)) return a;
    if (fz_is_infinite_rect(b)) return b;
    r.x0 = fz_mini(a.x0, b.x0);
    r.y0 = fz_mini(a.y0, b.y0);
    r.x1 = fz_maxi(a.x1, b.x1);
    r.y1 = fz_maxi(a.y1, b.y1);
    return r;
}
예제 #5
0
fz_bbox
fz_intersect_bbox(fz_bbox a, fz_bbox b)
{
    fz_bbox r;
    /* Check for empty box before infinite box */
    if (fz_is_empty_rect(a)) return fz_empty_bbox;
    if (fz_is_empty_rect(b)) return fz_empty_bbox;
    if (fz_is_infinite_rect(a)) return b;
    if (fz_is_infinite_rect(b)) return a;
    r.x0 = fz_maxi(a.x0, b.x0);
    r.y0 = fz_maxi(a.y0, b.y0);
    r.x1 = fz_mini(a.x1, b.x1);
    r.y1 = fz_mini(a.y1, b.y1);
    return (r.x1 < r.x0 || r.y1 < r.y0) ? fz_empty_bbox : r;
}
예제 #6
0
fz_rect
fz_intersect_rect(fz_rect a, fz_rect b)
{
    fz_rect r;
    /* Check for empty box before infinite box */
    if (fz_is_empty_rect(a)) return fz_empty_rect;
    if (fz_is_empty_rect(b)) return fz_empty_rect;
    if (fz_is_infinite_rect(a)) return b;
    if (fz_is_infinite_rect(b)) return a;
    r.x0 = fz_max(a.x0, b.x0);
    r.y0 = fz_max(a.y0, b.y0);
    r.x1 = fz_min(a.x1, b.x1);
    r.y1 = fz_min(a.y1, b.y1);
    return (r.x1 < r.x0 || r.y1 < r.y0) ? fz_empty_rect : r;
}
예제 #7
0
static void
fz_draw_clip_path(fz_device *devp, fz_path *path, fz_rect rect, int even_odd, fz_matrix ctm)
{
	fz_draw_device *dev = devp->user;
	float expansion = fz_matrix_expansion(ctm);
	float flatness = 0.3f / expansion;
	fz_bbox bbox;
	fz_draw_state *state = &dev->stack[dev->top];
	fz_colorspace *model;
	fz_context *ctx = dev->ctx;

	fz_reset_gel(dev->gel, state->scissor);
	fz_flatten_fill_path(dev->gel, path, ctm, flatness);
	fz_sort_gel(dev->gel);

	state = push_stack(dev);
	model = state->dest->colorspace;

	bbox = fz_bound_gel(dev->gel);
	bbox = fz_intersect_bbox(bbox, state->scissor);
	bbox = fz_intersect_bbox(bbox, fz_bbox_from_rect(rect));
	/* SumatraPDF: try to match rendering with and without display list */
	if (fz_is_infinite_rect(rect))
		bbox = fz_intersect_bbox(bbox, fz_bbox_from_rect(fz_bound_path(ctx, path, NULL, ctm)));

	if (fz_is_empty_rect(bbox) || fz_is_rect_gel(dev->gel))
	{
		state[1].scissor = bbox;
		state[1].mask = NULL;
#ifdef DUMP_GROUP_BLENDS
		dump_spaces(dev->top-1, "Clip (rectangular) begin\n");
#endif
		return;
	}

	fz_try(ctx)
	{
		state[1].mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
		fz_clear_pixmap(dev->ctx, state[1].mask);
		state[1].dest = fz_new_pixmap_with_bbox(dev->ctx, model, bbox);
		fz_clear_pixmap(dev->ctx, state[1].dest);
		if (state[1].shape)
		{
			state[1].shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
			fz_clear_pixmap(dev->ctx, state[1].shape);
		}

		fz_scan_convert(dev->gel, even_odd, bbox, state[1].mask, NULL);

		state[1].blendmode |= FZ_BLEND_ISOLATED;
		state[1].scissor = bbox;
#ifdef DUMP_GROUP_BLENDS
		dump_spaces(dev->top-1, "Clip (non-rectangular) begin\n");
#endif
	}
	fz_catch(ctx)
	{
		emergency_pop_stack(dev, state);
	}
}
예제 #8
0
fz_rect
fz_transform_rect(fz_matrix m, fz_rect r)
{
    fz_point s, t, u, v;

    if (fz_is_infinite_rect(r))
        return r;

    s.x = r.x0;
    s.y = r.y0;
    t.x = r.x0;
    t.y = r.y1;
    u.x = r.x1;
    u.y = r.y1;
    v.x = r.x1;
    v.y = r.y0;
    s = fz_transform_point(m, s);
    t = fz_transform_point(m, t);
    u = fz_transform_point(m, u);
    v = fz_transform_point(m, v);
    r.x0 = MIN4(s.x, t.x, u.x, v.x);
    r.y0 = MIN4(s.y, t.y, u.y, v.y);
    r.x1 = MAX4(s.x, t.x, u.x, v.x);
    r.y1 = MAX4(s.y, t.y, u.y, v.y);
    return r;
}
예제 #9
0
static void
fz_draw_clip_stroke_path(fz_device *devp, fz_path *path, fz_rect rect, fz_stroke_state *stroke, fz_matrix ctm)
{
	fz_draw_device *dev = devp->user;
	float expansion = fz_matrix_expansion(ctm);
	float flatness = 0.3f / expansion;
	float linewidth = stroke->linewidth;
	fz_bbox bbox;
	fz_draw_state *state = &dev->stack[dev->top];
	fz_colorspace *model;
	fz_context *ctx = dev->ctx;

	if (linewidth * expansion < 0.1f)
		linewidth = 1 / expansion;

	fz_reset_gel(dev->gel, state->scissor);
	if (stroke->dash_len > 0)
		fz_flatten_dash_path(dev->gel, path, stroke, ctm, flatness, linewidth);
	else
		fz_flatten_stroke_path(dev->gel, path, stroke, ctm, flatness, linewidth);
	fz_sort_gel(dev->gel);

	state = push_stack(dev);
	model = state->dest->colorspace;

	bbox = fz_bound_gel(dev->gel);
	bbox = fz_intersect_bbox(bbox, state->scissor);
	bbox = fz_intersect_bbox(bbox, fz_bbox_from_rect(rect));
	/* SumatraPDF: try to match rendering with and without display list */
	if (fz_is_infinite_rect(rect))
		bbox = fz_intersect_bbox(bbox, fz_bbox_from_rect(fz_bound_path(ctx, path, stroke, ctm)));

	fz_try(ctx)
	{
		state[1].mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
		fz_clear_pixmap(dev->ctx, state[1].mask);
		state[1].dest = fz_new_pixmap_with_bbox(dev->ctx, model, bbox);
		fz_clear_pixmap(dev->ctx, state[1].dest);
		if (state->shape)
		{
			state[1].shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
			fz_clear_pixmap(dev->ctx, state[1].shape);
		}

		if (!fz_is_empty_rect(bbox))
			fz_scan_convert(dev->gel, 0, bbox, state[1].mask, NULL);

		state[1].blendmode |= FZ_BLEND_ISOLATED;
		state[1].scissor = bbox;
#ifdef DUMP_GROUP_BLENDS
		dump_spaces(dev->top-1, "Clip (stroke) begin\n");
#endif
	}
	fz_catch(ctx)
	{
		emergency_pop_stack(dev, state);
	}
}
예제 #10
0
fz_bbox
fz_translate_bbox(fz_bbox a, int xoff, int yoff)
{
    fz_bbox b;

    if (fz_is_empty_rect(a)) return a;
    if (fz_is_infinite_rect(a)) return a;
    ADD_WITH_SAT(b.x0, a.x0, xoff);
    ADD_WITH_SAT(b.y0, a.y0, yoff);
    ADD_WITH_SAT(b.x1, a.x1, xoff);
    ADD_WITH_SAT(b.y1, a.y1, yoff);
    return b;
}
예제 #11
0
void
fz_reset_gel(fz_gel *gel, fz_bbox clip)
{
	if (fz_is_infinite_rect(clip))
	{
		gel->clip.x0 = gel->clip.y0 = BBOX_MAX;
		gel->clip.x1 = gel->clip.y1 = BBOX_MIN;
	}
	else {
		gel->clip.x0 = clip.x0 * FZ_AA_HSCALE(gel->ctx);
		gel->clip.x1 = clip.x1 * FZ_AA_HSCALE(gel->ctx);
		gel->clip.y0 = clip.y0 * FZ_AA_VSCALE(gel->ctx);
		gel->clip.y1 = clip.y1 * FZ_AA_VSCALE(gel->ctx);
	}

	gel->bbox.x0 = gel->bbox.y0 = BBOX_MAX;
	gel->bbox.x1 = gel->bbox.y1 = BBOX_MIN;

	gel->len = 0;
}
예제 #12
0
파일: util.c 프로젝트: iezbli/zbli
fz_buffer *
fz_new_buffer_from_stext_page(fz_context *ctx, fz_stext_page *text, const fz_rect *sel, int crlf)
{
	fz_buffer *buf;
	fz_rect hitbox;
	float x0, y0, x1, y1;
	int block_num;
	int need_newline;
	int i;

	need_newline = 0;

	if (fz_is_infinite_rect(sel))
	{
		x0 = y0 = -FLT_MAX;
		x1 = y1 = FLT_MAX;
	}
	else
	{
		x0 = sel->x0;
		y0 = sel->y0;
		x1 = sel->x1;
		y1 = sel->y1;
	}

	buf = fz_new_buffer(ctx, 256);
	fz_try(ctx)
	{
		for (block_num = 0; block_num < text->len; block_num++)
		{
			fz_stext_line *line;
			fz_stext_block *block;
			fz_stext_span *span;

			if (text->blocks[block_num].type != FZ_PAGE_BLOCK_TEXT)
				continue;

			block = text->blocks[block_num].u.text;
			for (line = block->lines; line < block->lines + block->len; line++)
			{
				int saw_text = 0;
				for (span = line->first_span; span; span = span->next)
				{
					for (i = 0; i < span->len; i++)
					{
						int c;
						fz_stext_char_bbox(ctx, &hitbox, span, i);
						c = span->text[i].c;
						if (c < 32)
							c = '?';
						if (hitbox.x1 >= x0 && hitbox.x0 <= x1 && hitbox.y1 >= y0 && hitbox.y0 <= y1)
						{
							saw_text = 1;
							if (need_newline)
							{
								if (crlf)
									fz_write_buffer_rune(ctx, buf, '\r');
								fz_write_buffer_rune(ctx, buf, '\n');
								need_newline = 0;
							}
							fz_write_buffer_rune(ctx, buf, c);
						}
					}
				}

				if (saw_text)
					need_newline = 1;
			}
		}
	}
	fz_catch(ctx)
	{
		fz_drop_buffer(ctx, buf);
		fz_rethrow(ctx);
	}

	return buf;
}