[cairo-commit] 3 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-shape.c test/clip-shape.ps.ref.png test/clip-shape.ref.png test/clip-shape.xlib-fallback.ref.png test/clip-shape.xlib.ref.png test/Makefile.am test/Makefile.sources

Chris Wilson ickle at kemper.freedesktop.org
Sun Apr 25 01:48:55 PDT 2010


 src/cairo-clip-private.h              |    2 
 src/cairo-clip.c                      |   50 ++++++++-----------
 src/cairo-image-surface.c             |   39 ++++++++-------
 src/cairo-surface-fallback.c          |   20 +++----
 src/cairo-xcb-surface-render.c        |   31 +++++-------
 src/drm/cairo-drm-i915-shader.c       |    9 +--
 src/drm/cairo-drm-i965-shader.c       |    7 +-
 test/Makefile.am                      |    4 +
 test/Makefile.sources                 |    1 
 test/clip-shape.c                     |   86 ++++++++++++++++++++++++++++++++++
 test/clip-shape.ps.ref.png            |binary
 test/clip-shape.ref.png               |binary
 test/clip-shape.xlib-fallback.ref.png |binary
 test/clip-shape.xlib.ref.png          |binary
 14 files changed, 168 insertions(+), 81 deletions(-)

New commits:
commit 240ebaf81a42c24c4d4267879c5ef8102e97017e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 25 09:44:18 2010 +0100

    clip: Fix sign reverse when combining with the clip surface.
    
    Finally, found the reversed sign in the clipping code, thanks cu!
    
    Fixes: test/clip-shape

diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index ff4aeb6..6b9ffd2 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -1190,26 +1190,6 @@ _cairo_clip_combine_with_surface (cairo_clip_t *clip,
 
     assert (clip_path != NULL);
 
-    if (clip_path->surface != NULL &&
-	clip_path->surface->backend == dst->backend)
-    {
-	cairo_surface_pattern_t pattern;
-
-	_cairo_pattern_init_for_surface (&pattern, clip_path->surface);
-	pattern.base.filter = CAIRO_FILTER_NEAREST;
-	cairo_matrix_init_translate (&pattern.base.matrix,
-				     -dst_x + clip_path->extents.x,
-				     -dst_y + clip_path->extents.y);
-	status = _cairo_surface_paint (dst,
-				       CAIRO_OPERATOR_IN,
-				       &pattern.base,
-				       NULL);
-
-	_cairo_pattern_fini (&pattern.base);
-
-	return status;
-    }
-
     need_translate = dst_x | dst_y;
     do {
 	if (clip_path->surface != NULL &&
@@ -1219,8 +1199,8 @@ _cairo_clip_combine_with_surface (cairo_clip_t *clip,
 
 	    _cairo_pattern_init_for_surface (&pattern, clip_path->surface);
 	    cairo_matrix_init_translate (&pattern.base.matrix,
-					 -dst_x + clip_path->extents.x,
-					 -dst_y + clip_path->extents.y);
+					 dst_x - clip_path->extents.x,
+					 dst_y - clip_path->extents.y);
 	    pattern.base.filter = CAIRO_FILTER_NEAREST;
 	    status = _cairo_surface_paint (dst,
 					   CAIRO_OPERATOR_IN,
commit 4d3632761b928c14fb1ce257af077f45658d8537
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 25 09:42:13 2010 +0100

    clip: Report the surface offset when retrieving the clip mask
    
    Stop the callers from guessing the origin of the clip surface by
    reporting it explicitly! This enables the clip to bypass any rectangles
    overlaid on top of the clip surface, which is common when the backends
    limit the clip to the extents of the operation -- but irrelevant to the
    actual content of the clip mask

diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h
index 815fbf8..8e30f13 100644
--- a/src/cairo-clip-private.h
+++ b/src/cairo-clip-private.h
@@ -112,7 +112,7 @@ cairo_private const cairo_rectangle_int_t *
 _cairo_clip_get_extents (const cairo_clip_t *clip);
 
 cairo_private cairo_surface_t *
-_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *dst);
+_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *dst, int *tx, int *ty);
 
 cairo_private cairo_status_t
 _cairo_clip_combine_with_surface (cairo_clip_t *clip,
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index fca4759..ff4aeb6 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -942,7 +942,8 @@ _cairo_clip_path_to_boxes (cairo_clip_path_t *clip_path,
 
 static cairo_surface_t *
 _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
-			      cairo_surface_t *target)
+			      cairo_surface_t *target,
+			      int *tx, int *ty)
 {
     const cairo_rectangle_int_t *clip_extents = &clip_path->extents;
     cairo_bool_t need_translate;
@@ -950,9 +951,19 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
     cairo_clip_path_t *prev;
     cairo_status_t status;
 
+    while (clip_path->prev != NULL &&
+	   clip_path->flags & CAIRO_CLIP_PATH_IS_BOX &&
+	   clip_path->path.maybe_fill_region)
+    {
+	clip_path = clip_path->prev;
+    }
+
+    clip_extents = &clip_path->extents;
     if (clip_path->surface != NULL &&
 	clip_path->surface->backend == target->backend)
     {
+	*tx = clip_extents->x;
+	*ty = clip_extents->y;
 	return clip_path->surface;
     }
 
@@ -1046,16 +1057,17 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
 	{
 	    cairo_surface_pattern_t pattern;
 	    cairo_surface_t *prev_surface;
+	    int prev_tx, prev_ty;
 
-	    prev_surface = _cairo_clip_path_get_surface (prev, target);
+	    prev_surface = _cairo_clip_path_get_surface (prev, target, &prev_tx, &prev_ty);
 	    if (unlikely (prev_surface->status))
 		goto BAIL;
 
 	    _cairo_pattern_init_for_surface (&pattern, prev_surface);
 	    pattern.base.filter = CAIRO_FILTER_NEAREST;
 	    cairo_matrix_init_translate (&pattern.base.matrix,
-					 clip_extents->x - prev->extents.x,
-					 clip_extents->y - prev->extents.y);
+					 clip_extents->x - prev_tx,
+					 clip_extents->y - prev_ty);
 	    status = _cairo_surface_paint (surface,
 					   CAIRO_OPERATOR_IN,
 					   &pattern.base,
@@ -1071,6 +1083,8 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
 	prev = prev->prev;
     }
 
+    *tx = clip_extents->x;
+    *ty = clip_extents->y;
     cairo_surface_destroy (clip_path->surface);
     return clip_path->surface = surface;
 
@@ -1158,11 +1172,11 @@ _cairo_debug_print_clip (FILE *stream, cairo_clip_t *clip)
 }
 
 cairo_surface_t *
-_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *target)
+_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *target, int *tx, int *ty)
 {
     /* XXX is_clear -> all_clipped */
     assert (clip->path != NULL);
-    return _cairo_clip_path_get_surface (clip->path, target);
+    return _cairo_clip_path_get_surface (clip->path, target, tx, ty);
 }
 
 cairo_status_t
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 7538826..3695818 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -1481,13 +1481,14 @@ _cairo_image_surface_fixup_unbounded (cairo_image_surface_t *dst,
 
     if (clip != NULL) {
 	cairo_surface_t *clip_surface;
+	int clip_x, clip_y;
 
-	clip_surface = _cairo_clip_get_surface (clip, &dst->base);
+	clip_surface = _cairo_clip_get_surface (clip, &dst->base, &clip_x, &clip_y);
 	assert (clip_surface->status == CAIRO_STATUS_SUCCESS);
 
 	mask = ((cairo_image_surface_t *) clip_surface)->pixman_image;
-	mask_x = -clip->path->extents.x;
-	mask_y = -clip->path->extents.y;
+	mask_x = -clip_x;
+	mask_y = -clip_y;
     } else {
 	if (rects->bounded.width  == rects->unbounded.width &&
 	    rects->bounded.height == rects->unbounded.height)
@@ -1852,6 +1853,7 @@ _clip_and_composite_combine (cairo_clip_t                  *clip,
 {
     pixman_image_t *tmp;
     cairo_surface_t *clip_surface;
+    int clip_x, clip_y;
     cairo_status_t status;
 
     tmp  = pixman_image_create_bits (dst->pixman_format,
@@ -1887,7 +1889,7 @@ _clip_and_composite_combine (cairo_clip_t                  *clip,
 	goto CLEANUP_SURFACE;
 
     assert (clip->path != NULL);
-    clip_surface = _cairo_clip_get_surface (clip, &dst->base);
+    clip_surface = _cairo_clip_get_surface (clip, &dst->base, &clip_x, &clip_y);
     if (unlikely (clip_surface->status))
 	goto CLEANUP_SURFACE;
 
@@ -1898,8 +1900,8 @@ _clip_and_composite_combine (cairo_clip_t                  *clip,
                                   ((cairo_image_surface_t *) clip_surface)->pixman_image,
                                   dst->pixman_image,
                                   0, 0,
-                                  extents->x - clip->path->extents.x,
-                                  extents->y - clip->path->extents.y,
+                                  extents->x - clip_x,
+                                  extents->y - clip_y,
                                   extents->x, extents->y,
                                   extents->width, extents->height);
 #else
@@ -1907,8 +1909,8 @@ _clip_and_composite_combine (cairo_clip_t                  *clip,
 	pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE,
                                   ((cairo_image_surface_t *) clip_surface)->pixman_image,
                                   NULL, dst->pixman_image,
-                                  extents->x - clip->path->extents.x,
-                                  extents->y - clip->path->extents.y,
+                                  extents->x - clip_x,
+                                  extents->y - clip_y,
                                   0, 0,
                                   extents->x, extents->y,
                                   extents->width, extents->height);
@@ -1919,8 +1921,8 @@ _clip_and_composite_combine (cairo_clip_t                  *clip,
                                   ((cairo_image_surface_t *) clip_surface)->pixman_image,
                                   dst->pixman_image,
                                   0, 0,
-                                  extents->x - clip->path->extents.x,
-                                  extents->y - clip->path->extents.y,
+                                  extents->x - clip_x,
+                                  extents->y - clip_y,
                                   extents->x, extents->y,
                                   extents->width, extents->height);
 #endif
@@ -1930,8 +1932,8 @@ _clip_and_composite_combine (cairo_clip_t                  *clip,
                                   ((cairo_image_surface_t *) clip_surface)->pixman_image,
                                   dst->pixman_image,
                                   0, 0,
-                                  extents->x - clip->path->extents.x,
-                                  extents->y - clip->path->extents.y,
+                                  extents->x - clip_x,
+                                  extents->y - clip_y,
                                   extents->x, extents->y,
                                   extents->width, extents->height);
     }
@@ -2741,13 +2743,14 @@ _composite_boxes (cairo_image_surface_t *dst,
 
 	if (need_clip_mask) {
 	    cairo_surface_t *clip_surface;
+	    int clip_x, clip_y;
 
-	    clip_surface = _cairo_clip_get_surface (clip, &dst->base);
+	    clip_surface = _cairo_clip_get_surface (clip, &dst->base, &clip_x, &clip_y);
 	    if (unlikely (clip_surface->status))
 		return clip_surface->status;
 
-	    mask_x = -clip->path->extents.x;
-	    mask_y = -clip->path->extents.y;
+	    mask_x = -clip_x;
+	    mask_y = -clip_y;
 
 	    if (op == CAIRO_OPERATOR_CLEAR) {
 		pattern = NULL;
@@ -2831,9 +2834,9 @@ _clip_and_composite_boxes (cairo_image_surface_t *dst,
     info.num_traps = traps.num_traps;
     info.traps = traps.traps;
     info.antialias = antialias;
-    status =  _clip_and_composite (dst, op, src,
-				   _composite_traps, &info,
-				   extents, clip);
+    status = _clip_and_composite (dst, op, src,
+				  _composite_traps, &info,
+				  extents, clip);
 
     _cairo_traps_fini (&traps);
     return status;
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index 7a69322..f2b017a 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -222,6 +222,7 @@ _clip_and_composite_combine (cairo_clip_t                  *clip,
     cairo_surface_pattern_t pattern;
     cairo_surface_pattern_t clip_pattern;
     cairo_surface_t *clip_surface;
+    int clip_x, clip_y;
     cairo_status_t status;
 
     /* We'd be better off here creating a surface identical in format
@@ -266,7 +267,7 @@ _clip_and_composite_combine (cairo_clip_t                  *clip,
 	goto CLEANUP_SURFACE;
 
     assert (clip->path != NULL);
-    clip_surface = _cairo_clip_get_surface (clip, dst);
+    clip_surface = _cairo_clip_get_surface (clip, dst, &clip_x, &clip_y);
     if (unlikely (clip_surface->status))
 	goto CLEANUP_SURFACE;
 
@@ -275,8 +276,8 @@ _clip_and_composite_combine (cairo_clip_t                  *clip,
     /* Combine that with the clip */
     status = _cairo_surface_composite (CAIRO_OPERATOR_DEST_IN,
 				       &clip_pattern.base, NULL, intermediate,
-				       extents->x - clip->path->extents.x,
-				       extents->y - clip->path->extents.y,
+				       extents->x - clip_x,
+				       extents->y - clip_y,
 				       0, 0,
 				       0, 0,
 				       extents->width, extents->height,
@@ -287,8 +288,8 @@ _clip_and_composite_combine (cairo_clip_t                  *clip,
     /* Punch the clip out of the destination */
     status = _cairo_surface_composite (CAIRO_OPERATOR_DEST_OUT,
 				       &clip_pattern.base, NULL, dst,
-				       extents->x - clip->path->extents.x,
-				       extents->y - clip->path->extents.y,
+				       extents->x - clip_x,
+				       extents->y - clip_y,
 				       0, 0,
 				       extents->x, extents->y,
 				       extents->width, extents->height,
@@ -477,9 +478,9 @@ _composite_trap_region (cairo_clip_t            *clip,
 
     if (clip != NULL) {
 	cairo_surface_t *clip_surface = NULL;
-	const cairo_rectangle_int_t *clip_extents;
+	int clip_x, clip_y;
 
-	clip_surface = _cairo_clip_get_surface (clip, dst);
+	clip_surface = _cairo_clip_get_surface (clip, dst, &clip_x, &clip_y);
 	if (unlikely (clip_surface->status))
 	    return clip_surface->status;
 
@@ -489,9 +490,8 @@ _composite_trap_region (cairo_clip_t            *clip,
 	}
 
 	_cairo_pattern_init_for_surface (&mask_pattern, clip_surface);
-	clip_extents = _cairo_clip_get_extents (clip);
-	mask_x = extents->x - clip_extents->x;
-	mask_y = extents->y - clip_extents->y;
+	mask_x = extents->x - clip_x;
+	mask_y = extents->y - clip_y;
 	mask = &mask_pattern.base;
     }
 
diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c
index 9cd51f8..5775a9e 100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -1894,6 +1894,7 @@ _clip_and_composite_combine (cairo_clip_t		*clip,
 {
     cairo_xcb_surface_t *tmp;
     cairo_surface_t *clip_surface;
+    int clip_x, clip_y;
     xcb_render_picture_t clip_picture;
     cairo_status_t status;
 
@@ -1952,7 +1953,7 @@ _clip_and_composite_combine (cairo_clip_t		*clip,
     if (unlikely (status))
 	goto CLEANUP_SURFACE;
 
-    clip_surface = _cairo_clip_get_surface (clip, &dst->base);
+    clip_surface = _cairo_clip_get_surface (clip, &dst->base, &clip_x, &clip_y);
     if (unlikely (clip_surface->status))
 	goto CLEANUP_SURFACE;
 
@@ -1972,8 +1973,8 @@ _clip_and_composite_combine (cairo_clip_t		*clip,
 	_cairo_xcb_connection_render_composite (dst->connection,
 						XCB_RENDER_PICT_OP_OUT_REVERSE,
 						clip_picture, XCB_NONE, dst->picture,
-						extents->x - clip->path->extents.x,
-						extents->y - clip->path->extents.y,
+						extents->x - clip_x,
+						extents->y - clip_y,
 						0, 0,
 						extents->x,     extents->y,
 						extents->width, extents->height);
@@ -1983,8 +1984,8 @@ _clip_and_composite_combine (cairo_clip_t		*clip,
 						XCB_RENDER_PICT_OP_ADD,
 						tmp->picture, clip_picture, dst->picture,
 						0, 0,
-						extents->x - clip->path->extents.x,
-						extents->y - clip->path->extents.y,
+						extents->x - clip_x,
+						extents->y - clip_y,
 						extents->x,     extents->y,
 						extents->width, extents->height);
     }
@@ -2182,13 +2183,10 @@ _cairo_xcb_surface_fixup_unbounded_with_mask (cairo_xcb_surface_t *dst,
     cairo_xcb_surface_t *mask;
     int mask_x, mask_y;
 
-    mask = (cairo_xcb_surface_t *) _cairo_clip_get_surface (clip, &dst->base);
+    mask = (cairo_xcb_surface_t *) _cairo_clip_get_surface (clip, &dst->base, &mask_x, &mask_y);
     if (unlikely (mask->base.status))
 	return mask->base.status;
 
-    mask_x = - clip->path->extents.x;
-    mask_y = - clip->path->extents.y;
-
     /* top */
     if (rects->bounded.y != rects->unbounded.y) {
 	int x = rects->unbounded.x;
@@ -2199,7 +2197,7 @@ _cairo_xcb_surface_fixup_unbounded_with_mask (cairo_xcb_surface_t *dst,
 	_cairo_xcb_connection_render_composite (dst->connection,
 						XCB_RENDER_PICT_OP_OUT_REVERSE,
 						mask->picture, XCB_NONE, dst->picture,
-						x + mask_x, y + mask_y,
+						x - mask_x, y - mask_y,
 						0, 0,
 						x, y,
 						width, height);
@@ -2215,7 +2213,7 @@ _cairo_xcb_surface_fixup_unbounded_with_mask (cairo_xcb_surface_t *dst,
 	_cairo_xcb_connection_render_composite (dst->connection,
 						XCB_RENDER_PICT_OP_OUT_REVERSE,
 						mask->picture, XCB_NONE, dst->picture,
-						x + mask_x, y + mask_y,
+						x - mask_x, y - mask_y,
 						0, 0,
 						x, y,
 						width, height);
@@ -2231,7 +2229,7 @@ _cairo_xcb_surface_fixup_unbounded_with_mask (cairo_xcb_surface_t *dst,
 	_cairo_xcb_connection_render_composite (dst->connection,
 						XCB_RENDER_PICT_OP_OUT_REVERSE,
 						mask->picture, XCB_NONE, dst->picture,
-						x + mask_x, y + mask_y,
+						x - mask_x, y - mask_y,
 						0, 0,
 						x, y,
 						width, height);
@@ -2247,7 +2245,7 @@ _cairo_xcb_surface_fixup_unbounded_with_mask (cairo_xcb_surface_t *dst,
 	_cairo_xcb_connection_render_composite (dst->connection,
 						XCB_RENDER_PICT_OP_OUT_REVERSE,
 						mask->picture, XCB_NONE, dst->picture,
-						x + mask_x, y + mask_y,
+						x - mask_x, y - mask_y,
 						0, 0,
 						x, y,
 						width, height);
@@ -2541,16 +2539,17 @@ _composite_boxes (cairo_xcb_surface_t *dst,
 
 	if (need_clip_mask) {
 	    cairo_surface_t *clip_surface;
+	    int clip_x, clip_y;
 
-	    clip_surface = _cairo_clip_get_surface (clip, &dst->base);
+	    clip_surface = _cairo_clip_get_surface (clip, &dst->base, &clip_x, &clip_y);
 	    if (unlikely (clip_surface->status))
 		return clip_surface->status;
 
 	    _cairo_pattern_init_for_surface (&mask, clip_surface);
 	    mask.base.filter = CAIRO_FILTER_NEAREST;
 	    cairo_matrix_init_translate (&mask.base.matrix,
-					 -clip->path->extents.x,
-					 -clip->path->extents.y);
+					 -clip_x,
+					 -clip_y);
 
 	    if (op == CAIRO_OPERATOR_CLEAR) {
 		src = NULL;
diff --git a/src/drm/cairo-drm-i915-shader.c b/src/drm/cairo-drm-i915-shader.c
index 13f9d85..a56513d 100644
--- a/src/drm/cairo-drm-i915-shader.c
+++ b/src/drm/cairo-drm-i915-shader.c
@@ -2403,11 +2403,11 @@ i915_shader_set_clip (i915_shader_t *shader,
 		      cairo_clip_t *clip)
 {
     cairo_surface_t *clip_surface;
-    const cairo_rectangle_int_t *clip_extents;
+    int clip_x, clip_y;
     union i915_shader_channel *channel;
     i915_surface_t *s;
 
-    clip_surface = _cairo_clip_get_surface (clip, &shader->target->intel.drm.base);
+    clip_surface = _cairo_clip_get_surface (clip, &shader->target->intel.drm.base, &clip_x, &clip_y);
     assert (clip_surface->status == CAIRO_STATUS_SUCCESS);
     assert (clip_surface->type == CAIRO_SURFACE_TYPE_DRM);
 
@@ -2434,13 +2434,12 @@ i915_shader_set_clip (i915_shader_t *shader,
 	SS3_NORMALIZED_COORDS |
 	i915_texture_extend (CAIRO_EXTEND_NONE);
 
-    clip_extents = _cairo_clip_get_extents (clip);
     cairo_matrix_init_scale (&shader->clip.base.matrix,
 			     1. / s->intel.drm.width,
 			     1. / s->intel.drm.height);
     cairo_matrix_translate (&shader->clip.base.matrix,
-			    NEAREST_BIAS - clip_extents->x,
-			    NEAREST_BIAS - clip_extents->y);
+			    NEAREST_BIAS - clip_x,
+			    NEAREST_BIAS - clip_y);
 }
 
 static cairo_status_t
diff --git a/src/drm/cairo-drm-i965-shader.c b/src/drm/cairo-drm-i965-shader.c
index fcfec29..f18494c 100644
--- a/src/drm/cairo-drm-i965-shader.c
+++ b/src/drm/cairo-drm-i965-shader.c
@@ -762,10 +762,11 @@ i965_shader_set_clip (i965_shader_t *shader,
 		      cairo_clip_t *clip)
 {
     cairo_surface_t *clip_surface;
+    int clip_x, clip_y;
     union i965_shader_channel *channel;
     i965_surface_t *s;
 
-    clip_surface = _cairo_clip_get_surface (clip, &shader->target->intel.drm.base);
+    clip_surface = _cairo_clip_get_surface (clip, &shader->target->intel.drm.base, &clip_x, &clip_y);
     assert (clip_surface->status == CAIRO_STATUS_SUCCESS);
     assert (clip_surface->type == CAIRO_SURFACE_TYPE_DRM);
     s = (i965_surface_t *) clip_surface;
@@ -793,8 +794,8 @@ i965_shader_set_clip (i965_shader_t *shader,
 			     1. / s->intel.drm.height);
 
     cairo_matrix_translate (&shader->clip.base.matrix,
-			    NEAREST_BIAS - clip->path->extents.x,
-			    NEAREST_BIAS - clip->path->extents.y);
+			    NEAREST_BIAS - clip_x,
+			    NEAREST_BIAS - clip_y);
 }
 
 static cairo_bool_t
commit 241ce933f8fa44210015dcdc4a66b3f9d8ac56e8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 25 09:37:50 2010 +0100

    test: Add clip-shape
    
    cu found a bug when using clipping and fills with the image backend, but
    it turns out to be the lost sign bug afflicting everything...
    
    To trigger the bug requires evaluating the clip surface prior to using
    in with _cairo_clip_combine_with_surface(). Which is taken along a
    particular path when using a clip mask with non-pixel geometry on image,
    but more easily hit by the fallback code.
    
    Reported-by: <cairouser at yahoo.com>

diff --git a/test/Makefile.am b/test/Makefile.am
index 5e2a382..65f80e9 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -241,6 +241,10 @@ REFERENCE_IMAGES = \
 	clip-push-group.ref.png \
 	clip-push-group.svg.ref.png \
 	clip-push-group.xlib.ref.png \
+	clip-shape.ref.png \
+	clip-shape.ps.ref.png \
+	clip-shape.xlib.ref.png \
+	clip-shape.xlib-fallback.ref.png \
 	clip-stroke.ref.png \
 	clip-stroke.xlib.ref.png \
 	clip-stroke.xlib-fallback.ref.png \
diff --git a/test/Makefile.sources b/test/Makefile.sources
index 1062e25..df6c666 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -33,6 +33,7 @@ test_sources = \
 	clip-nesting.c					\
 	clip-operator.c					\
 	clip-push-group.c				\
+	clip-shape.c					\
 	clip-stroke.c					\
 	clip-stroke-no-op.c				\
 	clip-stroke-unbounded.c				\
diff --git a/test/clip-shape.c b/test/clip-shape.c
new file mode 100644
index 0000000..6a74a6e
--- /dev/null
+++ b/test/clip-shape.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 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>
+ */
+
+/* Adapted from a bug report by <cairouser at yahoo.com> */
+
+#include "cairo-test.h"
+
+static const struct xy {
+   double x;
+   double y;
+} gp[] = {
+    { 100, 250 },
+    { 100, 100 },
+    { 150, 230 },
+    { 239, 100 },
+    { 239, 250 },
+};
+
+static const double vp[3] = { 100, 144, 238.5 };
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+    int i;
+
+    cairo_paint (cr); /* opaque background */
+
+    for (i = 0; i < 5; ++i)
+	cairo_line_to (cr, gp[i].x, gp[i].y);
+    cairo_close_path (cr);
+
+    cairo_set_source_rgb (cr, 1, 0, 0);
+    cairo_set_line_width (cr, 1.5);
+    cairo_stroke_preserve (cr);
+    cairo_clip (cr);
+
+    for (i = 1; i < 3; ++i) {
+	double x1 = vp[i - 1];
+	double x2 = vp[i];
+
+	cairo_move_to (cr, x1, 0);
+	cairo_line_to (cr, x1, height);
+	cairo_line_to (cr, x2, height);
+	cairo_line_to (cr, x2, 0);
+	cairo_close_path (cr);
+
+	if (i & 1)
+	    cairo_set_source_rgb (cr, 0, 1, 0);
+	else
+	    cairo_set_source_rgb (cr, 1, 1, 0);
+
+	cairo_fill (cr);
+    }
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_shape,
+	    "Test handling of clipping with a non-aligned shape",
+	    "clip", /* keywords */
+	    NULL, /* requirements */
+	    400, 300,
+	    NULL, draw)
diff --git a/test/clip-shape.ps.ref.png b/test/clip-shape.ps.ref.png
new file mode 100644
index 0000000..1125fb5
Binary files /dev/null and b/test/clip-shape.ps.ref.png differ
diff --git a/test/clip-shape.ref.png b/test/clip-shape.ref.png
new file mode 100644
index 0000000..e80f666
Binary files /dev/null and b/test/clip-shape.ref.png differ
diff --git a/test/clip-shape.xlib-fallback.ref.png b/test/clip-shape.xlib-fallback.ref.png
new file mode 100644
index 0000000..e9aa947
Binary files /dev/null and b/test/clip-shape.xlib-fallback.ref.png differ
diff --git a/test/clip-shape.xlib.ref.png b/test/clip-shape.xlib.ref.png
new file mode 100644
index 0000000..a6804a7
Binary files /dev/null and b/test/clip-shape.xlib.ref.png differ


More information about the cairo-commit mailing list