diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-08-13 12:33:21 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-08-13 13:15:36 +0100 |
commit | 279f6ceb595412bef165a808f05caa3044ef102c (patch) | |
tree | b94702c96796dc524402ba8330b6722f08761187 | |
parent | d391f0908c404344aa6873fbca2b7bd6499009e0 (diff) | |
download | cairo-279f6ceb595412bef165a808f05caa3044ef102c.tar.gz |
Only reduce the clip if it is not in active use for the operation
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/cairo-composite-rectangles-private.h | 12 | ||||
-rw-r--r-- | src/cairo-composite-rectangles.c | 26 | ||||
-rw-r--r-- | src/cairo-pdf-surface.c | 17 | ||||
-rw-r--r-- | src/cairo-ps-surface.c | 18 | ||||
-rw-r--r-- | src/cairo-recording-surface.c | 7 |
5 files changed, 44 insertions, 36 deletions
diff --git a/src/cairo-composite-rectangles-private.h b/src/cairo-composite-rectangles-private.h index c6dac3092..dd5bd4156 100644 --- a/src/cairo-composite-rectangles-private.h +++ b/src/cairo-composite-rectangles-private.h @@ -53,11 +53,13 @@ CAIRO_BEGIN_DECLS struct _cairo_composite_rectangles { cairo_rectangle_int_t source; cairo_rectangle_int_t mask; - cairo_rectangle_int_t bounded; /* dst */ - cairo_rectangle_int_t unbounded; /* clip */ + cairo_rectangle_int_t destination; + + cairo_rectangle_int_t bounded; /* source? IN mask? IN unbounded */ + cairo_rectangle_int_t unbounded; /* destination IN clip */ uint32_t is_bounded; - cairo_clip_t *clip; + cairo_clip_t *clip; /* clip will be reduced to the minimal container */ }; cairo_private cairo_int_status_t @@ -108,6 +110,10 @@ cairo_private cairo_int_status_t _cairo_composite_rectangles_intersect_mask_extents (cairo_composite_rectangles_t *extents, const cairo_box_t *box); +cairo_private cairo_bool_t +_cairo_composite_rectangles_can_reduce_clip (cairo_composite_rectangles_t *composite, + cairo_clip_t *clip); + cairo_private void _cairo_composite_rectangles_fini (cairo_composite_rectangles_t *extents); diff --git a/src/cairo-composite-rectangles.c b/src/cairo-composite-rectangles.c index 439f453bd..6083973f6 100644 --- a/src/cairo-composite-rectangles.c +++ b/src/cairo-composite-rectangles.c @@ -54,11 +54,12 @@ _cairo_composite_rectangles_init (cairo_composite_rectangles_t *extents, const cairo_clip_t *clip) { extents->clip = NULL; + extents->destination = *unbounded; if (_cairo_clip_is_all_clipped (clip)) return FALSE; - extents->unbounded = *unbounded; + extents->unbounded = extents->destination; if (clip != NULL) { if (! _cairo_rectangle_intersect (&extents->unbounded, _cairo_clip_get_extents (clip))) @@ -247,3 +248,26 @@ _cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *exten return _cairo_composite_rectangles_intersect (extents, clip); } + +cairo_bool_t +_cairo_composite_rectangles_can_reduce_clip (cairo_composite_rectangles_t *composite, + cairo_clip_t *clip) +{ + cairo_rectangle_int_t extents; + + if (clip == NULL) + return TRUE; + + /* XXX In the not a region case, we could still search through the boxes */ + if (! _cairo_clip_is_region (clip)) + return FALSE; + + extents = composite->destination; + if (composite->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE) + _cairo_rectangle_intersect (&extents, &composite->source); + if (composite->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) + _cairo_rectangle_intersect (&extents, &composite->mask); + + return cairo_region_contains_rectangle (_cairo_clip_get_region (clip), + &extents) == CAIRO_REGION_OVERLAP_IN; +} diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index ca3a4d237..dd5f68c19 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -5793,22 +5793,13 @@ _cairo_pdf_surface_set_clip (cairo_pdf_surface_t *surface, { cairo_clip_t *clip = composite->clip; - if (_cairo_clip_is_region (clip) && - cairo_region_contains_rectangle (_cairo_clip_get_region (clip), - &composite->unbounded) == CAIRO_REGION_OVERLAP_IN) - { - clip = NULL; - } + if (_cairo_composite_rectangles_can_reduce_clip (composite, clip)) + clip = NULL; if (clip == NULL) { - cairo_clip_t *current = surface->clipper.clip; - - if (current && _cairo_clip_is_region (current) && - cairo_region_contains_rectangle (_cairo_clip_get_region (current), - &composite->unbounded) == CAIRO_REGION_OVERLAP_IN) - { + if (_cairo_composite_rectangles_can_reduce_clip (composite, + surface->clipper.clip)) return CAIRO_STATUS_SUCCESS; - } } return _cairo_surface_clipper_set_clip (&surface->clipper, clip); diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c index 267fd59d3..a9961fe34 100644 --- a/src/cairo-ps-surface.c +++ b/src/cairo-ps-surface.c @@ -3617,28 +3617,18 @@ _cairo_ps_surface_set_clip (cairo_ps_surface_t *surface, { cairo_clip_t *clip = composite->clip; - if (_cairo_clip_is_region (clip) && - cairo_region_contains_rectangle (_cairo_clip_get_region (clip), - &composite->unbounded) == CAIRO_REGION_OVERLAP_IN) - { - clip = NULL; - } + if (_cairo_composite_rectangles_can_reduce_clip (composite, clip)) + clip = NULL; if (clip == NULL) { - cairo_clip_t *current = surface->clipper.clip; - - if (current && _cairo_clip_is_region (current) && - cairo_region_contains_rectangle (_cairo_clip_get_region (current), - &composite->unbounded) == CAIRO_REGION_OVERLAP_IN) - { + if (_cairo_composite_rectangles_can_reduce_clip (composite, + surface->clipper.clip)) return CAIRO_STATUS_SUCCESS; - } } return _cairo_surface_clipper_set_clip (&surface->clipper, clip); } - static cairo_int_status_t _cairo_ps_surface_paint (void *abstract_surface, cairo_operator_t op, diff --git a/src/cairo-recording-surface.c b/src/cairo-recording-surface.c index 87b911900..0daf67576 100644 --- a/src/cairo-recording-surface.c +++ b/src/cairo-recording-surface.c @@ -587,11 +587,8 @@ _command_init (cairo_recording_surface_t *surface, /* steal the clip */ command->clip = NULL; - if (! _cairo_clip_is_region (composite->clip) || - composite->mask.width > composite->unbounded.width || - composite->mask.height > composite->unbounded.height || - cairo_region_contains_rectangle (_cairo_clip_get_region (composite->clip), - &composite->unbounded) != CAIRO_REGION_OVERLAP_IN) + if (! _cairo_composite_rectangles_can_reduce_clip (composite, + composite->clip)) { command->clip = composite->clip; composite->clip = NULL; |