[cairo-commit] 11 commits - src/cairo-analysis-surface.c src/cairo-analysis-surface-private.h src/cairo.c src/cairo-clip.c src/cairo-clip-private.h src/cairo-directfb-surface.c src/cairo-fixed.c src/cairo-fixed-private.h src/cairo-glitz-surface.c src/cairo-gstate.c src/cairo-image-surface.c src/cairoint.h src/cairo-matrix.c src/cairo-meta-surface.c src/cairo-os2-surface.c src/cairo-paginated-surface.c src/cairo-path-fixed.c src/cairo-pattern.c src/cairo-pdf-surface.c src/cairo-ps-surface.c src/cairo-quartz-private.h src/cairo-quartz-surface.c src/cairo-rectangle.c src/cairo-region.c src/cairo-region-private.h src/cairo-scaled-font.c src/cairo-surface.c src/cairo-surface-fallback.c src/cairo-surface-fallback-private.h src/cairo-svg-surface.c src/cairo-traps.c src/cairo-win32-private.h src/cairo-win32-surface.c src/cairo-xcb-surface.c src/cairo-xlib-surface.c src/test-fallback-surface.c src/test-meta-surface.c src/test-paginated-surface.c

Vladimir Vukicevic vladimir at kemper.freedesktop.org
Wed Jul 18 14:00:00 PDT 2007


 src/cairo-analysis-surface-private.h |    4 
 src/cairo-analysis-surface.c         |    6 
 src/cairo-clip-private.h             |   10 -
 src/cairo-clip.c                     |  194 ++++++++++++++-------------
 src/cairo-directfb-surface.c         |   41 +++--
 src/cairo-fixed-private.h            |  245 +++++++++++++++++++++++++++++++++++
 src/cairo-fixed.c                    |  100 --------------
 src/cairo-glitz-surface.c            |   85 +++++++++---
 src/cairo-gstate.c                   |    2 
 src/cairo-image-surface.c            |   92 ++++++++++---
 src/cairo-matrix.c                   |   12 -
 src/cairo-meta-surface.c             |    2 
 src/cairo-os2-surface.c              |   10 -
 src/cairo-paginated-surface.c        |    6 
 src/cairo-path-fixed.c               |   11 -
 src/cairo-pattern.c                  |  124 ++++++++++++-----
 src/cairo-pdf-surface.c              |   12 -
 src/cairo-ps-surface.c               |    4 
 src/cairo-quartz-private.h           |    2 
 src/cairo-quartz-surface.c           |   26 +--
 src/cairo-rectangle.c                |   10 -
 src/cairo-region-private.h           |  105 +++++++++++++++
 src/cairo-region.c                   |  174 +++++++++++++++++++++++-
 src/cairo-scaled-font.c              |    4 
 src/cairo-surface-fallback-private.h |    2 
 src/cairo-surface-fallback.c         |   89 ++++++------
 src/cairo-surface.c                  |  101 +++++++-------
 src/cairo-svg-surface.c              |   93 ++++++-------
 src/cairo-traps.c                    |   76 ++++------
 src/cairo-win32-private.h            |    4 
 src/cairo-win32-surface.c            |   44 +++---
 src/cairo-xcb-surface.c              |  133 +++++++++++++------
 src/cairo-xlib-surface.c             |  135 +++++++++++++------
 src/cairo.c                          |    2 
 src/cairoint.h                       |  144 ++++++++++----------
 src/test-fallback-surface.c          |   12 -
 src/test-meta-surface.c              |    4 
 src/test-paginated-surface.c         |    4 
 38 files changed, 1393 insertions(+), 731 deletions(-)

New commits:
diff-tree c0a7d33ac6c81dd74ee2a9daaa3749a346ef4897 (from b719592428907d2010645303fb65d38dcb8b30c0)
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date:   Wed Jul 4 13:54:03 2007 +0200

    [fixpt] Fixup malloc usage to use _cairo_malloc_*
    
    Fix some introduced mallocs as a result of the fixed point patches.

diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index f0fcaa0..ffbcde2 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -635,7 +635,7 @@ _cairo_clip_copy_rectangle_list (cairo_c
 	if (_cairo_region_get_boxes (&clip->region, &n_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
 	    return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
 
-	rectangles = malloc (sizeof (cairo_rectangle_t) * n_boxes);
+	rectangles = _cairo_malloc_ab (n_boxes, sizeof (cairo_rectangle_t));
 	if (rectangles == NULL) {
 	    _cairo_region_boxes_fini (&clip->region, boxes);
 	    return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c
index b0c33f5..9fddaf8 100644
--- a/src/cairo-glitz-surface.c
+++ b/src/cairo-glitz-surface.c
@@ -164,7 +164,7 @@ _cairo_glitz_get_boxes_from_region (cair
     if (n == 0)
         return NULL;
 
-    gboxes = malloc (sizeof(glitz_box_t) * n);
+    gboxes = _cairo_malloc_ab (n, sizeof(glitz_box_t));
     if (gboxes == NULL)
         goto done;
 
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 4546183..dfdb7fb 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -905,7 +905,7 @@ _cairo_image_surface_composite_trapezoid
 
     /* Convert traps to pixman traps */
     if (num_traps > ARRAY_LENGTH(stack_traps)) {
-	pixman_traps = malloc (num_traps * sizeof(pixman_trapezoid_t));
+	pixman_traps = _cairo_malloc_ab (num_traps, sizeof(pixman_trapezoid_t));
 	if (pixman_traps == NULL)
 	    return CAIRO_STATUS_NO_MEMORY;
     }
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index c2f12d7..24efa34 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -1153,7 +1153,7 @@ _cairo_pattern_acquire_surface_for_gradi
     unsigned int i;
 
     if (pattern->n_stops > ARRAY_LENGTH(pixman_stops_static)) {
-	pixman_stops = malloc(pattern->n_stops * sizeof(pixman_gradient_stop_t));
+	pixman_stops = _cairo_malloc_ab (pattern->n_stops, sizeof(pixman_gradient_stop_t));
 	if (pixman_stops == NULL)
 	    return CAIRO_STATUS_NO_MEMORY;
     }
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index 684b43b..d10ee90 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -1264,7 +1264,7 @@ _cairo_xcb_surface_fill_rectangles (void
     render_color.alpha = color->alpha_short;
 
     if (num_rects > ARRAY_LENGTH(static_xrects)) {
-        xrects = malloc(sizeof(xcb_rectangle_t) * num_rects);
+        xrects = _cairo_malloc_ab (num_rects, sizeof(xcb_rectangle_t));
         if (xrects == NULL)
             return CAIRO_STATUS_NO_MEMORY;
     }
@@ -1493,7 +1493,7 @@ _cairo_xcb_surface_composite_trapezoids 
         int i;
 
         if (num_traps > ARRAY_LENGTH(xtraps_stack)) {
-            xtraps = malloc(sizeof(xcb_render_trapezoid_t) * num_traps);
+            xtraps = _cairo_malloc_ab (num_traps, sizeof(xcb_render_trapezoid_t));
             if (xtraps == NULL) {
                 status = CAIRO_STATUS_NO_MEMORY;
                 goto BAIL;
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index b685637..9d68a86 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -1542,7 +1542,7 @@ _cairo_xlib_surface_fill_rectangles (voi
     render_color.alpha = color->alpha_short;
 
     if (num_rects > ARRAY_LENGTH(static_xrects)) {
-        xrects = malloc(sizeof(XRectangle) * num_rects);
+        xrects = _cairo_malloc_ab (num_rects, sizeof(XRectangle));
         if (xrects == NULL)
             return CAIRO_STATUS_NO_MEMORY;
     }
@@ -1774,7 +1774,7 @@ _cairo_xlib_surface_composite_trapezoids
         int i;
 
         if (num_traps > ARRAY_LENGTH(xtraps_stack)) {
-            xtraps = malloc(sizeof(XTrapezoid) * num_traps);
+            xtraps = _cairo_malloc_ab (num_traps, sizeof(XTrapezoid));
             if (xtraps == NULL) {
                 status = CAIRO_STATUS_NO_MEMORY;
                 goto BAIL;
diff-tree b719592428907d2010645303fb65d38dcb8b30c0 (from 866b485314bfd5d8bbf865d19f6a589d08292e2a)
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date:   Wed Jul 4 12:16:27 2007 +0200

    [fixpt] Fix up compilation post pixman merge

diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 7a81c3f..c2f12d7 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -1170,7 +1170,6 @@ _cairo_pattern_acquire_surface_for_gradi
     {
 	cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) pattern;
 	pixman_point_fixed_t p1, p2;
-	pixman_linear_gradient_t gradient;
 
 	p1.x = _cairo_fixed_to_16_16 (linear->p1.x);
 	p1.y = _cairo_fixed_to_16_16 (linear->p1.y);
diff --git a/src/cairo-region-private.h b/src/cairo-region-private.h
index a3ee759..efb01ce 100644
--- a/src/cairo-region-private.h
+++ b/src/cairo-region-private.h
@@ -37,7 +37,7 @@
 #ifndef CAIRO_REGION_PRIVATE_H
 #define CAIRO_REGION_PRIVATE_H
 
-#include <pixman.h>
+#include <pixman/pixman.h>
 
 /* cairo_region_t is defined in cairoint.h */
 
diff --git a/src/cairo-region.c b/src/cairo-region.c
index 287c169..fe2b405 100644
--- a/src/cairo-region.c
+++ b/src/cairo-region.c
@@ -77,7 +77,7 @@ _cairo_region_init_boxes (cairo_region_t
 	pboxes[i].y2 = boxes[i].p2.y;
     }
 
-    if (!pixman_region_init_rects (region, pboxes, count))
+    if (!pixman_region_init_rects (&region->rgn, pboxes, count))
 	status = CAIRO_STATUS_NO_MEMORY;
 
     if (pboxes != stack_pboxes)
@@ -104,24 +104,25 @@ _cairo_region_copy (cairo_region_t *dst,
 int
 _cairo_region_num_boxes (cairo_region_t *region)
 {
-    return pixman_region_n_rects(&region->rgn);
+    return pixman_region_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_region_n_rects (&region->rgn);
+    int nboxes;
     pixman_box16_t *pboxes;
     cairo_box_int_t *cboxes;
     int i;
 
+    pboxes = pixman_region_rectangles (&region->rgn, &nboxes);
+
     if (nboxes == 0) {
 	*num_boxes = 0;
 	*boxes = NULL;
 	return CAIRO_STATUS_SUCCESS;
     }
 
-    pboxes = pixman_region_rectangles (&region->rgn);
     cboxes = _cairo_malloc_ab (nboxes, sizeof(cairo_box_int_t));
     if (cboxes == NULL)
 	return CAIRO_STATUS_NO_MEMORY;
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 5237c14..956dbb7 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -1429,12 +1429,12 @@ _cairo_svg_surface_emit_radial_pattern (
     double fx, fy;
     cairo_bool_t reverse_stops;
     cairo_status_t status;
-    cairo_point_t &c0, &c1;
+    cairo_point_t *c0, *c1;
     cairo_fixed_t radius0, radius1;
 
     extend = pattern->base.base.extend;
 
-    if (pattern->radius1 < pattern->radius2) {
+    if (pattern->r1 < pattern->r2) {
 	c0 = &pattern->c1;
 	c1 = &pattern->c2;
 	radius0 = pattern->r1;
@@ -1460,7 +1460,7 @@ _cairo_svg_surface_emit_radial_pattern (
     if (status)
 	return status;
 
-    if (radius0 == radius1) {
+    if (pattern->r1 == pattern->r2) {
 	_cairo_output_stream_printf (document->xml_node_defs,
 				     "<radialGradient id=\"radial%d\" "
 				     "gradientUnits=\"userSpaceOnUse\" "
diff-tree 866b485314bfd5d8bbf865d19f6a589d08292e2a (from 0abe5324a5b03149630a5b6496c980f83be4fd75)
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date:   Mon Jun 18 18:38:54 2007 -0700

    [fixpt] Let the compiler calculate the magic double-to-fixed value

diff --git a/src/cairo-fixed-private.h b/src/cairo-fixed-private.h
index 431e7ee..35b3748 100644
--- a/src/cairo-fixed-private.h
+++ b/src/cairo-fixed-private.h
@@ -128,18 +128,8 @@ _cairo_fixed_from_int (int i)
 /* The 16.16 number must always be available */
 #define CAIRO_MAGIC_NUMBER_FIXED_16_16 (103079215104.0)
 
-#if CAIRO_FIXED_BITS == 32
-
-# if CAIRO_FIXED_FRAC_BITS == 16
-#  define CAIRO_MAGIC_NUMBER_FIXED CAIRO_MAGIC_NUMBER_FIXED_16_16
-# elif CAIRO_FIXED_FRAC_BITS == 8
-#  define CAIRO_MAGIC_NUMBER_FIXED (26388279066624.0)
-# elif CAIRO_FIXED_FRAC_BITS == 6
-#  define CAIRO_MAGIC_NUMBER_FIXED (105553116266496.0)
-# else
-#  error Please define a magic number for your fixed point type!
-#  error See cairo-fixed-private.h for details.
-# endif
+#if CAIRO_FIXED_BITS <= 32
+#define CAIRO_MAGIC_NUMBER_FIXED ((1LL << (52 - CAIRO_FIXED_FRAC_BITS)) * 1.5)
 
 /* For 32-bit fixed point numbers */
 static inline cairo_fixed_t
diff-tree 0abe5324a5b03149630a5b6496c980f83be4fd75 (from dc035fecda0070e18a68e06f567f268fc39483f1)
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date:   Mon Jun 18 18:33:29 2007 -0700

    [fixpt] Create cairo_region wrapper around pixman_region16_t
    
    Insulate region-using code from implementation details;
    at some point we'll want to switch to using 32-bit regions.

diff --git a/src/cairo-analysis-surface-private.h b/src/cairo-analysis-surface-private.h
index bb11453..056972a 100644
--- a/src/cairo-analysis-surface-private.h
+++ b/src/cairo-analysis-surface-private.h
@@ -42,10 +42,10 @@ _cairo_analysis_surface_create (cairo_su
 				int			 width,
 				int			 height);
 
-cairo_private pixman_region16_t *
+cairo_private cairo_region_t *
 _cairo_analysis_surface_get_supported (cairo_surface_t *surface);
 
-cairo_private pixman_region16_t *
+cairo_private cairo_region_t *
 _cairo_analysis_surface_get_unsupported (cairo_surface_t *unsupported);
 
 cairo_private cairo_bool_t
diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index ff7e7d8..3dbc73c 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -234,14 +234,14 @@ FAIL:
     return NULL;
 }
 
-cairo_private pixman_region16_t *
+cairo_private cairo_region_t *
 _cairo_analysis_surface_get_supported (cairo_surface_t *abstract_surface)
 {
     /* XXX */
     return NULL;
 }
 
-cairo_private pixman_region16_t *
+cairo_private cairo_region_t *
 _cairo_analysis_surface_get_unsupported (cairo_surface_t *abstract_surface)
 {
     /* XXX */
diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h
index fa39423..61559ce 100644
--- a/src/cairo-clip-private.h
+++ b/src/cairo-clip-private.h
@@ -72,7 +72,7 @@ struct _cairo_clip {
     /*
      * A clip region that can be placed in the surface
      */
-    pixman_region16_t region;
+    cairo_region_t region;
     cairo_bool_t has_region;
     /*
      * If the surface supports path clipping, we store the list of
@@ -109,7 +109,7 @@ _cairo_clip_intersect_to_rectangle (cair
 
 cairo_private cairo_status_t
 _cairo_clip_intersect_to_region (cairo_clip_t      *clip,
-				 pixman_region16_t *region);
+				 cairo_region_t *region);
 
 cairo_private cairo_status_t
 _cairo_clip_combine_to_surface (cairo_clip_t                  *clip,
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index e670456..f0fcaa0 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -1,3 +1,4 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
 /* cairo - a vector graphics library with display and print output
  *
  * Copyright © 2002 University of Southern California
@@ -61,7 +62,7 @@ _cairo_clip_init (cairo_clip_t *clip, ca
 
     clip->serial = 0;
 
-    pixman_region_init (&clip->region);
+    _cairo_region_init (&clip->region);
     clip->has_region = FALSE;
 
     clip->path = NULL;
@@ -77,11 +78,13 @@ _cairo_clip_init_copy (cairo_clip_t *cli
 
     clip->serial = other->serial;
 
-    pixman_region_init (&clip->region);
+    _cairo_region_init (&clip->region);
 
     if (other->has_region) {
-	if (!pixman_region_copy (&clip->region, &other->region)) {
-	    pixman_region_fini (&clip->region);
+	if (_cairo_region_copy (&clip->region, &other->region) !=
+            CAIRO_STATUS_SUCCESS)
+        {
+	    _cairo_region_fini (&clip->region);
 	    cairo_surface_destroy (clip->surface);
 	    return CAIRO_STATUS_NO_MEMORY;
 	}
@@ -105,11 +108,11 @@ _cairo_clip_reset (cairo_clip_t *clip)
     clip->serial = 0;
 
     if (clip->has_region) {
-        /* pixman_region_fini just releases the resources used but
+        /* _cairo_region_fini just releases the resources used but
          * doesn't bother with leaving the region in a valid state.
-         * So pixman_region_init has to be called afterwards. */
-	pixman_region_fini (&clip->region);
-        pixman_region_init (&clip->region);
+         * So _cairo_region_init has to be called afterwards. */
+	_cairo_region_fini (&clip->region);
+        _cairo_region_init (&clip->region);
 
         clip->has_region = FALSE;
     }
@@ -169,20 +172,17 @@ _cairo_clip_intersect_to_rectangle (cair
 
     if (clip->has_region) {
 	cairo_status_t status = CAIRO_STATUS_SUCCESS;
-	pixman_region16_t intersection;
+	cairo_region_t intersection;
 
-	pixman_region_init_rect (&intersection,
-                                  rectangle->x, rectangle->y,
-                                  rectangle->width, rectangle->height);
-
-	if (!pixman_region_intersect (&intersection, &clip->region,
-				      &intersection)) {
-	    status = CAIRO_STATUS_NO_MEMORY;
-	} else {
-            _cairo_region_extents_rectangle (&intersection, rectangle);
-        }
+	_cairo_region_init_rect (&intersection, rectangle);
+
+	status = _cairo_region_intersect (&intersection, &clip->region,
+					  &intersection);
 
-        pixman_region_fini (&intersection);
+	if (!status)
+	    _cairo_region_get_extents (&intersection, rectangle);
+
+        _cairo_region_fini (&intersection);
 
         if (status)
             return status;
@@ -196,8 +196,10 @@ _cairo_clip_intersect_to_rectangle (cair
 
 cairo_status_t
 _cairo_clip_intersect_to_region (cairo_clip_t      *clip,
-				 pixman_region16_t *region)
+				 cairo_region_t *region)
 {
+    cairo_status_t status;
+
     if (!clip)
 	return CAIRO_STATUS_SUCCESS;
 
@@ -206,22 +208,19 @@ _cairo_clip_intersect_to_region (cairo_c
     }
 
     if (clip->has_region) {
-	if (!pixman_region_intersect (region, &clip->region, region))
-	    return CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_region_intersect (region, &clip->region, region);
+	if (status)
+	    return status;
     }
 
     if (clip->surface) {
-	cairo_status_t status = CAIRO_STATUS_SUCCESS;
-	pixman_region16_t clip_rect;
+	cairo_region_t clip_rect;
 
-        pixman_region_init_rect (&clip_rect,
-                                  clip->surface_rect.x, clip->surface_rect.y,
-                                  clip->surface_rect.width, clip->surface_rect.height);
+	_cairo_region_init_rect (&clip_rect, &clip->surface_rect);
 
-        if (!pixman_region_intersect (region, &clip_rect, region))
-	    status = CAIRO_STATUS_NO_MEMORY;
+	status = _cairo_region_intersect (region, &clip_rect, region);
 
-        pixman_region_fini (&clip_rect);
+	_cairo_region_fini (&clip_rect);
 
         if (status)
             return status;
@@ -327,7 +326,7 @@ _cairo_clip_intersect_region (cairo_clip
 			      cairo_traps_t   *traps,
 			      cairo_surface_t *target)
 {
-    pixman_region16_t region;
+    cairo_region_t region;
     cairo_int_status_t status;
 
     if (clip->mode != CAIRO_CLIP_MODE_REGION)
@@ -341,25 +340,25 @@ _cairo_clip_intersect_region (cairo_clip
     status = CAIRO_STATUS_SUCCESS;
 
     if (!clip->has_region) {
-        if (pixman_region_copy (&clip->region, &region))
+        status = _cairo_region_copy (&clip->region, &region);
+	if (status == CAIRO_STATUS_SUCCESS)
 	    clip->has_region = TRUE;
-	else
-	    status = CAIRO_STATUS_NO_MEMORY;
     } else {
-	pixman_region16_t intersection;
-        pixman_region_init (&intersection);
+	cairo_region_t intersection;
+        _cairo_region_init (&intersection);
+
+	status = _cairo_region_intersect (&intersection,
+		                         &clip->region,
+		                         &region);
 
-	if (!pixman_region_intersect (&intersection,
-				      &clip->region,
-				      &region) ||
-	    !pixman_region_copy (&clip->region, &intersection))
-	    status = CAIRO_STATUS_NO_MEMORY;
+	if (status == CAIRO_STATUS_SUCCESS)
+	    status = _cairo_region_copy (&clip->region, &intersection);
 
-        pixman_region_fini (&intersection);
+        _cairo_region_fini (&intersection);
     }
 
     clip->serial = _cairo_surface_allocate_clip_serial (target);
-    pixman_region_fini (&region);
+    _cairo_region_fini (&region);
 
     return status;
 }
@@ -507,7 +506,7 @@ _cairo_clip_translate (cairo_clip_t  *cl
                        cairo_fixed_t  ty)
 {
     if (clip->has_region) {
-        pixman_region_translate (&clip->region,
+        _cairo_region_translate (&clip->region,
                                  _cairo_fixed_integer_part (tx),
                                  _cairo_fixed_integer_part (ty));
     }
@@ -558,7 +557,8 @@ _cairo_clip_init_deep_copy (cairo_clip_t
          * whatever the right handling is happen */
     } else {
         if (other->has_region) {
-            if (!pixman_region_copy (&clip->region, &other->region))
+            if (_cairo_region_copy (&clip->region, &other->region) !=
+		CAIRO_STATUS_SUCCESS)
 		goto BAIL;
 	    clip->has_region = TRUE;
         }
@@ -584,7 +584,7 @@ _cairo_clip_init_deep_copy (cairo_clip_t
 
 BAIL:
     if (clip->has_region)
-	pixman_region_fini (&clip->region);
+	_cairo_region_fini (&clip->region);
     if (clip->surface)
 	cairo_surface_destroy (clip->surface);
 
@@ -597,19 +597,24 @@ static const cairo_rectangle_list_t _cai
   { CAIRO_STATUS_CLIP_NOT_REPRESENTABLE, NULL, 0 };
 
 static cairo_bool_t
-_cairo_clip_rect_to_user (cairo_gstate_t *gstate,
-                          double x, double y, double width, double height,
-                          cairo_rectangle_t *rectangle)
+_cairo_clip_int_rect_to_user (cairo_gstate_t *gstate,
+			      cairo_rectangle_int_t *clip_rect,
+			      cairo_rectangle_t *user_rect)
 {
-    double x2 = x + width;
-    double y2 = y + height;
     cairo_bool_t is_tight;
 
-    _cairo_gstate_backend_to_user_rectangle (gstate, &x, &y, &x2, &y2, &is_tight);
-    rectangle->x = x;
-    rectangle->y = y;
-    rectangle->width = x2 - x;
-    rectangle->height = y2 - y;
+    double x1 = clip_rect->x;
+    double y1 = clip_rect->y;
+    double x2 = clip_rect->x + clip_rect->width;
+    double y2 = clip_rect->y + clip_rect->height;
+
+    _cairo_gstate_backend_to_user_rectangle (gstate, &x1, &y1, &x2, &y2, &is_tight);
+
+    user_rect->x = x1;
+    user_rect->y = y1;
+    user_rect->width = x2 - x1;
+    user_rect->height = y2 - y1;
+
     return is_tight;
 }
 
@@ -617,50 +622,51 @@ cairo_private cairo_rectangle_list_t*
 _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
 {
     cairo_rectangle_list_t *list;
-    cairo_rectangle_t *rectangles;
+    cairo_rectangle_t *rectangles = NULL;
     int n_boxes;
 
     if (clip->path || clip->surface)
-        return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
-
-    n_boxes = clip->has_region ? pixman_region_n_rects (&clip->region) : 1;
-    if (n_boxes > 0) {
-	rectangles = _cairo_malloc_ab (n_boxes, sizeof (cairo_rectangle_t));
-	if (rectangles == NULL)
-	    return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
-    } else {
-	rectangles = NULL;
-    }
+	return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
 
     if (clip->has_region) {
-        pixman_box16_t *boxes;
+	cairo_box_int_t *boxes;
         int i;
-        
-        boxes = pixman_region_rectangles (&clip->region, NULL);
+
+	if (_cairo_region_get_boxes (&clip->region, &n_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
+	    return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
+
+	rectangles = malloc (sizeof (cairo_rectangle_t) * n_boxes);
+	if (rectangles == NULL) {
+	    _cairo_region_boxes_fini (&clip->region, boxes);
+	    return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
+	}
+
         for (i = 0; i < n_boxes; ++i) {
-            if (!_cairo_clip_rect_to_user(gstate, boxes[i].x1, boxes[i].y1,
-                                          boxes[i].x2 - boxes[i].x1,
-                                          boxes[i].y2 - boxes[i].y1,
-                                          &rectangles[i])) {
-                free (rectangles);
-                return (cairo_rectangle_list_t*)
-                    &_cairo_rectangles_not_representable;
-            }
+	    cairo_rectangle_int_t clip_rect = { boxes[i].p1.x, boxes[i].p1.y,
+						boxes[i].p2.x - boxes[i].p1.x,
+						boxes[i].p2.y - boxes[i].p1.y };
+
+            if (!_cairo_clip_int_rect_to_user(gstate, &clip_rect, &rectangles[i])) {
+		_cairo_region_boxes_fini (&clip->region, boxes);
+		free (rectangles);
+		return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
+	    }
         }
     } else {
         cairo_rectangle_int_t extents;
-        if (_cairo_surface_get_extents (_cairo_gstate_get_target (gstate),
-		                        &extents) != CAIRO_STATUS_SUCCESS) {
-            free (rectangles);
+
+	n_boxes = 1;
+
+	rectangles = malloc(sizeof (cairo_rectangle_t));
+	if (rectangles == NULL)
 	    return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
+
+	if (_cairo_surface_get_extents (_cairo_gstate_get_target (gstate), &extents) ||
+	    !_cairo_clip_int_rect_to_user(gstate, &extents, rectangles))
+	{
+	    free (rectangles);
+	    return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
 	}
-	if (! _cairo_clip_rect_to_user(gstate, extents.x, extents.y,
-                                          extents.width, extents.height,
-                                          rectangles)) {
-            free (rectangles);
-            return (cairo_rectangle_list_t*)
-                &_cairo_rectangles_not_representable;
-        }
     }
 
     list = malloc (sizeof (cairo_rectangle_list_t));
diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c
index d6f827c..78b3517 100644
--- a/src/cairo-directfb-surface.c
+++ b/src/cairo-directfb-surface.c
@@ -1095,8 +1095,8 @@ _cairo_directfb_surface_composite_trapez
 #endif /* DFB_COMPOSITE_TRAPEZOIDS */
 
 static cairo_int_status_t
-_cairo_directfb_surface_set_clip_region (void              *abstract_surface,
-                                         pixman_region16_t *region)
+_cairo_directfb_surface_set_clip_region (void           *abstract_surface,
+                                         cairo_region_t *region)
 {
     cairo_directfb_surface_t *surface = abstract_surface;
     
@@ -1105,16 +1105,19 @@ _cairo_directfb_surface_set_clip_region 
                 __FUNCTION__, surface, region);
     
     if (region) {
-        pixman_box16_t *boxes   = pixman_region_rects (region);
-        int             n_boxes = pixman_region_num_rects (region);
-        int             i;
-        
+        cairo_box_int_t *boxes;
+        int n_boxes, i;
+
+        if (_cairo_region_get_boxes (region, &n_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
+            return CAIRO_STATUS_NO_MEMORY;
+
         if (surface->n_clips != n_boxes) {
             if( surface->clips )
                 free (surface->clips);
             
             surface->clips = _cairo_malloc_ab (n_boxes, sizeof(DFBRegion));
             if (!surface->clips) {
+                _cairo_region_boxes_fini (region, boxes);
                 surface->n_clips = 0;
                 return CAIRO_STATUS_NO_MEMORY;
             }
@@ -1123,11 +1126,13 @@ _cairo_directfb_surface_set_clip_region 
         }
         
         for (i = 0; i < n_boxes; i++) {
-            surface->clips[i].x1 = boxes[i].x1;
-            surface->clips[i].y1 = boxes[i].y1;
-            surface->clips[i].x2 = boxes[i].x2;
-            surface->clips[i].y2 = boxes[i].y2;
+            surface->clips[i].x1 = boxes[i].p1.x;
+            surface->clips[i].y1 = boxes[i].p1.y;
+            surface->clips[i].x2 = boxes[i].p2.x;
+            surface->clips[i].y2 = boxes[i].p2.y;
         }
+
+        _cairo_region_boxes_fini (region, boxes);
     }
     else {
         if (surface->clips) {
diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c
index 72754ad..b0c33f5 100644
--- a/src/cairo-glitz-surface.c
+++ b/src/cairo-glitz-surface.c
@@ -34,7 +34,7 @@ typedef struct _cairo_glitz_surface {
     glitz_surface_t   *surface;
     glitz_format_t    *format;
     cairo_bool_t      has_clip;
-    pixman_region16_t clip;
+    cairo_region_t    clip;
 } cairo_glitz_surface_t;
 
 static const cairo_surface_backend_t *
@@ -47,7 +47,7 @@ _cairo_glitz_surface_finish (void *abstr
 
     if (surface->has_clip) {
         glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0);
-        pixman_region_fini (&surface->clip);
+        _cairo_region_fini (&surface->clip);
     }
 
     glitz_surface_destroy (surface->surface);
@@ -150,6 +150,36 @@ _CAIRO_MASK_FORMAT (cairo_format_masks_t
     return FALSE;
 }
 
+static glitz_box_t *
+_cairo_glitz_get_boxes_from_region (cairo_region_t *region, int *nboxes)
+{
+    cairo_box_int_t *cboxes;
+    glitz_box_t *gboxes;
+    int n, i;
+
+    if (_cairo_region_get_boxes (&surface->clip, &n, &cboxes) != CAIRO_STATUS_SUCCESS)
+        return NULL;
+
+    *nboxes = n;
+    if (n == 0)
+        return NULL;
+
+    gboxes = malloc (sizeof(glitz_box_t) * n);
+    if (gboxes == NULL)
+        goto done;
+
+    for (i = 0; i < n; i++) {
+        gboxes[i].x1 = cboxes[i].p1.x;
+        gboxes[i].y1 = cboxes[i].p1.y;
+        gboxes[i].x2 = cboxes[i].p2.x;
+        gboxes[i].y2 = cboxes[i].p2.y;
+    }
+
+done:
+    _cairo_region_boxes_fini (&sruface->clip, &cboxes);
+    return gboxes;
+}
+
 static cairo_status_t
 _cairo_glitz_surface_get_image (cairo_glitz_surface_t   *surface,
 				cairo_rectangle_int_t   *interest,
@@ -264,10 +294,17 @@ _cairo_glitz_surface_get_image (cairo_gl
     /* restore the clip, if any */
     if (surface->has_clip) {
 	glitz_box_t *box;
-	int	    n;
+        int n;
+
+        box = _cairo_glitz_get_boxes_from_region (&surface->clip, &n);
+        if (box == NULL && n != 0) {
+            free (pixels);
+            return CAIRO_STATUS_NO_MEMORY;
+        }
 
-	box = (glitz_box_t *) pixman_region_rectangles (&surface->clip, &n);
 	glitz_surface_set_clip_region (surface->surface, 0, 0, box, n);
+
+        free (box);
     }
 
     /*
@@ -1393,37 +1430,45 @@ _cairo_glitz_surface_composite_trapezoid
 
 static cairo_int_status_t
 _cairo_glitz_surface_set_clip_region (void		*abstract_surface,
-				      pixman_region16_t *region)
+                                      cairo_region_t	*region);
 {
     cairo_glitz_surface_t *surface = abstract_surface;
 
     if (region)
+
     {
 	glitz_box_t *box;
 	int	    n;
 
 	if (!surface->has_clip) {
-            pixman_region_init (&surface->clip);
+            _cairo_region_init (&surface->clip);
             surface->has_clip = TRUE;
         }
 
-	if (!pixman_region_copy (&surface->clip, region))
+	if (_cairo_region_copy (&surface->clip, region) != CAIRO_STATUS_SUCCESS)
         {
-	    pixman_region_fini (&surface->clip);
+            _cairo_region_fini (&surface->clip);
 	    surface->has_clip = FALSE;
             return CAIRO_STATUS_NO_MEMORY;
         }
 
-	box = (glitz_box_t *) pixman_region_rectangles (&surface->clip, &n);
+        box = _cairo_glitz_get_boxes_from_region (&surface->clip, &n);
+        if (box == NULL && n != 0) {
+            _cairo_region_fini (&surface->clip);
+	    surface->has_clip = FALSE;
+            return CAIRO_STATUS_NO_MEMORY;
+        }
 
 	glitz_surface_set_clip_region (surface->surface, 0, 0, box, n);
+
+        free (box);
     }
     else
     {
 	glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0);
 
 	if (surface->has_clip) {
-	    pixman_region_fini (&surface->clip);
+	    _cairo_region_fini (&surface->clip);
 	    surface->has_clip = FALSE;
         }
     }
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index b833d09..4546183 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -1032,11 +1032,11 @@ _cairo_image_surface_composite_trapezoid
 
 cairo_int_status_t
 _cairo_image_surface_set_clip_region (void *abstract_surface,
-				      pixman_region16_t *region)
+				      cairo_region_t *region)
 {
     cairo_image_surface_t *surface = (cairo_image_surface_t *) abstract_surface;
 
-    if (!pixman_image_set_clip_region (surface->pixman_image, region))
+    if (!pixman_image_set_clip_region (surface->pixman_image, &region->rgn))
 	return CAIRO_STATUS_NO_MEMORY;
 
     surface->has_clip = region != NULL;
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index a4c4682..7a81c3f 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -1771,10 +1771,10 @@ _cairo_pattern_acquire_surface (cairo_pa
 		cairo_color_t color;
 
 		_cairo_color_init_rgba (&color,
-					src->stops->color.red / 65535.0,
-					src->stops->color.green / 65535.0,
-					src->stops->color.blue / 65535.0,
-					src->stops->color.alpha / 65535.0);
+					src->stops->color.red,
+					src->stops->color.green,
+					src->stops->color.blue,
+					src->stops->color.alpha);
 
 		_cairo_pattern_init_solid (&solid, &color,
 					   CAIRO_COLOR_IS_OPAQUE (&color) ?
@@ -2140,13 +2140,13 @@ cairo_pattern_get_color_stop_rgba (cairo
     if (offset)
 	*offset = _cairo_fixed_to_double(gradient->stops[index].x);
     if (red)
-	*red = gradient->stops[index].color.red / (double) 0xffff;
+	*red = gradient->stops[index].color.red;
     if (green)
-	*green = gradient->stops[index].color.green / (double) 0xffff;
+	*green = gradient->stops[index].color.green;
     if (blue)
-	*blue = gradient->stops[index].color.blue / (double) 0xffff;
+	*blue = gradient->stops[index].color.blue;
     if (alpha)
-	*alpha = gradient->stops[index].color.alpha / (double) 0xffff;
+	*alpha = gradient->stops[index].color.alpha;
 
     return CAIRO_STATUS_SUCCESS;
 }
diff --git a/src/cairo-region-private.h b/src/cairo-region-private.h
new file mode 100644
index 0000000..a3ee759
--- /dev/null
+++ b/src/cairo-region-private.h
@@ -0,0 +1,105 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
+/* Cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2007 Mozilla Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation
+ *
+ * Contributor(s):
+ *	Vladimir Vukicevic <vladimir at pobox.com>
+ */
+
+#ifndef CAIRO_REGION_PRIVATE_H
+#define CAIRO_REGION_PRIVATE_H
+
+#include <pixman.h>
+
+/* cairo_region_t is defined in cairoint.h */
+
+struct _cairo_region {
+    pixman_region16_t rgn;
+};
+
+cairo_private void
+_cairo_region_init (cairo_region_t *region);
+
+cairo_private void
+_cairo_region_init_rect (cairo_region_t *region,
+			 cairo_rectangle_int_t *rect);
+
+cairo_private cairo_int_status_t
+_cairo_region_init_boxes (cairo_region_t *region,
+			  cairo_box_int_t *boxes,
+			  int count);
+
+cairo_private void
+_cairo_region_fini (cairo_region_t *region);
+
+cairo_private cairo_int_status_t
+_cairo_region_copy (cairo_region_t *dst,
+		    cairo_region_t *src);
+
+cairo_private int
+_cairo_region_num_boxes (cairo_region_t *region);
+
+cairo_private cairo_int_status_t
+_cairo_region_get_boxes (cairo_region_t *region,
+			 int *num_boxes,
+			 cairo_box_int_t **boxes);
+
+cairo_private void
+_cairo_region_boxes_fini (cairo_region_t *region,
+			  cairo_box_int_t *boxes);
+
+cairo_private void
+_cairo_region_get_extents (cairo_region_t *region,
+			   cairo_rectangle_int_t *extents);
+
+cairo_private cairo_int_status_t
+_cairo_region_subtract (cairo_region_t *dst,
+			cairo_region_t *a,
+			cairo_region_t *b);
+
+cairo_private cairo_int_status_t
+_cairo_region_intersect (cairo_region_t *dst,
+			 cairo_region_t *a,
+			 cairo_region_t *b);
+
+cairo_private cairo_int_status_t
+_cairo_region_union_rect (cairo_region_t *dst,
+			  cairo_region_t *src,
+			  cairo_rectangle_int_t *rect);
+
+cairo_private cairo_bool_t
+_cairo_region_not_empty (cairo_region_t *region);
+
+cairo_private void
+_cairo_region_translate (cairo_region_t *region,
+			 int x, int y);
+
+#endif /* CAIRO_REGION_PRIVATE_H */
diff --git a/src/cairo-region.c b/src/cairo-region.c
index 4538e1c..287c169 100644
--- a/src/cairo-region.c
+++ b/src/cairo-region.c
@@ -1,3 +1,4 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
 /* cairo - a vector graphics library with display and print output
  *
  * Copyright © 2005 Red Hat, Inc.
@@ -31,25 +32,177 @@
  *
  * Contributor(s):
  *	Owen Taylor <otaylor at redhat.com>
+ *      Vladimir Vukicevic <vladimir at pobox.com>
  */
 
 #include "cairoint.h"
 
+void
+_cairo_region_init (cairo_region_t *region)
+{
+    pixman_region_init (&region->rgn);
+}
+
+void
+_cairo_region_init_rect (cairo_region_t *region,
+			 cairo_rectangle_int_t *rect)
+{
+    pixman_region_init_rect (&region->rgn,
+			     rect->x, rect->y,
+			     rect->width, rect->height);
+}
+
+#define STACK_BOXES_LEN ((int) (CAIRO_STACK_BUFFER_SIZE / sizeof(pixman_box16_t)))
+
+cairo_int_status_t
+_cairo_region_init_boxes (cairo_region_t *region,
+			  cairo_box_int_t *boxes,
+			  int count)
+{
+    pixman_box16_t stack_pboxes[STACK_BOXES_LEN];
+    pixman_box16_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));
+	if (pboxes == NULL)
+	    return CAIRO_STATUS_NO_MEMORY;
+    }
+
+    for (i = 0; i < count; i++) {
+	pboxes[i].x1 = boxes[i].p1.x;
+	pboxes[i].y1 = boxes[i].p1.y;
+	pboxes[i].x2 = boxes[i].p2.x;
+	pboxes[i].y2 = boxes[i].p2.y;
+    }
+
+    if (!pixman_region_init_rects (region, pboxes, count))
+	status = CAIRO_STATUS_NO_MEMORY;
+
+    if (pboxes != stack_pboxes)
+	free (pboxes);
+
+    return status;
+}
+
+void
+_cairo_region_fini (cairo_region_t *region)
+{
+    pixman_region_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))
+	return CAIRO_STATUS_NO_MEMORY;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+int
+_cairo_region_num_boxes (cairo_region_t *region)
+{
+    return pixman_region_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_region_n_rects (&region->rgn);
+    pixman_box16_t *pboxes;
+    cairo_box_int_t *cboxes;
+    int i;
+
+    if (nboxes == 0) {
+	*num_boxes = 0;
+	*boxes = NULL;
+	return CAIRO_STATUS_SUCCESS;
+    }
+
+    pboxes = pixman_region_rectangles (&region->rgn);
+    cboxes = _cairo_malloc_ab (nboxes, sizeof(cairo_box_int_t));
+    if (cboxes == NULL)
+	return CAIRO_STATUS_NO_MEMORY;
+
+    for (i = 0; i < nboxes; i++) {
+	cboxes[i].p1.x = pboxes[i].x1;
+	cboxes[i].p1.y = pboxes[i].y1;
+	cboxes[i].p2.x = pboxes[i].x2;
+	cboxes[i].p2.y = pboxes[i].y2;
+    }
+
+    *num_boxes = nboxes;
+    *boxes = cboxes;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+void
+_cairo_region_boxes_fini (cairo_region_t *region, cairo_box_int_t *boxes)
+{
+    free (boxes);
+}
+
 /**
- * _cairo_region_extents_rectangle:
- * @region: a #pixman_region16_t
+ * _cairo_region_get_extents:
+ * @region: a #cairo_region_t
  * @rect: rectangle into which to store the extents
  *
- * Gets the bounding box of a region as a cairo_rectangle_int16_t
+ * Gets the bounding box of a region as a cairo_rectangle_int_t
  **/
 void
-_cairo_region_extents_rectangle (pixman_region16_t       *region,
-				 cairo_rectangle_int_t   *rect)
+_cairo_region_get_extents (cairo_region_t *region, cairo_rectangle_int_t *extents)
 {
-    pixman_box16_t *region_extents = pixman_region_extents (region);
+    pixman_box16_t *pextents = pixman_region_extents (&region->rgn);
+
+    extents->x = pextents->x1;
+    extents->y = pextents->y1;
+    extents->width = pextents->x2 - pextents->x1;
+    extents->height = pextents->y2 - pextents->y1;
+}
 
-    rect->x = region_extents->x1;
-    rect->y = region_extents->y1;
-    rect->width = region_extents->x2 - region_extents->x1;
-    rect->height = region_extents->y2 - region_extents->y1;
+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))
+	return CAIRO_STATUS_NO_MEMORY;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+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))
+	return CAIRO_STATUS_NO_MEMORY;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_int_status_t
+_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,
+				   rect->x, rect->y,
+				   rect->width, rect->height))
+	return CAIRO_STATUS_NO_MEMORY;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_bool_t
+_cairo_region_not_empty (cairo_region_t *region)
+{
+    return (cairo_bool_t) pixman_region_not_empty (&region->rgn);
+}
+
+void
+_cairo_region_translate (cairo_region_t *region,
+			 int x, int y)
+{
+    pixman_region_translate (&region->rgn, x, y);
 }
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index c4c215b..3929d8d 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -410,13 +410,13 @@ _composite_trap_region (cairo_clip_t    
 			cairo_pattern_t         *src,
 			cairo_operator_t         op,
 			cairo_surface_t         *dst,
-			pixman_region16_t       *trap_region,
+			cairo_region_t          *trap_region,
 			cairo_rectangle_int_t   *extents)
 {
     cairo_status_t status;
     cairo_pattern_union_t solid_pattern;
     cairo_pattern_union_t mask;
-    int num_rects = pixman_region_n_rects (trap_region);
+    int num_rects = _cairo_region_num_boxes (trap_region);
     unsigned int clip_serial;
     cairo_surface_t *clip_surface = clip ? clip->surface : NULL;
 
@@ -519,8 +519,8 @@ _clip_and_composite_trapezoids (cairo_pa
 				cairo_antialias_t antialias)
 {
     cairo_status_t status;
-    pixman_region16_t trap_region;
-    pixman_region16_t clear_region;
+    cairo_region_t trap_region;
+    cairo_region_t clear_region;
     cairo_bool_t has_trap_region = FALSE;
     cairo_bool_t has_clear_region = FALSE;
     cairo_rectangle_int_t extents;
@@ -553,7 +553,7 @@ _clip_and_composite_trapezoids (cairo_pa
             if (status)
                 goto out;
 
-            _cairo_region_extents_rectangle (&trap_region, &trap_extents);
+            _cairo_region_get_extents (&trap_region, &trap_extents);
         } else {
             cairo_box_t trap_box;
             _cairo_traps_extents (traps, &trap_box);
@@ -573,9 +573,7 @@ _clip_and_composite_trapezoids (cairo_pa
              * _cairo_surface_fill_rectangles() or to drawing with a
              * clip region, then we have an additional region to clear.
              */
-            pixman_region_init_rect (&clear_region,
-                                     extents.x, extents.y,
-                                     extents.width, extents.height);
+            _cairo_region_init_rect (&clear_region, &extents);
 
             has_clear_region = TRUE;
             status = _cairo_clip_intersect_to_region (clip, &clear_region);
@@ -583,15 +581,14 @@ _clip_and_composite_trapezoids (cairo_pa
             if (status)
                 goto out;
 
-            _cairo_region_extents_rectangle (&clear_region,  &extents);
+            _cairo_region_get_extents (&clear_region, &extents);
 
-            if (!pixman_region_subtract (&clear_region, &clear_region, &trap_region)) {
-                status = CAIRO_STATUS_NO_MEMORY;
+            status = _cairo_region_subtract (&clear_region, &clear_region, &trap_region);
+            if (status)
                 goto out;
-            }
 
-            if (!pixman_region_not_empty (&clear_region)) {
-                pixman_region_fini (&clear_region);
+            if (!_cairo_region_not_empty (&clear_region)) {
+                _cairo_region_fini (&clear_region);
                 has_clear_region = FALSE;
             }
         } else {
@@ -665,9 +662,9 @@ _clip_and_composite_trapezoids (cairo_pa
 
 out:
     if (has_trap_region)
-        pixman_region_fini (&trap_region);
+        _cairo_region_fini (&trap_region);
     if (has_clear_region)
-        pixman_region_fini (&clear_region);
+        _cairo_region_fini (&clear_region);
 
     return status;
 }
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index a5c3109..05d9939 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -1,3 +1,4 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
 /* cairo - a vector graphics library with display and print output
  *
  * Copyright © 2002 University of Southern California
@@ -1220,7 +1221,7 @@ _cairo_surface_fill_rectangle (cairo_sur
  * @region: the region to modify, in backend coordinates
  *
  * Applies an operator to a set of rectangles specified as a
- * #pixman_region16_t using a solid color as the source.
+ * #cairo_region_t using a solid color as the source.
  * See _cairo_surface_fill_rectangles() for full details.
  *
  * Return value: %CAIRO_STATUS_SUCCESS or the error that occurred
@@ -1229,10 +1230,10 @@ cairo_status_t
 _cairo_surface_fill_region (cairo_surface_t	   *surface,
 			    cairo_operator_t	    op,
 			    const cairo_color_t    *color,
-			    pixman_region16_t      *region)
+			    cairo_region_t         *region)
 {
-    int num_rects;
-    pixman_box16_t *boxes;
+    int num_boxes;
+    cairo_box_int_t *boxes;
     cairo_rectangle_int_t stack_rects[CAIRO_STACK_BUFFER_SIZE / sizeof (cairo_rectangle_int_t)];
     cairo_rectangle_int_t *rects;
     cairo_status_t status;
@@ -1240,27 +1241,33 @@ _cairo_surface_fill_region (cairo_surfac
 
     assert (! surface->is_snapshot);
 
-    boxes = pixman_region_rectangles (region, &num_rects);
-    
-    if (!num_rects)
+    status = _cairo_region_get_boxes (region, &num_boxes, &boxes);
+    if (status)
+	return status;
+
+    if (num_boxes == 0)
 	return CAIRO_STATUS_SUCCESS;
 
     rects = stack_rects;
-    if (num_rects > ARRAY_LENGTH (stack_rects)) {
-	rects = _cairo_malloc_ab (num_rects, sizeof (cairo_rectangle_int_t));
-	if (!rects)
+    if (num_boxes > ARRAY_LENGTH (stack_rects)) {
+	rects = _cairo_malloc_ab (num_boxes, sizeof (cairo_rectangle_int_t));
+	if (!rects) {
+	    _cairo_region_boxes_fini (region, boxes);
 	    return CAIRO_STATUS_NO_MEMORY;
+        }
     }
 
-    for (i = 0; i < num_rects; i++) {
-	rects[i].x = boxes[i].x1;
-	rects[i].y = boxes[i].y1;
-	rects[i].width = boxes[i].x2 - boxes[i].x1;
-	rects[i].height = boxes[i].y2 - boxes[i].y1;
+    for (i = 0; i < num_boxes; i++) {
+	rects[i].x = boxes[i].p1.x;
+	rects[i].y = boxes[i].p1.y;
+	rects[i].width = boxes[i].p2.x - boxes[i].p1.x;
+	rects[i].height = boxes[i].p2.y - boxes[i].p1.y;
     }
 
     status =  _cairo_surface_fill_rectangles (surface, op,
-					      color, rects, num_rects);
+					      color, rects, num_boxes);
+
+    _cairo_region_boxes_fini (region, boxes);
 
     if (rects != stack_rects)
 	free (rects);
@@ -1630,7 +1637,7 @@ _cairo_surface_reset_clip (cairo_surface
 /**
  * _cairo_surface_set_clip_region:
  * @surface: the #cairo_surface_t to reset the clip on
- * @region: the #pixman_region16_t to use for clipping
+ * @region: the #cairo_region_t to use for clipping
  * @serial: the clip serial number associated with the region
  *
  * This function sets the clipping for the surface to
@@ -1639,7 +1646,7 @@ _cairo_surface_reset_clip (cairo_surface
  */
 cairo_status_t
 _cairo_surface_set_clip_region (cairo_surface_t	    *surface,
-				pixman_region16_t   *region,
+				cairo_region_t	    *region,
 				unsigned int	    serial)
 {
     cairo_status_t status;
@@ -1952,8 +1959,8 @@ _cairo_surface_composite_fixup_unbounded
     cairo_rectangle_int_t drawn_rectangle;
     cairo_bool_t has_drawn_region = FALSE;
     cairo_bool_t has_clear_region = FALSE;
-    pixman_region16_t drawn_region;
-    pixman_region16_t clear_region;
+    cairo_region_t drawn_region;
+    cairo_region_t clear_region;
     cairo_status_t status;
 
     /* The area that was drawn is the area in the destination rectangle but not within
@@ -1974,17 +1981,15 @@ _cairo_surface_composite_fixup_unbounded
 
     /* Now compute the area that is in dst_rectangle but not in drawn_rectangle
      */
-    pixman_region_init_rect (&drawn_region,
-                              drawn_rectangle.x, drawn_rectangle.y,
-                              drawn_rectangle.width, drawn_rectangle.height);
-    pixman_region_init_rect (&clear_region,
-                              dst_rectangle.x, dst_rectangle.y,
-                              dst_rectangle.width, dst_rectangle.height);
+    _cairo_region_init_rect (&drawn_region, &drawn_rectangle);
+    _cairo_region_init_rect (&clear_region, &dst_rectangle);
 
     has_drawn_region = TRUE;
     has_clear_region = TRUE;
 
-    if (!pixman_region_subtract (&clear_region, &clear_region, &drawn_region)) {
+    if (_cairo_region_subtract (&clear_region, &clear_region, &drawn_region)
+	!= CAIRO_STATUS_SUCCESS)
+    {
         status = CAIRO_STATUS_NO_MEMORY;
         goto CLEANUP_REGIONS;
     }
@@ -1995,9 +2000,9 @@ _cairo_surface_composite_fixup_unbounded
 
 CLEANUP_REGIONS:
     if (has_drawn_region)
-        pixman_region_fini (&drawn_region);
+        _cairo_region_fini (&drawn_region);
     if (has_clear_region)
-        pixman_region_fini (&clear_region);
+        _cairo_region_fini (&clear_region);
 
     return status;
 }
diff --git a/src/cairo-traps.c b/src/cairo-traps.c
index 5ed1f7c..0a1ccbe 100644
--- a/src/cairo-traps.c
+++ b/src/cairo-traps.c
@@ -575,29 +575,30 @@ _cairo_traps_extents (cairo_traps_t *tra
     *extents = traps->extents;
 }
 
+#define STACK_BOXES_LEN ((int) (CAIRO_STACK_BUFFER_SIZE / sizeof(cairo_box_int_t)))
+
 /**
  * _cairo_traps_extract_region:
  * @traps: a #cairo_traps_t
- * @region: on return, %NULL is stored here if the trapezoids aren't
- *          exactly representable as a pixman region, otherwise a
- *          a pointer to such a region, newly allocated.
- *          (free with pixman region destroy)
+ * @region: a #cairo_region_t
  *
  * Determines if a set of trapezoids are exactly representable as a
- * pixman region, and if so creates such a region.
+ * cairo region.  If so, the passed-in region is initialized to
+ * the area representing the given traps.  It should be finalized
+ * with _cairo_region_fini().  If not, %CAIRO_INT_STATUS_UNSUPPORTED
+ * is returned.
  *
  * Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_INT_STATUS_UNSUPPORTED
  * or %CAIRO_STATUS_NO_MEMORY
  **/
 cairo_int_status_t
-_cairo_traps_extract_region (cairo_traps_t     *traps,
-			     pixman_region16_t *region)
+_cairo_traps_extract_region (cairo_traps_t  *traps,
+			     cairo_region_t *region)
 {
-#define NUM_STATIC_BOXES 16
-    pixman_box16_t static_boxes[NUM_STATIC_BOXES];
-    pixman_box16_t *boxes;
+    cairo_box_int_t stack_boxes[STACK_BOXES_LEN];
+    cairo_box_int_t *boxes = stack_boxes;
     int i, box_count;
-    pixman_bool_t status;
+    cairo_int_status_t status;
 
     for (i = 0; i < traps->num_traps; i++)
 	if (!(traps->traps[i].left.p1.x == traps->traps[i].left.p2.x
@@ -609,11 +610,8 @@ _cairo_traps_extract_region (cairo_traps
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
 	}
 
-    if (traps->num_traps <= NUM_STATIC_BOXES) {
-	boxes = static_boxes;
-    } else {
-	/*boxes = _cairo_malloc2 (traps->num_traps, sizeof(pixman_box16_t));*/
-	boxes = malloc (traps->num_traps * sizeof(pixman_box16_t));
+    if (traps->num_traps > ARRAY_LENGTH(stack_boxes)) {
+	boxes = _cairo_malloc_ab (traps->num_traps, sizeof(cairo_box_int_t));
 
 	if (boxes == NULL)
 	    return CAIRO_STATUS_NO_MEMORY;
@@ -633,23 +631,21 @@ _cairo_traps_extract_region (cairo_traps
 	if (x1 == x2 || y1 == y2)
 	    continue;
 
-	boxes[box_count].x1 = (short) x1;
-	boxes[box_count].y1 = (short) y1;
-	boxes[box_count].x2 = (short) x2;
-	boxes[box_count].y2 = (short) y2;
+	boxes[box_count].p1.x = x1;
+	boxes[box_count].p1.y = y1;
+	boxes[box_count].p2.x = x2;
+	boxes[box_count].p2.y = y2;
 
 	box_count++;
     }
 
-    status = pixman_region_init_rects (region, boxes, box_count);
+    status = _cairo_region_init_boxes (region, boxes, box_count);
 
-    if (boxes != static_boxes)
+    if (boxes != stack_boxes)
 	free (boxes);
 
-    if (!status) {
-	pixman_region_fini (region);
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-    }
+    if (status)
+	_cairo_region_fini (region);
 
-    return CAIRO_STATUS_SUCCESS;
+    return status;
 }
diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index c698e10..f433b3d 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -1374,8 +1374,8 @@ _cairo_win32_surface_fill_rectangles (vo
 }
 
 static cairo_int_status_t
-_cairo_win32_surface_set_clip_region (void              *abstract_surface,
-				      pixman_region16_t *region)
+_cairo_win32_surface_set_clip_region (void           *abstract_surface,
+				      cairo_region_t *region)
 {
     cairo_win32_surface_t *surface = abstract_surface;
     cairo_status_t status;
@@ -1404,9 +1404,9 @@ _cairo_win32_surface_set_clip_region (vo
 	return CAIRO_STATUS_SUCCESS;
 
     } else {
-	pixman_box16_t *boxes = pixman_region_rects (region);
-	int num_boxes = pixman_region_num_rects (region);
-	pixman_box16_t *extents = pixman_region_extents (region);
+	cairo_rectangle_int_t extents;
+	cairo_box_int_t *boxes;
+	int num_boxes;
 	RGNDATA *data;
 	size_t data_size;
 	RECT *rects;
@@ -1415,10 +1415,16 @@ _cairo_win32_surface_set_clip_region (vo
 
 	/* Create a GDI region for the cairo region */
 
+	_cairo_region_get_extents (region, &extents);
+	if (_cairo_region_get_boxes (region, &num_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
+	    return CAIRO_STATUS_NO_MEMORY;
+
 	data_size = sizeof (RGNDATAHEADER) + num_boxes * sizeof (RECT);
 	data = malloc (data_size);
-	if (!data)
+	if (!data) {
+	    _cairo_region_boxes_fini (region, boxes);
 	    return CAIRO_STATUS_NO_MEMORY;
+	}
 	rects = (RECT *)data->Buffer;
 
 	data->rdh.dwSize = sizeof (RGNDATAHEADER);
@@ -1431,12 +1437,14 @@ _cairo_win32_surface_set_clip_region (vo
 	data->rdh.rcBound.bottom = extents->y2;
 
 	for (i = 0; i < num_boxes; i++) {
-	    rects[i].left = boxes[i].x1;
-	    rects[i].top = boxes[i].y1;
-	    rects[i].right = boxes[i].x2;
-	    rects[i].bottom = boxes[i].y2;
+	    rects[i].left = boxes[i].p1.x;
+	    rects[i].top = boxes[i].p1.y;
+	    rects[i].right = boxes[i].p2.x;
+	    rects[i].bottom = boxes[i].p2.y;
 	}
 
+	_cairo_region_boxes_fini (region, &boxes);
+
 	gdi_region = ExtCreateRegion (NULL, data_size, data);
 	free (data);
 
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index 1c78a53..684b43b 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -1532,8 +1532,8 @@ _cairo_xcb_surface_composite_trapezoids 
 }
 
 static cairo_int_status_t
-_cairo_xcb_surface_set_clip_region (void              *abstract_surface,
-				    pixman_region16_t *region)
+_cairo_xcb_surface_set_clip_region (void           *abstract_surface,
+				    cairo_region_t *region)
 {
     cairo_xcb_surface_t *surface = abstract_surface;
 
@@ -1554,28 +1554,32 @@ _cairo_xcb_surface_set_clip_region (void
 	    xcb_render_change_picture (surface->dpy, surface->dst_picture,
 		XCB_RENDER_CP_CLIP_MASK, none);
     } else {
-	pixman_box16_t *boxes;
+	cairo_box_int_t *boxes;
 	xcb_rectangle_t *rects = NULL;
 	int n_boxes, i;
 
-	n_boxes = pixman_region_num_rects (region);
+        if (_cairo_region_get_boxes (region, &n_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
+            return CAIRO_STATUS_NO_MEMORY;
+
 	if (n_boxes > 0) {
 	    rects = _cairo_malloc_ab (n_boxes, sizeof(xcb_rectangle_t));
-	    if (rects == NULL)
+	    if (rects == NULL) {
+                _cairo_region_boxes_fini (region, boxes);
 		return CAIRO_STATUS_NO_MEMORY;
+            }
 	} else {
 	    rects = NULL;
 	}
 
-	boxes = pixman_region_rects (region);
-
 	for (i = 0; i < n_boxes; i++) {
-	    rects[i].x = boxes[i].x1;
-	    rects[i].y = boxes[i].y1;
-	    rects[i].width = boxes[i].x2 - boxes[i].x1;
-	    rects[i].height = boxes[i].y2 - boxes[i].y1;
+	    rects[i].x = boxes[i].p1.x;
+	    rects[i].y = boxes[i].p1.y;
+	    rects[i].width = boxes[i].p2.x - boxes[i].p1.x;
+	    rects[i].height = boxes[i].p2.y - boxes[i].p1.y;
 	}
 
+        _cairo_region_boxes_fini (region, boxes);
+
 	surface->have_clip_rects = TRUE;
 	surface->clip_rects = rects;
 	surface->num_clip_rects = n_boxes;
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index b1acf04..b685637 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -1813,8 +1813,8 @@ _cairo_xlib_surface_composite_trapezoids
 }
 
 static cairo_int_status_t
-_cairo_xlib_surface_set_clip_region (void              *abstract_surface,
-				     pixman_region16_t *region)
+_cairo_xlib_surface_set_clip_region (void           *abstract_surface,
+				     cairo_region_t *region)
 {
     cairo_xlib_surface_t *surface = abstract_surface;
 
@@ -1830,28 +1830,32 @@ _cairo_xlib_surface_set_clip_region (voi
     surface->num_clip_rects = 0;
 
     if (region != NULL) {
-	pixman_box16_t *boxes;
+	cairo_box_int_t *boxes;
 	XRectangle *rects = NULL;
 	int n_boxes, i;
 
-	n_boxes = pixman_region_n_rects (region);
+        if (_cairo_region_get_boxes (region, &n_boxes, &boxes) != CAIRO_STATUS_SUCCESS)
+            return CAIRO_STATUS_NO_MEMORY;
+
 	if (n_boxes > ARRAY_LENGTH (surface->embedded_clip_rects)) {
 	    rects = _cairo_malloc_ab (n_boxes, sizeof(XRectangle));
-	    if (rects == NULL)
+	    if (rects == NULL) {
+                _cairo_region_boxes_fini (region, boxes);
 		return CAIRO_STATUS_NO_MEMORY;
-	}else {
+            }
+	} else {
 	    rects = surface->embedded_clip_rects;
 	}
 
-	boxes = pixman_region_rectangles (region, NULL);
-
 	for (i = 0; i < n_boxes; i++) {
-	    rects[i].x = boxes[i].x1;
-	    rects[i].y = boxes[i].y1;
-	    rects[i].width = boxes[i].x2 - boxes[i].x1;
-	    rects[i].height = boxes[i].y2 - boxes[i].y1;
+	    rects[i].x = boxes[i].p1.x;
+	    rects[i].y = boxes[i].p1.y;
+	    rects[i].width = boxes[i].p2.x - boxes[i].p1.x;
+	    rects[i].height = boxes[i].p2.y - boxes[i].p1.y;
 	}
 
+        _cairo_region_boxes_fini (region, boxes);
+
 	surface->have_clip_rects = TRUE;
 	surface->clip_rects = rects;
 	surface->num_clip_rects = n_boxes;
diff --git a/src/cairoint.h b/src/cairoint.h
index f06a9cc..37b672b 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -241,6 +241,8 @@ be32_to_cpu(uint32_t v)
 #include "cairo-hash-private.h"
 #include "cairo-cache-private.h"
 
+typedef struct _cairo_region cairo_region_t;
+
 typedef struct _cairo_point {
     cairo_fixed_t x;
     cairo_fixed_t y;
@@ -282,12 +284,34 @@ typedef struct _cairo_rectangle_int32 {
     uint32_t width, height;
 } cairo_rectangle_int32_t;
 
+typedef struct _cairo_point_int16 {
+    int16_t x, y;
+} cairo_point_int16_t;
+
+typedef struct _cairo_point_int32 {
+    int16_t x, y;
+} cairo_point_int32_t;
+
+typedef struct _cairo_box_int16 {
+    cairo_point_int16_t p1;
+    cairo_point_int16_t p2;
+} cairo_box_int16_t;
+
+typedef struct _cairo_box_int32 {
+    cairo_point_int32_t p1;
+    cairo_point_int32_t p2;
+} cairo_box_int32_t;
+
 #if CAIRO_FIXED_BITS == 32 && CAIRO_FIXED_FRAC_BITS >= 16
 typedef cairo_rectangle_int16_t cairo_rectangle_int_t;
+typedef cairo_point_int16_t cairo_point_int_t;
+typedef cairo_box_int16_t cairo_box_int_t;
 #define CAIRO_RECT_INT_MIN INT16_MIN
 #define CAIRO_RECT_INT_MAX INT16_MAX
 #elif CAIRO_FIXED_BITS == 32
 typedef cairo_rectangle_int32_t cairo_rectangle_int_t;
+typedef cairo_point_int32_t cairo_point_int_t;
+typedef cairo_box_int32_t cairo_box_int_t;
 #define CAIRO_RECT_INT_MIN INT32_MIN
 #define CAIRO_RECT_INT_MAX INT32_MAX
 #else
@@ -784,7 +808,7 @@ struct _cairo_surface_backend {
      */
     cairo_warn cairo_int_status_t
     (*set_clip_region)		(void			*surface,
-				 pixman_region16_t	*region);
+				 cairo_region_t		*region);
 
     /* Intersect the given path against the clip path currently set in
      * the surface, using the given fill_rule and tolerance, and set
@@ -1769,7 +1793,7 @@ cairo_private cairo_status_t
 _cairo_surface_fill_region (cairo_surface_t	   *surface,
 			    cairo_operator_t	    op,
 			    const cairo_color_t    *color,
-			    pixman_region16_t      *region);
+			    cairo_region_t         *region);
 
 cairo_private cairo_status_t
 _cairo_surface_fill_rectangles (cairo_surface_t		*surface,
@@ -1892,7 +1916,7 @@ _cairo_surface_reset_clip (cairo_surface
 
 cairo_private cairo_status_t
 _cairo_surface_set_clip_region (cairo_surface_t	    *surface,
-				pixman_region16_t   *region,
+				cairo_region_t      *region,
 				unsigned int	    serial);
 
 cairo_private cairo_int_status_t
@@ -2050,7 +2074,7 @@ _cairo_image_surface_assume_ownership_of
  */
 cairo_private cairo_int_status_t
 _cairo_image_surface_set_clip_region (void *abstract_surface,
-				      pixman_region16_t *region);
+				      cairo_region_t *region);
 
 cairo_private cairo_image_surface_t *
 _cairo_image_surface_clone (cairo_image_surface_t	*surface,
@@ -2227,7 +2251,7 @@ _cairo_traps_extents (cairo_traps_t *tra
 
 cairo_private cairo_int_status_t
 _cairo_traps_extract_region (cairo_traps_t     *tr,
-			     pixman_region16_t *region);
+			     cairo_region_t *region);
 
 cairo_private void
 _cairo_trapezoid_array_translate_and_scale (cairo_trapezoid_t *offset_traps,
@@ -2336,9 +2360,7 @@ _cairo_gstate_get_antialias (cairo_gstat
 
 /* cairo-region.c */
 
-cairo_private void
-_cairo_region_extents_rectangle (pixman_region16_t       *region,
-				 cairo_rectangle_int_t   *rect);
+#include "cairo-region-private.h"
 
 /* cairo_unicode.c */
 
diff --git a/src/test-paginated-surface.c b/src/test-paginated-surface.c
index 99bd67c..1e08c2d 100644
--- a/src/test-paginated-surface.c
+++ b/src/test-paginated-surface.c
@@ -107,7 +107,7 @@ _test_paginated_surface_finish (void *ab
 
 static cairo_int_status_t
 _test_paginated_surface_set_clip_region (void *abstract_surface,
-					 pixman_region16_t *region)
+					 cairo_region_t *region)
 {
     test_paginated_surface_t *surface = abstract_surface;
 
diff-tree dc035fecda0070e18a68e06f567f268fc39483f1 (from 58d9664702308639ead888c7167e71ca605a8fe3)
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date:   Mon Jun 18 17:34:36 2007 -0700

    [fixpt] Fix xcb surface to handle conversion to 16.16

diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index 97148f5..1c78a53 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -742,17 +742,17 @@ _cairo_xcb_surface_set_matrix (cairo_xcb
     if (!surface->src_picture)
 	return CAIRO_STATUS_SUCCESS;
 
-    xtransform.matrix11 = _cairo_fixed_from_double (matrix->xx);
-    xtransform.matrix12 = _cairo_fixed_from_double (matrix->xy);
-    xtransform.matrix13 = _cairo_fixed_from_double (matrix->x0);
-
-    xtransform.matrix21 = _cairo_fixed_from_double (matrix->yx);
-    xtransform.matrix22 = _cairo_fixed_from_double (matrix->yy);
-    xtransform.matrix23 = _cairo_fixed_from_double (matrix->y0);
+    xtransform.matrix11 = _cairo_fixed_16_16_from_double (matrix->xx);
+    xtransform.matrix12 = _cairo_fixed_16_16_from_double (matrix->xy);
+    xtransform.matrix13 = _cairo_fixed_16_16_from_double (matrix->x0);
+
+    xtransform.matrix21 = _cairo_fixed_16_16_from_double (matrix->yx);
+    xtransform.matrix22 = _cairo_fixed_16_16_from_double (matrix->yy);
+    xtransform.matrix23 = _cairo_fixed_16_16_from_double (matrix->y0);
 
     xtransform.matrix31 = 0;
     xtransform.matrix32 = 0;
-    xtransform.matrix33 = _cairo_fixed_from_double (1);
+    xtransform.matrix33 = 1 << 16;
 
     if (!CAIRO_SURFACE_RENDER_HAS_PICTURE_TRANSFORM (surface))
     {
@@ -1251,6 +1251,9 @@ _cairo_xcb_surface_fill_rectangles (void
 {
     cairo_xcb_surface_t *surface = abstract_surface;
     xcb_render_color_t render_color;
+    xcb_rectangle_t static_xrects[16];
+    xcb_rectangle_t *xrects = static_xrects;
+    int i;
 
     if (!CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLE (surface))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -1260,12 +1263,27 @@ _cairo_xcb_surface_fill_rectangles (void
     render_color.blue  = color->blue_short;
     render_color.alpha = color->alpha_short;
 
-    /* XXX: This xcb_rectangle_t cast is evil... it needs to go away somehow. */
+    if (num_rects > ARRAY_LENGTH(static_xrects)) {
+        xrects = malloc(sizeof(xcb_rectangle_t) * num_rects);
+        if (xrects == NULL)
+            return CAIRO_STATUS_NO_MEMORY;
+    }
+
+    for (i = 0; i < num_rects; i++) {
+        xrects[i].x = rects[i].x;
+        xrects[i].y = rects[i].y;
+        xrects[i].width = rects[i].width;
+        xrects[i].height = rects[i].height;
+    }
+
     _cairo_xcb_surface_ensure_dst_picture (surface);
     xcb_render_fill_rectangles (surface->dpy,
 			   _render_operator (op),
 			   surface->dst_picture,
-			   render_color, num_rects, (xcb_rectangle_t *) rects);
+			   render_color, num_rects, xrects);
+
+    if (xrects != static_xrects)
+        free(xrects);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -1333,16 +1351,16 @@ _create_trapezoid_mask (cairo_xcb_surfac
 	return XCB_NONE;
 
     for (i = 0; i < num_traps; i++) {
-	offset_traps[i].top = traps[i].top - 0x10000 * dst_y;
-	offset_traps[i].bottom = traps[i].bottom - 0x10000 * dst_y;
-	offset_traps[i].left.p1.x = traps[i].left.p1.x - 0x10000 * dst_x;
-	offset_traps[i].left.p1.y = traps[i].left.p1.y - 0x10000 * dst_y;
-	offset_traps[i].left.p2.x = traps[i].left.p2.x - 0x10000 * dst_x;
-	offset_traps[i].left.p2.y = traps[i].left.p2.y - 0x10000 * dst_y;
-	offset_traps[i].right.p1.x = traps[i].right.p1.x - 0x10000 * dst_x;
-	offset_traps[i].right.p1.y = traps[i].right.p1.y - 0x10000 * dst_y;
-	offset_traps[i].right.p2.x = traps[i].right.p2.x - 0x10000 * dst_x;
-	offset_traps[i].right.p2.y = traps[i].right.p2.y - 0x10000 * dst_y;
+	offset_traps[i].top = _cairo_fixed_to_16_16(traps[i].top) - 0x10000 * dst_y;
+	offset_traps[i].bottom = _cairo_fixed_to_16_16(traps[i].bottom) - 0x10000 * dst_y;
+	offset_traps[i].left.p1.x = _cairo_fixed_to_16_16(traps[i].left.p1.x) - 0x10000 * dst_x;
+	offset_traps[i].left.p1.y = _cairo_fixed_to_16_16(traps[i].left.p1.y) - 0x10000 * dst_y;
+	offset_traps[i].left.p2.x = _cairo_fixed_to_16_16(traps[i].left.p2.x) - 0x10000 * dst_x;
+	offset_traps[i].left.p2.y = _cairo_fixed_to_16_16(traps[i].left.p2.y) - 0x10000 * dst_y;
+	offset_traps[i].right.p1.x = _cairo_fixed_to_16_16(traps[i].right.p1.x) - 0x10000 * dst_x;
+	offset_traps[i].right.p1.y = _cairo_fixed_to_16_16(traps[i].right.p1.y) - 0x10000 * dst_y;
+	offset_traps[i].right.p2.x = _cairo_fixed_to_16_16(traps[i].right.p2.x) - 0x10000 * dst_x;
+        offset_traps[i].right.p2.y = _cairo_fixed_to_16_16(traps[i].right.p2.y) - 0x10000 * dst_y;
     }
 
     xcb_render_trapezoids (dst->dpy, XCB_RENDER_PICT_OP_ADD,
@@ -1470,14 +1488,41 @@ _cairo_xcb_surface_composite_trapezoids 
 								 dst_x, dst_y, width, height);
 
     } else {
-	/* XXX: The XTrapezoid cast is evil and needs to go away somehow. */
+        xcb_render_trapezoid_t xtraps_stack[16];
+        xcb_render_trapezoid_t *xtraps = xtraps_stack;
+        int i;
+
+        if (num_traps > ARRAY_LENGTH(xtraps_stack)) {
+            xtraps = malloc(sizeof(xcb_render_trapezoid_t) * num_traps);
+            if (xtraps == NULL) {
+                status = CAIRO_STATUS_NO_MEMORY;
+                goto BAIL;
+            }
+        }
+
+        for (i = 0; i < num_traps; i++) {
+            xtraps[i].top = _cairo_fixed_to_16_16(traps[i].top);
+            xtraps[i].bottom = _cairo_fixed_to_16_16(traps[i].bottom);
+            xtraps[i].left.p1.x = _cairo_fixed_to_16_16(traps[i].left.p1.x);
+            xtraps[i].left.p1.y = _cairo_fixed_to_16_16(traps[i].left.p1.y);
+            xtraps[i].left.p2.x = _cairo_fixed_to_16_16(traps[i].left.p2.x);
+            xtraps[i].left.p2.y = _cairo_fixed_to_16_16(traps[i].left.p2.y);
+            xtraps[i].right.p1.x = _cairo_fixed_to_16_16(traps[i].right.p1.x);
+            xtraps[i].right.p1.y = _cairo_fixed_to_16_16(traps[i].right.p1.y);
+            xtraps[i].right.p2.x = _cairo_fixed_to_16_16(traps[i].right.p2.x);
+            xtraps[i].right.p2.y = _cairo_fixed_to_16_16(traps[i].right.p2.y);
+        }
+
 	xcb_render_trapezoids (dst->dpy,
 				    _render_operator (op),
 				    src->src_picture, dst->dst_picture,
 				    render_format->id,
 				    render_src_x + attributes.x_offset,
 				    render_src_y + attributes.y_offset,
-				    num_traps, (xcb_render_trapezoid_t *) traps);
+				    num_traps, xtraps);
+
+        if (xtraps != xtraps_stack)
+            free(xtraps);
     }
 
  BAIL:
diff-tree 58d9664702308639ead888c7167e71ca605a8fe3 (from aaf94ef6c4656d7e836e52c2a71db214a1c01b57)
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date:   Mon Jun 18 17:33:44 2007 -0700

    [fixpt] Fix xlib surface to handle conversion to 16.16

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index d0c248f..b1acf04 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -987,17 +987,17 @@ _cairo_xlib_surface_set_matrix (cairo_xl
     if (!surface->src_picture)
 	return CAIRO_STATUS_SUCCESS;
 
-    xtransform.matrix[0][0] = _cairo_fixed_from_double (matrix->xx);
-    xtransform.matrix[0][1] = _cairo_fixed_from_double (matrix->xy);
-    xtransform.matrix[0][2] = _cairo_fixed_from_double (matrix->x0);
-
-    xtransform.matrix[1][0] = _cairo_fixed_from_double (matrix->yx);
-    xtransform.matrix[1][1] = _cairo_fixed_from_double (matrix->yy);
-    xtransform.matrix[1][2] = _cairo_fixed_from_double (matrix->y0);
+    xtransform.matrix[0][0] = _cairo_fixed_16_16_from_double (matrix->xx);
+    xtransform.matrix[0][1] = _cairo_fixed_16_16_from_double (matrix->xy);
+    xtransform.matrix[0][2] = _cairo_fixed_16_16_from_double (matrix->x0);
+
+    xtransform.matrix[1][0] = _cairo_fixed_16_16_from_double (matrix->yx);
+    xtransform.matrix[1][1] = _cairo_fixed_16_16_from_double (matrix->yy);
+    xtransform.matrix[1][2] = _cairo_fixed_16_16_from_double (matrix->y0);
 
     xtransform.matrix[2][0] = 0;
     xtransform.matrix[2][1] = 0;
-    xtransform.matrix[2][2] = _cairo_fixed_from_double (1);
+    xtransform.matrix[2][2] = 1 << 16;
 
     if (memcmp (&xtransform, &surface->xtransform, sizeof (XTransform)) == 0)
 	return CAIRO_STATUS_SUCCESS;
@@ -1527,6 +1527,9 @@ _cairo_xlib_surface_fill_rectangles (voi
 {
     cairo_xlib_surface_t *surface = abstract_surface;
     XRenderColor render_color;
+    XRectangle static_xrects[16];
+    XRectangle *xrects = static_xrects;
+    int i;
 
     _cairo_xlib_display_notify (surface->screen_info->display);
 
@@ -1538,12 +1541,27 @@ _cairo_xlib_surface_fill_rectangles (voi
     render_color.blue  = color->blue_short;
     render_color.alpha = color->alpha_short;
 
-    /* XXX: This XRectangle cast is evil... it needs to go away somehow. */
+    if (num_rects > ARRAY_LENGTH(static_xrects)) {
+        xrects = malloc(sizeof(XRectangle) * num_rects);
+        if (xrects == NULL)
+            return CAIRO_STATUS_NO_MEMORY;
+    }
+
+    for (i = 0; i < num_rects; i++) {
+        xrects[i].x = rects[i].x;
+        xrects[i].y = rects[i].y;
+        xrects[i].width = rects[i].width;
+        xrects[i].height = rects[i].height;
+    }
+
     _cairo_xlib_surface_ensure_dst_picture (surface);
     XRenderFillRectangles (surface->dpy,
 			   _render_operator (op),
 			   surface->dst_picture,
-			   &render_color, (XRectangle *) rects, num_rects);
+			   &render_color, xrects, num_rects);
+
+    if (xrects != static_xrects)
+        free(xrects);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -1615,16 +1633,16 @@ _create_trapezoid_mask (cairo_xlib_surfa
 	return None;
 
     for (i = 0; i < num_traps; i++) {
-	offset_traps[i].top = traps[i].top - 0x10000 * dst_y;
-	offset_traps[i].bottom = traps[i].bottom - 0x10000 * dst_y;
-	offset_traps[i].left.p1.x = traps[i].left.p1.x - 0x10000 * dst_x;
-	offset_traps[i].left.p1.y = traps[i].left.p1.y - 0x10000 * dst_y;
-	offset_traps[i].left.p2.x = traps[i].left.p2.x - 0x10000 * dst_x;
-	offset_traps[i].left.p2.y = traps[i].left.p2.y - 0x10000 * dst_y;
-	offset_traps[i].right.p1.x = traps[i].right.p1.x - 0x10000 * dst_x;
-	offset_traps[i].right.p1.y = traps[i].right.p1.y - 0x10000 * dst_y;
-	offset_traps[i].right.p2.x = traps[i].right.p2.x - 0x10000 * dst_x;
-	offset_traps[i].right.p2.y = traps[i].right.p2.y - 0x10000 * dst_y;
+	offset_traps[i].top = _cairo_fixed_to_16_16(traps[i].top) - 0x10000 * dst_y;
+	offset_traps[i].bottom = _cairo_fixed_to_16_16(traps[i].bottom) - 0x10000 * dst_y;
+	offset_traps[i].left.p1.x = _cairo_fixed_to_16_16(traps[i].left.p1.x) - 0x10000 * dst_x;
+	offset_traps[i].left.p1.y = _cairo_fixed_to_16_16(traps[i].left.p1.y) - 0x10000 * dst_y;
+	offset_traps[i].left.p2.x = _cairo_fixed_to_16_16(traps[i].left.p2.x) - 0x10000 * dst_x;
+	offset_traps[i].left.p2.y = _cairo_fixed_to_16_16(traps[i].left.p2.y) - 0x10000 * dst_y;
+	offset_traps[i].right.p1.x = _cairo_fixed_to_16_16(traps[i].right.p1.x) - 0x10000 * dst_x;
+	offset_traps[i].right.p1.y = _cairo_fixed_to_16_16(traps[i].right.p1.y) - 0x10000 * dst_y;
+	offset_traps[i].right.p2.x = _cairo_fixed_to_16_16(traps[i].right.p2.x) - 0x10000 * dst_x;
+	offset_traps[i].right.p2.y = _cairo_fixed_to_16_16(traps[i].right.p2.y) - 0x10000 * dst_y;
     }
 
     XRenderCompositeTrapezoids (dst->dpy, PictOpAdd,
@@ -1751,14 +1769,41 @@ _cairo_xlib_surface_composite_trapezoids
 								 dst_x, dst_y, width, height);
 
     } else {
-	/* XXX: The XTrapezoid cast is evil and needs to go away somehow. */
+        XTrapezoid xtraps_stack[16];
+        XTrapezoid *xtraps = xtraps_stack;
+        int i;
+
+        if (num_traps > ARRAY_LENGTH(xtraps_stack)) {
+            xtraps = malloc(sizeof(XTrapezoid) * num_traps);
+            if (xtraps == NULL) {
+                status = CAIRO_STATUS_NO_MEMORY;
+                goto BAIL;
+            }
+        }
+
+        for (i = 0; i < num_traps; i++) {
+            xtraps[i].top = _cairo_fixed_to_16_16(traps[i].top);
+            xtraps[i].bottom = _cairo_fixed_to_16_16(traps[i].bottom);
+            xtraps[i].left.p1.x = _cairo_fixed_to_16_16(traps[i].left.p1.x);
+            xtraps[i].left.p1.y = _cairo_fixed_to_16_16(traps[i].left.p1.y);
+            xtraps[i].left.p2.x = _cairo_fixed_to_16_16(traps[i].left.p2.x);
+            xtraps[i].left.p2.y = _cairo_fixed_to_16_16(traps[i].left.p2.y);
+            xtraps[i].right.p1.x = _cairo_fixed_to_16_16(traps[i].right.p1.x);
+            xtraps[i].right.p1.y = _cairo_fixed_to_16_16(traps[i].right.p1.y);
+            xtraps[i].right.p2.x = _cairo_fixed_to_16_16(traps[i].right.p2.x);
+            xtraps[i].right.p2.y = _cairo_fixed_to_16_16(traps[i].right.p2.y);
+        }
+
 	XRenderCompositeTrapezoids (dst->dpy,
 				    _render_operator (op),
 				    src->src_picture, dst->dst_picture,
 				    pict_format,
 				    render_src_x + attributes.x_offset,
 				    render_src_y + attributes.y_offset,
-				    (XTrapezoid *) traps, num_traps);
+				    xtraps, num_traps);
+
+        if (xtraps != xtraps_stack)
+            free(xtraps);
     }
 
  BAIL:
diff-tree aaf94ef6c4656d7e836e52c2a71db214a1c01b57 (from e5fdacae1c5b7005b95db8f9065cce51ef19bf20)
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date:   Mon Jun 18 17:29:04 2007 -0700

    [fixpt] remove dependency on some pixman types
    
    Introduce cairo_gradient_stop_t, and remove pixman dependency
    for core pattern types.  Perform conversion from cairo types
    to pixman types as necessary in fallback code.

diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c
index 9e51d04..17b11ef 100644
--- a/src/cairo-matrix.c
+++ b/src/cairo-matrix.c
@@ -736,13 +736,13 @@ _cairo_matrix_to_pixman_matrix (const ca
         *pixman_transform = pixman_identity_transform;
     }
     else {
-        pixman_transform->matrix[0][0] = _cairo_fixed_from_double (matrix->xx);
-        pixman_transform->matrix[0][1] = _cairo_fixed_from_double (matrix->xy);
-        pixman_transform->matrix[0][2] = _cairo_fixed_from_double (matrix->x0);
+        pixman_transform->matrix[0][0] = _cairo_fixed_16_16_from_double (matrix->xx);
+        pixman_transform->matrix[0][1] = _cairo_fixed_16_16_from_double (matrix->xy);
+        pixman_transform->matrix[0][2] = _cairo_fixed_16_16_from_double (matrix->x0);
 
-        pixman_transform->matrix[1][0] = _cairo_fixed_from_double (matrix->yx);
-        pixman_transform->matrix[1][1] = _cairo_fixed_from_double (matrix->yy);
-        pixman_transform->matrix[1][2] = _cairo_fixed_from_double (matrix->y0);
+        pixman_transform->matrix[1][0] = _cairo_fixed_16_16_from_double (matrix->yx);
+        pixman_transform->matrix[1][1] = _cairo_fixed_16_16_from_double (matrix->yy);
+        pixman_transform->matrix[1][2] = _cairo_fixed_16_16_from_double (matrix->y0);
 
         pixman_transform->matrix[2][0] = 0;
         pixman_transform->matrix[2][1] = 0;
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 00c427e..a4c4682 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -134,7 +134,7 @@ _cairo_gradient_pattern_init_copy (cairo
     else if (other->stops)
     {
 	pattern->stops = _cairo_malloc_ab (other->stops_size,
-					 sizeof (pixman_gradient_stop_t));
+					   sizeof (cairo_gradient_stop_t));
 	if (pattern->stops == NULL) {
 	    pattern->stops_size = 0;
 	    pattern->n_stops = 0;
@@ -143,7 +143,7 @@ _cairo_gradient_pattern_init_copy (cairo
 	}
 
 	memcpy (pattern->stops, other->stops,
-		other->n_stops * sizeof (pixman_gradient_stop_t));
+		other->n_stops * sizeof (cairo_gradient_stop_t));
     }
 
     return CAIRO_STATUS_SUCCESS;
@@ -273,10 +273,10 @@ _cairo_pattern_init_radial (cairo_radial
 
     pattern->c1.x = _cairo_fixed_from_double (cx0);
     pattern->c1.y = _cairo_fixed_from_double (cy0);
-    pattern->radius1 = _cairo_fixed_from_double (fabs (radius0));
+    pattern->r1   = _cairo_fixed_from_double (fabs (radius0));
     pattern->c2.x = _cairo_fixed_from_double (cx1);
     pattern->c2.y = _cairo_fixed_from_double (cy1);
-    pattern->radius2 = _cairo_fixed_from_double (fabs (radius1));
+    pattern->r2   = _cairo_fixed_from_double (fabs (radius1));
 }
 
 /* We use a small freed pattern cache here, because we don't want to
@@ -741,7 +741,7 @@ cairo_pattern_set_user_data (cairo_patte
 static cairo_status_t
 _cairo_pattern_gradient_grow (cairo_gradient_pattern_t *pattern)
 {
-    pixman_gradient_stop_t *new_stops;
+    cairo_gradient_stop_t *new_stops;
     int old_size = pattern->stops_size;
     int embedded_size = ARRAY_LENGTH (pattern->stops_embedded);
     int new_size = 2 * MAX (old_size, 4);
@@ -757,11 +757,11 @@ _cairo_pattern_gradient_grow (cairo_grad
     assert (pattern->n_stops <= pattern->stops_size);
 
     if (pattern->stops == pattern->stops_embedded) {
-	new_stops = _cairo_malloc_ab (new_size, sizeof (pixman_gradient_stop_t));
+	new_stops = _cairo_malloc_ab (new_size, sizeof (cairo_gradient_stop_t));
 	if (new_stops)
-	    memcpy (new_stops, pattern->stops, old_size * sizeof (pixman_gradient_stop_t));
+	    memcpy (new_stops, pattern->stops, old_size * sizeof (cairo_gradient_stop_t));
     } else {
-	new_stops = realloc (pattern->stops, new_size * sizeof (pixman_gradient_stop_t));
+	new_stops = realloc (pattern->stops, new_size * sizeof (cairo_gradient_stop_t));
     }
 
     if (new_stops == NULL) {
@@ -782,7 +782,7 @@ _cairo_pattern_add_color_stop (cairo_gra
 			       double			 blue,
 			       double			 alpha)
 {
-    pixman_gradient_stop_t *stops;
+    cairo_gradient_stop_t *stops;
     cairo_fixed_t	   x;
     unsigned int	   i;
 
@@ -802,7 +802,7 @@ _cairo_pattern_add_color_stop (cairo_gra
 	if (x < stops[i].x)
 	{
 	    memmove (&stops[i + 1], &stops[i],
-		     sizeof (pixman_gradient_stop_t) * (pattern->n_stops - i));
+		     sizeof (cairo_gradient_stop_t) * (pattern->n_stops - i));
 
 	    break;
 	}
@@ -810,10 +810,15 @@ _cairo_pattern_add_color_stop (cairo_gra
 
     stops[i].x = x;
 
-    stops[i].color.red   = _cairo_color_double_to_short (red);
-    stops[i].color.green = _cairo_color_double_to_short (green);
-    stops[i].color.blue  = _cairo_color_double_to_short (blue);
-    stops[i].color.alpha = _cairo_color_double_to_short (alpha);
+    stops[i].color.red   = red;
+    stops[i].color.green = green;
+    stops[i].color.blue  = blue;
+    stops[i].color.alpha = alpha;
+
+    stops[i].color.red_short   = _cairo_color_double_to_short (red);
+    stops[i].color.green_short = _cairo_color_double_to_short (green);
+    stops[i].color.blue_short  = _cairo_color_double_to_short (blue);
+    stops[i].color.alpha_short = _cairo_color_double_to_short (alpha);
 
     pattern->n_stops++;
 }
@@ -1143,27 +1148,62 @@ _cairo_pattern_acquire_surface_for_gradi
     cairo_status_t	  status;
     cairo_bool_t	  repeat = FALSE;
 
+    pixman_gradient_stop_t pixman_stops_static[2];
+    pixman_gradient_stop_t *pixman_stops = pixman_stops_static;
+    unsigned int i;
+
+    if (pattern->n_stops > ARRAY_LENGTH(pixman_stops_static)) {
+	pixman_stops = malloc(pattern->n_stops * sizeof(pixman_gradient_stop_t));
+	if (pixman_stops == NULL)
+	    return CAIRO_STATUS_NO_MEMORY;
+    }
+
+    for (i = 0; i < pattern->n_stops; i++) {
+	pixman_stops[i].x = _cairo_fixed_to_16_16 (pattern->stops[i].x);
+	pixman_stops[i].color.red = pattern->stops[i].color.red_short;
+	pixman_stops[i].color.green = pattern->stops[i].color.green_short;
+	pixman_stops[i].color.blue = pattern->stops[i].color.blue_short;
+	pixman_stops[i].color.alpha = pattern->stops[i].color.alpha_short;
+    }
+
     if (pattern->base.type == CAIRO_PATTERN_TYPE_LINEAR)
     {
 	cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) pattern;
+	pixman_point_fixed_t p1, p2;
+	pixman_linear_gradient_t gradient;
+
+	p1.x = _cairo_fixed_to_16_16 (linear->p1.x);
+	p1.y = _cairo_fixed_to_16_16 (linear->p1.y);
+	p2.x = _cairo_fixed_to_16_16 (linear->p2.x);
+	p2.y = _cairo_fixed_to_16_16 (linear->p2.y);
 
-	pixman_image = pixman_image_create_linear_gradient (&linear->p1,
-							    &linear->p2,
-							    pattern->stops,
+	pixman_image = pixman_image_create_linear_gradient (&p1, &p2,
+							    pixman_stops,
 							    pattern->n_stops);
     }
     else
     {
 	cairo_radial_pattern_t *radial = (cairo_radial_pattern_t *) pattern;
+	pixman_point_fixed_t c1, c2;
+	pixman_fixed_t r1, r2;
 
-	pixman_image = pixman_image_create_radial_gradient (&radial->c1,
-							    &radial->c2,
-							    radial->radius1,
-							    radial->radius2,
-							    pattern->stops,
+	c1.x = _cairo_fixed_to_16_16 (radial->c1.x);
+	c1.y = _cairo_fixed_to_16_16 (radial->c1.y);
+	r1   = _cairo_fixed_to_16_16 (radial->r1);
+
+	c2.x = _cairo_fixed_to_16_16 (radial->c2.x);
+	c2.y = _cairo_fixed_to_16_16 (radial->c2.y);
+	r2   = _cairo_fixed_to_16_16 (radial->r2);
+
+	pixman_image = pixman_image_create_radial_gradient (&c1, &c2,
+							    r1, r2,
+							    pixman_stops,
 							    pattern->n_stops);
     }
 
+    if (pixman_stops != pixman_stops_static)
+	free (pixman_stops);
+
     if (pixman_image == NULL)
 	return CAIRO_STATUS_NO_MEMORY;
 
@@ -1977,10 +2017,15 @@ _cairo_pattern_get_extents (cairo_patter
      * horizontal/vertical linear gradients).
      */
 
+    /* XXX: because extents are represented as x, y, w, h we can't
+     * actually have a rectangle that covers our entire valid
+     * coordinate space, since we'd need width/height to be 2*INT_MAX.
+     */
+
     extents->x = 0;
     extents->y = 0;
-    extents->width = INT16_MAX;
-    extents->height = INT16_MAX;
+    extents->width = CAIRO_RECT_INT_MAX;
+    extents->height = CAIRO_RECT_INT_MAX;
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -2208,13 +2253,13 @@ cairo_pattern_get_radial_circles (cairo_
     if (y0)
 	*y0 = _cairo_fixed_to_double (radial->c1.y);
     if (r0)
-	*r0 = _cairo_fixed_to_double (radial->radius1);
+	*r0 = _cairo_fixed_to_double (radial->r1);
     if (x1)
 	*x1 = _cairo_fixed_to_double (radial->c2.x);
     if (y1)
 	*y1 = _cairo_fixed_to_double (radial->c2.y);
     if (r1)
-	*r1 = _cairo_fixed_to_double (radial->radius2);
+	*r1 = _cairo_fixed_to_double (radial->r2);
 
     return CAIRO_STATUS_SUCCESS;
 }
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 9fdb0ca..a1a1b66 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -1566,10 +1566,10 @@ _cairo_pdf_surface_emit_radial_pattern (
     cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &surface->cairo_to_pdf);
     x1 = _cairo_fixed_to_double (pattern->c1.x);
     y1 = _cairo_fixed_to_double (pattern->c1.y);
-    r1 = _cairo_fixed_to_double (pattern->radius1);
+    r1 = _cairo_fixed_to_double (pattern->r1);
     x2 = _cairo_fixed_to_double (pattern->c2.x);
     y2 = _cairo_fixed_to_double (pattern->c2.y);
-    r2 = _cairo_fixed_to_double (pattern->radius2);
+    r2 = _cairo_fixed_to_double (pattern->r2);
 
     pattern_resource = _cairo_pdf_surface_new_object (surface);
     _cairo_output_stream_printf (surface->output,
@@ -3061,10 +3061,10 @@ _gradient_pattern_supported (cairo_patte
 
         x1 = _cairo_fixed_to_double (radial->c1.x);
         y1 = _cairo_fixed_to_double (radial->c1.y);
-        r1 = _cairo_fixed_to_double (radial->radius1);
+        r1 = _cairo_fixed_to_double (radial->r1);
         x2 = _cairo_fixed_to_double (radial->c2.x);
         y2 = _cairo_fixed_to_double (radial->c2.y);
-        r2 = _cairo_fixed_to_double (radial->radius2);
+        r2 = _cairo_fixed_to_double (radial->r2);
 
         d = sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1));
         if (d > fabs(r2 - r1)) {
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index c9aa1c0..01b1cc6 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -970,12 +970,12 @@ cairo_status_t
 _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t	 *scaled_font,
 					 const cairo_glyph_t	 *glyphs,
 					 int                      num_glyphs,
-					 cairo_rectangle_int_t   *extents)
+					 cairo_rectangle_int16_t *extents)
 {
     cairo_status_t status = CAIRO_STATUS_SUCCESS;
     int i;
-    int min_x = INT16_MAX, max_x = INT16_MIN;
-    int	min_y = INT16_MAX, max_y = INT16_MIN;
+    short min_x = INT16_MAX, max_x = INT16_MIN;
+    short min_y = INT16_MAX, max_y = INT16_MIN;
 
     if (scaled_font->status)
 	return scaled_font->status;
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index 93b1b61..c4c215b 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -991,7 +991,7 @@ _cairo_surface_fallback_show_glyphs (cai
 				     cairo_scaled_font_t	*scaled_font)
 {
     cairo_status_t status;
-    cairo_rectangle_int_t extents, glyph_extents;
+    cairo_rectangle_int_t extents;
     cairo_show_glyphs_info_t glyph_info;
 
     status = _cairo_surface_get_extents (surface, &extents);
@@ -999,6 +999,8 @@ _cairo_surface_fallback_show_glyphs (cai
 	return status;
 
     if (_cairo_operator_bounded_by_mask (op)) {
+        cairo_rectangle_int16_t glyph_extents;
+        cairo_rectangle_int_t glyph_extents_full;
 	status = _cairo_scaled_font_glyph_device_extents (scaled_font,
 							  glyphs,
 							  num_glyphs,
@@ -1006,7 +1008,11 @@ _cairo_surface_fallback_show_glyphs (cai
 	if (status)
 	    return status;
 
-	_cairo_rectangle_intersect (&extents, &glyph_extents);
+        glyph_extents_full.x = glyph_extents.x;
+        glyph_extents_full.y = glyph_extents.y;
+        glyph_extents_full.width = glyph_extents.width;
+        glyph_extents_full.height = glyph_extents.height;
+	_cairo_rectangle_intersect (&extents, &glyph_extents_full);
     }
 
     status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents);
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index ec0916a..5237c14 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -1,3 +1,4 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
 /* cairo - a vector graphics library with display and print output
  *
  * Copyright © 2004 Red Hat, Inc
@@ -1197,7 +1198,7 @@ _cairo_svg_surface_emit_pattern_stops (c
 		    cairo_bool_t reverse_stops,
 		    cairo_bool_t emulate_reflect)
 {
-    pixman_gradient_stop_t *stops;
+    cairo_gradient_stop_t *stops;
     double offset;
     unsigned int n_stops;
     unsigned int i;
@@ -1211,16 +1212,16 @@ _cairo_svg_surface_emit_pattern_stops (c
 					 "stop-color: rgb(%f%%,%f%%,%f%%); "
 					 "stop-opacity: %f;\"/>\n",
 					 _cairo_fixed_to_double (pattern->stops[0].x),
-					 pattern->stops[0].color.red   / 655.35,
-					 pattern->stops[0].color.green / 655.35,
-					 pattern->stops[0].color.blue  / 655.35,
-					 pattern->stops[0].color.alpha / 65535.0);
+					 pattern->stops[0].color.red   * 100.0,
+					 pattern->stops[0].color.green * 100.0,
+					 pattern->stops[0].color.blue  * 100.0,
+					 pattern->stops[0].color.alpha);
 	    return;
     }
 
     if (emulate_reflect || reverse_stops) {
 	n_stops = emulate_reflect ? pattern->n_stops * 2 - 2: pattern->n_stops;
-	stops = _cairo_malloc_ab (n_stops, sizeof (pixman_gradient_stop_t));
+	stops = _cairo_malloc_ab (n_stops, sizeof (cairo_gradient_stop_t));
 
 	for (i = 0; i < pattern->n_stops; i++) {
 	    if (reverse_stops) {
@@ -1259,22 +1260,22 @@ _cairo_svg_surface_emit_pattern_stops (c
 					 "stop-color: rgb(%f%%,%f%%,%f%%); "
 					 "stop-opacity: %f;\"/>\n",
 					 offset,
-					 stops[i].color.red   / 655.35,
-					 stops[i].color.green / 655.35,
-					 stops[i].color.blue  / 655.35,
-					 stops[i].color.alpha / 65535.0);
+					 stops[i].color.red   * 100.0,
+					 stops[i].color.green * 100.0,
+					 stops[i].color.blue  * 100.0,
+					 stops[i].color.alpha);
 	}
     else {
 	cairo_bool_t found = FALSE;
 	unsigned int offset_index;
-	pixman_color_t offset_color_start, offset_color_stop;
+	cairo_color_t offset_color_start, offset_color_stop;
 
 	for (i = 0; i < n_stops; i++) {
 	    if (_cairo_fixed_to_double (stops[i].x) >= -start_offset) {
 		if (i > 0) {
 		    if (stops[i].x != stops[i-1].x) {
 			double x0, x1;
-			pixman_color_t *color0, *color1;
+			cairo_color_t *color0, *color1;
 
 			x0 = _cairo_fixed_to_double (stops[i-1].x);
 			x1 = _cairo_fixed_to_double (stops[i].x);
@@ -1310,20 +1311,20 @@ _cairo_svg_surface_emit_pattern_stops (c
 				     "<stop offset=\"0\" style=\""
 				     "stop-color: rgb(%f%%,%f%%,%f%%); "
 				     "stop-opacity: %f;\"/>\n",
-				     offset_color_start.red   / 655.35,
-				     offset_color_start.green / 655.35,
-				     offset_color_start.blue  / 655.35,
-				     offset_color_start.alpha / 65535.0);
+				     offset_color_start.red   * 100.0,
+				     offset_color_start.green * 100.0,
+				     offset_color_start.blue  * 100.0,
+				     offset_color_start.alpha);
 	for (i = offset_index; i < n_stops; i++) {
 	    _cairo_output_stream_printf (output,
 					 "<stop offset=\"%f\" style=\""
 					 "stop-color: rgb(%f%%,%f%%,%f%%); "
 					 "stop-opacity: %f;\"/>\n",
 					 _cairo_fixed_to_double (stops[i].x) + start_offset,
-					 stops[i].color.red   / 655.35,
-					 stops[i].color.green / 655.35,
-					 stops[i].color.blue  / 655.35,
-					 stops[i].color.alpha / 65535.0);
+					 stops[i].color.red   * 100.0,
+					 stops[i].color.green * 100.0,
+					 stops[i].color.blue  * 100.0,
+					 stops[i].color.alpha);
 	}
 	for (i = 0; i < offset_index; i++) {
 	    _cairo_output_stream_printf (output,
@@ -1331,20 +1332,20 @@ _cairo_svg_surface_emit_pattern_stops (c
 					 "stop-color: rgb(%f%%,%f%%,%f%%); "
 					 "stop-opacity: %f;\"/>\n",
 					 1.0 + _cairo_fixed_to_double (stops[i].x) + start_offset,
-					 stops[i].color.red   / 655.35,
-					 stops[i].color.green / 655.35,
-					 stops[i].color.blue  / 655.35,
-					 stops[i].color.alpha / 65535.0);
+					 stops[i].color.red   * 100.0,
+					 stops[i].color.green * 100.0,
+					 stops[i].color.blue  * 100.0,
+					 stops[i].color.alpha);
 	}
 
 	_cairo_output_stream_printf (output,
 				     "<stop offset=\"1\" style=\""
 				     "stop-color: rgb(%f%%,%f%%,%f%%); "
 				     "stop-opacity: %f;\"/>\n",
-				     offset_color_stop.red   / 655.35,
-				     offset_color_stop.green / 655.35,
-				     offset_color_stop.blue  / 655.35,
-				     offset_color_stop.alpha / 65535.0);
+				     offset_color_stop.red   * 100.0,
+				     offset_color_stop.green * 100.0,
+				     offset_color_stop.blue  * 100.0,
+				     offset_color_stop.alpha);
 
     }
 
@@ -1428,22 +1429,22 @@ _cairo_svg_surface_emit_radial_pattern (
     double fx, fy;
     cairo_bool_t reverse_stops;
     cairo_status_t status;
-    pixman_point_fixed_t *c0, *c1;
-    pixman_fixed_t radius0, radius1;
+    cairo_point_t &c0, &c1;
+    cairo_fixed_t radius0, radius1;
 
     extend = pattern->base.base.extend;
 
     if (pattern->radius1 < pattern->radius2) {
 	c0 = &pattern->c1;
 	c1 = &pattern->c2;
-	radius0 = pattern->radius1;
-	radius1 = pattern->radius2;
+	radius0 = pattern->r1;
+	radius1 = pattern->r2;
 	reverse_stops = FALSE;
     } else {
 	c0 = &pattern->c2;
 	c1 = &pattern->c1;
-	radius0 = pattern->radius2;
-	radius1 = pattern->radius1;
+	radius0 = pattern->r2;
+	radius1 = pattern->r1;
 	reverse_stops = TRUE;
     }
 
@@ -1459,7 +1460,7 @@ _cairo_svg_surface_emit_radial_pattern (
     if (status)
 	return status;
 
-    if (pattern->radius1 == pattern->radius2) {
+    if (radius0 == radius1) {
 	_cairo_output_stream_printf (document->xml_node_defs,
 				     "<radialGradient id=\"radial%d\" "
 				     "gradientUnits=\"userSpaceOnUse\" "
@@ -1482,19 +1483,19 @@ _cairo_svg_surface_emit_radial_pattern (
 					 "<stop offset=\"0\" style=\""
 					 "stop-color: rgb(%f%%,%f%%,%f%%); "
 					 "stop-opacity: %f;\"/>\n",
-					 pattern->base.stops[0].color.red   / 655.35,
-					 pattern->base.stops[0].color.green / 655.35,
-					 pattern->base.stops[0].color.blue  / 655.35,
-					 pattern->base.stops[0].color.alpha / 65535.0);
+					 pattern->base.stops[0].color.red   * 100.0,
+					 pattern->base.stops[0].color.green * 100.0,
+					 pattern->base.stops[0].color.blue  * 100.0,
+					 pattern->base.stops[0].color.alpha);
 	    if (pattern->base.n_stops > 1)
 		_cairo_output_stream_printf (document->xml_node_defs,
 					     "<stop offset=\"0\" style=\""
 					     "stop-color: rgb(%f%%,%f%%,%f%%); "
 					     "stop-opacity: %f;\"/>\n",
-					     pattern->base.stops[1].color.red   / 655.35,
-					     pattern->base.stops[1].color.green / 655.35,
-					     pattern->base.stops[1].color.blue  / 655.35,
-					     pattern->base.stops[1].color.alpha / 65535.0);
+					     pattern->base.stops[1].color.red   * 100.0,
+					     pattern->base.stops[1].color.green * 100.0,
+					     pattern->base.stops[1].color.blue  * 100.0,
+					     pattern->base.stops[1].color.alpha);
 	}
 
     } else {
diff --git a/src/cairoint.h b/src/cairoint.h
index f0ea702..f06a9cc 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -998,33 +998,34 @@ typedef struct _cairo_surface_pattern {
     cairo_surface_t *surface;
 } cairo_surface_pattern_t;
 
+typedef struct _cairo_gradient_stop {
+    cairo_fixed_t x;
+    cairo_color_t color;
+} cairo_gradient_stop_t;
+
 typedef struct _cairo_gradient_pattern {
     cairo_pattern_t base;
 
     unsigned int	    n_stops;
     unsigned int	    stops_size;
-    pixman_gradient_stop_t *stops;
-    pixman_gradient_stop_t  stops_embedded[2];
+    cairo_gradient_stop_t  *stops;
+    cairo_gradient_stop_t   stops_embedded[2];
 } cairo_gradient_pattern_t;
 
 typedef struct _cairo_linear_pattern {
     cairo_gradient_pattern_t base;
 
-    pixman_point_fixed_t     p1;
-    pixman_point_fixed_t     p2;
-    pixman_gradient_stop_t  *stops;
-    int			     n_stops;
+    cairo_point_t p1;
+    cairo_point_t p2;
 } cairo_linear_pattern_t;
 
 typedef struct _cairo_radial_pattern {
     cairo_gradient_pattern_t base;
 
-    pixman_point_fixed_t     c1;
-    pixman_point_fixed_t     c2;
-    pixman_fixed_t           radius1;
-    pixman_fixed_t           radius2;
-    pixman_gradient_stop_t  *stops;
-    int                      n_stops;
+    cairo_point_t c1;
+    cairo_fixed_t r1;
+    cairo_point_t c2;
+    cairo_fixed_t r2;
 } cairo_radial_pattern_t;
 
 typedef union {
@@ -1643,7 +1644,7 @@ cairo_private cairo_status_t
 _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t	 *scaled_font,
 					 const cairo_glyph_t	 *glyphs,
 					 int                      num_glyphs,
-					 cairo_rectangle_int_t   *extents);
+					 cairo_rectangle_int16_t *extents);
 
 cairo_private cairo_status_t
 _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
diff-tree e5fdacae1c5b7005b95db8f9065cce51ef19bf20 (from be3516335cda8587d9baf5bd0097d3ce1cb64ab1)
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date:   Mon Jun 18 17:05:34 2007 -0700

    [fixpt] fix up image surface to translate to 16.16 for pixman

diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 4959c33..b833d09 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -1,3 +1,4 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
 /* cairo - a vector graphics library with display and print output
  *
  * Copyright © 2003 University of Southern California
@@ -821,6 +822,8 @@ _cairo_image_surface_composite (cairo_op
     return status;
 }
 
+#define STACK_RECTS_LEN (CAIRO_STACK_BUFFER_SIZE / sizeof(pixman_rectangle16_t))
+
 static cairo_int_status_t
 _cairo_image_surface_fill_rectangles (void		      *abstract_surface,
 				      cairo_operator_t	       op,
@@ -831,24 +834,48 @@ _cairo_image_surface_fill_rectangles (vo
     cairo_image_surface_t *surface = abstract_surface;
 
     pixman_color_t pixman_color;
+    pixman_rectangle16_t stack_rects[STACK_RECTS_LEN];
+    pixman_rectangle16_t *pixman_rects = stack_rects;
+    int i;
+
+    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
 
     pixman_color.red   = color->red_short;
     pixman_color.green = color->green_short;
     pixman_color.blue  = color->blue_short;
     pixman_color.alpha = color->alpha_short;
 
+    if (num_rects > ARRAY_LENGTH(stack_rects)) {
+	pixman_rects = _cairo_malloc_ab (num_rects, sizeof(pixman_rectangle16_t));
+	if (pixman_rects == NULL)
+	    return CAIRO_STATUS_NO_MEMORY;
+    }		 
+
+    for (i = 0; i < num_rects; i++) {
+	pixman_rects[i].x = rects[i].x;
+	pixman_rects[i].y = rects[i].y;
+	pixman_rects[i].width = rects[i].width;
+	pixman_rects[i].height = rects[i].height;
+    }
+
     /* XXX: pixman_fill_rectangles() should be implemented */
-    /* XXX: The pixman_rectangle_t cast is evil... it needs to go away somehow. */
     if (!pixman_image_fill_rectangles (_pixman_operator(op),
 				       surface->pixman_image,
 				       &pixman_color,
 				       num_rects,
-				       (pixman_rectangle16_t *) rects))
-	return CAIRO_STATUS_NO_MEMORY;
+				       pixman_rects))
+	status = CAIRO_STATUS_NO_MEMORY;
 
-    return CAIRO_STATUS_SUCCESS;
+    if (pixman_rects != stack_rects)
+	free (pixman_rects);
+
+    return status;
 }
 
+#undef STACK_RECTS_LEN
+
+#define STACK_TRAPS_LEN ((int) (CAIRO_STACK_BUFFER_SIZE / sizeof(pixman_trapezoid_t)))
+
 static cairo_int_status_t
 _cairo_image_surface_composite_trapezoids (cairo_operator_t	op,
 					   cairo_pattern_t	*pattern,
@@ -870,9 +897,31 @@ _cairo_image_surface_composite_trapezoid
     pixman_image_t		*mask;
     pixman_format_code_t	 format;
     uint32_t			*mask_data;
+    pixman_trapezoid_t		 stack_traps[STACK_TRAPS_LEN];
+    pixman_trapezoid_t		*pixman_traps = stack_traps;
     int				 mask_stride;
     int				 mask_bpp;
-    int				 ret;
+    int				 ret, i;
+
+    /* Convert traps to pixman traps */
+    if (num_traps > ARRAY_LENGTH(stack_traps)) {
+	pixman_traps = malloc (num_traps * sizeof(pixman_trapezoid_t));
+	if (pixman_traps == NULL)
+	    return CAIRO_STATUS_NO_MEMORY;
+    }
+
+    for (i = 0; i < num_traps; i++) {
+	pixman_traps[i].top = _cairo_fixed_to_16_16 (traps[i].top);
+	pixman_traps[i].bottom = _cairo_fixed_to_16_16 (traps[i].bottom);
+	pixman_traps[i].left.p1.x = _cairo_fixed_to_16_16 (traps[i].left.p1.x);
+	pixman_traps[i].left.p1.y = _cairo_fixed_to_16_16 (traps[i].left.p1.y);
+	pixman_traps[i].left.p2.x = _cairo_fixed_to_16_16 (traps[i].left.p2.x);
+	pixman_traps[i].left.p2.y = _cairo_fixed_to_16_16 (traps[i].left.p2.y);
+	pixman_traps[i].right.p1.x = _cairo_fixed_to_16_16 (traps[i].right.p1.x);
+	pixman_traps[i].right.p1.y = _cairo_fixed_to_16_16 (traps[i].right.p1.y);
+	pixman_traps[i].right.p2.x = _cairo_fixed_to_16_16 (traps[i].right.p2.x);
+	pixman_traps[i].right.p2.y = _cairo_fixed_to_16_16 (traps[i].right.p2.y);
+    }
 
     /* Special case adding trapezoids onto a mask surface; we want to avoid
      * creating an intermediate temporary mask unecessarily.
@@ -894,8 +943,9 @@ _cairo_image_surface_composite_trapezoid
 	antialias != CAIRO_ANTIALIAS_NONE)
     {
 	pixman_add_trapezoids (dst->pixman_image, 0, 0,
-			       num_traps, (pixman_trapezoid_t *) traps);
-	return CAIRO_STATUS_SUCCESS;
+			       num_traps, pixman_traps);
+	status = CAIRO_STATUS_SUCCESS;
+	goto finish;
     }
 
     status = _cairo_pattern_acquire_surface (pattern, &dst->base,
@@ -903,7 +953,7 @@ _cairo_image_surface_composite_trapezoid
 					     (cairo_surface_t **) &src,
 					     &attributes);
     if (status)
-	return status;
+	goto finish;
 
     status = _cairo_image_surface_set_attributes (src, &attributes);
     if (status)
@@ -943,10 +993,8 @@ _cairo_image_surface_composite_trapezoid
 	goto CLEANUP_IMAGE_DATA;
     }
 
-    /* XXX: The pixman_trapezoid_t cast is evil and needs to go away
-     * somehow. */
     pixman_add_trapezoids (mask, - dst_x, - dst_y,
-			   num_traps, (pixman_trapezoid_t *) traps);
+			   num_traps, pixman_traps);
 
     pixman_image_composite (_pixman_operator (op),
 			    src->pixman_image,
@@ -973,9 +1021,15 @@ _cairo_image_surface_composite_trapezoid
  CLEANUP_SOURCE:
     _cairo_pattern_release_surface (pattern, &src->base, &attributes);
 
+ finish:
+    if (pixman_traps != stack_traps)
+	free (pixman_traps);
+
     return status;
 }
 
+#undef STACK_TRAPS_LEN
+
 cairo_int_status_t
 _cairo_image_surface_set_clip_region (void *abstract_surface,
 				      pixman_region16_t *region)
diff-tree be3516335cda8587d9baf5bd0097d3ce1cb64ab1 (from 9c38aa3b96a1e926ef422837fc3102e902a796fc)
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date:   Mon Jun 18 16:56:24 2007 -0700

    [fixpt] Replace cairo_rectangle_int16_t with cairo_rectangle_int_t
    
    Mostly s/cairo_rectangle_int16_t/cairo_rectangle_int_t/,
    as well as definitions to pick cairo_rectangle_int_t.

diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index 26a373f..ff7e7d8 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -49,7 +49,7 @@ typedef struct {
 
 static cairo_int_status_t
 _cairo_analysis_surface_get_extents (void	 		*abstract_surface,
-				     cairo_rectangle_int16_t	*rectangle)
+				     cairo_rectangle_int_t	*rectangle)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
 
diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h
index e7190cf..fa39423 100644
--- a/src/cairo-clip-private.h
+++ b/src/cairo-clip-private.h
@@ -63,7 +63,7 @@ struct _cairo_clip {
      * clip paths
      */
     cairo_surface_t *surface;
-    cairo_rectangle_int16_t surface_rect;
+    cairo_rectangle_int_t surface_rect;
     /*
      * Surface clip serial number to store
      * in the surface when this clip is set
@@ -105,7 +105,7 @@ _cairo_clip_clip (cairo_clip_t       *cl
 
 cairo_private cairo_status_t
 _cairo_clip_intersect_to_rectangle (cairo_clip_t            *clip,
-				    cairo_rectangle_int16_t *rectangle);
+				    cairo_rectangle_int_t   *rectangle);
 
 cairo_private cairo_status_t
 _cairo_clip_intersect_to_region (cairo_clip_t      *clip,
@@ -117,7 +117,7 @@ _cairo_clip_combine_to_surface (cairo_cl
 				cairo_surface_t               *dst,
 				int                            dst_x,
 				int                            dst_y,
-				const cairo_rectangle_int16_t *extents);
+				const cairo_rectangle_int_t   *extents);
 
 cairo_private void
 _cairo_clip_translate (cairo_clip_t  *clip,
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index abc5033..e670456 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -120,13 +120,13 @@ _cairo_clip_reset (cairo_clip_t *clip)
 
 static cairo_status_t
 _cairo_clip_path_intersect_to_rectangle (cairo_clip_path_t       *clip_path,
-   				         cairo_rectangle_int16_t *rectangle)
+   				         cairo_rectangle_int_t   *rectangle)
 {
     while (clip_path) {
         cairo_status_t status;
         cairo_traps_t traps;
         cairo_box_t extents;
-        cairo_rectangle_int16_t extents_rect;
+        cairo_rectangle_int_t extents_rect;
 
         _cairo_traps_init (&traps);
 
@@ -153,7 +153,7 @@ _cairo_clip_path_intersect_to_rectangle 
 
 cairo_status_t
 _cairo_clip_intersect_to_rectangle (cairo_clip_t            *clip,
-				    cairo_rectangle_int16_t *rectangle)
+				    cairo_rectangle_int_t *rectangle)
 {
     if (!clip)
 	return CAIRO_STATUS_SUCCESS;
@@ -240,7 +240,7 @@ _cairo_clip_combine_to_surface (cairo_cl
 				cairo_surface_t               *dst,
 				int                           dst_x,
 				int                           dst_y,
-				const cairo_rectangle_int16_t *extents)
+				const cairo_rectangle_int_t *extents)
 {
     cairo_pattern_union_t pattern;
     cairo_status_t status;
@@ -372,7 +372,7 @@ _cairo_clip_intersect_mask (cairo_clip_t
 {
     cairo_pattern_union_t pattern;
     cairo_box_t extents;
-    cairo_rectangle_int16_t surface_rect, target_rect;
+    cairo_rectangle_int_t surface_rect, target_rect;
     cairo_surface_t *surface;
     cairo_status_t status;
 
@@ -648,7 +648,7 @@ _cairo_clip_copy_rectangle_list (cairo_c
             }
         }
     } else {
-        cairo_rectangle_int16_t extents;
+        cairo_rectangle_int_t extents;
         if (_cairo_surface_get_extents (_cairo_gstate_get_target (gstate),
 		                        &extents) != CAIRO_STATUS_SUCCESS) {
             free (rectangles);
diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c
index 5505501..d6f827c 100644
--- a/src/cairo-directfb-surface.c
+++ b/src/cairo-directfb-surface.c
@@ -320,9 +320,9 @@ _directfb_buffer_surface_create (IDirect
 
 static cairo_status_t
 _directfb_acquire_surface (cairo_directfb_surface_t *surface, 
-                                              cairo_rectangle_int16_t *intrest_rec,
+                                              cairo_rectangle_int_t *intrest_rec,
                                               cairo_image_surface_t **image_out,
-                                              cairo_rectangle_int16_t *image_rect_out,
+                                              cairo_rectangle_int_t *image_rect_out,
                                               void                  **image_extra,
                                               DFBSurfaceLockFlags       lock_flags)
 {   
@@ -499,9 +499,9 @@ _cairo_directfb_surface_release_source_i
 
 static cairo_status_t
 _cairo_directfb_surface_acquire_dest_image (void                   *abstract_surface,
-                                            cairo_rectangle_int16_t      *interest_rect,
+                                            cairo_rectangle_int_t      *interest_rect,
                                             cairo_image_surface_t **image_out,
-                                            cairo_rectangle_int16_t      *image_rect_out,
+                                            cairo_rectangle_int_t      *image_rect_out,
                                             void                  **image_extra)
 {
     cairo_directfb_surface_t *surface = abstract_surface;
@@ -515,9 +515,9 @@ _cairo_directfb_surface_acquire_dest_ima
 
 static void
 _cairo_directfb_surface_release_dest_image (void                  *abstract_surface,
-                                            cairo_rectangle_int16_t     *interest_rect,
+                                            cairo_rectangle_int_t     *interest_rect,
                                             cairo_image_surface_t *image,
-                                            cairo_rectangle_int16_t     *image_rect,
+                                            cairo_rectangle_int_t     *image_rect,
                                             void                  *image_extra)
 {
     cairo_directfb_surface_t *surface = abstract_surface;
@@ -911,7 +911,7 @@ static cairo_int_status_t
 _cairo_directfb_surface_fill_rectangles (void                *abstract_surface,
                                          cairo_operator_t     op,
                                          const cairo_color_t *color,
-                                         cairo_rectangle_int16_t   *rects,
+                                         cairo_rectangle_int_t   *rects,
                                          int                  n_rects)
 {
     cairo_directfb_surface_t *dst = abstract_surface;
@@ -1142,7 +1142,7 @@ _cairo_directfb_surface_set_clip_region 
 
 static cairo_int_status_t
 _cairo_directfb_abstract_surface_get_extents (void              *abstract_surface,
-                                              cairo_rectangle_int16_t *rectangle)
+                                              cairo_rectangle_int_t *rectangle)
 {
     cairo_directfb_surface_t *surface = abstract_surface;
     
diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c
index 51ba56b..72754ad 100644
--- a/src/cairo-glitz-surface.c
+++ b/src/cairo-glitz-surface.c
@@ -152,9 +152,9 @@ _CAIRO_MASK_FORMAT (cairo_format_masks_t
 
 static cairo_status_t
 _cairo_glitz_surface_get_image (cairo_glitz_surface_t   *surface,
-				cairo_rectangle_int16_t *interest,
+				cairo_rectangle_int_t   *interest,
 				cairo_image_surface_t  **image_out,
-				cairo_rectangle_int16_t *rect_out)
+				cairo_rectangle_int_t   *rect_out)
 {
     cairo_image_surface_t *image;
     int			  x1, y1, x2, y2;
@@ -426,9 +426,9 @@ _cairo_glitz_surface_release_source_imag
 
 static cairo_status_t
 _cairo_glitz_surface_acquire_dest_image (void                    *abstract_surface,
-					 cairo_rectangle_int16_t *interest_rect,
+					 cairo_rectangle_int_t   *interest_rect,
 					 cairo_image_surface_t  **image_out,
-					 cairo_rectangle_int16_t *image_rect_out,
+					 cairo_rectangle_int_t   *image_rect_out,
 					 void                   **image_extra)
 {
     cairo_glitz_surface_t *surface = abstract_surface;
@@ -448,9 +448,9 @@ _cairo_glitz_surface_acquire_dest_image 
 
 static void
 _cairo_glitz_surface_release_dest_image (void                    *abstract_surface,
-					 cairo_rectangle_int16_t *interest_rect,
+					 cairo_rectangle_int_t   *interest_rect,
 					 cairo_image_surface_t   *image,
-					 cairo_rectangle_int16_t *image_rect,
+					 cairo_rectangle_int_t   *image_rect,
 					 void                    *image_extra)
 {
     cairo_glitz_surface_t *surface = abstract_surface;
@@ -487,8 +487,8 @@ _cairo_glitz_surface_clone_similar (void
     {
 	cairo_image_surface_t *image_src = (cairo_image_surface_t *) src;
 	cairo_content_t	      content;
-	cairo_rectangle_int16_t image_extent;
-	cairo_rectangle_int16_t extent;
+	cairo_rectangle_int_t image_extent;
+	cairo_rectangle_int_t extent;
 
 	content = _cairo_content_from_format (image_src->format);
 
@@ -1073,7 +1073,7 @@ static cairo_int_status_t
 _cairo_glitz_surface_fill_rectangles (void		      *abstract_dst,
 				      cairo_operator_t	       op,
 				      const cairo_color_t     *color,
-				      cairo_rectangle_int16_t *rects,
+				      cairo_rectangle_int_t   *rects,
 				      int		       n_rects)
 {
     cairo_glitz_surface_t *dst = abstract_dst;
@@ -1433,7 +1433,7 @@ _cairo_glitz_surface_set_clip_region (vo
 
 static cairo_int_status_t
 _cairo_glitz_surface_get_extents (void		          *abstract_surface,
-				  cairo_rectangle_int16_t *rectangle)
+				  cairo_rectangle_int_t   *rectangle)
 {
     cairo_glitz_surface_t *surface = abstract_surface;
 
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 901fa58..cda40b1 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -1214,7 +1214,7 @@ _cairo_gstate_clip_extents (cairo_gstate
         		    double         *x2,
         		    double         *y2)
 {
-    cairo_rectangle_int16_t extents;
+    cairo_rectangle_int_t extents;
     cairo_status_t status;
     
     status = _cairo_surface_get_extents (gstate->target, &extents);
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index e3178ff..4959c33 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -565,9 +565,9 @@ _cairo_image_surface_release_source_imag
 
 static cairo_status_t
 _cairo_image_surface_acquire_dest_image (void                    *abstract_surface,
-					 cairo_rectangle_int16_t *interest_rect,
+					 cairo_rectangle_int_t   *interest_rect,
 					 cairo_image_surface_t  **image_out,
-					 cairo_rectangle_int16_t *image_rect_out,
+					 cairo_rectangle_int_t   *image_rect_out,
 					 void                   **image_extra)
 {
     cairo_image_surface_t *surface = abstract_surface;
@@ -585,9 +585,9 @@ _cairo_image_surface_acquire_dest_image 
 
 static void
 _cairo_image_surface_release_dest_image (void                    *abstract_surface,
-					 cairo_rectangle_int16_t *interest_rect,
+					 cairo_rectangle_int_t   *interest_rect,
 					 cairo_image_surface_t   *image,
-					 cairo_rectangle_int16_t *image_rect,
+					 cairo_rectangle_int_t   *image_rect,
 					 void                    *image_extra)
 {
 }
@@ -825,7 +825,7 @@ static cairo_int_status_t
 _cairo_image_surface_fill_rectangles (void		      *abstract_surface,
 				      cairo_operator_t	       op,
 				      const cairo_color_t     *color,
-				      cairo_rectangle_int16_t *rects,
+				      cairo_rectangle_int_t   *rects,
 				      int		       num_rects)
 {
     cairo_image_surface_t *surface = abstract_surface;
@@ -992,7 +992,7 @@ _cairo_image_surface_set_clip_region (vo
 
 static cairo_int_status_t
 _cairo_image_surface_get_extents (void			  *abstract_surface,
-				  cairo_rectangle_int16_t *rectangle)
+				  cairo_rectangle_int_t   *rectangle)
 {
     cairo_image_surface_t *surface = abstract_surface;
 
diff --git a/src/cairo-meta-surface.c b/src/cairo-meta-surface.c
index 30a64e7..9997baf 100644
--- a/src/cairo-meta-surface.c
+++ b/src/cairo-meta-surface.c
@@ -556,7 +556,7 @@ _cairo_meta_surface_intersect_clip_path 
  */
 static cairo_int_status_t
 _cairo_meta_surface_get_extents (void			 *abstract_surface,
-				 cairo_rectangle_int16_t *rectangle)
+				 cairo_rectangle_int_t   *rectangle)
 {
     cairo_meta_surface_t *surface = abstract_surface;
 
diff --git a/src/cairo-os2-surface.c b/src/cairo-os2-surface.c
index 1535de4..b448887 100644
--- a/src/cairo-os2-surface.c
+++ b/src/cairo-os2-surface.c
@@ -517,9 +517,9 @@ _cairo_os2_surface_release_source_image 
 
 static cairo_status_t
 _cairo_os2_surface_acquire_dest_image (void                     *abstract_surface,
-                                       cairo_rectangle_int16_t  *interest_rect,
+                                       cairo_rectangle_int_t    *interest_rect,
                                        cairo_image_surface_t   **image_out,
-                                       cairo_rectangle_int16_t  *image_rect,
+                                       cairo_rectangle_int_t    *image_rect,
                                        void                    **image_extra)
 {
     cairo_os2_surface_t *local_os2_surface;
@@ -552,9 +552,9 @@ _cairo_os2_surface_acquire_dest_image (v
 
 static void
 _cairo_os2_surface_release_dest_image (void                    *abstract_surface,
-                                       cairo_rectangle_int16_t *interest_rect,
+                                       cairo_rectangle_int_t   *interest_rect,
                                        cairo_image_surface_t   *image,
-                                       cairo_rectangle_int16_t *image_rect,
+                                       cairo_rectangle_int_t   *image_rect,
                                        void                    *image_extra)
 {
     cairo_os2_surface_t *local_os2_surface;
@@ -628,7 +628,7 @@ _cairo_os2_surface_release_dest_image (v
 
 static cairo_int_status_t
 _cairo_os2_surface_get_extents (void                    *abstract_surface,
-                                cairo_rectangle_int16_t *rectangle)
+                                cairo_rectangle_int_t   *rectangle)
 {
     cairo_os2_surface_t *local_os2_surface;
 
diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index 1747094..00a1ef2 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -178,7 +178,7 @@ _cairo_paginated_surface_acquire_source_
     cairo_paginated_surface_t *surface = abstract_surface;
     cairo_surface_t *image;
     cairo_status_t status;
-    cairo_rectangle_int16_t extents;
+    cairo_rectangle_int_t extents;
 
     status = _cairo_surface_get_extents (surface->target, &extents);
     if (status)
@@ -354,7 +354,7 @@ _cairo_paginated_surface_intersect_clip_
 
 static cairo_int_status_t
 _cairo_paginated_surface_get_extents (void	              *abstract_surface,
-				      cairo_rectangle_int16_t *rectangle)
+				      cairo_rectangle_int_t   *rectangle)
 {
     cairo_paginated_surface_t *surface = abstract_surface;
 
@@ -501,7 +501,7 @@ _cairo_paginated_surface_snapshot (void 
 #if 0
     return _cairo_surface_snapshot (other->meta);
 #else
-    cairo_rectangle_int16_t extents;
+    cairo_rectangle_int_t extents;
     cairo_surface_t *surface;
 
     status = _cairo_surface_get_extents (other->target, &extents);
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 782173b..00c427e 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -1512,7 +1512,7 @@ _cairo_pattern_acquire_surface_for_surfa
 	cairo_t *cr;
 	int w,h;
 
-	cairo_rectangle_int16_t extents;
+	cairo_rectangle_int_t extents;
 	status = _cairo_surface_get_extents (pattern->surface, &extents);
 	if (status)
 	    return status;
@@ -1585,7 +1585,7 @@ _cairo_pattern_acquire_surface_for_surfa
     }
     else
     {
-	cairo_rectangle_int16_t extents;
+	cairo_rectangle_int_t extents;
 	status = _cairo_surface_get_extents (pattern->surface, &extents);
 	if (status)
 	    return status;
@@ -1914,13 +1914,13 @@ CLEANUP_SOURCE:
  **/
 cairo_status_t
 _cairo_pattern_get_extents (cairo_pattern_t         *pattern,
-			    cairo_rectangle_int16_t *extents)
+			    cairo_rectangle_int_t   *extents)
 {
     if (pattern->extend == CAIRO_EXTEND_NONE &&
 	pattern->type == CAIRO_PATTERN_TYPE_SURFACE)
     {
 	cairo_status_t status;
-	cairo_rectangle_int16_t surface_extents;
+	cairo_rectangle_int_t surface_extents;
 	cairo_surface_pattern_t *surface_pattern =
 	    (cairo_surface_pattern_t *) pattern;
 	cairo_surface_t *surface = surface_pattern->surface;
@@ -1948,9 +1948,9 @@ _cairo_pattern_get_extents (cairo_patter
 		y = surface_extents.y + sy * surface_extents.height;
 		cairo_matrix_transform_point (&imatrix, &x, &y);
 		if (x < 0) x = 0;
-		if (x > INT16_MAX) x = INT16_MAX;
+		if (x > CAIRO_RECT_INT_MAX) x = CAIRO_RECT_INT_MAX;
 		if (y < 0) y = 0;
-		if (y > INT16_MAX) y = INT16_MAX;
+		if (y > CAIRO_RECT_INT_MAX) y = CAIRO_RECT_INT_MAX;
 		lx = floor (x); rx = ceil (x);
 		ty = floor (y); by = ceil (y);
 		if (!set) {
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 3cb5081..9fdb0ca 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -910,7 +910,7 @@ _cairo_pdf_surface_emit_surface_pattern 
     cairo_matrix_t cairo_p2d, pdf_p2d;
     cairo_extend_t extend = cairo_pattern_get_extend (&pattern->base);
     double xstep, ystep;
-    cairo_rectangle_int16_t surface_extents;
+    cairo_rectangle_int_t surface_extents;
 
     /* XXX: Should do something clever here for PDF source surfaces ? */
 
@@ -1744,7 +1744,7 @@ _cairo_pdf_surface_show_page (void *abst
 
 static cairo_int_status_t
 _cairo_pdf_surface_get_extents (void		        *abstract_surface,
-				cairo_rectangle_int16_t *rectangle)
+				cairo_rectangle_int_t   *rectangle)
 {
     cairo_pdf_surface_t *surface = abstract_surface;
 
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index ba16c8a..7db9d0a 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -1878,7 +1878,7 @@ _cairo_ps_surface_intersect_clip_path (v
 
 static cairo_int_status_t
 _cairo_ps_surface_get_extents (void		       *abstract_surface,
-			       cairo_rectangle_int16_t *rectangle)
+			       cairo_rectangle_int_t   *rectangle)
 {
     cairo_ps_surface_t *surface = abstract_surface;
 
@@ -1913,7 +1913,7 @@ _cairo_ps_surface_paint (void			*abstrac
 {
     cairo_ps_surface_t *surface = abstract_surface;
     cairo_output_stream_t *stream = surface->stream;
-    cairo_rectangle_int16_t extents, pattern_extents;
+    cairo_rectangle_int_t extents, pattern_extents;
     cairo_status_t status;
 
     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
diff --git a/src/cairo-quartz-private.h b/src/cairo-quartz-private.h
index cd1b15c..9f42a8b 100644
--- a/src/cairo-quartz-private.h
+++ b/src/cairo-quartz-private.h
@@ -51,7 +51,7 @@ typedef struct cairo_quartz_surface {
     CGContextRef cgContext;
     CGAffineTransform cgContextBaseCTM;
 
-    cairo_rectangle_int16_t extents;
+    cairo_rectangle_int_t extents;
 
     /* These are stored while drawing operations are in place, set up
      * by quartz_setup_source() and quartz_finish_source()
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index c65b299..540bdca 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -436,7 +436,7 @@ _cairo_quartz_surface_to_quartz (cairo_s
 
 	cairo_surface_t *ref_type = target;
 	cairo_surface_t *new_surf = NULL;
-	cairo_rectangle_int16_t rect;
+	cairo_rectangle_int_t rect;
 	if (ref_type == NULL)
 	    ref_type = cairo_quartz_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
 
@@ -545,7 +545,7 @@ _cairo_quartz_cairo_repeating_surface_pa
 {
     cairo_surface_pattern_t *spat;
     cairo_surface_t *pat_surf;
-    cairo_rectangle_int16_t extents;
+    cairo_rectangle_int_t extents;
 
     CGRect pbounds;
     CGAffineTransform ptransform, stransform;
@@ -675,7 +675,7 @@ _cairo_quartz_setup_source (cairo_quartz
 	    cairo_quartz_surface_t *quartz_surf = _cairo_quartz_surface_to_quartz ((cairo_surface_t *) surface, pat_surf);
 	    CGImageRef img = CGBitmapContextCreateImage (quartz_surf->cgContext);
 	    cairo_matrix_t m = spat->base.matrix;
-	    cairo_rectangle_int16_t extents;
+	    cairo_rectangle_int_t extents;
 
 	    if (!img)
 		return DO_UNSUPPORTED;
@@ -896,10 +896,10 @@ _cairo_quartz_surface_release_source_ima
 
 static cairo_status_t
 _cairo_quartz_surface_acquire_dest_image (void *abstract_surface,
-					   cairo_rectangle_int16_t *interest_rect,
-					   cairo_image_surface_t **image_out,
-					   cairo_rectangle_int16_t *image_rect,
-					   void **image_extra)
+					  cairo_rectangle_int_t *interest_rect,
+					  cairo_image_surface_t **image_out,
+					  cairo_rectangle_int_t *image_rect,
+					  void **image_extra)
 {
     cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
     cairo_int_status_t status;
@@ -920,10 +920,10 @@ _cairo_quartz_surface_acquire_dest_image
 
 static void
 _cairo_quartz_surface_release_dest_image (void *abstract_surface,
-					   cairo_rectangle_int16_t *interest_rect,
-					   cairo_image_surface_t *image,
-					   cairo_rectangle_int16_t *image_rect,
-					   void *image_extra)
+					  cairo_rectangle_int_t *interest_rect,
+					  cairo_image_surface_t *image,
+					  cairo_rectangle_int_t *image_rect,
+					  void *image_extra)
 {
     cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
     unsigned char *imageData = (unsigned char *) image_extra;
@@ -1080,7 +1080,7 @@ _cairo_quartz_surface_clone_similar (voi
 
 static cairo_int_status_t
 _cairo_quartz_surface_get_extents (void *abstract_surface,
-				    cairo_rectangle_int16_t *extents)
+				   cairo_rectangle_int_t *extents)
 {
     cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
 
diff --git a/src/cairo-rectangle.c b/src/cairo-rectangle.c
index fca4e42..bda8224 100644
--- a/src/cairo-rectangle.c
+++ b/src/cairo-rectangle.c
@@ -41,19 +41,19 @@
 /* XXX We currently have a confusing mix of boxes and rectangles as
  * exemplified by this function.  A cairo_box_t is a rectangular area
  * represented by the coordinates of the upper left and lower right
- * corners, expressed in fixed point numbers.  A cairo_rectangle_int16_t is
+ * corners, expressed in fixed point numbers.  A cairo_rectangle_int_t is
  * also a rectangular area, but represented by the upper left corner
  * and the width and the height, as integer numbers.
  *
- * This function converts a cairo_box_t to a cairo_rectangle_int16_t by
+ * This function converts a cairo_box_t to a cairo_rectangle_int_t by
  * increasing the area to the nearest integer coordinates.  We should
- * standardize on cairo_rectangle_int16_t and cairo_rectangle_int16_t, and
+ * standardize on cairo_rectangle_fixed_t and cairo_rectangle_int_t, and
  * this function could be renamed to the more reasonable
  * _cairo_rectangle_fixed_round.
  */
 
 void
-_cairo_box_round_to_rectangle (cairo_box_t *box, cairo_rectangle_int16_t *rectangle)
+_cairo_box_round_to_rectangle (cairo_box_t *box, cairo_rectangle_int_t *rectangle)
 {
     rectangle->x = _cairo_fixed_integer_floor (box->p1.x);
     rectangle->y = _cairo_fixed_integer_floor (box->p1.y);
@@ -62,7 +62,7 @@ _cairo_box_round_to_rectangle (cairo_box
 }
 
 void
-_cairo_rectangle_intersect (cairo_rectangle_int16_t *dest, cairo_rectangle_int16_t *src)
+_cairo_rectangle_intersect (cairo_rectangle_int_t *dest, cairo_rectangle_int_t *src)
 {
     int x1, y1, x2, y2;
 
diff --git a/src/cairo-region.c b/src/cairo-region.c
index c675a18..4538e1c 100644
--- a/src/cairo-region.c
+++ b/src/cairo-region.c
@@ -44,7 +44,7 @@
  **/
 void
 _cairo_region_extents_rectangle (pixman_region16_t       *region,
-				 cairo_rectangle_int16_t *rect)
+				 cairo_rectangle_int_t   *rect)
 {
     pixman_box16_t *region_extents = pixman_region_extents (region);
 
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index ef70a38..c9aa1c0 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -970,7 +970,7 @@ cairo_status_t
 _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t	 *scaled_font,
 					 const cairo_glyph_t	 *glyphs,
 					 int                      num_glyphs,
-					 cairo_rectangle_int16_t *extents)
+					 cairo_rectangle_int_t   *extents)
 {
     cairo_status_t status = CAIRO_STATUS_SUCCESS;
     int i;
diff --git a/src/cairo-surface-fallback-private.h b/src/cairo-surface-fallback-private.h
index e0f83c4..13d92d0 100644
--- a/src/cairo-surface-fallback-private.h
+++ b/src/cairo-surface-fallback-private.h
@@ -99,7 +99,7 @@ cairo_private cairo_status_t
 _cairo_surface_fallback_fill_rectangles (cairo_surface_t         *surface,
 					 cairo_operator_t	 op,
 					 const cairo_color_t	 *color,
-					 cairo_rectangle_int16_t *rects,
+					 cairo_rectangle_int_t   *rects,
 					 int			 num_rects);
 
 cairo_private cairo_status_t
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index 0397809..93b1b61 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -42,9 +42,9 @@
 
 typedef struct {
     cairo_surface_t *dst;
-    cairo_rectangle_int16_t extents;
+    cairo_rectangle_int_t extents;
     cairo_image_surface_t *image;
-    cairo_rectangle_int16_t image_rect;
+    cairo_rectangle_int_t image_rect;
     void *image_extra;
 } fallback_state_t;
 
@@ -106,7 +106,7 @@ typedef cairo_status_t (*cairo_draw_func
 					     cairo_surface_t               *dst,
 					     int                            dst_x,
 					     int                            dst_y,
-					     const cairo_rectangle_int16_t *extents);
+					     const cairo_rectangle_int_t   *extents);
 
 static cairo_status_t
 _create_composite_mask_pattern (cairo_surface_pattern_t       *mask_pattern,
@@ -114,7 +114,7 @@ _create_composite_mask_pattern (cairo_su
 				cairo_draw_func_t             draw_func,
 				void                          *draw_closure,
 				cairo_surface_t               *dst,
-				const cairo_rectangle_int16_t *extents)
+				const cairo_rectangle_int_t   *extents)
 {
     cairo_surface_t *mask;
     cairo_status_t status;
@@ -159,7 +159,7 @@ _clip_and_composite_with_mask (cairo_cli
 			       cairo_draw_func_t              draw_func,
 			       void                          *draw_closure,
 			       cairo_surface_t               *dst,
-			       const cairo_rectangle_int16_t *extents)
+			       const cairo_rectangle_int_t   *extents)
 {
     cairo_surface_pattern_t mask_pattern;
     cairo_status_t status;
@@ -193,7 +193,7 @@ _clip_and_composite_combine (cairo_clip_
 			     cairo_draw_func_t              draw_func,
 			     void                          *draw_closure,
 			     cairo_surface_t               *dst,
-			     const cairo_rectangle_int16_t *extents)
+			     const cairo_rectangle_int_t   *extents)
 {
     cairo_surface_t *intermediate;
     cairo_surface_pattern_t dst_pattern;
@@ -281,7 +281,7 @@ _clip_and_composite_source (cairo_clip_t
 			    cairo_draw_func_t              draw_func,
 			    void                          *draw_closure,
 			    cairo_surface_t               *dst,
-			    const cairo_rectangle_int16_t *extents)
+			    const cairo_rectangle_int_t   *extents)
 {
     cairo_surface_pattern_t mask_pattern;
     cairo_status_t status;
@@ -322,7 +322,7 @@ _clip_and_composite_source (cairo_clip_t
 }
 
 static int
-_cairo_rectangle_empty (const cairo_rectangle_int16_t *rect)
+_cairo_rectangle_empty (const cairo_rectangle_int_t *rect)
 {
     return rect->width == 0 || rect->height == 0;
 }
@@ -355,7 +355,7 @@ _clip_and_composite (cairo_clip_t       
 		     cairo_draw_func_t              draw_func,
 		     void                          *draw_closure,
 		     cairo_surface_t               *dst,
-		     const cairo_rectangle_int16_t *extents)
+		     const cairo_rectangle_int_t   *extents)
 {
     cairo_pattern_union_t solid_pattern;
     cairo_status_t status;
@@ -411,7 +411,7 @@ _composite_trap_region (cairo_clip_t    
 			cairo_operator_t         op,
 			cairo_surface_t         *dst,
 			pixman_region16_t       *trap_region,
-			cairo_rectangle_int16_t *extents)
+			cairo_rectangle_int_t   *extents)
 {
     cairo_status_t status;
     cairo_pattern_union_t solid_pattern;
@@ -483,7 +483,7 @@ _composite_traps_draw_func (void        
 			    cairo_surface_t               *dst,
 			    int                            dst_x,
 			    int                            dst_y,
-			    const cairo_rectangle_int16_t *extents)
+			    const cairo_rectangle_int_t   *extents)
 {
     cairo_composite_traps_info_t *info = closure;
     cairo_pattern_union_t pattern;
@@ -523,7 +523,7 @@ _clip_and_composite_trapezoids (cairo_pa
     pixman_region16_t clear_region;
     cairo_bool_t has_trap_region = FALSE;
     cairo_bool_t has_clear_region = FALSE;
-    cairo_rectangle_int16_t extents;
+    cairo_rectangle_int_t extents;
     cairo_composite_traps_info_t traps_info;
 
     if (traps->num_traps == 0)
@@ -545,7 +545,7 @@ _clip_and_composite_trapezoids (cairo_pa
     }
 
     if (_cairo_operator_bounded_by_mask (op)) {
-        cairo_rectangle_int16_t trap_extents;
+        cairo_rectangle_int_t trap_extents;
 
         if (has_trap_region) {
             status = _cairo_clip_intersect_to_region (clip, &trap_region);
@@ -678,7 +678,7 @@ _cairo_surface_fallback_paint (cairo_sur
 			       cairo_pattern_t	*source)
 {
     cairo_status_t status;
-    cairo_rectangle_int16_t extents;
+    cairo_rectangle_int_t extents;
     cairo_box_t box;
     cairo_traps_t traps;
 
@@ -687,7 +687,7 @@ _cairo_surface_fallback_paint (cairo_sur
 	return status;
 
     if (_cairo_operator_bounded_by_source (op)) {
-	cairo_rectangle_int16_t source_extents;
+	cairo_rectangle_int_t source_extents;
 	status = _cairo_pattern_get_extents (source, &source_extents);
 	if (status)
 	    return status;
@@ -727,7 +727,7 @@ _cairo_surface_mask_draw_func (void     
 			       cairo_surface_t               *dst,
 			       int                            dst_x,
 			       int                            dst_y,
-			       const cairo_rectangle_int16_t *extents)
+			       const cairo_rectangle_int_t *extents)
 {
     cairo_pattern_t *mask = closure;
 
@@ -754,7 +754,7 @@ _cairo_surface_fallback_mask (cairo_surf
 			      cairo_pattern_t		*mask)
 {
     cairo_status_t status;
-    cairo_rectangle_int16_t extents, source_extents, mask_extents;
+    cairo_rectangle_int_t extents, source_extents, mask_extents;
 
     status = _cairo_surface_get_extents (surface, &extents);
     if (status)
@@ -804,14 +804,14 @@ _cairo_surface_fallback_stroke (cairo_su
     cairo_status_t status;
     cairo_traps_t traps;
     cairo_box_t box;
-    cairo_rectangle_int16_t extents;
+    cairo_rectangle_int_t extents;
 
     status = _cairo_surface_get_extents (surface, &extents);
     if (status)
         return status;
 
     if (_cairo_operator_bounded_by_source (op)) {
-	cairo_rectangle_int16_t source_extents;
+	cairo_rectangle_int_t source_extents;
 	status = _cairo_pattern_get_extents (source, &source_extents);
 	if (status)
 	    return status;
@@ -866,14 +866,14 @@ _cairo_surface_fallback_fill (cairo_surf
     cairo_status_t status;
     cairo_traps_t traps;
     cairo_box_t box;
-    cairo_rectangle_int16_t extents;
+    cairo_rectangle_int_t extents;
 
     status = _cairo_surface_get_extents (surface, &extents);
     if (status)
         return status;
 
     if (_cairo_operator_bounded_by_source (op)) {
-	cairo_rectangle_int16_t source_extents;
+	cairo_rectangle_int_t source_extents;
 	status = _cairo_pattern_get_extents (source, &source_extents);
 	if (status)
 	    return status;
@@ -928,7 +928,7 @@ _cairo_surface_old_show_glyphs_draw_func
 					  cairo_surface_t               *dst,
 					  int                            dst_x,
 					  int                            dst_y,
-					  const cairo_rectangle_int16_t *extents)
+					  const cairo_rectangle_int_t *extents)
 {
     cairo_show_glyphs_info_t *glyph_info = closure;
     cairo_pattern_union_t pattern;
@@ -991,7 +991,7 @@ _cairo_surface_fallback_show_glyphs (cai
 				     cairo_scaled_font_t	*scaled_font)
 {
     cairo_status_t status;
-    cairo_rectangle_int16_t extents, glyph_extents;
+    cairo_rectangle_int_t extents, glyph_extents;
     cairo_show_glyphs_info_t glyph_info;
 
     status = _cairo_surface_get_extents (surface, &extents);
@@ -1121,11 +1121,11 @@ cairo_status_t
 _cairo_surface_fallback_fill_rectangles (cairo_surface_t         *surface,
 					 cairo_operator_t	  op,
 					 const cairo_color_t	 *color,
-					 cairo_rectangle_int16_t *rects,
+					 cairo_rectangle_int_t   *rects,
 					 int			  num_rects)
 {
     fallback_state_t state;
-    cairo_rectangle_int16_t *offset_rects = NULL;
+    cairo_rectangle_int_t *offset_rects = NULL;
     cairo_status_t status;
     int x1, y1, x2, y2;
     int i;
@@ -1165,7 +1165,7 @@ _cairo_surface_fallback_fill_rectangles 
     /* If the fetched image isn't at 0,0, we need to offset the rectangles */
 
     if (state.image_rect.x != 0 || state.image_rect.y != 0) {
-      offset_rects = _cairo_malloc_ab (num_rects, sizeof (cairo_rectangle_int16_t));
+	offset_rects = _cairo_malloc_ab (num_rects, sizeof (cairo_rectangle_int_t));
 	if (offset_rects == NULL) {
 	    status = CAIRO_STATUS_NO_MEMORY;
 	    goto DONE;
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 7877458..a5c3109 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -956,9 +956,9 @@ _cairo_surface_release_source_image (cai
  **/
 cairo_status_t
 _cairo_surface_acquire_dest_image (cairo_surface_t         *surface,
-				   cairo_rectangle_int16_t *interest_rect,
+				   cairo_rectangle_int_t   *interest_rect,
 				   cairo_image_surface_t  **image_out,
-				   cairo_rectangle_int16_t *image_rect,
+				   cairo_rectangle_int_t   *image_rect,
 				   void                   **image_extra)
 {
     assert (!surface->finished);
@@ -982,9 +982,9 @@ _cairo_surface_acquire_dest_image (cairo
  **/
 void
 _cairo_surface_release_dest_image (cairo_surface_t         *surface,
-				   cairo_rectangle_int16_t *interest_rect,
+				   cairo_rectangle_int_t   *interest_rect,
 				   cairo_image_surface_t   *image,
-				   cairo_rectangle_int16_t *image_rect,
+				   cairo_rectangle_int_t   *image_rect,
 				   void                    *image_extra)
 {
     assert (!surface->finished);
@@ -1194,7 +1194,7 @@ _cairo_surface_fill_rectangle (cairo_sur
 			       int		    width,
 			       int		    height)
 {
-    cairo_rectangle_int16_t rect;
+    cairo_rectangle_int_t rect;
 
     assert (! surface->is_snapshot);
 
@@ -1233,8 +1233,8 @@ _cairo_surface_fill_region (cairo_surfac
 {
     int num_rects;
     pixman_box16_t *boxes;
-    cairo_rectangle_int16_t stack_rects[CAIRO_STACK_BUFFER_SIZE / sizeof (cairo_rectangle_int16_t)];
-    cairo_rectangle_int16_t *rects;
+    cairo_rectangle_int_t stack_rects[CAIRO_STACK_BUFFER_SIZE / sizeof (cairo_rectangle_int_t)];
+    cairo_rectangle_int_t *rects;
     cairo_status_t status;
     int i;
 
@@ -1247,7 +1247,7 @@ _cairo_surface_fill_region (cairo_surfac
 
     rects = stack_rects;
     if (num_rects > ARRAY_LENGTH (stack_rects)) {
-	rects = _cairo_malloc_ab (num_rects, sizeof (cairo_rectangle_int16_t));
+	rects = _cairo_malloc_ab (num_rects, sizeof (cairo_rectangle_int_t));
 	if (!rects)
 	    return CAIRO_STATUS_NO_MEMORY;
     }
@@ -1288,7 +1288,7 @@ cairo_status_t
 _cairo_surface_fill_rectangles (cairo_surface_t		*surface,
 				cairo_operator_t         op,
 				const cairo_color_t	*color,
-				cairo_rectangle_int16_t	*rects,
+				cairo_rectangle_int_t	*rects,
 				int			 num_rects)
 {
     cairo_int_status_t status;
@@ -1813,7 +1813,7 @@ _cairo_surface_set_clip (cairo_surface_t
  */
 cairo_status_t
 _cairo_surface_get_extents (cairo_surface_t         *surface,
-			    cairo_rectangle_int16_t *rectangle)
+			    cairo_rectangle_int_t   *rectangle)
 {
     if (surface->status)
 	return surface->status;
@@ -1941,15 +1941,15 @@ _cairo_surface_old_show_glyphs (cairo_sc
 
 static cairo_status_t
 _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t         *dst,
-						   cairo_rectangle_int16_t *src_rectangle,
-						   cairo_rectangle_int16_t *mask_rectangle,
+						   cairo_rectangle_int_t   *src_rectangle,
+						   cairo_rectangle_int_t   *mask_rectangle,
 						   int			    dst_x,
 						   int			    dst_y,
 						   unsigned int		    width,
 						   unsigned int		    height)
 {
-    cairo_rectangle_int16_t dst_rectangle;
-    cairo_rectangle_int16_t drawn_rectangle;
+    cairo_rectangle_int_t dst_rectangle;
+    cairo_rectangle_int_t drawn_rectangle;
     cairo_bool_t has_drawn_region = FALSE;
     cairo_bool_t has_clear_region = FALSE;
     pixman_region16_t drawn_region;
@@ -2043,9 +2043,9 @@ _cairo_surface_composite_fixup_unbounded
 					  unsigned int		      width,
 					  unsigned int		      height)
 {
-    cairo_rectangle_int16_t src_tmp, mask_tmp;
-    cairo_rectangle_int16_t *src_rectangle = NULL;
-    cairo_rectangle_int16_t *mask_rectangle = NULL;
+    cairo_rectangle_int_t src_tmp, mask_tmp;
+    cairo_rectangle_int_t *src_rectangle = NULL;
+    cairo_rectangle_int_t *mask_rectangle = NULL;
 
     assert (! dst->is_snapshot);
 
@@ -2118,9 +2118,9 @@ _cairo_surface_composite_shape_fixup_unb
 						unsigned int		    width,
 						unsigned int		    height)
 {
-    cairo_rectangle_int16_t src_tmp, mask_tmp;
-    cairo_rectangle_int16_t *src_rectangle = NULL;
-    cairo_rectangle_int16_t *mask_rectangle = NULL;
+    cairo_rectangle_int_t src_tmp, mask_tmp;
+    cairo_rectangle_int_t *src_rectangle = NULL;
+    cairo_rectangle_int_t *mask_rectangle = NULL;
 
     assert (! dst->is_snapshot);
 
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 93b9517..ec0916a 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -888,7 +888,7 @@ _cairo_svg_surface_emit_composite_image_
 {
     cairo_surface_t *surface;
     cairo_surface_attributes_t surface_attr;
-    cairo_rectangle_int16_t extents;
+    cairo_rectangle_int_t extents;
     cairo_status_t status;
     cairo_matrix_t p2u;
 
@@ -1647,7 +1647,7 @@ _cairo_svg_surface_fill (void			*abstrac
 
 static cairo_int_status_t
 _cairo_svg_surface_get_extents (void		        *abstract_surface,
-				cairo_rectangle_int16_t *rectangle)
+				cairo_rectangle_int_t   *rectangle)
 {
     cairo_svg_surface_t *surface = abstract_surface;
 
diff --git a/src/cairo-win32-private.h b/src/cairo-win32-private.h
index 08aeafa..5f5d8d0 100644
--- a/src/cairo-win32-private.h
+++ b/src/cairo-win32-private.h
@@ -71,11 +71,11 @@ typedef struct _cairo_win32_surface {
 
     cairo_surface_t *image;
 
-    cairo_rectangle_int16_t clip_rect;
+    cairo_rectangle_int_t clip_rect;
 
     HRGN saved_clip;
 
-    cairo_rectangle_int16_t extents;
+    cairo_rectangle_int_t extents;
 
     /* Surface DC flags */
     uint32_t flags;
diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index 7f86eb8..c698e10 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -547,9 +547,9 @@ _cairo_win32_surface_release_source_imag
 
 static cairo_status_t
 _cairo_win32_surface_acquire_dest_image (void                    *abstract_surface,
-					 cairo_rectangle_int16_t *interest_rect,
+					 cairo_rectangle_int_t   *interest_rect,
 					 cairo_image_surface_t  **image_out,
-					 cairo_rectangle_int16_t *image_rect,
+					 cairo_rectangle_int_t   *image_rect,
 					 void                   **image_extra)
 {
     cairo_win32_surface_t *surface = abstract_surface;
@@ -615,9 +615,9 @@ _cairo_win32_surface_acquire_dest_image 
 
 static void
 _cairo_win32_surface_release_dest_image (void                    *abstract_surface,
-					 cairo_rectangle_int16_t *interest_rect,
+					 cairo_rectangle_int_t   *interest_rect,
 					 cairo_image_surface_t   *image,
-					 cairo_rectangle_int16_t *image_rect,
+					 cairo_rectangle_int_t   *image_rect,
 					 void                    *image_extra)
 {
     cairo_win32_surface_t *surface = abstract_surface;
@@ -736,7 +736,7 @@ static cairo_int_status_t
 _cairo_win32_surface_composite_inner (cairo_win32_surface_t *src,
 				      cairo_image_surface_t *src_image,
 				      cairo_win32_surface_t *dst,
-				      cairo_rectangle_int16_t src_extents,
+				      cairo_rectangle_int_t src_extents,
 				      cairo_rectangle_int32_t src_r,
 				      cairo_rectangle_int32_t dst_r,
 				      int alpha,
@@ -844,7 +844,7 @@ _cairo_win32_surface_composite (cairo_op
     cairo_image_surface_t *src_image = NULL;
 
     cairo_format_t src_format;
-    cairo_rectangle_int16_t src_extents;
+    cairo_rectangle_int_t src_extents;
 
     cairo_rectangle_int32_t src_r = { src_x, src_y, width, height };
     cairo_rectangle_int32_t dst_r = { dst_x, dst_y, width, height };
@@ -1312,7 +1312,7 @@ static cairo_int_status_t
 _cairo_win32_surface_fill_rectangles (void			*abstract_surface,
 				      cairo_operator_t		op,
 				      const cairo_color_t	*color,
-				      cairo_rectangle_int16_t		*rects,
+				      cairo_rectangle_int_t	*rects,
 				      int			num_rects)
 {
     cairo_win32_surface_t *surface = abstract_surface;
@@ -1465,7 +1465,7 @@ _cairo_win32_surface_set_clip_region (vo
 
 static cairo_int_status_t
 _cairo_win32_surface_get_extents (void		          *abstract_surface,
-				  cairo_rectangle_int16_t *rectangle)
+				  cairo_rectangle_int_t   *rectangle)
 {
     cairo_win32_surface_t *surface = abstract_surface;
 
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index f16de3f..97148f5 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -297,14 +297,14 @@ _CAIRO_MASK_FORMAT (cairo_format_masks_t
 
 static cairo_status_t
 _get_image_surface (cairo_xcb_surface_t     *surface,
-		    cairo_rectangle_int16_t *interest_rect,
+		    cairo_rectangle_int_t   *interest_rect,
 		    cairo_image_surface_t  **image_out,
-		    cairo_rectangle_int16_t *image_rect)
+		    cairo_rectangle_int_t   *image_rect)
 {
     cairo_image_surface_t *image;
     xcb_get_image_reply_t *imagerep;
     int bpp, bytes_per_line;
-    int x1, y1, x2, y2;
+    short x1, y1, x2, y2;
     unsigned char *data;
     cairo_format_masks_t masks;
     cairo_format_t format;
@@ -642,9 +642,9 @@ _cairo_xcb_surface_release_source_image 
 
 static cairo_status_t
 _cairo_xcb_surface_acquire_dest_image (void                    *abstract_surface,
-				       cairo_rectangle_int16_t *interest_rect,
+				       cairo_rectangle_int_t   *interest_rect,
 				       cairo_image_surface_t  **image_out,
-				       cairo_rectangle_int16_t *image_rect_out,
+				       cairo_rectangle_int_t   *image_rect_out,
 				       void                   **image_extra)
 {
     cairo_xcb_surface_t *surface = abstract_surface;
@@ -663,9 +663,9 @@ _cairo_xcb_surface_acquire_dest_image (v
 
 static void
 _cairo_xcb_surface_release_dest_image (void                   *abstract_surface,
-				       cairo_rectangle_int16_t      *interest_rect,
+				       cairo_rectangle_int_t  *interest_rect,
 				       cairo_image_surface_t  *image,
-				       cairo_rectangle_int16_t      *image_rect,
+				       cairo_rectangle_int_t  *image_rect,
 				       void                   *image_extra)
 {
     cairo_xcb_surface_t *surface = abstract_surface;
@@ -1246,7 +1246,7 @@ static cairo_int_status_t
 _cairo_xcb_surface_fill_rectangles (void			     *abstract_surface,
 				     cairo_operator_t	      op,
 				     const cairo_color_t	*     color,
-				     cairo_rectangle_int16_t *rects,
+				     cairo_rectangle_int_t *rects,
 				     int			      num_rects)
 {
     cairo_xcb_surface_t *surface = abstract_surface;
@@ -1547,7 +1547,7 @@ _cairo_xcb_surface_set_clip_region (void
 
 static cairo_int_status_t
 _cairo_xcb_surface_get_extents (void		        *abstract_surface,
-				cairo_rectangle_int16_t *rectangle)
+				cairo_rectangle_int_t   *rectangle)
 {
     cairo_xcb_surface_t *surface = abstract_surface;
 
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 4c7a699..d0c248f 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -496,13 +496,13 @@ _swap_ximage_to_native (XImage *ximage)
 
 static cairo_status_t
 _get_image_surface (cairo_xlib_surface_t    *surface,
-		    cairo_rectangle_int16_t *interest_rect,
+		    cairo_rectangle_int_t   *interest_rect,
 		    cairo_image_surface_t  **image_out,
-		    cairo_rectangle_int16_t *image_rect)
+		    cairo_rectangle_int_t   *image_rect)
 {
     cairo_image_surface_t *image;
     XImage *ximage;
-    int x1, y1, x2, y2;
+    short x1, y1, x2, y2;
     cairo_format_masks_t masks;
     cairo_format_t format;
 
@@ -879,9 +879,9 @@ _cairo_xlib_surface_release_source_image
 
 static cairo_status_t
 _cairo_xlib_surface_acquire_dest_image (void                    *abstract_surface,
-					cairo_rectangle_int16_t *interest_rect,
+					cairo_rectangle_int_t   *interest_rect,
 					cairo_image_surface_t  **image_out,
-					cairo_rectangle_int16_t *image_rect_out,
+					cairo_rectangle_int_t   *image_rect_out,
 					void                   **image_extra)
 {
     cairo_xlib_surface_t *surface = abstract_surface;
@@ -902,9 +902,9 @@ _cairo_xlib_surface_acquire_dest_image (
 
 static void
 _cairo_xlib_surface_release_dest_image (void                    *abstract_surface,
-					cairo_rectangle_int16_t *interest_rect,
+					cairo_rectangle_int_t   *interest_rect,
 					cairo_image_surface_t   *image,
-					cairo_rectangle_int16_t *image_rect,
+					cairo_rectangle_int_t   *image_rect,
 					void                    *image_extra)
 {
     cairo_xlib_surface_t *surface = abstract_surface;
@@ -1522,7 +1522,7 @@ static cairo_int_status_t
 _cairo_xlib_surface_fill_rectangles (void		     *abstract_surface,
 				     cairo_operator_t	      op,
 				     const cairo_color_t     *color,
-				     cairo_rectangle_int16_t *rects,
+				     cairo_rectangle_int_t   *rects,
 				     int			      num_rects)
 {
     cairo_xlib_surface_t *surface = abstract_surface;
@@ -1819,7 +1819,7 @@ _cairo_xlib_surface_set_clip_region (voi
 
 static cairo_int_status_t
 _cairo_xlib_surface_get_extents (void		         *abstract_surface,
-				 cairo_rectangle_int16_t *rectangle)
+				 cairo_rectangle_int_t   *rectangle)
 {
     cairo_xlib_surface_t *surface = abstract_surface;
 
diff --git a/src/cairo.c b/src/cairo.c
index 6859e45..f3c2f16 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -478,7 +478,7 @@ void
 cairo_push_group_with_content (cairo_t *cr, cairo_content_t content)
 {
     cairo_status_t status;
-    cairo_rectangle_int16_t extents;
+    cairo_rectangle_int_t extents;
     cairo_surface_t *parent_surface, *group_surface = NULL;
 
     if (cr->status)
diff --git a/src/cairoint.h b/src/cairoint.h
index 9665297..f0ea702 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -282,6 +282,18 @@ typedef struct _cairo_rectangle_int32 {
     uint32_t width, height;
 } cairo_rectangle_int32_t;
 
+#if CAIRO_FIXED_BITS == 32 && CAIRO_FIXED_FRAC_BITS >= 16
+typedef cairo_rectangle_int16_t cairo_rectangle_int_t;
+#define CAIRO_RECT_INT_MIN INT16_MIN
+#define CAIRO_RECT_INT_MAX INT16_MAX
+#elif CAIRO_FIXED_BITS == 32
+typedef cairo_rectangle_int32_t cairo_rectangle_int_t;
+#define CAIRO_RECT_INT_MIN INT32_MIN
+#define CAIRO_RECT_INT_MAX INT32_MAX
+#else
+#error Not sure how to pick a cairo_rectangle_int_t for your CAIRO_FIXED_BITS!
+#endif
+
 /* Sure wish C had a real enum type so that this would be distinct
    from cairo_status_t. Oh well, without that, I'll use this bogus 1000
    offset */
@@ -357,7 +369,7 @@ typedef struct _cairo_edge {
     cairo_line_t edge;
     int clockWise;
 
-    cairo_fixed_16_16_t current_x;
+    cairo_fixed_t current_x;
 } cairo_edge_t;
 
 typedef struct _cairo_polygon {
@@ -404,10 +416,10 @@ typedef struct _cairo_color cairo_color_
 typedef struct _cairo_image_surface cairo_image_surface_t;
 
 cairo_private void
-_cairo_box_round_to_rectangle (cairo_box_t *box, cairo_rectangle_int16_t *rectangle);
+_cairo_box_round_to_rectangle (cairo_box_t *box, cairo_rectangle_int_t *rectangle);
 
 cairo_private void
-_cairo_rectangle_intersect (cairo_rectangle_int16_t *dest, cairo_rectangle_int16_t *src);
+_cairo_rectangle_intersect (cairo_rectangle_int_t *dest, cairo_rectangle_int_t *src);
 
 /* cairo_array.c structures and functions */
 
@@ -683,16 +695,16 @@ struct _cairo_surface_backend {
 
     cairo_warn cairo_status_t
     (*acquire_dest_image)       (void                    *abstract_surface,
-				 cairo_rectangle_int16_t *interest_rect,
+				 cairo_rectangle_int_t   *interest_rect,
 				 cairo_image_surface_t  **image_out,
-				 cairo_rectangle_int16_t *image_rect,
+				 cairo_rectangle_int_t   *image_rect,
 				 void                   **image_extra);
 
     void
     (*release_dest_image)       (void                    *abstract_surface,
-				 cairo_rectangle_int16_t *interest_rect,
+				 cairo_rectangle_int_t   *interest_rect,
 				 cairo_image_surface_t   *image,
-				 cairo_rectangle_int16_t *image_rect,
+				 cairo_rectangle_int_t   *image_rect,
 				 void                    *image_extra);
 
     /* Create a new surface (@clone_out) with the following
@@ -733,7 +745,7 @@ struct _cairo_surface_backend {
     (*fill_rectangles)		(void			 *surface,
 				 cairo_operator_t	  op,
 				 const cairo_color_t     *color,
-				 cairo_rectangle_int16_t *rects,
+				 cairo_rectangle_int_t   *rects,
 				 int			  num_rects);
 
     /* XXX: dst should be the first argument for consistency */
@@ -807,7 +819,7 @@ struct _cairo_surface_backend {
      */
     cairo_warn cairo_int_status_t
     (*get_extents)		(void			 *surface,
-				 cairo_rectangle_int16_t *rectangle);
+				 cairo_rectangle_int_t   *rectangle);
 
     /*
      * This is an optional entry to let the surface manage its own glyph
@@ -1631,7 +1643,7 @@ cairo_private cairo_status_t
 _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t	 *scaled_font,
 					 const cairo_glyph_t	 *glyphs,
 					 int                      num_glyphs,
-					 cairo_rectangle_int16_t *extents);
+					 cairo_rectangle_int_t   *extents);
 
 cairo_private cairo_status_t
 _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
@@ -1762,7 +1774,7 @@ cairo_private cairo_status_t
 _cairo_surface_fill_rectangles (cairo_surface_t		*surface,
 				cairo_operator_t         op,
 				const cairo_color_t	*color,
-				cairo_rectangle_int16_t *rects,
+				cairo_rectangle_int_t	*rects,
 				int			 num_rects);
 
 cairo_private cairo_status_t
@@ -1836,16 +1848,16 @@ _cairo_surface_release_source_image (cai
 
 cairo_private cairo_status_t
 _cairo_surface_acquire_dest_image (cairo_surface_t         *surface,
-				   cairo_rectangle_int16_t *interest_rect,
+				   cairo_rectangle_int_t   *interest_rect,
 				   cairo_image_surface_t  **image_out,
-				   cairo_rectangle_int16_t *image_rect,
+				   cairo_rectangle_int_t   *image_rect,
 				   void                   **image_extra);
 
 cairo_private void
 _cairo_surface_release_dest_image (cairo_surface_t        *surface,
-				   cairo_rectangle_int16_t      *interest_rect,
+				   cairo_rectangle_int_t  *interest_rect,
 				   cairo_image_surface_t  *image,
-				   cairo_rectangle_int16_t      *image_rect,
+				   cairo_rectangle_int_t  *image_rect,
 				   void                   *image_extra);
 
 cairo_private cairo_status_t
@@ -1894,7 +1906,7 @@ _cairo_surface_set_clip (cairo_surface_t
 
 cairo_private cairo_status_t
 _cairo_surface_get_extents (cairo_surface_t         *surface,
-			    cairo_rectangle_int16_t *rectangle);
+			    cairo_rectangle_int_t   *rectangle);
 
 cairo_private cairo_status_t
 _cairo_surface_old_show_glyphs (cairo_scaled_font_t	*scaled_font,
@@ -2309,7 +2321,7 @@ _cairo_pattern_acquire_surfaces (cairo_p
 
 cairo_private cairo_status_t
 _cairo_pattern_get_extents (cairo_pattern_t	    *pattern,
-			    cairo_rectangle_int16_t *extents);
+			    cairo_rectangle_int_t   *extents);
 
 cairo_private void
 _cairo_pattern_reset_static_data (void);
@@ -2325,7 +2337,7 @@ _cairo_gstate_get_antialias (cairo_gstat
 
 cairo_private void
 _cairo_region_extents_rectangle (pixman_region16_t       *region,
-				 cairo_rectangle_int16_t *rect);
+				 cairo_rectangle_int_t   *rect);
 
 /* cairo_unicode.c */
 
diff --git a/src/test-fallback-surface.c b/src/test-fallback-surface.c
index b2fa03e..db25874 100644
--- a/src/test-fallback-surface.c
+++ b/src/test-fallback-surface.c
@@ -140,9 +140,9 @@ _test_fallback_surface_release_source_im
 
 static cairo_status_t
 _test_fallback_surface_acquire_dest_image (void		           *abstract_surface,
-					   cairo_rectangle_int16_t *interest_rect,
+					   cairo_rectangle_int_t   *interest_rect,
 					   cairo_image_surface_t  **image_out,
-					   cairo_rectangle_int16_t *image_rect_out,
+					   cairo_rectangle_int_t   *image_rect_out,
 					   void			  **image_extra)
 {
     test_fallback_surface_t *surface = abstract_surface;
@@ -156,9 +156,9 @@ _test_fallback_surface_acquire_dest_imag
 
 static void
 _test_fallback_surface_release_dest_image (void			   *abstract_surface,
-					   cairo_rectangle_int16_t *interest_rect,
+					   cairo_rectangle_int_t   *interest_rect,
 					   cairo_image_surface_t   *image,
-					   cairo_rectangle_int16_t *image_rect,
+					   cairo_rectangle_int_t   *image_rect,
 					   void			   *image_extra)
 {
     test_fallback_surface_t *surface = abstract_surface;
@@ -191,8 +191,8 @@ _test_fallback_surface_clone_similar (vo
 }
 
 static cairo_int_status_t
-_test_fallback_surface_get_extents (void		            *abstract_surface,
-				    cairo_rectangle_int16_t *rectangle)
+_test_fallback_surface_get_extents (void		  *abstract_surface,
+				    cairo_rectangle_int_t *rectangle)
 {
     test_fallback_surface_t *surface = abstract_surface;
 
diff --git a/src/test-meta-surface.c b/src/test-meta-surface.c
index e2f6a09..3992b4c 100644
--- a/src/test-meta-surface.c
+++ b/src/test-meta-surface.c
@@ -174,7 +174,7 @@ _test_meta_surface_intersect_clip_path (
 
 static cairo_int_status_t
 _test_meta_surface_get_extents (void			*abstract_surface,
-				cairo_rectangle_int16_t	*rectangle)
+				cairo_rectangle_int_t	*rectangle)
 {
     test_meta_surface_t *surface = abstract_surface;
 
@@ -300,7 +300,7 @@ _test_meta_surface_snapshot (void *abstr
 #if 0
     return _cairo_surface_snapshot (other->meta);
 #else
-    cairo_rectangle_int16_t extents;
+    cairo_rectangle_int_t extents;
     cairo_surface_t *surface;
 
     status = _cairo_surface_get_extents (other->image, &extents);
diff --git a/src/test-paginated-surface.c b/src/test-paginated-surface.c
index 53e97eb..99bd67c 100644
--- a/src/test-paginated-surface.c
+++ b/src/test-paginated-surface.c
@@ -149,7 +149,7 @@ _test_paginated_surface_set_clip_region 
 
 static cairo_int_status_t
 _test_paginated_surface_get_extents (void			*abstract_surface,
-				     cairo_rectangle_int16_t	*rectangle)
+				     cairo_rectangle_int_t	*rectangle)
 {
     test_paginated_surface_t *surface = abstract_surface;
 
diff-tree 9c38aa3b96a1e926ef422837fc3102e902a796fc (from 0048a26a4477d3acb5dd0231756cfaae92d240a9)
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date:   Mon Jun 18 16:30:09 2007 -0700

    [fixpt] Use _cairo_fixed_mul insted of manual multiplication

diff --git a/src/cairo-fixed-private.h b/src/cairo-fixed-private.h
index 333a60b..431e7ee 100644
--- a/src/cairo-fixed-private.h
+++ b/src/cairo-fixed-private.h
@@ -71,7 +71,6 @@ typedef uint32_t cairo_fixed_unsigned_t;
  * No configurable bits below this.
  */
 
-
 #if (CAIRO_FIXED_BITS != 32)
 # error CAIRO_FIXED_BITS must be 32, and the type must be a 32-bit type.
 # error To remove this limitation, you will have to fix the tesselator.
diff --git a/src/cairo-path-fixed.c b/src/cairo-path-fixed.c
index dfd30b1..89380d3 100644
--- a/src/cairo-path-fixed.c
+++ b/src/cairo-path-fixed.c
@@ -1,3 +1,4 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
 /* cairo - a vector graphics library with display and print output
  *
  * Copyright © 2002 University of Southern California
@@ -509,25 +510,19 @@ _cairo_path_fixed_offset_and_scale (cair
 {
     cairo_path_buf_t *buf = path->buf_head;
     int i;
-    cairo_int64_t i64temp;
-    cairo_fixed_t fixedtemp;
 
     while (buf) {
 	 for (i = 0; i < buf->num_points; i++) {
 	     if (scalex == CAIRO_FIXED_ONE) {
 		 buf->points[i].x += offx;
 	     } else {
-		 fixedtemp = buf->points[i].x + offx;
-		 i64temp = _cairo_int32x32_64_mul (fixedtemp, scalex);
-		 buf->points[i].x = _cairo_int64_to_int32(_cairo_int64_rsl (i64temp, 16));
+		 buf->points[i].x = _cairo_fixed_mul (buf->points[i].x + offx, scalex);
 	     }
 
 	     if (scaley == CAIRO_FIXED_ONE) {
 		 buf->points[i].y += offy;
 	     } else {
-		 fixedtemp = buf->points[i].y + offy;
-		 i64temp = _cairo_int32x32_64_mul (fixedtemp, scaley);
-		 buf->points[i].y = _cairo_int64_to_int32(_cairo_int64_rsl (i64temp, 16));
+		 buf->points[i].y = _cairo_fixed_mul (buf->points[i].y + offy, scaley);
 	     }
 	 }
 
diff --git a/src/cairo-traps.c b/src/cairo-traps.c
index 1cc8be6..5ed1f7c 100644
--- a/src/cairo-traps.c
+++ b/src/cairo-traps.c
@@ -1,3 +1,4 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
 /*
  * Copyright © 2002 Keith Packard
  * Copyright © 2007 Red Hat, Inc.
@@ -348,21 +349,16 @@ _cairo_trapezoid_array_translate_and_sca
         cairo_fixed_t ysc = _cairo_fixed_from_double (sy);
 
         for (i = 0; i < num_traps; i++) {
-#define FIXED_MUL(_a, _b) \
-            (_cairo_int64_to_int32(_cairo_int64_rsl(_cairo_int32x32_64_mul((_a), (_b)), 16)))
-
-            offset_traps[i].top = FIXED_MUL(src_traps[i].top + yoff, ysc);
-            offset_traps[i].bottom = FIXED_MUL(src_traps[i].bottom + yoff, ysc);
-            offset_traps[i].left.p1.x = FIXED_MUL(src_traps[i].left.p1.x + xoff, xsc);
-            offset_traps[i].left.p1.y = FIXED_MUL(src_traps[i].left.p1.y + yoff, ysc);
-            offset_traps[i].left.p2.x = FIXED_MUL(src_traps[i].left.p2.x + xoff, xsc);
-            offset_traps[i].left.p2.y = FIXED_MUL(src_traps[i].left.p2.y + yoff, ysc);
-            offset_traps[i].right.p1.x = FIXED_MUL(src_traps[i].right.p1.x + xoff, xsc);
-            offset_traps[i].right.p1.y = FIXED_MUL(src_traps[i].right.p1.y + yoff, ysc);
-            offset_traps[i].right.p2.x = FIXED_MUL(src_traps[i].right.p2.x + xoff, xsc);
-            offset_traps[i].right.p2.y = FIXED_MUL(src_traps[i].right.p2.y + yoff, ysc);
-
-#undef FIXED_MUL
+            offset_traps[i].top = _cairo_fixed_mul (src_traps[i].top + yoff, ysc);
+            offset_traps[i].bottom = _cairo_fixed_mul (src_traps[i].bottom + yoff, ysc);
+            offset_traps[i].left.p1.x = _cairo_fixed_mul (src_traps[i].left.p1.x + xoff, xsc);
+            offset_traps[i].left.p1.y = _cairo_fixed_mul (src_traps[i].left.p1.y + yoff, ysc);
+            offset_traps[i].left.p2.x = _cairo_fixed_mul (src_traps[i].left.p2.x + xoff, xsc);
+            offset_traps[i].left.p2.y = _cairo_fixed_mul (src_traps[i].left.p2.y + yoff, ysc);
+            offset_traps[i].right.p1.x = _cairo_fixed_mul (src_traps[i].right.p1.x + xoff, xsc);
+            offset_traps[i].right.p1.y = _cairo_fixed_mul (src_traps[i].right.p1.y + yoff, ysc);
+            offset_traps[i].right.p2.x = _cairo_fixed_mul (src_traps[i].right.p2.x + xoff, xsc);
+            offset_traps[i].right.p2.y = _cairo_fixed_mul (src_traps[i].right.p2.y + yoff, ysc);
         }
     }
 }
diff-tree 0048a26a4477d3acb5dd0231756cfaae92d240a9 (from 76c32f899af63649bf911533a2ed6b42e617da41)
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date:   Mon Jun 18 16:26:14 2007 -0700

    [fixpt] Make fixed point methods static inline and generic
    
    Move the fixed point methods to static inline versions in
    cairo-fixed-private.h, and don't hardcode fixed to be 16.16.

diff --git a/src/cairo-fixed-private.h b/src/cairo-fixed-private.h
new file mode 100644
index 0000000..333a60b
--- /dev/null
+++ b/src/cairo-fixed-private.h
@@ -0,0 +1,256 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
+/* Cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2007 Mozilla Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation
+ *
+ * Contributor(s):
+ *	Vladimir Vukicevic <vladimir at pobox.com>
+ */
+
+#ifndef CAIRO_FIXED_PRIVATE_H
+#define CAIRO_FIXED_PRIVATE_H
+
+#include "cairo-wideint-private.h"
+
+/*
+ * Fixed-point configuration
+ */
+
+typedef int32_t		cairo_fixed_16_16_t;
+typedef cairo_int64_t	cairo_fixed_32_32_t;
+typedef cairo_int64_t	cairo_fixed_48_16_t;
+typedef cairo_int128_t	cairo_fixed_64_64_t;
+typedef cairo_int128_t	cairo_fixed_96_32_t;
+
+/* Eventually, we should allow changing this, but I think
+ * there are some assumptions in the tesselator about the
+ * size of a fixed type.
+ */
+#define CAIRO_FIXED_BITS	32
+
+/* The number of fractional bits.  Changing this involves
+ * making sure that you compute a double-to-fixed magic number.
+ * (see below).
+ */
+#define CAIRO_FIXED_FRAC_BITS	16
+
+/* A signed type CAIRO_FIXED_BITS in size; the main fixed point type */
+typedef int32_t cairo_fixed_t;
+
+/* An unsigned type of the same size as cairo_fixed_t */
+typedef uint32_t cairo_fixed_unsigned_t;
+
+/*
+ * No configurable bits below this.
+ */
+
+
+#if (CAIRO_FIXED_BITS != 32)
+# error CAIRO_FIXED_BITS must be 32, and the type must be a 32-bit type.
+# error To remove this limitation, you will have to fix the tesselator.
+#endif
+
+#define CAIRO_FIXED_ONE        ((cairo_fixed_t)(1 << CAIRO_FIXED_FRAC_BITS))
+#define CAIRO_FIXED_ONE_DOUBLE ((double)(1 << CAIRO_FIXED_FRAC_BITS))
+#define CAIRO_FIXED_EPSILON    ((cairo_fixed_t)(1))
+
+#define CAIRO_FIXED_FRAC_MASK  (((cairo_fixed_unsigned_t)(-1)) >> (CAIRO_FIXED_BITS - CAIRO_FIXED_FRAC_BITS))
+#define CAIRO_FIXED_WHOLE_MASK (~CAIRO_FIXED_FRAC_MASK)
+
+static inline cairo_fixed_t
+_cairo_fixed_from_int (int i)
+{
+    return i << CAIRO_FIXED_FRAC_BITS;
+}
+
+/* This is the "magic number" approach to converting a double into fixed
+ * point as described here:
+ *
+ * http://www.stereopsis.com/sree/fpu2006.html (an overview)
+ * http://www.d6.com/users/checker/pdfs/gdmfp.pdf (in detail)
+ *
+ * The basic idea is to add a large enough number to the double that the
+ * literal floating point is moved up to the extent that it forces the
+ * double's value to be shifted down to the bottom of the mantissa (to make
+ * room for the large number being added in). Since the mantissa is, at a
+ * given moment in time, a fixed point integer itself, one can convert a
+ * float to various fixed point representations by moving around the point
+ * of a floating point number through arithmetic operations. This behavior
+ * is reliable on most modern platforms as it is mandated by the IEEE-754
+ * standard for floating point arithmetic.
+ *
+ * For our purposes, a "magic number" must be carefully selected that is
+ * both large enough to produce the desired point-shifting effect, and also
+ * has no lower bits in its representation that would interfere with our
+ * value at the bottom of the mantissa. The magic number is calculated as
+ * follows:
+ *
+ *          (2 ^ (MANTISSA_SIZE - FRACTIONAL_SIZE)) * 1.5
+ *
+ * where in our case:
+ *  - MANTISSA_SIZE for 64-bit doubles is 52
+ *  - FRACTIONAL_SIZE for 16.16 fixed point is 16
+ *
+ * Although this approach provides a very large speedup of this function
+ * on a wide-array of systems, it does come with two caveats:
+ *
+ * 1) It uses banker's rounding as opposed to arithmetic rounding.
+ * 2) It doesn't function properly if the FPU is in single-precision
+ *    mode.
+ */
+
+/* The 16.16 number must always be available */
+#define CAIRO_MAGIC_NUMBER_FIXED_16_16 (103079215104.0)
+
+#if CAIRO_FIXED_BITS == 32
+
+# if CAIRO_FIXED_FRAC_BITS == 16
+#  define CAIRO_MAGIC_NUMBER_FIXED CAIRO_MAGIC_NUMBER_FIXED_16_16
+# elif CAIRO_FIXED_FRAC_BITS == 8
+#  define CAIRO_MAGIC_NUMBER_FIXED (26388279066624.0)
+# elif CAIRO_FIXED_FRAC_BITS == 6
+#  define CAIRO_MAGIC_NUMBER_FIXED (105553116266496.0)
+# else
+#  error Please define a magic number for your fixed point type!
+#  error See cairo-fixed-private.h for details.
+# endif
+
+/* For 32-bit fixed point numbers */
+static inline cairo_fixed_t
+_cairo_fixed_from_double (double d)
+{
+    union {
+        double d;
+        int32_t i[2];
+    } u;
+
+    u.d = d + CAIRO_MAGIC_NUMBER_FIXED;
+#ifdef FLOAT_WORDS_BIGENDIAN
+    return u.i[1];
+#else
+    return u.i[0];
+#endif
+}
+
+#else
+# error Please define a magic number for your fixed point type!
+# error See cairo-fixed-private.h for details.
+#endif
+
+static inline cairo_fixed_t
+_cairo_fixed_from_26_6 (uint32_t i)
+{
+#if CAIRO_FIXED_FRAC_BITS > 6
+    return i << (CAIRO_FIXED_FRAC_BITS - 6);
+#else
+    return i >> (6 - CAIRO_FIXED_FRAC_BITS);
+#endif
+}
+
+static inline double
+_cairo_fixed_to_double (cairo_fixed_t f)
+{
+    return ((double) f) / CAIRO_FIXED_ONE_DOUBLE;
+}
+
+static inline int
+_cairo_fixed_is_integer (cairo_fixed_t f)
+{
+    return (f & CAIRO_FIXED_FRAC_MASK) == 0;
+}
+
+static inline int
+_cairo_fixed_integer_part (cairo_fixed_t f)
+{
+    return f >> CAIRO_FIXED_FRAC_BITS;
+}
+
+static inline int
+_cairo_fixed_integer_floor (cairo_fixed_t f)
+{
+    if (f >= 0)
+        return f >> CAIRO_FIXED_FRAC_BITS;
+    else
+        return -((-f - 1) >> CAIRO_FIXED_FRAC_BITS) - 1;
+}
+
+static inline int
+_cairo_fixed_integer_ceil (cairo_fixed_t f)
+{
+    if (f > 0)
+	return ((f - 1)>>CAIRO_FIXED_FRAC_BITS) + 1;
+    else
+	return - (-f >> CAIRO_FIXED_FRAC_BITS);
+}
+
+/* A bunch of explicit 16.16 operators; we need these
+ * to interface with pixman and other backends that require
+ * 16.16 fixed point types.
+ */
+static inline cairo_fixed_16_16_t
+_cairo_fixed_to_16_16 (cairo_fixed_t f)
+{
+#if CAIRO_FIXED_FRAC_BITS > 16
+    return f >> (CAIRO_FIXED_FRAC_BITS - 16);
+#else
+    return f << (16 - CAIRO_FIXED_FRAC_BITS);
+#endif
+}
+
+static inline cairo_fixed_16_16_t
+_cairo_fixed_16_16_from_double (double d)
+{
+    union {
+        double d;
+        int32_t i[2];
+    } u;
+
+    u.d = d + CAIRO_MAGIC_NUMBER_FIXED_16_16;
+#ifdef FLOAT_WORDS_BIGENDIAN
+    return u.i[1];
+#else
+    return u.i[0];
+#endif
+}
+
+#if CAIRO_FIXED_BITS == 32
+
+static inline cairo_fixed_t
+_cairo_fixed_mul (cairo_fixed_t a, cairo_fixed_t b)
+{
+    cairo_int64_t temp = _cairo_int32x32_64_mul (a, b);
+    return _cairo_int64_to_int32(_cairo_int64_rsl (temp, CAIRO_FIXED_FRAC_BITS));
+}
+
+#else
+# error Please define multiplication and other operands for your fixed-point type size
+#endif
+
+#endif /* CAIRO_FIXED_PRIVATE_H */
diff --git a/src/cairo-fixed.c b/src/cairo-fixed.c
index fe6c2dc..2bb0dfe 100644
--- a/src/cairo-fixed.c
+++ b/src/cairo-fixed.c
@@ -36,102 +36,4 @@
 
 #include "cairoint.h"
 
-cairo_fixed_t
-_cairo_fixed_from_int (int i)
-{
-    return i << 16;
-}
-
-/* This is the "magic number" approach to converting a double into fixed
- * point as described here:
- *
- * http://www.stereopsis.com/sree/fpu2006.html (an overview)
- * http://www.d6.com/users/checker/pdfs/gdmfp.pdf (in detail)
- *
- * The basic idea is to add a large enough number to the double that the
- * literal floating point is moved up to the extent that it forces the
- * double's value to be shifted down to the bottom of the mantissa (to make
- * room for the large number being added in). Since the mantissa is, at a
- * given moment in time, a fixed point integer itself, one can convert a
- * float to various fixed point representations by moving around the point
- * of a floating point number through arithmetic operations. This behavior
- * is reliable on most modern platforms as it is mandated by the IEEE-754
- * standard for floating point arithmetic.
- *
- * For our purposes, a "magic number" must be carefully selected that is
- * both large enough to produce the desired point-shifting effect, and also
- * has no lower bits in its representation that would interfere with our
- * value at the bottom of the mantissa. The magic number is calculated as
- * follows:
- *
- *          (2 ^ (MANTISSA_SIZE - FRACTIONAL_SIZE)) * 1.5
- *
- * where in our case:
- *  - MANTISSA_SIZE for 64-bit doubles is 52
- *  - FRACTIONAL_SIZE for 16.16 fixed point is 16
- *
- * Although this approach provides a very large speedup of this function
- * on a wide-array of systems, it does come with two caveats:
- *
- * 1) It uses banker's rounding as opposed to arithmetic rounding.
- * 2) It doesn't function properly if the FPU is in single-precision
- *    mode.
- */
-#define CAIRO_MAGIC_NUMBER_FIXED_16_16 (103079215104.0)
-cairo_fixed_t
-_cairo_fixed_from_double (double d)
-{
-    union {
-        double d;
-        int32_t i[2];
-    } u;
-
-    u.d = d + CAIRO_MAGIC_NUMBER_FIXED_16_16;
-#ifdef FLOAT_WORDS_BIGENDIAN
-    return u.i[1];
-#else
-    return u.i[0];
-#endif
-}
-
-cairo_fixed_t
-_cairo_fixed_from_26_6 (uint32_t i)
-{
-    return i << 10;
-}
-
-double
-_cairo_fixed_to_double (cairo_fixed_t f)
-{
-    return ((double) f) / 65536.0;
-}
-
-int
-_cairo_fixed_is_integer (cairo_fixed_t f)
-{
-    return (f & 0xFFFF) == 0;
-}
-
-int
-_cairo_fixed_integer_part (cairo_fixed_t f)
-{
-    return f >> 16;
-}
-
-int
-_cairo_fixed_integer_floor (cairo_fixed_t f)
-{
-    if (f >= 0)
-	return f >> 16;
-    else
-	return -((-f - 1) >> 16) - 1;
-}
-
-int
-_cairo_fixed_integer_ceil (cairo_fixed_t f)
-{
-    if (f > 0)
-	return ((f - 1)>>16) + 1;
-    else
-	return - (-f >> 16);
-}
+#include "cairo-fixed-private.h"
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 9911b4a..c65b299 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -282,7 +282,7 @@ static void
 ComputeGradientValue (void *info, const float *in, float *out)
 {
     float fdist = *in; /* 0.0 .. 1.0 */
-    cairo_fixed_16_16_t fdist_fix = _cairo_fixed_from_double(*in);
+    cairo_fixed_t fdist_fix = _cairo_fixed_from_double(*in);
     cairo_gradient_pattern_t *grad = (cairo_gradient_pattern_t*) info;
     unsigned int i;
 
diff --git a/src/cairoint.h b/src/cairoint.h
index 4fd8a84..9665297 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -182,15 +182,7 @@ do {					\
 #include "cairo-mutex-private.h"
 #include "cairo-wideint-private.h"
 #include "cairo-malloc-private.h"
-
-typedef int32_t		cairo_fixed_16_16_t;
-typedef cairo_int64_t	cairo_fixed_32_32_t;
-typedef cairo_int64_t	cairo_fixed_48_16_t;
-typedef cairo_int128_t	cairo_fixed_64_64_t;
-typedef cairo_int128_t	cairo_fixed_96_32_t;
-
-/* The common 16.16 format gets a shorter name */
-typedef cairo_fixed_16_16_t cairo_fixed_t;
+#include "cairo-fixed-private.h"
 
 #define CAIRO_ALPHA_IS_OPAQUE(alpha) ((alpha) >= ((double)0xff00 / (double)0xffff))
 #define CAIRO_ALPHA_SHORT_IS_OPAQUE(alpha) ((alpha) >= 0xff00)
@@ -1114,33 +1106,6 @@ _cairo_restrict_value (double *value, do
 cairo_private int
 _cairo_lround (double d);
 
-/* cairo_fixed.c */
-cairo_private cairo_fixed_t
-_cairo_fixed_from_int (int i);
-
-#define CAIRO_FIXED_ONE _cairo_fixed_from_int (1)
-
-cairo_private cairo_fixed_t
-_cairo_fixed_from_double (double d);
-
-cairo_private cairo_fixed_t
-_cairo_fixed_from_26_6 (uint32_t i);
-
-cairo_private double
-_cairo_fixed_to_double (cairo_fixed_t f);
-
-cairo_private int
-_cairo_fixed_is_integer (cairo_fixed_t f);
-
-cairo_private int
-_cairo_fixed_integer_part (cairo_fixed_t f);
-
-cairo_private int
-_cairo_fixed_integer_floor (cairo_fixed_t f);
-
-cairo_private int
-_cairo_fixed_integer_ceil (cairo_fixed_t f);
-
 /* cairo_gstate.c */
 cairo_private cairo_status_t
 _cairo_gstate_init (cairo_gstate_t  *gstate,


More information about the cairo-commit mailing list