[cairo-commit] 7 commits - configure.in src/cairo-image-surface.c src/cairo-region.c src/cairo-region-private.h src/cairo-xlib-surface.c test/large-clip.c test/large-clip-ref.png test/Makefile.am

Søren Sandmann Pedersen sandmann at kemper.freedesktop.org
Fri Jun 13 13:22:41 PDT 2008


 configure.in               |    2 -
 src/cairo-image-surface.c  |    2 -
 src/cairo-region-private.h |    2 -
 src/cairo-region.c         |   38 ++++++++++++++---------------
 src/cairo-xlib-surface.c   |   29 ++++++++++++++++++++--
 test/Makefile.am           |    2 +
 test/large-clip-ref.png    |binary
 test/large-clip.c          |   58 +++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 108 insertions(+), 25 deletions(-)

New commits:
commit c57b1eca18db12b8d56d73093d5cae28ed388298
Merge: b9acf62... cba1543...
Author: Søren Sandmann <sandmann at redhat.com>
Date:   Fri Jun 13 16:18:13 2008 -0400

    Merge branch 'region32'

commit cba1543c9274db5a84aab26a4d6642a1151106c1
Author: Søren Sandmann <sandmann at redhat.com>
Date:   Mon Jun 9 03:30:26 2008 -0400

    Remove large-clip from xfail list

diff --git a/test/Makefile.am b/test/Makefile.am
index 26d6cf3..7dba516 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -737,7 +737,6 @@ extend-pad$(EXEEXT)				\
 filter-nearest-offset$(EXEEXT)			\
 filter-bilinear-extents$(EXEEXT)		\
 large-source$(EXEEXT)				\
-large-clip$(EXEEXT)				\
 long-lines$(EXEEXT)				\
 self-intersecting$(EXEEXT)			\
 surface-pattern$(EXEEXT)			\
commit a95e81261f246874bab157dd83131a4f0baebe06
Author: Søren Sandmann <sandmann at redhat.com>
Date:   Mon Jun 9 03:04:06 2008 -0400

    Require pixman 0.11.2 for 32 bit regions

diff --git a/configure.in b/configure.in
index 2596876..d7fc160 100644
--- a/configure.in
+++ b/configure.in
@@ -314,7 +314,7 @@ CAIRO_LIBS=$CAIRO_NONPKGCONFIG_LIBS
 
 dnl ===========================================================================
 
