summaryrefslogtreecommitdiff
path: root/src/cairo-spans-compositor.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-02-28 22:27:18 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-02-28 22:27:18 +0000
commit3c665102c2b7ccd69aec7658e398ce6dd6dae38b (patch)
treed3d944842b95779043f787e18e027259b8ffe03a /src/cairo-spans-compositor.c
parentbe5ab6df68cba1bd0709fa4319e29141d4491d94 (diff)
downloadcairo-3c665102c2b7ccd69aec7658e398ce6dd6dae38b.tar.gz
spans+image: Fix clipping with polygons and spans
Fixes: clip-source, random-clip Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/cairo-spans-compositor.c')
-rw-r--r--src/cairo-spans-compositor.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/src/cairo-spans-compositor.c b/src/cairo-spans-compositor.c
index f069bcdc5..b106d73c9 100644
--- a/src/cairo-spans-compositor.c
+++ b/src/cairo-spans-compositor.c
@@ -620,7 +620,7 @@ composite_polygon (const cairo_spans_compositor_t *compositor,
cairo_bool_t needs_clip;
cairo_int_status_t status;
- needs_clip = composite_needs_clip (extents, &polygon->extents);
+ needs_clip = extents->clip->path != NULL || extents->clip->num_boxes > 1;
if (needs_clip) {
return CAIRO_INT_STATUS_UNSUPPORTED;
converter = _cairo_clip_tor_scan_converter_create (extents->clip,
@@ -879,25 +879,45 @@ _cairo_spans_compositor_stroke (const cairo_compositor_t *_compositor,
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
cairo_polygon_t polygon;
+ cairo_fill_rule_t fill_rule = CAIRO_FILL_RULE_WINDING;
if (extents->mask.width > extents->unbounded.width ||
extents->mask.height > extents->unbounded.height)
{
- _cairo_polygon_init_with_clip (&polygon, extents->clip);
+ cairo_box_t limits;
+ _cairo_box_from_rectangle (&limits, &extents->unbounded);
+ _cairo_polygon_init (&polygon, &limits, 1);
}
else
{
- _cairo_polygon_init_with_clip (&polygon, NULL);
+ _cairo_polygon_init (&polygon, NULL, 0);
}
status = _cairo_path_fixed_stroke_to_polygon (path,
style,
ctm, ctm_inverse,
tolerance,
&polygon);
+ if (status == CAIRO_INT_STATUS_SUCCESS && extents->clip->num_boxes > 1) {
+ status = _cairo_polygon_intersect_with_boxes (&polygon, &fill_rule,
+ extents->clip->boxes,
+ extents->clip->num_boxes);
+ }
if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
+ cairo_clip_t *saved_clip = extents->clip;
+
+ if (extents->is_bounded) {
+ extents->clip = _cairo_clip_copy_path (extents->clip);
+ extents->clip = _cairo_clip_intersect_box(extents->clip,
+ &polygon.extents);
+ }
+
status = clip_and_composite_polygon (compositor, extents, &polygon,
- CAIRO_FILL_RULE_WINDING,
- antialias);
+ fill_rule, antialias);
+
+ if (extents->clip != saved_clip) {
+ _cairo_clip_destroy (extents->clip);
+ extents->clip = saved_clip;
+ }
}
_cairo_polygon_fini (&polygon);
}
@@ -949,22 +969,27 @@ _cairo_spans_compositor_fill (const cairo_compositor_t *_compositor,
}
status = _cairo_path_fixed_fill_to_polygon (path, tolerance, &polygon);
- if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
+ if (status == CAIRO_INT_STATUS_SUCCESS && extents->clip->num_boxes > 1) {
status = _cairo_polygon_intersect_with_boxes (&polygon, &fill_rule,
extents->clip->boxes,
extents->clip->num_boxes);
}
if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
- if (extents->is_bounded) {
- if (extents->clip->boxes != &extents->clip->embedded_box)
- free (extents->clip->boxes);
+ cairo_clip_t *saved_clip = extents->clip;
- extents->clip->num_boxes = 1;
- extents->clip->boxes = &extents->clip->embedded_box;
- extents->clip->boxes[0] = polygon.extents;
+ if (extents->is_bounded) {
+ extents->clip = _cairo_clip_copy_path (extents->clip);
+ extents->clip = _cairo_clip_intersect_box(extents->clip,
+ &polygon.extents);
}
+
status = clip_and_composite_polygon (compositor, extents, &polygon,
fill_rule, antialias);
+
+ if (extents->clip != saved_clip) {
+ _cairo_clip_destroy (extents->clip);
+ extents->clip = saved_clip;
+ }
}
_cairo_polygon_fini (&polygon);
}