summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-08-13 12:33:21 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2011-08-13 13:15:36 +0100
commit279f6ceb595412bef165a808f05caa3044ef102c (patch)
treeb94702c96796dc524402ba8330b6722f08761187
parentd391f0908c404344aa6873fbca2b7bd6499009e0 (diff)
downloadcairo-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.h12
-rw-r--r--src/cairo-composite-rectangles.c26
-rw-r--r--src/cairo-pdf-surface.c17
-rw-r--r--src/cairo-ps-surface.c18
-rw-r--r--src/cairo-recording-surface.c7
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;