summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2009-09-10 19:11:36 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2009-09-10 19:11:36 +0100
commit94aeae9b2ec563201a0e65705504d1d70c33a619 (patch)
tree6a3a11c448c778765c5fc3a314da397aef5a88e1
parent496e79b63762c70fd022b2d9e2d6107bcce1807a (diff)
[clip] Simplify applying a box clip
If the clip path is a simple box, then for many operations it is entirely representation by the alteration of extents and so we can skip a few steps during reconstruction.
-rw-r--r--src/cairo-clip-private.h3
-rw-r--r--src/cairo-clip.c84
2 files changed, 48 insertions, 39 deletions
diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h
index 131d4c7e..15b4a4bf 100644
--- a/src/cairo-clip-private.h
+++ b/src/cairo-clip-private.h
@@ -45,7 +45,8 @@ extern const cairo_private cairo_rectangle_list_t _cairo_rectangles_nil;
enum {
CAIRO_CLIP_PATH_HAS_REGION = 0x1,
- CAIRO_CLIP_PATH_REGION_IS_UNSUPPORTED = 0x2
+ CAIRO_CLIP_PATH_REGION_IS_UNSUPPORTED = 0x2,
+ CAIRO_CLIP_PATH_IS_BOX = 0x4
};
struct _cairo_clip_path {
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index fde41212..fd1e9e85 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -213,16 +213,12 @@ _cairo_clip_intersect_rectangle (cairo_clip_t *clip,
cairo_status_t status;
if (clip->path != NULL) {
- cairo_box_t box;
-
- if (_cairo_path_fixed_is_box (&clip->path->path, &box)) {
- if (box.p1.x >= _cairo_fixed_from_int (rect->x) &&
- box.p1.y >= _cairo_fixed_from_int (rect->y) &&
- box.p2.x <= _cairo_fixed_from_int (rect->x + rect->width) &&
- box.p2.y <= _cairo_fixed_from_int (rect->y + rect->height))
- {
- return CAIRO_STATUS_SUCCESS;
- }
+ if (rect->x <= clip->path->extents.x &&
+ rect->y <= clip->path->extents.y &&
+ rect->x + rect->width >= clip->path->extents.x + clip->path->extents.width &&
+ rect->y + rect->height >= clip->path->extents.y + clip->path->extents.height)
+ {
+ return CAIRO_STATUS_SUCCESS;
}
}
@@ -255,6 +251,7 @@ _cairo_clip_intersect_rectangle (cairo_clip_t *clip,
clip_path->fill_rule = CAIRO_FILL_RULE_WINDING;
clip_path->tolerance = 1;
clip_path->antialias = CAIRO_ANTIALIAS_NONE;
+ clip_path->flags |= CAIRO_CLIP_PATH_IS_BOX;
/* could preallocate the region if it proves worthwhile */
@@ -317,6 +314,8 @@ _cairo_clip_intersect_path (cairo_clip_t *clip,
cairo_clip_path_t *clip_path;
cairo_status_t status;
cairo_rectangle_int_t extents;
+ cairo_box_t box;
+ cairo_bool_t is_box = FALSE;
if (clip->path != NULL) {
if (clip->path->fill_rule == fill_rule &&
@@ -335,23 +334,21 @@ _cairo_clip_intersect_path (cairo_clip_t *clip,
return CAIRO_STATUS_SUCCESS;
}
+ is_box = _cairo_path_fixed_is_box (path, &box);
if (clip->path != NULL) {
- cairo_box_t box;
-
if (! _cairo_rectangle_intersect (&extents, &clip->path->extents)) {
_cairo_clip_set_all_clipped (clip);
return CAIRO_STATUS_SUCCESS;
}
/* does this clip wholly subsume the others? */
- if (_cairo_path_fixed_is_box (path, &box)) {
- if (box.p1.x <= _cairo_fixed_from_int (clip->path->extents.x) &&
- box.p2.x >= _cairo_fixed_from_int (clip->path->extents.x + clip->path->extents.width) &&
- box.p1.y <= _cairo_fixed_from_int (clip->path->extents.y) &&
- box.p2.y >= _cairo_fixed_from_int (clip->path->extents.y + clip->path->extents.height))
- {
- return CAIRO_STATUS_SUCCESS;
- }
+ if (is_box &&
+ box.p1.x <= _cairo_fixed_from_int (clip->path->extents.x) &&
+ box.p2.x >= _cairo_fixed_from_int (clip->path->extents.x + clip->path->extents.width) &&
+ box.p1.y <= _cairo_fixed_from_int (clip->path->extents.y) &&
+ box.p2.y >= _cairo_fixed_from_int (clip->path->extents.y + clip->path->extents.height))
+ {
+ return CAIRO_STATUS_SUCCESS;
}
}
@@ -370,6 +367,8 @@ _cairo_clip_intersect_path (cairo_clip_t *clip,
clip_path->fill_rule = fill_rule;
clip_path->tolerance = tolerance;
clip_path->antialias = antialias;
+ if (is_box)
+ clip_path->flags |= CAIRO_CLIP_PATH_IS_BOX;
return CAIRO_STATUS_SUCCESS;
}
@@ -1126,6 +1125,8 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
status = _combine_region (surface, prev->region, clip_extents);
if (unlikely (status))
goto BAIL;
+ } else if (prev->flags & CAIRO_CLIP_PATH_IS_BOX) {
+ /* a simple box only affects the extents */
} else if (prev->path.is_rectilinear) {
if (need_translate) {
_cairo_path_fixed_translate (&prev->path,
@@ -1281,23 +1282,30 @@ _cairo_clip_combine_with_surface (cairo_clip_t *clip,
return status;
}
- if (need_translate) {
- _cairo_path_fixed_translate (&clip_path->path,
- _cairo_fixed_from_int (-extents->x),
- _cairo_fixed_from_int (-extents->y));
- }
- status = _cairo_surface_fill (dst,
- CAIRO_OPERATOR_IN,
- &pattern.base,
- &clip_path->path,
- clip_path->fill_rule,
- clip_path->tolerance,
- clip_path->antialias,
- NULL);
- if (need_translate) {
- _cairo_path_fixed_translate (&clip_path->path,
- _cairo_fixed_from_int (extents->x),
- _cairo_fixed_from_int (extents->y));
+ if (clip_path->flags & CAIRO_CLIP_PATH_IS_BOX) {
+ cairo_region_t clip_region;
+
+ _cairo_region_init_rectangle (&clip_region, &clip_path->extents);
+ status = _combine_region (dst, &clip_region, extents);
+ } else {
+ if (need_translate) {
+ _cairo_path_fixed_translate (&clip_path->path,
+ _cairo_fixed_from_int (-extents->x),
+ _cairo_fixed_from_int (-extents->y));
+ }
+ status = _cairo_surface_fill (dst,
+ CAIRO_OPERATOR_IN,
+ &pattern.base,
+ &clip_path->path,
+ clip_path->fill_rule,
+ clip_path->tolerance,
+ clip_path->antialias,
+ NULL);
+ if (need_translate) {
+ _cairo_path_fixed_translate (&clip_path->path,
+ _cairo_fixed_from_int (extents->x),
+ _cairo_fixed_from_int (extents->y));
+ }
}
if (unlikely (status))
@@ -1336,7 +1344,7 @@ _cairo_clip_drop_cache (cairo_clip_t *clip)
clip_path->surface = NULL;
}
- clip_path->flags = 0;
+ clip_path->flags &= ~CAIRO_CLIP_PATH_HAS_REGION;
} while ((clip_path = clip_path->prev) != NULL);
}