[cairo-commit] 2 commits - src/cairo-clip.c src/cairo-clip-private.h src/cairo-image-surface.c src/cairo-surface-fallback.c src/cairo-xcb-surface-render.c src/drm test/clip-twice-rectangle.c test/clip-twice-rectangle.ref.png test/Makefile.am test/Makefile.sources
Chris Wilson
ickle at kemper.freedesktop.org
Fri Feb 12 04:24:42 PST 2010
src/cairo-clip-private.h | 6 ++
src/cairo-clip.c | 84 ++++++++++++++++++++++++++++++++++++++
src/cairo-image-surface.c | 74 ++++++++-------------------------
src/cairo-surface-fallback.c | 71 +-------------------------------
src/cairo-xcb-surface-render.c | 78 +++++++++--------------------------
src/drm/cairo-drm-i915-surface.c | 47 +--------------------
src/drm/cairo-drm-i965-surface.c | 47 +--------------------
test/Makefile.am | 1
test/Makefile.sources | 1
test/clip-twice-rectangle.c | 70 +++++++++++++++++++++++++++++++
test/clip-twice-rectangle.ref.png |binary
11 files changed, 209 insertions(+), 270 deletions(-)
New commits:
commit 5390df961f6dff8e25e5aac21062026a81710d88
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Feb 12 12:20:35 2010 +0000
clip: Restrict composite extents to clip extents
Fixes test/clip-rectangle-twice.
diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h
index a3303fe..b9a39ae 100644
--- a/src/cairo-clip-private.h
+++ b/src/cairo-clip-private.h
@@ -128,6 +128,12 @@ _cairo_clip_get_boxes (cairo_clip_t *clip,
cairo_box_t **boxes,
int *count);
+cairo_private cairo_status_t
+_cairo_clip_to_boxes (cairo_clip_t **clip,
+ cairo_composite_rectangles_t *extents,
+ cairo_box_t **boxes,
+ int *num_boxes);
+
cairo_private cairo_bool_t
_cairo_clip_contains_rectangle (cairo_clip_t *clip,
const cairo_composite_rectangles_t *extents);
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index abcf659..fdb9470 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -1335,6 +1335,90 @@ _cairo_clip_get_boxes (cairo_clip_t *clip,
return CAIRO_STATUS_SUCCESS;
}
+static cairo_bool_t
+box_is_aligned (const cairo_box_t *box)
+{
+ return
+ _cairo_fixed_is_integer (box->p1.x) &&
+ _cairo_fixed_is_integer (box->p1.y) &&
+ _cairo_fixed_is_integer (box->p2.x) &&
+ _cairo_fixed_is_integer (box->p2.y);
+}
+
+static void
+intersect_with_boxes (cairo_composite_rectangles_t *extents,
+ cairo_box_t *boxes,
+ int num_boxes)
+{
+ cairo_rectangle_int_t rect;
+ cairo_box_t box;
+ cairo_bool_t is_empty;
+
+ box.p1.x = box.p1.y = INT_MIN;
+ box.p2.x = box.p2.y = INT_MAX;
+ while (num_boxes--) {
+ if (boxes->p1.x < box.p1.x)
+ box.p1.x = boxes->p1.x;
+ if (boxes->p1.y < box.p1.y)
+ box.p1.y = boxes->p1.y;
+
+ if (boxes->p2.x > box.p2.x)
+ box.p2.x = boxes->p2.x;
+ if (boxes->p2.y > box.p2.y)
+ box.p2.y = boxes->p2.y;
+ }
+
+ _cairo_box_round_to_rectangle (&box, &rect);
+ is_empty = _cairo_rectangle_intersect (&extents->bounded, &rect);
+ is_empty = _cairo_rectangle_intersect (&extents->unbounded, &rect);
+}
+
+cairo_status_t
+_cairo_clip_to_boxes (cairo_clip_t **clip,
+ cairo_composite_rectangles_t *extents,
+ cairo_box_t **boxes,
+ int *num_boxes)
+{
+ cairo_status_t status;
+ const cairo_rectangle_int_t *rect;
+
+ rect = extents->is_bounded ? &extents->bounded : &extents->unbounded;
+
+ if (*clip == NULL)
+ goto EXTENTS;
+
+ status = _cairo_clip_rectangle (*clip, rect);
+ if (unlikely (status))
+ return status;
+
+ status = _cairo_clip_get_boxes (*clip, boxes, num_boxes);
+ switch ((int) status) {
+ case CAIRO_STATUS_SUCCESS:
+ intersect_with_boxes (extents, *boxes, *num_boxes);
+ if (rect->width == 0 || rect->height == 0 ||
+ extents->is_bounded ||
+ (*num_boxes == 1 && box_is_aligned (*boxes)))
+ {
+ *clip = NULL;
+ }
+ goto DONE;
+
+ case CAIRO_INT_STATUS_UNSUPPORTED:
+ goto EXTENTS;
+
+ default:
+ return status;
+ }
+
+ EXTENTS:
+ status = CAIRO_STATUS_SUCCESS;
+ _cairo_box_from_rectangle (&(*boxes)[0], rect);
+ *num_boxes = 1;
+ DONE:
+ return status;
+}
+
+
static cairo_rectangle_list_t *
_cairo_rectangle_list_create_in_error (cairo_status_t status)
{
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index d4bff51..76f50f7 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -2017,7 +2017,7 @@ _clip_and_composite (cairo_image_surface_t *dst,
const cairo_pattern_t *src,
image_draw_func_t draw_func,
void *draw_closure,
- const cairo_composite_rectangles_t*extents,
+ cairo_composite_rectangles_t*extents,
cairo_clip_t *clip)
{
cairo_status_t status;
@@ -2025,6 +2025,9 @@ _clip_and_composite (cairo_image_surface_t *dst,
cairo_bool_t need_clip_surface = FALSE;
if (clip != NULL) {
+ cairo_rectangle_int_t rect;
+ cairo_bool_t is_empty;
+
status = _cairo_clip_get_region (clip, &clip_region);
if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
return CAIRO_STATUS_SUCCESS;
@@ -2032,6 +2035,15 @@ _clip_and_composite (cairo_image_surface_t *dst,
assert (! _cairo_status_is_error (status));
need_clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED;
+ cairo_region_get_extents (clip_region, &rect);
+ is_empty = ! _cairo_rectangle_intersect (&extents->unbounded, &rect);
+ if (unlikely (is_empty))
+ return CAIRO_STATUS_SUCCESS;
+
+ is_empty = ! _cairo_rectangle_intersect (&extents->bounded, &rect);
+ if (unlikely (is_empty && extents->is_bounded))
+ return CAIRO_STATUS_SUCCESS;
+
if (clip_region != NULL && cairo_region_num_rectangles (clip_region) == 1)
clip_region = NULL;
}
@@ -2781,7 +2793,7 @@ _clip_and_composite_boxes (cairo_image_surface_t *dst,
const cairo_pattern_t *src,
cairo_boxes_t *boxes,
cairo_antialias_t antialias,
- const cairo_composite_rectangles_t *extents,
+ cairo_composite_rectangles_t *extents,
cairo_clip_t *clip)
{
cairo_traps_t traps;
@@ -2886,7 +2898,7 @@ _clip_and_composite_trapezoids (cairo_image_surface_t *dst,
const cairo_pattern_t *src,
cairo_traps_t *traps,
cairo_antialias_t antialias,
- const cairo_composite_rectangles_t *extents,
+ cairo_composite_rectangles_t *extents,
cairo_clip_t *clip)
{
composite_traps_info_t info;
@@ -2942,56 +2954,6 @@ _clip_and_composite_trapezoids (cairo_image_surface_t *dst,
extents, clip);
}
-static cairo_bool_t
-box_is_aligned (const cairo_box_t *box)
-{
- return
- _cairo_fixed_is_integer (box->p1.x) &&
- _cairo_fixed_is_integer (box->p1.y) &&
- _cairo_fixed_is_integer (box->p2.x) &&
- _cairo_fixed_is_integer (box->p2.y);
-}
-
-static inline cairo_status_t
-_clip_to_boxes (cairo_clip_t **clip,
- const cairo_composite_rectangles_t *extents,
- cairo_box_t **boxes,
- int *num_boxes)
-{
- cairo_status_t status;
- const cairo_rectangle_int_t *rect;
-
- rect = extents->is_bounded ? &extents->bounded : &extents->unbounded;
-
- if (*clip == NULL)
- goto EXTENTS;
-
- status = _cairo_clip_rectangle (*clip, rect);
- if (unlikely (status))
- return status;
-
- status = _cairo_clip_get_boxes (*clip, boxes, num_boxes);
- switch ((int) status) {
- case CAIRO_STATUS_SUCCESS:
- if (extents->is_bounded || (*num_boxes == 1 && box_is_aligned (*boxes)))
- *clip = NULL;
- goto DONE;
-
- case CAIRO_INT_STATUS_UNSUPPORTED:
- goto EXTENTS;
-
- default:
- return status;
- }
-
- EXTENTS:
- status = CAIRO_STATUS_SUCCESS;
- _cairo_box_from_rectangle (&(*boxes)[0], rect);
- *num_boxes = 1;
- DONE:
- return status;
-}
-
static cairo_clip_path_t *
_clip_get_single_path (cairo_clip_t *clip)
{
@@ -3044,7 +3006,7 @@ _cairo_image_surface_paint (void *abstract_surface,
have_clip = TRUE;
}
- status = _clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
+ status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status)) {
if (have_clip)
_cairo_clip_fini (&local_clip);
@@ -3396,7 +3358,7 @@ _cairo_image_surface_stroke (void *abstract_surface,
have_clip = TRUE;
}
- status = _clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
+ status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status)) {
if (have_clip)
_cairo_clip_fini (&local_clip);
@@ -3497,7 +3459,7 @@ _cairo_image_surface_fill (void *abstract_surface,
have_clip = TRUE;
}
- status = _clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
+ status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status)) {
if (have_clip)
_cairo_clip_fini (&local_clip);
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index 9047787..232e15e 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -139,9 +139,6 @@ _create_composite_mask_pattern (cairo_surface_pattern_t *mask_pattern,
assert (status != CAIRO_INT_STATUS_NOTHING_TO_DO);
clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED;
-
- if (clip_region && cairo_region_num_rectangles (clip_region) == 1)
- clip_region = NULL;
}
/* We need to use solid here, because to use CAIRO_OPERATOR_SOURCE with
@@ -337,10 +334,6 @@ _clip_and_composite_source (cairo_clip_t *clip,
assert (! _cairo_status_is_error (status));
if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
return CAIRO_STATUS_SUCCESS;
-
- /* a solitary clip rectangle is already accommodated by extents */
- if (clip_region && cairo_region_num_rectangles (clip_region) == 1)
- clip_region = NULL;
}
@@ -456,10 +449,6 @@ _clip_and_composite (cairo_clip_t *clip,
dst, extents);
}
} else {
- /* a solitary clip rectangle is already accommodated by extents */
- if (clip_region && cairo_region_num_rectangles (clip_region) == 1)
- clip_region = NULL;
-
status = draw_func (draw_closure, op,
src, dst,
0, 0,
@@ -506,10 +495,6 @@ _composite_trap_region (cairo_clip_t *clip,
mask = &mask_pattern.base;
}
- /* reduce a solitary clipping region to the extents */
- if (cairo_region_num_rectangles (trap_region) == 1)
- trap_region = NULL;
-
status = _cairo_surface_composite (op, src, mask, dst,
extents->x, extents->y,
mask_x, mask_y,
@@ -892,56 +877,6 @@ _composite_spans_draw_func (void *closure,
clip_region);
}
-static cairo_bool_t
-box_is_aligned (const cairo_box_t *box)
-{
- return
- _cairo_fixed_is_integer (box->p1.x) &&
- _cairo_fixed_is_integer (box->p1.y) &&
- _cairo_fixed_is_integer (box->p2.x) &&
- _cairo_fixed_is_integer (box->p2.y);
-}
-
-static inline cairo_status_t
-_clip_to_boxes (cairo_clip_t **clip,
- const cairo_composite_rectangles_t *extents,
- cairo_box_t **boxes,
- int *num_boxes)
-{
- cairo_status_t status;
- const cairo_rectangle_int_t *rect;
-
- rect = extents->is_bounded ? &extents->bounded : &extents->unbounded;
-
- if (*clip == NULL)
- goto EXTENTS;
-
- status = _cairo_clip_rectangle (*clip, rect);
- if (unlikely (status))
- return status;
-
- status = _cairo_clip_get_boxes (*clip, boxes, num_boxes);
- switch ((int) status) {
- case CAIRO_STATUS_SUCCESS:
- if (extents->is_bounded || (*num_boxes == 1 && box_is_aligned (*boxes)))
- *clip = NULL;
- goto DONE;
-
- case CAIRO_INT_STATUS_UNSUPPORTED:
- goto EXTENTS;
-
- default:
- return status;
- }
-
- EXTENTS:
- status = CAIRO_STATUS_SUCCESS;
- _cairo_box_from_rectangle (&(*boxes)[0], rect);
- *num_boxes = 1;
- DONE:
- return status;
-}
-
cairo_status_t
_cairo_surface_fallback_paint (cairo_surface_t *surface,
cairo_operator_t op,
@@ -971,7 +906,7 @@ _cairo_surface_fallback_paint (cairo_surface_t *surface,
if (_cairo_clip_contains_rectangle (clip, &extents))
clip = NULL;
- status = _clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
+ status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status))
return status;
@@ -1110,7 +1045,7 @@ _cairo_surface_fallback_stroke (cairo_surface_t *surface,
if (_cairo_clip_contains_rectangle (clip, &extents))
clip = NULL;
- status = _clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
+ status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status))
return status;
@@ -1215,7 +1150,7 @@ _cairo_surface_fallback_fill (cairo_surface_t *surface,
if (_cairo_clip_contains_rectangle (clip, &extents))
clip = NULL;
- status = _clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
+ status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status))
return status;
diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c
index 5d19792..9122d64 100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -2344,7 +2344,7 @@ _clip_and_composite (cairo_xcb_surface_t *dst,
const cairo_pattern_t *src,
xcb_draw_func_t draw_func,
void *draw_closure,
- const cairo_composite_rectangles_t*extents,
+ cairo_composite_rectangles_t*extents,
cairo_clip_t *clip)
{
cairo_status_t status;
@@ -2352,6 +2352,9 @@ _clip_and_composite (cairo_xcb_surface_t *dst,
cairo_bool_t need_clip_surface = FALSE;
if (clip != NULL) {
+ cairo_rectangle_int_t rect;
+ cairo_bool_t is_empty;
+
status = _cairo_clip_get_region (clip, &clip_region);
if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
return CAIRO_STATUS_SUCCESS;
@@ -2359,6 +2362,15 @@ _clip_and_composite (cairo_xcb_surface_t *dst,
assert (! _cairo_status_is_error (status));
need_clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED;
+ cairo_region_get_extents (clip_region, &rect);
+ is_empty = ! _cairo_rectangle_intersect (&extents->unbounded, &rect);
+ if (unlikely (is_empty))
+ return CAIRO_STATUS_SUCCESS;
+
+ is_empty = ! _cairo_rectangle_intersect (&extents->bounded, &rect);
+ if (unlikely (is_empty && extents->is_bounded))
+ return CAIRO_STATUS_SUCCESS;
+
if (clip_region != NULL && cairo_region_num_rectangles (clip_region) == 1)
clip_region = NULL;
}
@@ -2574,7 +2586,7 @@ _clip_and_composite_boxes (cairo_xcb_surface_t *dst,
const cairo_pattern_t *src,
cairo_boxes_t *boxes,
cairo_antialias_t antialias,
- const cairo_composite_rectangles_t *extents,
+ cairo_composite_rectangles_t *extents,
cairo_clip_t *clip)
{
composite_traps_info_t info;
@@ -2855,56 +2867,6 @@ _composite_mask (void *closure,
/* high level rasteriser -> compositor */
-static cairo_bool_t
-box_is_aligned (const cairo_box_t *box)
-{
- return
- _cairo_fixed_is_integer (box->p1.x) &&
- _cairo_fixed_is_integer (box->p1.y) &&
- _cairo_fixed_is_integer (box->p2.x) &&
- _cairo_fixed_is_integer (box->p2.y);
-}
-
-static inline cairo_status_t
-_clip_to_boxes (cairo_clip_t **clip,
- const cairo_composite_rectangles_t *extents,
- cairo_box_t **boxes,
- int *num_boxes)
-{
- cairo_status_t status;
- const cairo_rectangle_int_t *rect;
-
- rect = extents->is_bounded ? &extents->bounded: &extents->unbounded;
-
- if (*clip == NULL)
- goto EXTENTS;
-
- status = _cairo_clip_rectangle (*clip, rect);
- if (unlikely (status))
- return status;
-
- status = _cairo_clip_get_boxes (*clip, boxes, num_boxes);
- switch ((int) status) {
- case CAIRO_STATUS_SUCCESS:
- if (extents->is_bounded || (*num_boxes == 1 && box_is_aligned (*boxes)))
- *clip = NULL;
- goto DONE;
-
- case CAIRO_INT_STATUS_UNSUPPORTED:
- goto EXTENTS;
-
- default:
- return status;
- }
-
- EXTENTS:
- status = CAIRO_STATUS_SUCCESS;
- _cairo_box_from_rectangle (&(*boxes)[0], rect);
- *num_boxes = 1;
- DONE:
- return status;
-}
-
static cairo_clip_path_t *
_clip_get_single_path (cairo_clip_t *clip)
{
@@ -2965,7 +2927,7 @@ _cairo_xcb_surface_render_paint (cairo_xcb_surface_t *surface,
have_clip = TRUE;
}
- status = _clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
+ status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status)) {
if (have_clip)
_cairo_clip_fini (&local_clip);
@@ -3231,7 +3193,7 @@ _cairo_xcb_surface_render_stroke_via_mask (cairo_xcb_surface_t *dst,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip,
- const cairo_composite_rectangles_t *extents)
+ cairo_composite_rectangles_t *extents)
{
cairo_surface_t *image;
cairo_status_t status;
@@ -3319,7 +3281,7 @@ _cairo_xcb_surface_render_stroke (cairo_xcb_surface_t *surface,
have_clip = TRUE;
}
- status = _clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
+ status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status)) {
if (have_clip)
_cairo_clip_fini (&local_clip);
@@ -3417,7 +3379,7 @@ _cairo_xcb_surface_render_fill_via_mask (cairo_xcb_surface_t *dst,
double tolerance,
cairo_antialias_t antialias,
cairo_clip_t *clip,
- const cairo_composite_rectangles_t *extents)
+ cairo_composite_rectangles_t *extents)
{
cairo_surface_t *image;
cairo_status_t status;
@@ -3502,7 +3464,7 @@ _cairo_xcb_surface_render_fill (cairo_xcb_surface_t *surface,
have_clip = TRUE;
}
- status = _clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
+ status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status)) {
if (have_clip)
_cairo_clip_fini (&local_clip);
@@ -3562,7 +3524,7 @@ _cairo_xcb_surface_render_glyphs_via_mask (cairo_xcb_surface_t *dst,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_clip_t *clip,
- const cairo_composite_rectangles_t *extents)
+ cairo_composite_rectangles_t *extents)
{
cairo_surface_t *image;
cairo_content_t content;
diff --git a/src/drm/cairo-drm-i915-surface.c b/src/drm/cairo-drm-i915-surface.c
index d3c3940..3872832 100644
--- a/src/drm/cairo-drm-i915-surface.c
+++ b/src/drm/cairo-drm-i915-surface.c
@@ -910,47 +910,6 @@ _clip_and_composite_boxes (i915_surface_t *dst,
extents, clip);
}
-static cairo_bool_t
-box_is_aligned (const cairo_box_t *box)
-{
- return
- _cairo_fixed_is_integer (box->p1.x) &&
- _cairo_fixed_is_integer (box->p1.y) &&
- _cairo_fixed_is_integer (box->p2.x) &&
- _cairo_fixed_is_integer (box->p2.y);
-}
-
-static inline cairo_status_t
-_clip_to_boxes (cairo_clip_t **clip,
- const cairo_composite_rectangles_t *extents,
- cairo_box_t **boxes,
- int *num_boxes)
-{
- cairo_status_t status;
- const cairo_rectangle_int_t *rect;
-
- rect = extents->is_bounded ? &extents->bounded: &extents->unbounded;
-
- if (*clip == NULL)
- goto EXTENTS;
-
- status = _cairo_clip_rectangle (*clip, rect);
- if (unlikely (status))
- return status;
-
- status = _cairo_clip_get_boxes (*clip, boxes, num_boxes);
- if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
- if (extents->is_bounded || (*num_boxes == 1 && box_is_aligned (*boxes)))
- *clip = NULL;
- return status;
- }
-
- EXTENTS:
- _cairo_box_from_rectangle (&(*boxes)[0], rect);
- *num_boxes = 1;
- return CAIRO_STATUS_SUCCESS;
-}
-
static cairo_clip_path_t *
_clip_get_solitary_path (cairo_clip_t *clip)
{
@@ -1004,7 +963,7 @@ i915_surface_paint (void *abstract_dst,
have_clip = TRUE;
}
- status = _clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
+ status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status)) {
if (have_clip)
_cairo_clip_fini (&local_clip);
@@ -1211,7 +1170,7 @@ i915_surface_stroke (void *abstract_dst,
have_clip = TRUE;
}
- status = _clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
+ status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status)) {
if (have_clip)
_cairo_clip_fini (&local_clip);
@@ -1320,7 +1279,7 @@ i915_surface_fill (void *abstract_dst,
have_clip = TRUE;
}
- status = _clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
+ status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status)) {
if (have_clip)
_cairo_clip_fini (&local_clip);
diff --git a/src/drm/cairo-drm-i965-surface.c b/src/drm/cairo-drm-i965-surface.c
index e1bdf5f..10331dd 100644
--- a/src/drm/cairo-drm-i965-surface.c
+++ b/src/drm/cairo-drm-i965-surface.c
@@ -1071,47 +1071,6 @@ _clip_and_composite_boxes (i965_surface_t *dst,
extents, clip);
}
-static cairo_bool_t
-box_is_aligned (const cairo_box_t *box)
-{
- return
- _cairo_fixed_is_integer (box->p1.x) &&
- _cairo_fixed_is_integer (box->p1.y) &&
- _cairo_fixed_is_integer (box->p2.x) &&
- _cairo_fixed_is_integer (box->p2.y);
-}
-
-static inline cairo_status_t
-_clip_to_boxes (cairo_clip_t **clip,
- const cairo_composite_rectangles_t *extents,
- cairo_box_t **boxes,
- int *num_boxes)
-{
- cairo_status_t status;
- const cairo_rectangle_int_t *rect;
-
- rect = extents->is_bounded ? &extents->bounded: &extents->unbounded;
-
- if (*clip == NULL)
- goto EXTENTS;
-
- status = _cairo_clip_rectangle (*clip, rect);
- if (unlikely (status))
- return status;
-
- status = _cairo_clip_get_boxes (*clip, boxes, num_boxes);
- if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
- if (extents->is_bounded || (*num_boxes == 1 && box_is_aligned (*boxes)))
- *clip = NULL;
- return status;
- }
-
- EXTENTS:
- _cairo_box_from_rectangle (&(*boxes)[0], rect);
- *num_boxes = 1;
- return CAIRO_STATUS_SUCCESS;
-}
-
static cairo_int_status_t
i965_surface_paint (void *abstract_dst,
cairo_operator_t op,
@@ -1145,7 +1104,7 @@ i965_surface_paint (void *abstract_dst,
have_clip = TRUE;
}
- status = _clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
+ status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status)) {
if (have_clip)
_cairo_clip_fini (&local_clip);
@@ -1333,7 +1292,7 @@ i965_surface_stroke (void *abstract_dst,
have_clip = TRUE;
}
- status = _clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
+ status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status)) {
if (have_clip)
_cairo_clip_fini (&local_clip);
@@ -1440,7 +1399,7 @@ i965_surface_fill (void *abstract_dst,
have_clip = TRUE;
}
- status = _clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
+ status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
if (unlikely (status)) {
if (have_clip)
_cairo_clip_fini (&local_clip);
commit 51047483f462a905567b42275ae061ead4df0a07
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Feb 12 12:18:30 2010 +0000
test: Add clip-twice-rectangle
Jeff Muizeelar found another bug with clipping whereby the clip was
been incorrectly discarded.
diff --git a/test/Makefile.am b/test/Makefile.am
index 10e322a..a2cfb7d 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -265,6 +265,7 @@ REFERENCE_IMAGES = \
clip-twice.test-paginated.rgb24.ref.png \
clip-twice.xlib.ref.png \
clip-twice.xlib.rgb24.ref.png \
+ clip-twice-rectangle.ref.png \
clipped-group.pdf.ref.png \
clipped-group.ps2.ref.png \
clipped-group.ps3.ref.png \
diff --git a/test/Makefile.sources b/test/Makefile.sources
index a8aa0e9..87c25a0 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -33,6 +33,7 @@ test_sources = \
clip-stroke-unbounded.c \
clip-text.c \
clip-twice.c \
+ clip-twice-rectangle.c \
clip-unbounded.c \
clip-zero.c \
clipped-group.c \
diff --git a/test/clip-twice-rectangle.c b/test/clip-twice-rectangle.c
new file mode 100644
index 0000000..28f16ec
--- /dev/null
+++ b/test/clip-twice-rectangle.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright © 2010 Mozilla Corporation
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+ cairo_surface_t *mask;
+ cairo_t *cr2;
+
+ cairo_set_source_rgb (cr, 0, 1, 0);
+ cairo_paint (cr);
+
+ /* clip twice, note that the intersection is smaller then the extents */
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_rectangle (cr, 10, 10, 80, 80);
+ cairo_rectangle (cr, 20, 20, 60, 60);
+ cairo_clip (cr);
+
+ cairo_rectangle (cr, 0, 40, 40, 30);
+ cairo_clip (cr);
+
+ /* and exercise the bug found by Jeff Muizelaar */
+ mask = cairo_surface_create_similar (cairo_get_target (cr),
+ CAIRO_CONTENT_ALPHA,
+ width-20, height-20);
+ cr2 = cairo_create (mask);
+ cairo_surface_destroy (mask);
+
+ cairo_set_source_rgba (cr2, 1, 1, 1, 1);
+ cairo_paint (cr2);
+
+ cairo_set_source_rgb (cr, 1, 0, 0);
+ cairo_mask_surface (cr, cairo_get_target (cr2), 0, 0);
+ cairo_destroy (cr2);
+
+ return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_twice_rectangle,
+ "Tests clipping twice using rectangles",
+ "clip", /* keywords */
+ NULL, /* requirements */
+ 100, 100,
+ NULL, draw)
diff --git a/test/clip-twice-rectangle.ref.png b/test/clip-twice-rectangle.ref.png
new file mode 100644
index 0000000..d0e65ea
Binary files /dev/null and b/test/clip-twice-rectangle.ref.png differ
More information about the cairo-commit
mailing list