diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-05-30 20:57:04 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-05-30 21:05:23 +0100 |
commit | 41bef0fc385381b8c6b9091ec7ca2abe04cfc147 (patch) | |
tree | afffbc846a708980178d63117c1a2643f9be5cb9 | |
parent | 631bf299256e11a17511977f357e0353fb5615f7 (diff) |
traps: Ensure that we correctly clip when using multiple clip boxes
We need to be more careful when trying to discard a clip to be sure that
it is truly not required. In particular, we need to not throw a way a
clip region when it has more than one box intersecting the mask.
Reported-by: Alexander Larsson
Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=697357
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/cairo-composite-rectangles.c | 7 | ||||
-rw-r--r-- | src/cairo-traps-compositor.c | 32 |
2 files changed, 21 insertions, 18 deletions
diff --git a/src/cairo-composite-rectangles.c b/src/cairo-composite-rectangles.c index c26098af4..e6639d0c3 100644 --- a/src/cairo-composite-rectangles.c +++ b/src/cairo-composite-rectangles.c @@ -167,6 +167,13 @@ _cairo_composite_rectangles_intersect (cairo_composite_rectangles_t *extents, _cairo_clip_get_extents (extents->clip))) return CAIRO_INT_STATUS_NOTHING_TO_DO; + if (! _cairo_rectangle_intersect (&extents->bounded, + _cairo_clip_get_extents (extents->clip)) && + extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) + { + return CAIRO_INT_STATUS_NOTHING_TO_DO; + } + if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) _cairo_pattern_sampled_area (&extents->source_pattern.base, &extents->bounded, diff --git a/src/cairo-traps-compositor.c b/src/cairo-traps-compositor.c index 02fbe7514..988d23c8d 100644 --- a/src/cairo-traps-compositor.c +++ b/src/cairo-traps-compositor.c @@ -928,12 +928,20 @@ need_bounded_clip (cairo_composite_rectangles_t *extents) { unsigned int flags = 0; - if (extents->unbounded.width < extents->destination.width || - extents->unbounded.height < extents->destination.height) + if (extents->clip->num_boxes > 1 || + extents->mask.width > extents->unbounded.width || + extents->mask.height > extents->unbounded.height) { flags |= NEED_CLIP_REGION; } + if (extents->clip->num_boxes > 1 || + extents->mask.width > extents->bounded.width || + extents->mask.height > extents->bounded.height) + { + flags |= FORCE_CLIP_REGION; + } + if (! _cairo_clip_is_region (extents->clip)) flags |= NEED_CLIP_SURFACE; @@ -2160,18 +2168,14 @@ _cairo_traps_compositor_stroke (const cairo_compositor_t *_compositor, double tolerance, cairo_traps_t *traps); composite_traps_info_t info; - unsigned flags = 0; + unsigned flags; if (antialias == CAIRO_ANTIALIAS_BEST || antialias == CAIRO_ANTIALIAS_GOOD) { func = _cairo_path_fixed_stroke_polygon_to_traps; + flags = 0; } else { func = _cairo_path_fixed_stroke_to_traps; - if (extents->clip->num_boxes > 1 || - extents->mask.width > extents->unbounded.width || - extents->mask.height > extents->unbounded.height) - { - flags = NEED_CLIP_REGION | FORCE_CLIP_REGION; - } + flags = need_bounded_clip (extents) & ~NEED_CLIP_SURFACE; } info.antialias = antialias; @@ -2299,7 +2303,6 @@ _cairo_traps_compositor_glyphs (const cairo_compositor_t *_compositor, &num_glyphs); if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { cairo_composite_glyphs_info_t info; - unsigned flags = 0; info.font = scaled_font; info.glyphs = glyphs; @@ -2307,16 +2310,9 @@ _cairo_traps_compositor_glyphs (const cairo_compositor_t *_compositor, info.use_mask = overlap || ! extents->is_bounded; info.extents = extents->bounded; - if (extents->mask.width > extents->bounded.width || - extents->mask.height > extents->bounded.height) - { - flags |= FORCE_CLIP_REGION; - } - status = clip_and_composite (compositor, extents, composite_glyphs, NULL, &info, - need_bounded_clip (extents) | - flags); + need_bounded_clip (extents) | FORCE_CLIP_REGION); } _cairo_scaled_font_thaw_cache (scaled_font); |