-PIXMAN_VERSION="0.10.0"
+PIXMAN_VERSION="0.11.2"
 PIXMAN_REQUIRES="pixman-1 >= $PIXMAN_VERSION"
 PKG_CHECK_MODULES(pixman, $PIXMAN_REQUIRES, ,
 	[AC_MSG_ERROR([pixman >= $PIXMAN_VERSION is required
commit c3121543f87e372d18aaa5b8a132d28bcc4bf450
Author: Søren Sandmann <sandmann at redhat.com>
Date:   Mon Jun 9 01:11:38 2008 -0400

    Fix xlib incarnation of the large-clip bug.
    
    Intersect the clip region with the bounds of the surface to prevent
    overflows when converting from 32 to 16 bits.

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 7397573..0c29968 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -1995,15 +1995,36 @@ _cairo_xlib_surface_set_clip_region (void           *abstract_surface,
 	cairo_status_t status;
 	XRectangle *rects = NULL;
 	int n_boxes, i;
+	cairo_rectangle_int_t rect;
+	cairo_region_t bound, bounded;
+
+	rect.x = rect.y = 0;
+	rect.width = surface->width;
+	rect.height = surface->height;
+
+	/* Intersect the region with the bounds of the surface. This
+	 * is necessary so we don't wrap around when we convert cairo's
+	 * 32 bit region into 16 bit rectangles.
+	 */
+	_cairo_region_init_rect (&bound, &rect);
+	_cairo_region_init (&bounded);
+	status = _cairo_region_intersect (&bounded, &bound, region);
+	if (status) {
+	    _cairo_region_fini (&bound);
+	    _cairo_region_fini (&bounded);
+	    return status;
+	}
 
-	status = _cairo_region_get_boxes (region, &n_boxes, &boxes);
+	status = _cairo_region_get_boxes (&bounded, &n_boxes, &boxes);
         if (status)
             return status;
 
 	if (n_boxes > ARRAY_LENGTH (surface->embedded_clip_rects)) {
 	    rects = _cairo_malloc_ab (n_boxes, sizeof (XRectangle));
 	    if (rects == NULL) {
-                _cairo_region_boxes_fini (region, boxes);
+                _cairo_region_boxes_fini (&bounded, boxes);
+		_cairo_region_fini (&bound);
+		_cairo_region_fini (&bounded);
 		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
             }
 	} else {
@@ -2017,7 +2038,9 @@ _cairo_xlib_surface_set_clip_region (void           *abstract_surface,
 	    rects[i].height = boxes[i].p2.y - boxes[i].p1.y;
 	}
 
-        _cairo_region_boxes_fini (region, boxes);
+        _cairo_region_boxes_fini (&bounded, boxes);
+	_cairo_region_fini (&bounded);
+	_cairo_region_fini (&bound);
 
 	surface->have_clip_rects = TRUE;
 	surface->clip_rects = rects;
commit 75fdccc1db2d78a546528164054a54509dac1490
Author: Søren Sandmann <sandmann at redhat.com>
Date:   Mon Jun 9 00:43:47 2008 -0400

    Use 32 bit pixman regions for cairo_region_t

diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index cd80aed..d25cb96 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -1193,7 +1193,7 @@ _cairo_image_surface_set_clip_region (void *abstract_surface,
 {
     cairo_image_surface_t *surface = (cairo_image_surface_t *) abstract_surface;
 
-    if (! pixman_image_set_clip_region (surface->pixman_image, &region->rgn))
+    if (! pixman_image_set_clip_region32 (surface->pixman_image, &region->rgn))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     surface->has_clip = region != NULL;
diff --git a/src/cairo-region-private.h b/src/cairo-region-private.h
index 4e2d723..53c1e8a 100644
--- a/src/cairo-region-private.h
+++ b/src/cairo-region-private.h
@@ -44,7 +44,7 @@
 /* #cairo_region_t is defined in cairoint.h */
 
 struct _cairo_region {
-    pixman_region16_t rgn;
+    pixman_region32_t rgn;
 };
 
 cairo_private void
diff --git a/src/cairo-region.c b/src/cairo-region.c
index d78628e..746b3b1 100644
--- a/src/cairo-region.c
+++ b/src/cairo-region.c
@@ -40,14 +40,14 @@
 void
 _cairo_region_init (cairo_region_t *region)
 {
-    pixman_region_init (&region->rgn);
+    pixman_region32_init (&region->rgn);
 }
 
 void
 _cairo_region_init_rect (cairo_region_t *region,
 			 cairo_rectangle_int_t *rect)
 {
-    pixman_region_init_rect (&region->rgn,
+    pixman_region32_init_rect (&region->rgn,
 			     rect->x, rect->y,
 			     rect->width, rect->height);
 }
@@ -57,13 +57,13 @@ _cairo_region_init_boxes (cairo_region_t *region,
 			  cairo_box_int_t *boxes,
 			  int count)
 {
-    pixman_box16_t stack_pboxes[CAIRO_STACK_ARRAY_LENGTH (pixman_box16_t)];
-    pixman_box16_t *pboxes = stack_pboxes;
+    pixman_box32_t stack_pboxes[CAIRO_STACK_ARRAY_LENGTH (pixman_box32_t)];
+    pixman_box32_t *pboxes = stack_pboxes;
     cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
     int i;
 
     if (count > ARRAY_LENGTH(stack_pboxes)) {
-	pboxes = _cairo_malloc_ab (count, sizeof(pixman_box16_t));
+	pboxes = _cairo_malloc_ab (count, sizeof(pixman_box32_t));
 	if (pboxes == NULL)
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
@@ -75,7 +75,7 @@ _cairo_region_init_boxes (cairo_region_t *region,
 	pboxes[i].y2 = boxes[i].p2.y;
     }
 
-    if (!pixman_region_init_rects (&region->rgn, pboxes, count))
+    if (!pixman_region32_init_rects (&region->rgn, pboxes, count))
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     if (pboxes != stack_pboxes)
@@ -87,13 +87,13 @@ _cairo_region_init_boxes (cairo_region_t *region,
 void
 _cairo_region_fini (cairo_region_t *region)
 {
-    pixman_region_fini (&region->rgn);
+    pixman_region32_fini (&region->rgn);
 }
 
 cairo_int_status_t
 _cairo_region_copy (cairo_region_t *dst, cairo_region_t *src)
 {
-    if (!pixman_region_copy (&dst->rgn, &src->rgn))
+    if (!pixman_region32_copy (&dst->rgn, &src->rgn))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     return CAIRO_STATUS_SUCCESS;
@@ -102,18 +102,18 @@ _cairo_region_copy (cairo_region_t *dst, cairo_region_t *src)
 int
 _cairo_region_num_boxes (cairo_region_t *region)
 {
-    return pixman_region_n_rects (&region->rgn);
+    return pixman_region32_n_rects (&region->rgn);
 }
 
 cairo_int_status_t
 _cairo_region_get_boxes (cairo_region_t *region, int *num_boxes, cairo_box_int_t **boxes)
 {
     int nboxes;
-    pixman_box16_t *pboxes;
+    pixman_box32_t *pboxes;
     cairo_box_int_t *cboxes;
     int i;
 
-    pboxes = pixman_region_rectangles (&region->rgn, &nboxes);
+    pboxes = pixman_region32_rectangles (&region->rgn, &nboxes);
 
     if (nboxes == 0) {
 	*num_boxes = 0;
@@ -154,7 +154,7 @@ _cairo_region_boxes_fini (cairo_region_t *region, cairo_box_int_t *boxes)
 void
 _cairo_region_get_extents (cairo_region_t *region, cairo_rectangle_int_t *extents)
 {
-    pixman_box16_t *pextents = pixman_region_extents (&region->rgn);
+    pixman_box32_t *pextents = pixman_region32_extents (&region->rgn);
 
     extents->x = pextents->x1;
     extents->y = pextents->y1;
@@ -165,7 +165,7 @@ _cairo_region_get_extents (cairo_region_t *region, cairo_rectangle_int_t *extent
 cairo_int_status_t
 _cairo_region_subtract (cairo_region_t *dst, cairo_region_t *a, cairo_region_t *b)
 {
-    if (!pixman_region_subtract (&dst->rgn, &a->rgn, &b->rgn))
+    if (!pixman_region32_subtract (&dst->rgn, &a->rgn, &b->rgn))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     return CAIRO_STATUS_SUCCESS;
@@ -174,7 +174,7 @@ _cairo_region_subtract (cairo_region_t *dst, cairo_region_t *a, cairo_region_t *
 cairo_int_status_t
 _cairo_region_intersect (cairo_region_t *dst, cairo_region_t *a, cairo_region_t *b)
 {
-    if (!pixman_region_intersect (&dst->rgn, &a->rgn, &b->rgn))
+    if (!pixman_region32_intersect (&dst->rgn, &a->rgn, &b->rgn))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     return CAIRO_STATUS_SUCCESS;
@@ -185,7 +185,7 @@ _cairo_region_union_rect (cairo_region_t *dst,
 			  cairo_region_t *src,
 			  cairo_rectangle_int_t *rect)
 {
-    if (!pixman_region_union_rect (&dst->rgn, &src->rgn,
+    if (!pixman_region32_union_rect (&dst->rgn, &src->rgn,
 				   rect->x, rect->y,
 				   rect->width, rect->height))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -196,25 +196,25 @@ _cairo_region_union_rect (cairo_region_t *dst,
 cairo_bool_t
 _cairo_region_not_empty (cairo_region_t *region)
 {
-    return (cairo_bool_t) pixman_region_not_empty (&region->rgn);
+    return (cairo_bool_t) pixman_region32_not_empty (&region->rgn);
 }
 
 void
 _cairo_region_translate (cairo_region_t *region,
 			 int x, int y)
 {
-    pixman_region_translate (&region->rgn, x, y);
+    pixman_region32_translate (&region->rgn, x, y);
 }
 
 pixman_region_overlap_t
 _cairo_region_contains_rectangle (cairo_region_t *region, cairo_rectangle_int_t *rect)
 {
-    pixman_box16_t pbox;
+    pixman_box32_t pbox;
 
     pbox.x1 = rect->x;
     pbox.y1 = rect->y;
     pbox.x2 = rect->x + rect->width;
     pbox.y2 = rect->y + rect->height;
 
-    return pixman_region_contains_rectangle (&region->rgn, &pbox);
+    return pixman_region32_contains_rectangle (&region->rgn, &pbox);
 }
commit bd0cf0562349e88857943a521bf37fca5709f47e
Author: Søren Sandmann <sandmann at redhat.com>
Date:   Mon Jun 9 00:09:25 2008 -0400

    Add the correct reference image for the large-clip test

diff --git a/test/large-clip-ref.png b/test/large-clip-ref.png
index d53d489..9e46d2d 100644
Binary files a/test/large-clip-ref.png and b/test/large-clip-ref.png differ
commit 60971fb5142dedc6d5248133bacf6e08b585abc4
Author: Søren Sandmann <sandmann at redhat.com>
Date:   Sun Jun 8 17:48:19 2008 -0400

    New large-clip test
    
    This tests clipping to a rectangle that doesn't fit in 16 bits.

diff --git a/test/Makefile.am b/test/Makefile.am
index f8256b4..26d6cf3 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -71,6 +71,7 @@ infinite-join$(EXEEXT)					\
 in-fill-empty-trapezoid$(EXEEXT)			\
 in-fill-trapezoid$(EXEEXT)				\
 invalid-matrix$(EXEEXT)					\
+large-clip$(EXEEXT)					\
 large-font$(EXEEXT)					\
 large-source$(EXEEXT)					\
 leaky-dash$(EXEEXT)					\
@@ -443,6 +444,7 @@ REFERENCE_IMAGES = \
 	image-surface-source-ref.png \
 	infinite-join-ref.png	\
 	infinite-join-ps-ref.png	\
+	large-clip-ref.png	\
 	large-font-ref.png	\
 	large-source-ref.png	\
 	leaky-dash-ps-argb32-ref.png	\
@@ -735,6 +737,7 @@ extend-pad$(EXEEXT)				\
 filter-nearest-offset$(EXEEXT)			\
 filter-bilinear-extents$(EXEEXT)		\
 large-source$(EXEEXT)				\
+large-clip$(EXEEXT)				\
 long-lines$(EXEEXT)				\
 self-intersecting$(EXEEXT)			\
 surface-pattern$(EXEEXT)			\
diff --git a/test/large-clip-ref.png b/test/large-clip-ref.png
new file mode 100644
index 0000000..d53d489
Binary files /dev/null and b/test/large-clip-ref.png differ
diff --git a/test/large-clip.c b/test/large-clip.c
new file mode 100644
index 0000000..3fccaf8
--- /dev/null
+++ b/test/large-clip.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Soren Sandmann <sandmann at redhat.com>
+ */
+
+#include "cairo-test.h"
+
+#define SIZE 100
+
+static cairo_test_draw_function_t draw;
+
+cairo_test_t test = {
+    "large-clip",
+    "Incorrect clipping when the clip rectangle doesn't fit in 16 bits signed",
+    SIZE, SIZE,
+    draw
+};
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+    cairo_set_source_rgb (cr, 0, 0, 1);
+    cairo_paint (cr);
+
+    cairo_rectangle (cr, 0, 0, 65536 + 25, 65536 + 25);
+    cairo_clip (cr);
+    
+    cairo_set_source_rgb (cr, 1, 0, 0);
+    cairo_paint (cr);
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+int
+main (void)
+{
+    return cairo_test (&test);
+}


More information about the cairo-commit mailing list