summaryrefslogtreecommitdiff
path: root/src/cairo-path-stroke-polygon.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-08-25 12:57:01 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2012-08-26 11:08:02 +0100
commitaeb039b16dc302192113a7f10c4b86e7d13eb221 (patch)
tree6a88077254f8618b6d366f9fe19c3a4c78013559 /src/cairo-path-stroke-polygon.c
parentbdf83008f4b2c723fd8e65e2a92bc47a2e7bc442 (diff)
downloadcairo-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.c37
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;