summaryrefslogtreecommitdiff
path: root/src/cairo-surface-clipper.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-07-29 11:57:01 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2011-07-29 11:58:07 +0100
commit74a86a76a9c32a74d63712b718c90669889820e6 (patch)
treec5bee313eca1a4d61c68817fc3b72395316f4b37 /src/cairo-surface-clipper.c
parentaac9b261762cdb8039daedfe63a56a83faa0155f (diff)
downloadcairo-74a86a76a9c32a74d63712b718c90669889820e6.tar.gz
clipper: Detect a incremental change in the general clip-path
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/cairo-surface-clipper.c')
-rw-r--r--src/cairo-surface-clipper.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/src/cairo-surface-clipper.c b/src/cairo-surface-clipper.c
index c1644b495..e730300e3 100644
--- a/src/cairo-surface-clipper.c
+++ b/src/cairo-surface-clipper.c
@@ -98,14 +98,16 @@ _cairo_surface_clipper_intersect_clip_boxes (cairo_surface_clipper_t *clipper,
static cairo_status_t
_cairo_surface_clipper_intersect_clip_path_recursive (cairo_surface_clipper_t *clipper,
- cairo_clip_path_t *clip_path)
+ cairo_clip_path_t *clip_path,
+ cairo_clip_path_t *end)
{
cairo_status_t status;
- if (clip_path->prev != NULL) {
+ if (clip_path->prev != end) {
status =
_cairo_surface_clipper_intersect_clip_path_recursive (clipper,
- clip_path->prev);
+ clip_path->prev,
+ end);
if (unlikely (status))
return status;
}
@@ -122,6 +124,7 @@ _cairo_surface_clipper_set_clip (cairo_surface_clipper_t *clipper,
const cairo_clip_t *clip)
{
cairo_status_t status;
+ cairo_bool_t incremental = FALSE;
if (_cairo_clip_equal (clip, clipper->clip))
return CAIRO_STATUS_SUCCESS;
@@ -129,9 +132,31 @@ _cairo_surface_clipper_set_clip (cairo_surface_clipper_t *clipper,
/* all clipped out state should never propagate this far */
assert (!_cairo_clip_is_all_clipped (clip));
+ /* XXX Is this an incremental clip? */
+ if (clipper->clip &&
+ clip->num_boxes == clipper->clip->num_boxes &&
+ memcmp (clip->boxes, clipper->clip->boxes,
+ sizeof (cairo_box_t) * clip->num_boxes) == 0)
+ {
+ cairo_clip_path_t *clip_path = clip->path;
+ while (clip_path != clipper->clip->path)
+ clip_path = clip_path->prev;
+
+ if (clip_path) {
+ assert (clip_path != clipper->clip->path);
+ incremental = TRUE;
+ status = _cairo_surface_clipper_intersect_clip_path_recursive (clipper,
+ clip->path,
+ clipper->clip->path);
+ }
+ }
+
_cairo_clip_destroy (clipper->clip);
clipper->clip = _cairo_clip_copy (clip);
+ if (incremental)
+ return status;
+
status = clipper->intersect_clip_path (clipper, NULL, 0, 0, 0);
if (unlikely (status))
return status;
@@ -145,7 +170,8 @@ _cairo_surface_clipper_set_clip (cairo_surface_clipper_t *clipper,
if (clip->path != NULL) {
status = _cairo_surface_clipper_intersect_clip_path_recursive (clipper,
- clip->path);
+ clip->path,
+ NULL);
}
return status;