Example #1
0
fz_rect *
fz_bound_text(fz_context *ctx, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm, fz_rect *bbox)
{
	fz_text_span *span;
	fz_matrix tm, trm;
	fz_rect gbox;
	int i;

	*bbox = fz_empty_rect;

	for (span = text->head; span; span = span->next)
	{
		if (span->len > 0)
		{
			tm = span->trm;
			for (i = 0; i < span->len; i++)
			{
				if (span->items[i].gid >= 0)
				{
					tm.e = span->items[i].x;
					tm.f = span->items[i].y;
					fz_concat(&trm, &tm, ctm);
					fz_bound_glyph(ctx, span->font, span->items[i].gid, &trm, &gbox);
					fz_union_rect(bbox, &gbox);
				}
			}

		}
	}

	if (!fz_is_empty_rect(bbox))
	{
		if (stroke)
			fz_adjust_rect_for_stroke(ctx, bbox, stroke, ctm);

		/* Compensate for the glyph cache limited positioning precision */
		bbox->x0 -= 1;
		bbox->y0 -= 1;
		bbox->x1 += 1;
		bbox->y1 += 1;
	}

	return bbox;
}
Example #2
0
static void
fz_list_clip_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm)
{
	fz_display_node *node;
	fz_context *ctx = dev->ctx;
	node = fz_new_display_node(ctx, FZ_CMD_CLIP_STROKE_TEXT, ctm, NULL, NULL, 0);
	fz_try(ctx)
	{
		node->rect = fz_bound_text(dev->ctx, text, ctm);
		fz_adjust_rect_for_stroke(&node->rect, stroke, &ctm);
		node->item.text = fz_clone_text(dev->ctx, text);
		node->stroke = fz_keep_stroke_state(dev->ctx, stroke);
	}
	fz_catch(ctx)
	{
		fz_free_display_node(ctx, node);
		fz_rethrow(ctx);
	}
	fz_append_display_node(dev->user, node);
}
Example #3
0
File: path.c Project: haggl/mupdf
fz_rect *
fz_bound_path(fz_context *ctx, fz_path *path, const fz_stroke_state *stroke, const fz_matrix *ctm, fz_rect *r)
{
    fz_point p;
    int i = 0, k = 0;

    /* If the path is empty, return the empty rectangle here - don't wait
     * for it to be expanded in the stroked case below.
     * A path must start with a moveto - and if that's all there is
     * then the path is empty. */
    if (path->cmd_len == 0 || path->cmd_len == 1)
    {
        *r = fz_empty_rect;
        return r;
    }

    /* Initial moveto point */
    p.x = path->coords[0];
    p.y = path->coords[1];
    fz_transform_point(&p, ctm);
    r->x0 = r->x1 = p.x;
    r->y0 = r->y1 = p.y;

    while (i < path->cmd_len)
    {
        switch (path->cmds[i++])
        {
        case FZ_CURVETO:
            p.x = path->coords[k++];
            p.y = path->coords[k++];
            bound_expand(r, fz_transform_point(&p, ctm));
            p.x = path->coords[k++];
            p.y = path->coords[k++];
            bound_expand(r, fz_transform_point(&p, ctm));
            p.x = path->coords[k++];
            p.y = path->coords[k++];
            bound_expand(r, fz_transform_point(&p, ctm));
            break;
        case FZ_MOVETO:
            if (k + 2 == path->coord_len)
            {
                /* Trailing Moveto - cannot affect bbox */
                k += 2;
                break;
            }
        /* fallthrough */
        case FZ_LINETO:
            p.x = path->coords[k++];
            p.y = path->coords[k++];
            bound_expand(r, fz_transform_point(&p, ctm));
            break;
        case FZ_CLOSE_PATH:
            break;
        }
    }

    if (stroke)
    {
        fz_adjust_rect_for_stroke(r, stroke, ctm);
    }

    return r;
}