mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-02-04 20:00:33 +01:00
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>
This commit is contained in:
parent
bdf83008f4
commit
aeb039b16d
1 changed files with 37 additions and 0 deletions
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue