diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-08-25 12:57:01 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-08-26 11:08:02 +0100 |
commit | aeb039b16dc302192113a7f10c4b86e7d13eb221 (patch) | |
tree | 6a88077254f8618b6d366f9fe19c3a4c78013559 /src/cairo-path-stroke-polygon.c | |
parent | bdf83008f4b2c723fd8e65e2a92bc47a2e7bc442 (diff) | |
download | cairo-aeb039b16dc302192113a7f10c4b86e7d13eb221.tar.gz |
stroke: Skip spline evaluation when stroking to a polygon
If the spline is wholly outside the clip region, accounting for the
stroke width and additional rendering, then we can simplify that spline
with a straight line.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/cairo-path-stroke-polygon.c')
-rw-r--r-- | src/cairo-path-stroke-polygon.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/cairo-path-stroke-polygon.c b/src/cairo-path-stroke-polygon.c index b7c18b72e..242fb24a1 100644 --- a/src/cairo-path-stroke-polygon.c +++ b/src/cairo-path-stroke-polygon.c @@ -81,6 +81,9 @@ struct stroker { cairo_bool_t has_first_face; cairo_stroke_face_t first_face; + + cairo_bool_t has_bounds; + cairo_box_t bounds; }; static inline double @@ -165,6 +168,10 @@ add_fan (struct stroker *stroker, { int start, stop, step, i, npoints; + if (stroker->has_bounds && + ! _cairo_box_contains_point (&stroker->bounds, midpt)) + return; + assert (stroker->pen.num_vertices); if (clockwise) { @@ -1207,6 +1214,11 @@ curve_to (void *closure, cairo_spline_t spline; cairo_stroke_face_t face; + if (stroker->has_bounds && + ! _cairo_spline_intersects (&stroker->current_face.point, b, c, b, + &stroker->bounds)) + return line_to (closure, d); + if (! _cairo_spline_init (&spline, spline_to, stroker, &stroker->current_face.point, b, c, d)) return line_to (closure, d); @@ -1305,6 +1317,31 @@ _cairo_path_fixed_stroke_to_polygon (const cairo_path_fixed_t *path, polygon); } + stroker.has_bounds = polygon->num_limits; + if (stroker.has_bounds) { + /* Extend the bounds in each direction to account for the maximum area + * we might generate trapezoids, to capture line segments that are + * outside of the bounds but which might generate rendering that's + * within bounds. + */ + double dx, dy; + cairo_fixed_t fdx, fdy; + int i; + + stroker.bounds = polygon->limits[0]; + for (i = 1; i < polygon->num_limits; i++) + _cairo_box_add_box (&stroker.bounds, &polygon->limits[i]); + + _cairo_stroke_style_max_distance_from_path (style, path, ctm, &dx, &dy); + fdx = _cairo_fixed_from_double (dx); + fdy = _cairo_fixed_from_double (dy); + + stroker.bounds.p1.x -= fdx; + stroker.bounds.p2.x += fdx; + stroker.bounds.p1.y -= fdy; + stroker.bounds.p2.y += fdy; + } + stroker.style = *style; stroker.ctm = ctm; stroker.ctm_inverse = ctm_inverse; |