fz_rect fz_bound_path(fz_path *path, fz_stroke_state *stroke, fz_matrix ctm) { fz_point p; fz_rect r = fz_empty_rect; int i = 0; if (path->len) { p.x = path->items[1].v; p.y = path->items[2].v; p = fz_transform_point(ctm, p); r.x0 = r.x1 = p.x; r.y0 = r.y1 = p.y; } while (i < path->len) { switch (path->items[i++].k) { case FZ_CURVETO: p.x = path->items[i++].v; p.y = path->items[i++].v; r = bound_expand(r, fz_transform_point(ctm, p)); p.x = path->items[i++].v; p.y = path->items[i++].v; r = bound_expand(r, fz_transform_point(ctm, p)); p.x = path->items[i++].v; p.y = path->items[i++].v; r = bound_expand(r, fz_transform_point(ctm, p)); break; case FZ_MOVETO: case FZ_LINETO: p.x = path->items[i++].v; p.y = path->items[i++].v; r = bound_expand(r, fz_transform_point(ctm, p)); break; case FZ_CLOSE_PATH: break; } } if (stroke) { float miterlength = stroke->miterlimit; float linewidth = stroke->linewidth; float expand = MAX(miterlength, linewidth) * 0.5f; r.x0 -= expand; r.y0 -= expand; r.x1 += expand; r.y1 += expand; } return r; }
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; }