[cairo-commit] 101 commits - boilerplate/cairo-boilerplate.c configure.in perf/text.c pixman/configure.in pixman/src src/cairo-arc.c src/cairo-atsui-font.c src/cairo-bentley-ottmann.c src/cairo.c src/cairo-cff-subset.c src/cairo-clip.c src/cairo-clip-private.h src/cairo-ft-font.c src/cairo-gstate.c src/cairo.h src/cairo-hash.c src/cairo-image-surface.c src/cairoint.h src/cairo-matrix.c src/cairo-meta-surface.c src/cairo-output-stream.c src/cairo-output-stream-private.h src/cairo-paginated-surface.c src/cairo-path-bounds.c src/cairo-path.c src/cairo-path-fill.c src/cairo-path-stroke.c src/cairo-pattern.c src/cairo-pdf-surface.c src/cairo-pen.c src/cairo-polygon.c src/cairo-ps-surface.c src/cairo-scaled-font.c src/cairo-skiplist.c src/cairo-spline.c src/cairo-surface.c src/cairo-surface-fallback.c src/cairo-svg-surface.c src/cairo-traps.c src/cairo-truetype-subset.c src/cairo-type1-fallback.c src/cairo-win32-font.c src/cairo-xlib-surface.c src/check-headers.sh src/test-fallback-surface.c src/test-meta-surface.c test/buffer-diff.c test/.gitignore test/invalid-matrix.c test/Makefile.am

Carl Worth cworth at kemper.freedesktop.org
Wed Apr 11 13:16:42 PDT 2007


 boilerplate/cairo-boilerplate.c   |   45 ++-
 configure.in                      |   15 -
 perf/text.c                       |    4 
 pixman/configure.in               |    3 
 pixman/src/fbmmx.c                |  215 ++++++--------
 pixman/src/fbmmx.h                |   19 -
 pixman/src/icimage.c              |   33 +-
 pixman/src/icrect.c               |   74 +++-
 pixman/src/ictrap.c               |   37 +-
 pixman/src/pixman-remap.h         |    1 
 pixman/src/pixman.h               |    8 
 src/cairo-arc.c                   |    2 
 src/cairo-atsui-font.c            |   22 -
 src/cairo-bentley-ottmann.c       |   73 +++-
 src/cairo-cff-subset.c            |    6 
 src/cairo-clip-private.h          |    6 
 src/cairo-clip.c                  |   75 +++--
 src/cairo-ft-font.c               |   93 ++++--
 src/cairo-gstate.c                |   76 ++---
 src/cairo-hash.c                  |   13 
 src/cairo-image-surface.c         |   21 +
 src/cairo-matrix.c                |    4 
 src/cairo-meta-surface.c          |    6 
 src/cairo-output-stream-private.h |    2 
 src/cairo-output-stream.c         |   97 +++---
 src/cairo-paginated-surface.c     |   44 ++
 src/cairo-path-bounds.c           |    6 
 src/cairo-path-fill.c             |   38 --
 src/cairo-path-stroke.c           |   64 +++-
 src/cairo-path.c                  |   57 ++-
 src/cairo-pattern.c               |   53 +--
 src/cairo-pdf-surface.c           |  191 +++++++-----
 src/cairo-pen.c                   |   35 +-
 src/cairo-polygon.c               |   60 ++--
 src/cairo-ps-surface.c            |  114 +++++--
 src/cairo-scaled-font.c           |   87 ++++-
 src/cairo-skiplist.c              |    2 
 src/cairo-spline.c                |   24 -
 src/cairo-surface-fallback.c      |   44 +-
 src/cairo-surface.c               |   18 -
 src/cairo-svg-surface.c           |  159 +++++++---
 src/cairo-traps.c                 |   56 ++-
 src/cairo-truetype-subset.c       |   39 ++
 src/cairo-type1-fallback.c        |   33 +-
 src/cairo-win32-font.c            |   10 
 src/cairo-xlib-surface.c          |  126 +++++---
 src/cairo.c                       |  565 ++++++++++++++++++++++----------------
 src/cairo.h                       |   40 +-
 src/cairoint.h                    |   78 +++--
 src/check-headers.sh              |    2 
 src/test-fallback-surface.c       |   22 +
 src/test-meta-surface.c           |   16 -
 test/.gitignore                   |    1 
 test/Makefile.am                  |   17 -
 test/buffer-diff.c                |    5 
 test/invalid-matrix.c             |  142 +++++++++
 56 files changed, 1948 insertions(+), 1150 deletions(-)

New commits:
diff-tree e36794ad34282a4d671d7cc5527e9c650c2736fe (from parents)
Merge: b6924722b8c8e5f4356d3c8ba438a702ffb8a5ed b745126a04c126acc695e8abb6372c1890b03f07
Author: Carl Worth <cworth at cworth.org>
Date:   Wed Apr 11 13:15:57 2007 -0700

    Merge branch 'warn-unused-result' into cairo

diff-tree b745126a04c126acc695e8abb6372c1890b03f07 (from 61b8e346135f8b61b22257541c97b9f262c17826)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Apr 11 12:26:21 2007 +0100

    Use find | xargs to overcome shell command line limit.
    
    Once again we have hit the command line limit with the sheer volume of
    generated test output. So replace the glob with a find which has the
    additional advantage of only needing to walk the tree once to generate
    the file lists - this begins to be noticeable with such large directories.

diff --git a/test/Makefile.am b/test/Makefile.am
index 74ead62..d43f774 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -523,14 +523,16 @@ CLEANFILES =					\
 	$(EXTRA_LTLIBRARIES)			\
 	$(EXTRA_PROGRAMS)
 
-# some systems cannot handle all of our clean files together
+# most systems cannot handle all of our clean files together
 clean-local:
-	-$(RM) *.ps
-	-$(RM) *.pdf
-	-$(RM) *.svg
-	-$(RM) *-out.png
-	-$(RM) *-diff.png
-	-$(RM) *.log
+	-find . \
+	    \( -name '*.ps' -print0 \) , \
+	    \( -name '*.pdf' -print0 \) , \
+	    \( -name '*.svg' -print0 \) , \
+	    \( -name '*-out.png' -print0 \) , \
+	    \( -name '*-diff.png' -print0 \) , \
+	    \( -name '*.log' -print0 \) \
+	    | xargs -0 rm -f
 
 # Check tests under valgrind
 # Saves log to valgrind-log
diff-tree 61b8e346135f8b61b22257541c97b9f262c17826 (from efee2087387ba49e36d8d6104c4e2dd3ffeba081)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Apr 11 11:59:27 2007 +0100

    Unexport fbSolidFillmmx and fbCopyAreammx.
    
    By unexporting these function we have exact control over their call sites
    and so can convert the initial guards into asserts which transforms the
    two functions to return unconditional success and hence conversion to
    void.

diff --git a/pixman/src/fbmmx.c b/pixman/src/fbmmx.c
index 0287e79..e11f849 100644
--- a/pixman/src/fbmmx.c
+++ b/pixman/src/fbmmx.c
@@ -1658,6 +1658,102 @@ fbCompositeSolidMask_nx8x8888mmx (pixman
     _mm_empty();
 }
 
+static void
+fbSolidFillmmx (FbPixels	*pDraw,
+		int		x,
+		int		y,
+		int		width,
+		int		height,
+		FbBits		xor)
+{
+    FbStride	stride;
+    int		bpp;
+    ullong	fill;
+    __m64	vfill;
+    CARD32	byte_width;
+    CARD8	*byte_line;
+    FbBits      *bits;
+    int		xoff, yoff;
+
+    CHECKPOINT();
+
+    fbGetDrawable(pDraw, bits, stride, bpp, xoff, yoff);
+
+    assert (bpp == 32 || (xor >> 16 == (xor & 0xffff)));
+    assert (bpp == 16 || bpp == 32);
+
+    if (bpp == 16)
+    {
+	stride = stride * sizeof (FbBits) / 2;
+	byte_line = (CARD8 *)(((CARD16 *)bits) + stride * (y + yoff) + (x + xoff));
+	byte_width = 2 * width;
+	stride *= 2;
+    }
+    else
+    {
+	stride = stride * sizeof (FbBits) / 4;
+	byte_line = (CARD8 *)(((CARD32 *)bits) + stride * (y + yoff) + (x + xoff));
+	byte_width = 4 * width;
+	stride *= 4;
+    }
+
+    fill = ((ullong)xor << 32) | xor;
+    vfill = M64(fill);
+
+    while (height--)
+    {
+	unsigned int w;
+	CARD8 *d = byte_line;
+	byte_line += stride;
+	w = byte_width;
+
+	while (w >= 2 && ((unsigned long)d & 3))
+	{
+	    *(CARD16 *)d = xor;
+	    w -= 2;
+	    d += 2;
+	}
+
+	while (w >= 4 && ((unsigned long)d & 7))
+	{
+	    *(CARD32 *)d = xor;
+
+	    w -= 4;
+	    d += 4;
+	}
+
+	while (w >= 64)
+	{
+	    *(__m64*) (d +  0) = vfill;
+	    *(__m64*) (d +  8) = vfill;
+	    *(__m64*) (d + 16) = vfill;
+	    *(__m64*) (d + 24) = vfill;
+	    *(__m64*) (d + 32) = vfill;
+	    *(__m64*) (d + 40) = vfill;
+	    *(__m64*) (d + 48) = vfill;
+	    *(__m64*) (d + 56) = vfill;
+
+	    w -= 64;
+	    d += 64;
+	}
+	while (w >= 4)
+	{
+	    *(CARD32 *)d = xor;
+
+	    w -= 4;
+	    d += 4;
+	}
+	if (w >= 2)
+	{
+	    *(CARD16 *)d = xor;
+	    w -= 2;
+	    d += 2;
+	}
+    }
+
+    _mm_empty();
+}
+
 void
 fbCompositeSolidMaskSrc_nx8x8888mmx (pixman_operator_t      op,
 				     PicturePtr pSrc,
@@ -1687,8 +1783,8 @@ fbCompositeSolidMaskSrc_nx8x8888mmx (pix
     srca = src >> 24;
     if (srca == 0)
     {
-	if (fbSolidFillmmx (pDst->pDrawable, xDst, yDst, width, height, 0))
-	    return;
+	fbSolidFillmmx (pDst->pDrawable, xDst, yDst, width, height, 0);
+	return;
     }
 
     srcsrc = (ullong)src << 32 | src;
@@ -2592,107 +2688,7 @@ fbCompositeSrcAdd_8888x8888mmx (pixman_o
     _mm_empty();
 }
 
-Bool
-fbSolidFillmmx (FbPixels	*pDraw,
-		int		x,
-		int		y,
-		int		width,
-		int		height,
-		FbBits		xor)
-{
-    FbStride	stride;
-    int		bpp;
-    ullong	fill;
-    __m64	vfill;
-    CARD32	byte_width;
-    CARD8	*byte_line;
-    FbBits      *bits;
-    int		xoff, yoff;
-
-    CHECKPOINT();
-
-    fbGetDrawable(pDraw, bits, stride, bpp, xoff, yoff);
-
-    if (bpp == 16 && (xor >> 16 != (xor & 0xffff)))
-	return FALSE;
-
-    if (bpp != 16 && bpp != 32)
-	return FALSE;
-
-    if (bpp == 16)
-    {
-	stride = stride * sizeof (FbBits) / 2;
-	byte_line = (CARD8 *)(((CARD16 *)bits) + stride * (y + yoff) + (x + xoff));
-	byte_width = 2 * width;
-	stride *= 2;
-    }
-    else
-    {
-	stride = stride * sizeof (FbBits) / 4;
-	byte_line = (CARD8 *)(((CARD32 *)bits) + stride * (y + yoff) + (x + xoff));
-	byte_width = 4 * width;
-	stride *= 4;
-    }
-
-    fill = ((ullong)xor << 32) | xor;
-    vfill = M64(fill);
-
-    while (height--)
-    {
-	unsigned int w;
-	CARD8 *d = byte_line;
-	byte_line += stride;
-	w = byte_width;
-
-	while (w >= 2 && ((unsigned long)d & 3))
-	{
-	    *(CARD16 *)d = xor;
-	    w -= 2;
-	    d += 2;
-	}
-
-	while (w >= 4 && ((unsigned long)d & 7))
-	{
-	    *(CARD32 *)d = xor;
-
-	    w -= 4;
-	    d += 4;
-	}
-
-	while (w >= 64)
-	{
-	    *(__m64*) (d +  0) = vfill;
-	    *(__m64*) (d +  8) = vfill;
-	    *(__m64*) (d + 16) = vfill;
-	    *(__m64*) (d + 24) = vfill;
-	    *(__m64*) (d + 32) = vfill;
-	    *(__m64*) (d + 40) = vfill;
-	    *(__m64*) (d + 48) = vfill;
-	    *(__m64*) (d + 56) = vfill;
-
-	    w -= 64;
-	    d += 64;
-	}
-	while (w >= 4)
-	{
-	    *(CARD32 *)d = xor;
-
-	    w -= 4;
-	    d += 4;
-	}
-	if (w >= 2)
-	{
-	    *(CARD16 *)d = xor;
-	    w -= 2;
-	    d += 2;
-	}
-    }
-
-    _mm_empty();
-    return TRUE;
-}
-
-Bool
+static void
 fbCopyAreammx (FbPixels	*pSrc,
 	       FbPixels	*pDst,
 	       int		src_x,
@@ -2721,16 +2717,8 @@ fbCopyAreammx (FbPixels	*pSrc,
     fbGetDrawable(pSrc, src_bits, src_stride, src_bpp, src_xoff, src_yoff);
     fbGetDrawable(pDst, dst_bits, dst_stride, dst_bpp, dst_xoff, dst_yoff);
 
-    if (src_bpp != 16 && src_bpp != 32)
-	return FALSE;
-
-    if (dst_bpp != 16 && dst_bpp != 32)
-	return FALSE;
-
-    if (src_bpp != dst_bpp)
-    {
-	return FALSE;
-    }
+    assert (src_bpp == dst_bpp);
+    assert (src_bpp == 16 || src_bpp == 32);
 
     if (src_bpp == 16)
     {
@@ -2811,7 +2799,6 @@ fbCopyAreammx (FbPixels	*pSrc,
     }
 
     _mm_empty();
-    return TRUE;
 }
 
 void
diff --git a/pixman/src/fbmmx.h b/pixman/src/fbmmx.h
index 054ac0b..9c20cd6 100644
--- a/pixman/src/fbmmx.h
+++ b/pixman/src/fbmmx.h
@@ -283,16 +283,6 @@ void fbCompositeSrc_8888x8888mmx (pixman
 				  CARD16     width,
 				  CARD16     height);
 pixman_private
-Bool fbCopyAreammx (FbPixels	*pSrc,
-		    FbPixels	*pDst,
-		    int		src_x,
-		    int		src_y,
-		    int		dst_x,
-		    int		dst_y,
-		    int		width,
-		    int		height);
-
-pixman_private
 void fbCompositeCopyAreammx (pixman_operator_t	op,
 			     PicturePtr	pSrc,
 			     PicturePtr	pMask,
@@ -305,13 +295,4 @@ void fbCompositeCopyAreammx (pixman_oper
 			     INT16      yDst,
 			     CARD16     width,
 			     CARD16     height);
-
-pixman_private
-Bool fbSolidFillmmx (FbPixels	*pDraw,
-		     int		x,
-		     int		y,
-		     int		width,
-		     int		height,
-		     FbBits		xor);
-
 #endif /* USE_MMX */
diff --git a/pixman/src/pixman-remap.h b/pixman/src/pixman-remap.h
index 02ab3c4..6004fe7 100644
--- a/pixman/src/pixman-remap.h
+++ b/pixman/src/pixman-remap.h
@@ -78,4 +78,3 @@
 #define RenderLineFixedEdgeInit _cairo_pixman_render_line_fixed_edge_init
 #define RenderSampleCeilY _cairo_pixman_render_sample_ceil_y
 #define RenderSampleFloorY _cairo_pixman_render_sample_floor_y
-#define fbSolidFillmmx _cairo_pixman_solid_fill_mmx
diff-tree efee2087387ba49e36d8d6104c4e2dd3ffeba081 (from bec097b5e281fcf2453de53946e89c13b37ecd1a)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Apr 11 11:26:27 2007 +0100

    Propagate errors up through pixman_composite_trapezoids()
    
    Change the return type to indicate errors detected during
    pixman_composite_trapezoids() and add checking for failures during
    region ops.

diff --git a/pixman/src/ictrap.c b/pixman/src/ictrap.c
index 252fa69..3e6b8c6 100644
--- a/pixman/src/ictrap.c
+++ b/pixman/src/ictrap.c
@@ -102,10 +102,7 @@ pixman_trapezoid_bounds (int ntrap, cons
     }
 }
 
-/* XXX: There are failure cases in this function. Don't we need to
- * propagate the errors out?
- */
-void
+int
 pixman_composite_trapezoids (pixman_operator_t	      op,
 			     pixman_image_t	      *src,
 			     pixman_image_t	      *dst,
@@ -114,15 +111,16 @@ pixman_composite_trapezoids (pixman_oper
 			     const pixman_trapezoid_t *traps,
 			     int		      ntraps)
 {
-    pixman_image_t	*image = NULL;
-    pixman_box16_t	traps_bounds, dst_bounds, bounds;
-    pixman_region16_t	traps_region, dst_region;
-    int16_t		xDst, yDst;
-    int16_t		xRel, yRel;
-    pixman_format_t	*format;
+    pixman_image_t		*image = NULL;
+    pixman_box16_t		 traps_bounds, dst_bounds, bounds;
+    pixman_region16_t		 traps_region, dst_region;
+    int16_t			 xDst, yDst;
+    int16_t			 xRel, yRel;
+    pixman_format_t		*format;
+    pixman_region_status_t	 status;
 
     if (ntraps == 0)
-	return;
+	return 0;
 
     /*
      * Check for solid alpha add
@@ -131,7 +129,7 @@ pixman_composite_trapezoids (pixman_oper
     {
 	for (; ntraps; ntraps--, traps++)
 	    fbRasterizeTrapezoid (dst, traps, 0, 0);
-	return;
+	return 0;
     }
 
     xDst = traps[0].left.p1.x >> 16;
@@ -149,7 +147,12 @@ pixman_composite_trapezoids (pixman_oper
     dst_bounds.y2 = pixman_image_get_height (dst);
 
     pixman_region_init_with_extents (&dst_region, &dst_bounds);
-    pixman_region_intersect (&traps_region, &traps_region, &dst_region);
+    status = pixman_region_intersect (&traps_region, &traps_region, &dst_region);
+    if (status != PIXMAN_REGION_STATUS_SUCCESS) {
+	pixman_region_fini (&traps_region);
+	pixman_region_fini (&dst_region);
+	return 1;
+    }
 
     bounds = *(pixman_region_extents (&traps_region));
 
@@ -157,11 +160,11 @@ pixman_composite_trapezoids (pixman_oper
     pixman_region_fini (&dst_region);
 
     if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
-	return;
+	return 0;
 
     format = pixman_format_create (PIXMAN_FORMAT_NAME_A8);
     if (!format)
-	return;
+	return 1;
 
     image = FbCreateAlphaPicture (dst, format,
 				  bounds.x2 - bounds.x1,
@@ -169,7 +172,7 @@ pixman_composite_trapezoids (pixman_oper
     if (!image)
     {
 	pixman_format_destroy (format);
-	return;
+	return 1;
     }
 
     for (; ntraps; ntraps--, traps++)
@@ -189,6 +192,8 @@ pixman_composite_trapezoids (pixman_oper
     pixman_image_destroy (image);
 
     pixman_format_destroy (format);
+
+    return 0;
 }
 
 void
diff --git a/pixman/src/pixman.h b/pixman/src/pixman.h
index fceed2a..fb2ccf7 100644
--- a/pixman/src/pixman.h
+++ b/pixman/src/pixman.h
@@ -466,7 +466,7 @@ pixman_fill_rectangles (pixman_operator_
 
 /* ictrap.c */
 
-pixman_private void
+pixman_private int
 pixman_composite_trapezoids (pixman_operator_t		op,
 			     pixman_image_t		*src,
 			     pixman_image_t		*dst,
diff-tree bec097b5e281fcf2453de53946e89c13b37ecd1a (from 909334ee00701e18b2f2033b1c3a27714ce988fb)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Apr 11 11:13:30 2007 +0100

    Propagate region errors from pixman_color_rects().
    
    Region operations within pixman_color_rects can fail, so cleanup and
    propagate.

diff --git a/pixman/src/icrect.c b/pixman/src/icrect.c
index a6c080c..982c114 100644
--- a/pixman/src/icrect.c
+++ b/pixman/src/icrect.c
@@ -180,7 +180,7 @@ pixman_fill_rect_general (pixman_image_t
     }
 }
 
-static void
+static int
 pixman_color_rects (pixman_image_t	 *dst,
 	      pixman_image_t	 *clipPict,
 	      pixman_color_t	 *color,
@@ -195,6 +195,7 @@ pixman_color_rects (pixman_image_t	 *dst
     pixman_box16_t     *clipped_rects;
     int	                i, n_clipped_rects;
     FillFunc            func;
+    pixman_region_status_t status;
 
     pixman_color_to_pixel (&dst->image_format,
 			   color,
@@ -208,16 +209,29 @@ pixman_color_rects (pixman_image_t	 *dst
                              dst->pixels->x, dst->pixels->y,
 			     dst->pixels->width, dst->pixels->height);
 
-    pixman_region_intersect (&clip, &clip, clipPict->hasCompositeClip ?
-                             &clipPict->compositeClip : NULL);
+    status = pixman_region_intersect (&clip, &clip,
+	                              clipPict->hasCompositeClip ?
+                                      &clipPict->compositeClip :
+				      NULL);
+    if (status != PIXMAN_REGION_STATUS_SUCCESS)
+    {
+	pixman_region_fini (&clip);
+	return 1;
+    }
     if (clipPict->alphaMap)
     {
 	pixman_region_translate (&clip,
 				 -clipPict->alphaOrigin.x,
 				 -clipPict->alphaOrigin.y);
-	pixman_region_intersect (&clip, &clip, 
-                                 clipPict->alphaMap->hasCompositeClip ?
-                                 &clipPict->alphaMap->compositeClip : NULL);
+	status = pixman_region_intersect (&clip, &clip,
+		                          clipPict->alphaMap->hasCompositeClip ?
+					  &clipPict->alphaMap->compositeClip :
+					  NULL);
+	if (status != PIXMAN_REGION_STATUS_SUCCESS)
+	{
+	    pixman_region_fini (&clip);
+	    return 1;
+	}
 	pixman_region_translate (&clip,
 				 clipPict->alphaOrigin.x,
 				 clipPict->alphaOrigin.y);
@@ -236,13 +250,25 @@ pixman_color_rects (pixman_image_t	 *dst
 
     for (i = 0; i < nRect; i++)
     {
-	pixman_region_union_rect (&rects_as_region, &rects_as_region,
-				  rects[i].x, rects[i].y,
-				  rects[i].width, rects[i].height);
+	status = pixman_region_union_rect (&rects_as_region, &rects_as_region,
+				           rects[i].x, rects[i].y,
+					   rects[i].width, rects[i].height);
+	if (status != PIXMAN_REGION_STATUS_SUCCESS)
+	{
+	    break;
+	}
     }
 
-    pixman_region_intersect (&rects_as_region, &rects_as_region, &clip);
+    /* any earlier failure will also trigger a failure here... */
+    status = pixman_region_intersect (&rects_as_region,
+	                              &rects_as_region,
+				      &clip);
     pixman_region_fini (&clip);
+    if (status != PIXMAN_REGION_STATUS_SUCCESS)
+    {
+	pixman_region_fini (&rects_as_region);
+	return 1;
+    }
 
     n_clipped_rects = pixman_region_num_rects (&rects_as_region);
     clipped_rects = pixman_region_rects (&rects_as_region);
@@ -275,9 +301,11 @@ pixman_color_rects (pixman_image_t	 *dst
 	    rects[i].y += yoff;
 	}
     }
+
+    return 0;
 }
 
-void pixman_fill_rectangle (pixman_operator_t	op,
+int pixman_fill_rectangle (pixman_operator_t	op,
 		      pixman_image_t		*dst,
 		      const pixman_color_t	*color,
 		      int		x,
@@ -292,16 +320,17 @@ void pixman_fill_rectangle (pixman_opera
     rect.width = width;
     rect.height = height;
 
-    pixman_fill_rectangles (op, dst, color, &rect, 1);
+    return pixman_fill_rectangles (op, dst, color, &rect, 1);
 }
 
-void
+int
 pixman_fill_rectangles (pixman_operator_t		op,
 		  pixman_image_t		*dst,
 		  const pixman_color_t		*color,
 		  const pixman_rectangle_t	*rects,
 		  int			nRects)
 {
+    int ret = 1;
     pixman_color_t color_s = *color;
 
     if (color_s.alpha == 0xffff)
@@ -316,12 +345,16 @@ pixman_fill_rectangles (pixman_operator_
     {
       /* We cast away the constness of rects here, because pixman_color_rects
 	 temporarily modifies it */
-	pixman_color_rects (dst, dst, &color_s, nRects, (pixman_rectangle_t *)rects, 0, 0);
-	if (dst->alphaMap)
-	    pixman_color_rects (dst->alphaMap, dst,
-			  &color_s, nRects, (pixman_rectangle_t *)rects,
-			  dst->alphaOrigin.x,
-			  dst->alphaOrigin.y);
+	ret = pixman_color_rects (dst, dst,
+	                          &color_s,
+				  nRects, (pixman_rectangle_t *)rects,
+				  0, 0);
+	if (!ret && dst->alphaMap)
+	    ret = pixman_color_rects (dst->alphaMap, dst,
+			              &color_s,
+				      nRects, (pixman_rectangle_t *)rects,
+			              dst->alphaOrigin.x,
+			              dst->alphaOrigin.y);
     }
     else
     {
@@ -364,9 +397,12 @@ pixman_fill_rectangles (pixman_operator_
 	}
 
 	pixman_image_destroy (src);
+	ret = 0;
 bail2:
 	FbPixelsDestroy (pixels);
 bail1:
 	;
     }
+
+    return ret;
 }
diff --git a/pixman/src/pixman.h b/pixman/src/pixman.h
index 779e305..fceed2a 100644
--- a/pixman/src/pixman.h
+++ b/pixman/src/pixman.h
@@ -448,7 +448,7 @@ pixman_pixel_to_color (const pixman_form
 
 /* icrect.c */
 
-pixman_private void
+pixman_private int
 pixman_fill_rectangle (pixman_operator_t	op,
 		       pixman_image_t		*dst,
 		       const pixman_color_t	*color,
@@ -457,7 +457,7 @@ pixman_fill_rectangle (pixman_operator_t
 		       unsigned int		width,
 		       unsigned int		height);
 
-pixman_private void
+pixman_private int
 pixman_fill_rectangles (pixman_operator_t		op,
 			pixman_image_t			*dst,
 			const pixman_color_t		*color,
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index ccfe4d9..a3da894 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -917,8 +917,10 @@ _cairo_image_surface_fill_rectangles (vo
     pixman_color.alpha = color->alpha_short;
 
     /* XXX: The pixman_rectangle_t cast is evil... it needs to go away somehow. */
-    pixman_fill_rectangles (_pixman_operator(op), surface->pixman_image,
-			    &pixman_color, (pixman_rectangle_t *) rects, num_rects);
+    if (pixman_fill_rectangles (_pixman_operator(op), surface->pixman_image,
+		                &pixman_color,
+				(pixman_rectangle_t *) rects, num_rects))
+	return CAIRO_STATUS_NO_MEMORY;
 
     return CAIRO_STATUS_SUCCESS;
 }
diff-tree 909334ee00701e18b2f2033b1c3a27714ce988fb (from 5b67efcbd8acad60080129e0a8a307671b18b4fc)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Apr 11 10:45:55 2007 +0100

    FbClipImage* should check for errors during region operations.
    
    Propagate the error from pixman_region_intersect().

diff --git a/pixman/src/icimage.c b/pixman/src/icimage.c
index a0f12ce..34d68ef 100644
--- a/pixman/src/icimage.c
+++ b/pixman/src/icimage.c
@@ -558,6 +558,7 @@ FbClipImageReg (pixman_region16_t	*regio
 		int		dx,
 		int		dy)
 {
+    int ret = 1;
     if (pixman_region_num_rects (region) == 1 &&
 	pixman_region_num_rects (clip) == 1)
     {
@@ -581,11 +582,14 @@ FbClipImageReg (pixman_region16_t	*regio
     }
     else
     {
+	pixman_region_status_t status;
+
 	pixman_region_translate (region, dx, dy);
-	pixman_region_intersect (region, clip, region);
+	status = pixman_region_intersect (region, clip, region);
+	ret = status == PIXMAN_REGION_STATUS_SUCCESS;
 	pixman_region_translate (region, -dx, -dy);
     }
-    return 1;
+    return ret;
 }
 
 static inline int
@@ -600,19 +604,25 @@ FbClipImageSrc (pixman_region16_t	*regio
 
     /* XXX davidr hates this, wants to never use source-based clipping */
     if (image->repeat != PIXMAN_REPEAT_NONE || image->pSourcePict) {
+	int ret = 1;
 	/* XXX no source clipping */
 	if (image->compositeClipSource &&
 	    image->clientClipType != CT_NONE) {
+	    pixman_region_status_t status;
+
 	    pixman_region_translate (region,
 			   dx - image->clipOrigin.x,
 			   dy - image->clipOrigin.y);
-	    pixman_region_intersect (region, &image->clientClip, region);
+	    status = pixman_region_intersect (region,
+		                              &image->clientClip,
+					      region);
+	    ret = status == PIXMAN_REGION_STATUS_SUCCESS;
 	    pixman_region_translate (region,
 			   - (dx - image->clipOrigin.x),
 			   - (dy - image->clipOrigin.y));
 	}
 
-	return 1;
+	return ret;
     } else {
 	pixman_region16_t *clip;
 
diff-tree 5b67efcbd8acad60080129e0a8a307671b18b4fc (from e1abc3c26dd797ba9a888362713c5e5c1257867b)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Apr 11 10:38:09 2007 +0100

    Propagate region failures during pixman_image_set_clip_region().
    
    Operating on regions can fail so check the status and return an error,
    after any necessary cleanup.

diff --git a/pixman/src/icimage.c b/pixman/src/icimage.c
index e011461..a0f12ce 100644
--- a/pixman/src/icimage.c
+++ b/pixman/src/icimage.c
@@ -509,7 +509,11 @@ pixman_image_set_clip_region (pixman_ima
 
     if (region) {
         pixman_region_init (&image->clientClip);
-	pixman_region_copy (&image->clientClip, region);
+	if (pixman_region_copy (&image->clientClip, region) !=
+		PIXMAN_REGION_STATUS_SUCCESS) {
+	    pixman_region_fini (&image->clientClip);
+	    return 1;
+	}
 	image->clientClipType = CT_REGION;
     }
 
@@ -530,9 +534,14 @@ pixman_image_set_clip_region (pixman_ima
 	pixman_region_translate (&image->compositeClip,
 				 - image->clipOrigin.x,
 				 - image->clipOrigin.y);
-	pixman_region_intersect (&image->compositeClip,
+	if (pixman_region_intersect (&image->compositeClip,
 				 &image->compositeClip,
-				 region);
+				 region) != PIXMAN_REGION_STATUS_SUCCESS) {
+	    pixman_image_destroyClip (image);
+	    pixman_region_fini (&image->compositeClip);
+	    image->hasCompositeClip = 0;
+	    return 1;
+	}
 	pixman_region_translate (&image->compositeClip,
 				 image->clipOrigin.x,
 				 image->clipOrigin.y);
diff-tree e1abc3c26dd797ba9a888362713c5e5c1257867b (from 054c28a09de2c8ec2dc7111d786bca41a94f5a83)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Apr 11 09:51:58 2007 +0100

    Provide a private entry point for cairo_scaled_font_status().
    
    Add slim_hidden* markup for cairo_scaled_font_status() as we now use
    it internally.

diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 954a4a4..b582539 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -153,6 +153,7 @@ cairo_scaled_font_status (cairo_scaled_f
 {
     return scaled_font->status;
 }
+slim_hidden_def (cairo_scaled_font_status);
 
 /* Here we keep a unique mapping from
  * cairo_font_face_t/matrix/ctm/options => cairo_scaled_font_t.
diff --git a/src/cairoint.h b/src/cairoint.h
index 6f1d3c7..628ee41 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -2531,6 +2531,7 @@ slim_hidden_proto (cairo_scaled_font_get
 slim_hidden_proto (cairo_scaled_font_get_font_options);
 slim_hidden_proto (cairo_scaled_font_glyph_extents);
 slim_hidden_proto_no_warn (cairo_scaled_font_reference);
+slim_hidden_proto (cairo_scaled_font_status);
 slim_hidden_proto (cairo_set_operator);
 slim_hidden_proto (cairo_set_source);
 slim_hidden_proto (cairo_set_source_surface);
diff-tree 054c28a09de2c8ec2dc7111d786bca41a94f5a83 (from 0a54ca2d2340c55896ee6951efe6917322813431)
Author: Carl Worth <cworth at cworth.org>
Date:   Wed Apr 11 02:26:08 2007 -0700

    boilerplate: Add error checking for cairo_surface_write_to_png

diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c
index 1640545..109f75b 100644
--- a/boilerplate/cairo-boilerplate.c
+++ b/boilerplate/cairo-boilerplate.c
@@ -228,6 +228,7 @@ test_paginated_write_to_png (cairo_surfa
     cairo_surface_t *image;
     cairo_format_t format;
     test_paginated_closure_t *tpc;
+    cairo_status_t status;
 
     /* show page first.  the automatic show_page is too late for us */
     /* XXX use cairo_surface_show_page() when that's added */
@@ -256,7 +257,13 @@ test_paginated_write_to_png (cairo_surfa
 						 tpc->height,
 						 tpc->stride);
 
-    cairo_surface_write_to_png (image, filename);
+    status = cairo_surface_write_to_png (image, filename);
+    if (status) {
+	CAIRO_BOILERPLATE_LOG ("Error writing %s: %s. Exiting\n",
+			       filename,
+			       cairo_status_to_string (status));
+	exit (1);
+    }
 
     cairo_surface_destroy (image);
 
diff-tree 0a54ca2d2340c55896ee6951efe6917322813431 (from 5661de9e1c93bd548b400de2619b6de6133d6483)
Author: Carl Worth <cworth at cworth.org>
Date:   Wed Apr 11 02:22:22 2007 -0700

    boilerplate: Add error checking for cairo_surface_set_user_data

diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c
index e277f1c..1640545 100644
--- a/boilerplate/cairo-boilerplate.c
+++ b/boilerplate/cairo-boilerplate.c
@@ -120,6 +120,24 @@ create_image_surface (const char		 *name
     return cairo_image_surface_create (format, width, height);
 }
 
+static void
+xcairo_surface_set_user_data (cairo_surface_t		 *surface,
+			      const cairo_user_data_key_t *key,
+			      void			 *user_data,
+			      cairo_destroy_func_t	 destroy)
+{
+    cairo_status_t status;
+
+    status = cairo_surface_set_user_data (surface,
+					  key, user_data,
+					  destroy);
+    if (status) {
+	CAIRO_BOILERPLATE_LOG ("Error: %s. Exiting\n",
+			       cairo_status_to_string (status));
+	exit (1);
+    }
+}
+
 #ifdef CAIRO_HAS_TEST_SURFACES
 
 #include "test-fallback-surface.h"
@@ -186,8 +204,8 @@ create_test_paginated_surface (const cha
 						       tpc->height,
 						       tpc->stride);
 
-    cairo_surface_set_user_data (surface, &test_paginated_closure_key,
-				 tpc, NULL);
+    xcairo_surface_set_user_data (surface, &test_paginated_closure_key,
+				  tpc, NULL);
 
     return surface;
 }
@@ -1179,7 +1197,7 @@ create_pdf_surface (const char			 *name,
 	ptc->target = NULL;
     }
 
-    cairo_surface_set_user_data (surface, &pdf_closure_key, ptc, NULL);
+    xcairo_surface_set_user_data (surface, &pdf_closure_key, ptc, NULL);
 
     return surface;
 }
@@ -1285,7 +1303,7 @@ create_svg_surface (const char			 *name,
 	ptc->target = NULL;
     }
 
-    cairo_surface_set_user_data (surface, &svg_closure_key, ptc, NULL);
+    xcairo_surface_set_user_data (surface, &svg_closure_key, ptc, NULL);
 
     return surface;
 }
diff-tree 5661de9e1c93bd548b400de2619b6de6133d6483 (from 8d5aa0fb8d3ac6302dd5e832425f3285ad84280a)
Author: Carl Worth <cworth at cworth.org>
Date:   Wed Apr 11 02:08:36 2007 -0700

    SVG: Add missing error checking for calls to _cairo_output_stream_destroy

diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 7b92142..3fb6b79 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -1734,6 +1734,7 @@ _cairo_svg_surface_paint (void		    *abs
 			  cairo_operator_t   op,
 			  cairo_pattern_t   *source)
 {
+    cairo_status_t status;
     cairo_svg_surface_t *surface = abstract_surface;
 
     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
@@ -1759,8 +1760,12 @@ _cairo_svg_surface_paint (void		    *abs
      * and an optimiszation in meta surface. */
     if (surface->clip_level == 0 &&
 	(op == CAIRO_OPERATOR_CLEAR ||
-	 op == CAIRO_OPERATOR_SOURCE)) {
-	_cairo_output_stream_destroy (surface->xml_node);
+	 op == CAIRO_OPERATOR_SOURCE))
+    {
+	status = _cairo_output_stream_destroy (surface->xml_node);
+	if (status)
+	    return status;
+
 	surface->xml_node = _cairo_memory_stream_create ();
 
 	if (op == CAIRO_OPERATOR_CLEAR) {
@@ -1788,6 +1793,7 @@ _cairo_svg_surface_mask (void		    *abst
 			cairo_pattern_t	    *source,
 			cairo_pattern_t	    *mask)
 {
+    cairo_status_t status;
     cairo_svg_surface_t *surface = abstract_surface;
     cairo_svg_document_t *document = surface->document;
     cairo_output_stream_t *mask_stream;
@@ -1813,7 +1819,10 @@ _cairo_svg_surface_mask (void		    *abst
 				 "  </g>\n"
 				 "</mask>\n");
     _cairo_memory_stream_copy (mask_stream, document->xml_node_defs);
-    _cairo_output_stream_destroy (mask_stream);
+
+    status = _cairo_output_stream_destroy (mask_stream);
+    if (status)
+	return status;
 
     snprintf (buffer, sizeof buffer, "mask=\"url(#mask%d);\"",
 	      document->mask_id);
@@ -2141,7 +2150,7 @@ _cairo_svg_document_destroy (cairo_svg_d
 static cairo_status_t
 _cairo_svg_document_finish (cairo_svg_document_t *document)
 {
-    cairo_status_t status;
+    cairo_status_t status, status2;
     cairo_output_stream_t *output = document->output_stream;
     cairo_meta_snapshot_t *snapshot;
     cairo_svg_surface_t *surface;
@@ -2209,10 +2218,15 @@ _cairo_svg_document_finish (cairo_svg_do
 
     _cairo_output_stream_printf (output, "</svg>\n");
 
-    _cairo_output_stream_destroy (document->xml_node_glyphs);
-    _cairo_output_stream_destroy (document->xml_node_defs);
+    status = _cairo_output_stream_destroy (document->xml_node_glyphs);
 
-    status = _cairo_output_stream_destroy (output);
+    status2 = _cairo_output_stream_destroy (document->xml_node_defs);
+    if (status == CAIRO_STATUS_SUCCESS)
+	status = status2;
+
+    status2 = _cairo_output_stream_destroy (output);
+    if (status == CAIRO_STATUS_SUCCESS)
+	status = status2;
 
     for (i = 0; i < document->meta_snapshots.num_elements; i++) {
 	snapshot = _cairo_array_index (&document->meta_snapshots, i);
diff-tree 8d5aa0fb8d3ac6302dd5e832425f3285ad84280a (from 9c810625e796704e32e76caae18d2129219f46db)
Author: Carl Worth <cworth at cworth.org>
Date:   Wed Apr 11 02:03:10 2007 -0700

    SVG: Add missing error checks and propagation
    
    The function calls that get the new treatment here are:
    
    	_cairo_meta_surface_replay
    	_cairo_surface_show_page
    	_cairo_array_append
    
    all within _cairo_svg_surface_emit_meta_surface

diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 70dce46..7b92142 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -992,10 +992,12 @@ _cairo_svg_surface_emit_composite_image_
     return status;
 }
 
-static int
+static cairo_status_t
 _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document,
-		   cairo_meta_surface_t *surface)
+				      cairo_meta_surface_t *surface,
+				      int		   *id)
 {
+    cairo_status_t status;
     cairo_surface_t *paginated_surface;
     cairo_surface_t *svg_surface;
     cairo_meta_snapshot_t new_snapshot;
@@ -1005,7 +1007,7 @@ _cairo_svg_surface_emit_meta_surface (ca
     cairo_meta_surface_t *meta;
     cairo_meta_snapshot_t *snapshot;
     unsigned int num_elements;
-    unsigned int i, id;
+    unsigned int i;
 
     /* search in already emitted meta snapshots */
     num_elements = document->meta_snapshots.num_elements;
@@ -1014,7 +1016,8 @@ _cairo_svg_surface_emit_meta_surface (ca
 	meta = snapshot->meta;
 	if (meta->commands.num_elements == surface->commands.num_elements &&
 	    _cairo_array_index (&meta->commands, 0) == _cairo_array_index (&surface->commands, 0)) {
-	    return snapshot->id;
+	    *id = snapshot->id;
+	    return CAIRO_STATUS_SUCCESS;
 	}
     }
 
@@ -1027,12 +1030,26 @@ _cairo_svg_surface_emit_meta_surface (ca
     cairo_surface_set_fallback_resolution (paginated_surface,
 					   document->owner->x_fallback_resolution,
 					   document->owner->y_fallback_resolution);
-    _cairo_meta_surface_replay ((cairo_surface_t *)meta, paginated_surface);
-    _cairo_surface_show_page (paginated_surface);
+
+    status = _cairo_meta_surface_replay ((cairo_surface_t *)meta, paginated_surface);
+    if (status) {
+	cairo_surface_destroy (&meta->base);
+	return status;
+    }
+
+    status = _cairo_surface_show_page (paginated_surface);
+    if (status) {
+	cairo_surface_destroy (&meta->base);
+	return status;
+    }
 
     new_snapshot.meta = meta;
     new_snapshot.id = ((cairo_svg_surface_t *) svg_surface)->id;
-    _cairo_array_append (&document->meta_snapshots, &new_snapshot);
+    status = _cairo_array_append (&document->meta_snapshots, &new_snapshot);
+    if (status) {
+	cairo_surface_destroy (&meta->base);
+	return status;
+    }
 
     if (meta->content == CAIRO_CONTENT_ALPHA) {
 	_cairo_svg_surface_emit_alpha_filter (document);
@@ -1065,7 +1082,7 @@ _cairo_svg_surface_emit_meta_surface (ca
 
     _cairo_output_stream_printf (document->xml_node_defs, "</g>\n");
 
-    id = new_snapshot.id;
+    *id = new_snapshot.id;
 
     cairo_surface_destroy (paginated_surface);
 
@@ -1076,7 +1093,7 @@ _cairo_svg_surface_emit_meta_surface (ca
 
     /* cairo_surface_destroy (svg_surface); */
 
-    return id;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
@@ -1099,7 +1116,9 @@ _cairo_svg_surface_emit_composite_meta_p
 
     meta_surface = (cairo_meta_surface_t *) pattern->surface;
 
-    id = _cairo_svg_surface_emit_meta_surface (document, meta_surface);
+    status = _cairo_svg_surface_emit_meta_surface (document, meta_surface, &id);
+    if (status)
+	return status;
 
     if (pattern_id != invalid_pattern_id) {
 	_cairo_output_stream_printf (output,
diff-tree 9c810625e796704e32e76caae18d2129219f46db (from 5ae82deb6942fae1515740551c71e9eb24750a7c)
Author: Carl Worth <cworth at cworth.org>
Date:   Wed Apr 11 01:55:59 2007 -0700

    PDF: Added error checking and propagation for _cairo_array_append

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 5e2e1bd..38b447e 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -154,7 +154,7 @@ _cairo_pdf_surface_open_stream (cairo_pd
 static cairo_status_t
 _cairo_pdf_surface_close_stream (cairo_pdf_surface_t	*surface);
 
-static void
+static cairo_status_t
 _cairo_pdf_surface_add_stream (cairo_pdf_surface_t	*surface,
 			       cairo_pdf_resource_t	 stream);
 
@@ -210,26 +210,26 @@ _cairo_pdf_surface_update_object (cairo_
     object->offset = _cairo_output_stream_get_position (surface->output);
 }
 
-static void
+static cairo_status_t
 _cairo_pdf_surface_add_stream (cairo_pdf_surface_t	*surface,
 			       cairo_pdf_resource_t	 stream)
 {
-    /* XXX: Should be checking the return value here. */
-    _cairo_array_append (&surface->streams, &stream);
+    return _cairo_array_append (&surface->streams, &stream);
 }
 
-static void
+static cairo_status_t
 _cairo_pdf_surface_add_pattern (cairo_pdf_surface_t	*surface,
 				cairo_pdf_resource_t	 pattern)
 {
-    /* XXX: Should be checking the return value here. */
-    _cairo_array_append (&surface->patterns, &pattern);
+    return _cairo_array_append (&surface->patterns, &pattern);
 }
 
-static cairo_pdf_resource_t
-_cairo_pdf_surface_add_alpha (cairo_pdf_surface_t *surface, double alpha)
+static cairo_status_t
+_cairo_pdf_surface_add_alpha (cairo_pdf_surface_t *surface,
+			      double alpha,
+			      cairo_pdf_resource_t *resource)
 {
-    cairo_pdf_resource_t resource;
+    cairo_status_t status;
     int num_alphas, i;
     double other;
 
@@ -237,16 +237,18 @@ _cairo_pdf_surface_add_alpha (cairo_pdf_
     for (i = 0; i < num_alphas; i++) {
 	_cairo_array_copy_element (&surface->alphas, i, &other);
 	if (alpha == other) {
-	    resource.id  = i;
-	    return resource;
+	    resource->id  = i;
+	    return CAIRO_STATUS_SUCCESS;
 	}
     }
 
-    /* XXX: Should be checking the return value here. */
-    _cairo_array_append (&surface->alphas, &alpha);
+    status = _cairo_array_append (&surface->alphas, &alpha);
+    if (status)
+	return status;
+
+    resource->id = _cairo_array_num_elements (&surface->alphas) - 1;
 
-    resource.id = _cairo_array_num_elements (&surface->alphas) - 1;
-    return resource;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_surface_t *
@@ -599,7 +601,7 @@ _cairo_pdf_surface_pause_content_stream 
     return _cairo_pdf_surface_close_stream (surface);
 }
 
-static void
+static cairo_status_t
 _cairo_pdf_surface_resume_content_stream (cairo_pdf_surface_t *surface)
 {
     cairo_pdf_resource_t stream;
@@ -612,12 +614,13 @@ _cairo_pdf_surface_resume_content_stream
 					     surface->width,
 					     surface->height);
 
-    _cairo_pdf_surface_add_stream (surface, stream);
+    return _cairo_pdf_surface_add_stream (surface, stream);
 }
 
 static cairo_int_status_t
 _cairo_pdf_surface_start_page (void *abstract_surface)
 {
+    cairo_status_t status;
     cairo_pdf_surface_t *surface = abstract_surface;
     cairo_pdf_resource_t stream;
 
@@ -629,7 +632,9 @@ _cairo_pdf_surface_start_page (void *abs
 					     surface->width,
 					     surface->height);
 
-    _cairo_pdf_surface_add_stream (surface, stream);
+    status = _cairo_pdf_surface_add_stream (surface, stream);
+    if (status)
+	return status;
 
     _cairo_output_stream_printf (surface->output,
 				 "1 0 0 -1 0 %f cm\r\n",
@@ -849,9 +854,14 @@ static cairo_status_t
 _cairo_pdf_surface_emit_solid_pattern (cairo_pdf_surface_t *surface,
 		    cairo_solid_pattern_t *pattern)
 {
+    cairo_status_t status;
     cairo_pdf_resource_t alpha;
 
-    alpha = _cairo_pdf_surface_add_alpha (surface, pattern->color.alpha);
+    status = _cairo_pdf_surface_add_alpha (surface,
+					   pattern->color.alpha,
+					   &alpha);
+    if (status)
+	return status;
 
     /* With some work, we could separate the stroking
      * or non-stroking color here as actually needed. */
@@ -1018,12 +1028,21 @@ _cairo_pdf_surface_emit_surface_pattern 
 				 image_resource.id);
 
     status = _cairo_pdf_surface_close_stream (surface);
+    if (status)
+	goto BAIL;
 
-    _cairo_pdf_surface_resume_content_stream (surface);
+    status = _cairo_pdf_surface_resume_content_stream (surface);
+    if (status)
+	goto BAIL;
 
-    _cairo_pdf_surface_add_pattern (surface, stream);
+    status = _cairo_pdf_surface_add_pattern (surface, stream);
+    if (status)
+	goto BAIL;
+
+    status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha);
+    if (status)
+	goto BAIL;
 
-    alpha = _cairo_pdf_surface_add_alpha (surface, 1.0);
     /* With some work, we could separate the stroking
      * or non-stroking pattern here as actually needed. */
     _cairo_output_stream_printf (surface->output,
@@ -1243,9 +1262,13 @@ _cairo_pdf_surface_emit_linear_pattern (
 				 x0, y0, x1, y1,
 				 function.id);
 
-    _cairo_pdf_surface_add_pattern (surface, pattern_resource);
+    status = _cairo_pdf_surface_add_pattern (surface, pattern_resource);
+    if (status)
+	return status;
 
-    alpha = _cairo_pdf_surface_add_alpha (surface, 1.0);
+    status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha);
+    if (status)
+	return status;
 
     /* Use pattern */
     /* With some work, we could separate the stroking
@@ -1258,9 +1281,7 @@ _cairo_pdf_surface_emit_linear_pattern (
 				 pattern_resource.id,
 				 alpha.id);
 
-    _cairo_pdf_surface_resume_content_stream (surface);
-
-    return CAIRO_STATUS_SUCCESS;
+    return _cairo_pdf_surface_resume_content_stream (surface);
 }
 
 static cairo_status_t
@@ -1324,9 +1345,13 @@ _cairo_pdf_surface_emit_radial_pattern (
 				 x0, y0, r0, x1, y1, r1,
 				 function.id);
 
-    _cairo_pdf_surface_add_pattern (surface, pattern_resource);
+    status = _cairo_pdf_surface_add_pattern (surface, pattern_resource);
+    if (status)
+	return status;
 
-    alpha = _cairo_pdf_surface_add_alpha (surface, 1.0);
+    status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha);
+    if (status)
+	return status;
 
     /* Use pattern */
     /* With some work, we could separate the stroking
@@ -1339,9 +1364,7 @@ _cairo_pdf_surface_emit_radial_pattern (
 				 pattern_resource.id,
 				 alpha.id);
 
-    _cairo_pdf_surface_resume_content_stream (surface);
-
-    return CAIRO_STATUS_SUCCESS;
+    return _cairo_pdf_surface_resume_content_stream (surface);
 }
 
 static cairo_status_t
diff-tree 5ae82deb6942fae1515740551c71e9eb24750a7c (from 8c31cca2af11c544a6028bf42c2187625b978f56)
Author: Carl Worth <cworth at cworth.org>
Date:   Wed Apr 11 01:47:21 2007 -0700

    PS: Add missing check for return value of _cairo_meta_surface_replay
    
    Here we have to change the return type of a couple of functions in
    order to propagate the error condition.

diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index c41b021..d725c53 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -1722,7 +1722,7 @@ _cairo_ps_surface_emit_solid_pattern (ca
 				     pattern->color.blue);
 }
 
-static void
+static cairo_status_t
 _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
 		      cairo_surface_pattern_t *pattern)
 {
@@ -1737,7 +1737,11 @@ _cairo_ps_surface_emit_surface_pattern (
 
     if (_cairo_surface_is_meta (pattern->surface)) {
 	_cairo_output_stream_printf (surface->stream, "/MyPattern {\n");
-	_cairo_meta_surface_replay (pattern->surface, &surface->base);
+
+	status = _cairo_meta_surface_replay (pattern->surface, &surface->base);
+	if (status)
+	    return status;
+
 	bbox_width = surface->width;
 	bbox_height = surface->height;
 	xstep = surface->width;
@@ -1825,6 +1829,8 @@ _cairo_ps_surface_emit_surface_pattern (
 				 inverse.x0, inverse.y0);
     _cairo_output_stream_printf (surface->stream,
 				 "makepattern setpattern\n");
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static void
@@ -1841,12 +1847,13 @@ _cairo_ps_surface_emit_radial_pattern (c
     /* XXX: NYI */
 }
 
-static void
+static cairo_status_t
 _cairo_ps_surface_emit_pattern (cairo_ps_surface_t *surface, cairo_pattern_t *pattern)
 {
     /* FIXME: We should keep track of what pattern is currently set in
      * the postscript file and only emit code if we're setting a
      * different pattern. */
+    cairo_status_t status;
 
     switch (pattern->type) {
     case CAIRO_PATTERN_TYPE_SOLID:
@@ -1854,7 +1861,10 @@ _cairo_ps_surface_emit_pattern (cairo_ps
 	break;
 
     case CAIRO_PATTERN_TYPE_SURFACE:
-	_cairo_ps_surface_emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern);
+	status = _cairo_ps_surface_emit_surface_pattern (surface,
+							 (cairo_surface_pattern_t *) pattern);
+	if (status)
+	    return status;
 	break;
 
     case CAIRO_PATTERN_TYPE_LINEAR:
@@ -1865,6 +1875,8 @@ _cairo_ps_surface_emit_pattern (cairo_ps
 	_cairo_ps_surface_emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern);
 	break;
     }
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_int_status_t
@@ -1978,7 +1990,9 @@ _cairo_ps_surface_paint (void			*abstrac
 
     _cairo_rectangle_intersect (&extents, &pattern_extents);
 
-    _cairo_ps_surface_emit_pattern (surface, source);
+    status = _cairo_ps_surface_emit_pattern (surface, source);
+    if (status)
+	return status;
 
     _cairo_output_stream_printf (stream, "%d %d M\n",
 				 extents.x, extents.y);
@@ -1992,6 +2006,7 @@ _cairo_ps_surface_paint (void			*abstrac
 				 extents.x,
 				 extents.y + extents.height);
     _cairo_output_stream_printf (stream, "P F\n");
+
     return CAIRO_STATUS_SUCCESS;
 }
 
diff-tree 8c31cca2af11c544a6028bf42c2187625b978f56 (from 01ac5f1aea298434b617d935512e2e72033989fd)
Author: Carl Worth <cworth at cworth.org>
Date:   Wed Apr 11 01:42:02 2007 -0700

    PS: Add missing checks for return value of _cairo_pattern_get_extents
    
    Propagation is extremely straightforward in this case.

diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 6a917f2..c41b021 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -1950,6 +1950,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_status_t status;
 
     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
 	return _cairo_ps_surface_analyze_operation (surface, op, source);
@@ -1967,8 +1968,14 @@ _cairo_ps_surface_paint (void			*abstrac
     _cairo_output_stream_printf (stream,
 				 "%% _cairo_ps_surface_paint\n");
 
-    _cairo_surface_get_extents (&surface->base, &extents);
-    _cairo_pattern_get_extents (source, &pattern_extents);
+    status = _cairo_surface_get_extents (&surface->base, &extents);
+    if (status)
+	return status;
+
+    status = _cairo_pattern_get_extents (source, &pattern_extents);
+    if (status)
+	return status;
+
     _cairo_rectangle_intersect (&extents, &pattern_extents);
 
     _cairo_ps_surface_emit_pattern (surface, source);
diff-tree 01ac5f1aea298434b617d935512e2e72033989fd (from bd0b328f7e07b3a292190aef6f82622800230f6f)
Author: Carl Worth <cworth at cworth.org>
Date:   Wed Apr 11 01:35:11 2007 -0700

    Assert that cairo_matrix_invert succeeds rather than ignoring tis return value
    
    This assertion is safe as an internal consistency check thanks to
    the recent checks added to cairo_pattern_set_matrix.

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 069fed0..5e2e1bd 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -983,7 +983,9 @@ _cairo_pdf_surface_emit_surface_pattern 
      * pattern cell.
      */
     cairo_p2d = pattern->base.matrix;
-    cairo_matrix_invert (&cairo_p2d);
+    status = cairo_matrix_invert (&cairo_p2d);
+    /* cairo_pattern_set_matrix ensures the matrix is invertible */
+    assert (status == CAIRO_STATUS_SUCCESS);
 
     cairo_matrix_init_identity (&pdf_p2d);
     cairo_matrix_translate (&pdf_p2d, 0.0, surface_extents.height);
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 76d8f45..6a917f2 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -1726,11 +1726,14 @@ static void
 _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
 		      cairo_surface_pattern_t *pattern)
 {
+    cairo_status_t status;
     double bbox_width, bbox_height;
     double xstep, ystep;
     cairo_matrix_t inverse = pattern->base.matrix;
 
-    cairo_matrix_invert (&inverse);
+    status = cairo_matrix_invert (&inverse);
+    /* cairo_pattern_set_matrix ensures the matrix is invertible */
+    assert (status == CAIRO_STATUS_SUCCESS);
 
     if (_cairo_surface_is_meta (pattern->surface)) {
 	_cairo_output_stream_printf (surface->stream, "/MyPattern {\n");
diff-tree bd0b328f7e07b3a292190aef6f82622800230f6f (from a6186604f794f2746089abc9c1716384c23aafc4)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 22:55:00 2007 -0700

    test/invalid-matrix: Add new test to exercise CAIRO_STATUS_INVALID_MATRIX paths
    
    This new test exercises every path where the user might possibly
    pass in an invalid matrix. Currently the test fails if no error
    is reported. Also, if an incorrect error is reported, (such as
    CAIRO_STATUS_NO_MEMORY instead of CAIRO_STATUS_INVALID_MATRIX),
    this is logged as a warning in invalid-matrix.log, but the test
    still passes.
    
    It would still be worthwhile to follow up quickly and fix those
    cases to propagate the correct error value.

diff --git a/test/.gitignore b/test/.gitignore
index a6d21da..34a300a 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -66,6 +66,7 @@ gradient-alpha
 imagediff
 infinite-join
 in-fill-empty-trapezoid
+invalid-matrix
 leaky-dash
 leaky-polygon
 line-width
diff --git a/test/Makefile.am b/test/Makefile.am
index 0461853..74ead62 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -49,6 +49,7 @@ get-path-extents                \
 gradient-alpha			\
 infinite-join			\
 in-fill-empty-trapezoid		\
+invalid-matrix			\
 leaky-dash			\
 leaky-polygon			\
 line-width			\
diff --git a/test/invalid-matrix.c b/test/invalid-matrix.c
new file mode 100644
index 0000000..91140a4
--- /dev/null
+++ b/test/invalid-matrix.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl Worth <cworth at cworth.org>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_draw_function_t draw;
+
+cairo_test_t test = {
+    "invalid-matrix",
+    "Test that all relevant public functions return CAIRO_STATUS_INVALID_MATRIX as appropriate",
+    0, 0,
+    draw
+};
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+    cairo_status_t status;
+    cairo_surface_t *target;
+    cairo_font_face_t *font_face;
+    cairo_font_options_t *font_options;
+    cairo_scaled_font_t *scaled_font;
+    cairo_pattern_t *pattern;
+    cairo_t *cr2;
+    cairo_matrix_t identity, invalid = {
+	4.0, 4.0,
+	4.0, 4.0,
+	4.0, 4.0
+    };
+
+#define CHECK_STATUS(status, function_name)						\
+if ((status) == CAIRO_STATUS_SUCCESS) {							\
+    cairo_test_log ("Error: %s with invalid matrix passed",				\
+		    (function_name));							\
+    return CAIRO_TEST_FAILURE;								\
+} else if ((status) != CAIRO_STATUS_INVALID_MATRIX) {					\
+    cairo_test_log ("Warning: %s with invalid matrix returned unexpected status "	\
+		    "(%d): %s\n",							\
+		    (function_name),							\
+		    status,								\
+		    cairo_status_to_string (status));					\
+}
+
+    cairo_matrix_init_identity (&identity);
+
+    target = cairo_get_target (cr);
+
+    /* test cairo_transform with invalid matrix */
+    cr2 = cairo_create (target);
+    cairo_transform (cr2, &invalid);
+
+    status = cairo_status (cr2);
+    CHECK_STATUS (status,"cairo_transform");
+
+    cairo_destroy (cr2);
+
+    /* test cairo_set_matrix with invalid matrix */
+    cr2 = cairo_create (target);
+    cairo_set_matrix (cr2, &invalid);
+
+    status = cairo_status (cr2);
+    CHECK_STATUS (status, "cairo_set_matrix");
+
+    cairo_destroy (cr2);
+
+    /* test cairo_set_font_matrix with invalid matrix */
+    cr2 = cairo_create (target);
+    cairo_set_font_matrix (cr2, &invalid);
+
+    /* draw some text to force the font to be resolved */
+    cairo_show_text (cr2, "hello");
+
+    status = cairo_status (cr2);
+    CHECK_STATUS (status, "cairo_set_font_matrix");
+
+    cairo_destroy (cr2);
+
+    /* test cairo_scaled_font_create with invalid matrix */
+    font_face = cairo_get_font_face (cr);
+    font_options = cairo_font_options_create ();
+    cairo_get_font_options (cr, font_options);
+    scaled_font = cairo_scaled_font_create (font_face,
+					    &invalid,
+					    &identity,
+					    font_options);
+    status = cairo_scaled_font_status (scaled_font);
+    CHECK_STATUS (status, "cairo_scaled_font_create");
+
+    cairo_scaled_font_destroy (scaled_font);
+
+    scaled_font = cairo_scaled_font_create (font_face,
+					    &identity,
+					    &invalid,
+					    font_options);
+    status = cairo_scaled_font_status (scaled_font);
+    CHECK_STATUS (status, "cairo_scaled_font_create");
+
+    cairo_scaled_font_destroy (scaled_font);
+    cairo_font_options_destroy (font_options);
+
+    /* test cairo_pattern_set_matrix with invalid matrix */
+    pattern = cairo_pattern_create_rgb (1.0, 1.0, 1.0);
+    cairo_pattern_set_matrix (pattern, &invalid);
+    status = cairo_pattern_status (pattern);
+    CHECK_STATUS (status, "cairo_pattern_set_matrix");
+    cairo_pattern_destroy (pattern);
+
+    /* test cairo_matrix_invert with invalid matrix */
+    status = cairo_matrix_invert (&invalid);
+    CHECK_STATUS (status, "cairo_matrix_invert");
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+int
+main (void)
+{
+    return cairo_test (&test);
+}
diff-tree a6186604f794f2746089abc9c1716384c23aafc4 (from 8e72852f0b9f2cd8558eb6c11acb326e73fceb12)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 22:52:37 2007 -0700

    cairo_pattern_set_matrix: Validate that matrix is invertible
    
    If not, set an error in the pattern.

diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index ce61600..ec8f0d0 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -932,10 +932,18 @@ void
 cairo_pattern_set_matrix (cairo_pattern_t      *pattern,
 			  const cairo_matrix_t *matrix)
 {
+    cairo_matrix_t inverse;
+    cairo_status_t status;
+
     if (pattern->status)
 	return;
 
     pattern->matrix = *matrix;
+
+    inverse = *matrix;
+    status = cairo_matrix_invert (&inverse);
+    if (status)
+	_cairo_pattern_set_error (pattern, status);
 }
 slim_hidden_def (cairo_pattern_set_matrix);
 
diff-tree 8e72852f0b9f2cd8558eb6c11acb326e73fceb12 (from 2f1221e0f225f305c3f9c8e7311fe8f3fecab34b)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 22:51:44 2007 -0700

    _cairo_gstate_ensure_scaled_font: Add missing propagation for error hiding inside the scaled_font

diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index f5bf6de..c5d5f38 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -1450,6 +1450,9 @@ _cairo_gstate_ensure_scaled_font (cairo_
     if (gstate->scaled_font == NULL)
 	return CAIRO_STATUS_NO_MEMORY;
 
+    if (cairo_scaled_font_status (gstate->scaled_font))
+	return cairo_scaled_font_status (gstate->scaled_font);
+
     return CAIRO_STATUS_SUCCESS;
 }
 
diff-tree 2f1221e0f225f305c3f9c8e7311fe8f3fecab34b (from dca69f73e3a11d397a701f82331d5aaa7194bd7f)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 22:50:46 2007 -0700

    _cairo_gstate_ensure_scaled_font: Prefer to treat a pointer as a pointer, not a Boolean value

diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index c17d9d7..f5bf6de 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -1447,8 +1447,7 @@ _cairo_gstate_ensure_scaled_font (cairo_
 						    &gstate->font_matrix,
 						    &gstate->ctm,
 						    &options);
-
-    if (!gstate->scaled_font)
+    if (gstate->scaled_font == NULL)
 	return CAIRO_STATUS_NO_MEMORY;
 
     return CAIRO_STATUS_SUCCESS;
diff-tree dca69f73e3a11d397a701f82331d5aaa7194bd7f (from 4ce2b62bcea49eccc0a4ee3781a115e4a34d3ad4)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 17:16:39 2007 -0700

    Check (and assert) return values of cairo_matrix_invert
    
    Now that we have matrix validation at the time of _cairo_scaled_font_init
    we know that it is safe to invert this matrix.

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index ddb1bce..069fed0 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -2285,6 +2285,7 @@ static cairo_status_t
 _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t		*surface,
 					   cairo_scaled_font_subset_t	*font_subset)
 {
+    cairo_status_t status;
     cairo_pdf_resource_t *glyphs, encoding, char_procs, subset_resource, to_unicode_stream;
     cairo_pdf_font_t font;
     cairo_matrix_t matrix;
@@ -2361,7 +2362,9 @@ _cairo_pdf_surface_emit_type3_font_subse
 
     subset_resource = _cairo_pdf_surface_new_object (surface);
     matrix = font_subset->scaled_font->scale;
-    cairo_matrix_invert (&matrix);
+    status = cairo_matrix_invert (&matrix);
+    /* _cairo_scaled_font_init ensures the matrix is invertible */
+    assert (status == CAIRO_STATUS_SUCCESS);
     _cairo_output_stream_printf (surface->output,
 				 "%d 0 obj\r\n"
 				 "<< /Type /Font\r\n"
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 0260996..76d8f45 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -668,6 +668,7 @@ _cairo_ps_surface_emit_type3_font_subset
 
 
 {
+    cairo_status_t status;
     cairo_matrix_t matrix;
     unsigned int i;
 
@@ -680,7 +681,9 @@ _cairo_ps_surface_emit_type3_font_subset
 				 font_subset->subset_id);
 
     matrix = font_subset->scaled_font->scale;
-    cairo_matrix_invert (&matrix);
+    status = cairo_matrix_invert (&matrix);
+    /* _cairo_scaled_font_init ensures the matrix is invertible */
+    assert (status == CAIRO_STATUS_SUCCESS);
     _cairo_output_stream_printf (surface->final_stream,
 				 "\t/FontType\t3\n"
 				 "\t/FontMatrix\t[%f %f %f %f 0 0]\n"
diff-tree 4ce2b62bcea49eccc0a4ee3781a115e4a34d3ad4 (from fd8c1e4dc851dd4ce8f84a3e47abdc4906c83b0f)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 17:12:51 2007 -0700

    _cairo_scaled_font_init: Detect an invalid matrix and return an error.
    
    Also fix all callers to notice and propagate the error, (though
    some paths will still lose the CAIRO_STATUS_INVALID_MATRIX value
    due to a return value of NULL at one point).

diff --git a/src/cairo-atsui-font.c b/src/cairo-atsui-font.c
index 8aca207..92d38f2 100644
--- a/src/cairo-atsui-font.c
+++ b/src/cairo-atsui-font.c
@@ -230,8 +230,13 @@ _cairo_atsui_font_create_scaled (cairo_f
     if (font == NULL)
 	return CAIRO_STATUS_NO_MEMORY;
 
-    _cairo_scaled_font_init(&font->base, font_face, font_matrix, ctm, options,
-			    &cairo_atsui_scaled_font_backend);
+    status = _cairo_scaled_font_init (&font->base,
+				      font_face, font_matrix, ctm, options,
+				      &cairo_atsui_scaled_font_backend);
+    if (status) {
+	free (font);
+	return status;
+    }
 
     _cairo_matrix_compute_scale_factors (&font->base.scale, 
 					 &xscale, &yscale, 1);
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 6b51e7f..954a4a4 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -351,6 +351,23 @@ _cairo_scaled_font_init (cairo_scaled_fo
 			 const cairo_font_options_t	   *options,
 			 const cairo_scaled_font_backend_t *backend)
 {
+    cairo_matrix_t inverse;
+    cairo_status_t status;
+
+    /* Initialize scaled_font->scale early for easier bail out on an
+     * invalid matrix. */
+    _cairo_scaled_font_init_key (scaled_font, font_face,
+				 font_matrix, ctm, options);
+
+    cairo_matrix_multiply (&scaled_font->scale,
+			   &scaled_font->font_matrix,
+			   &scaled_font->ctm);
+
+    inverse = scaled_font->scale;
+    status = cairo_matrix_invert (&inverse);
+    if (status)
+	return status;
+
     scaled_font->glyphs = _cairo_cache_create (_cairo_scaled_glyph_keys_equal,
 					       _cairo_scaled_glyph_destroy,
 					       max_glyphs_cached_per_font);
@@ -361,15 +378,8 @@ _cairo_scaled_font_init (cairo_scaled_fo
 
     _cairo_user_data_array_init (&scaled_font->user_data);
 
-    _cairo_scaled_font_init_key (scaled_font, font_face,
-				 font_matrix, ctm, options);
-
     cairo_font_face_reference (font_face);
 
-    cairo_matrix_multiply (&scaled_font->scale,
-			   &scaled_font->font_matrix,
-			   &scaled_font->ctm);
-
     CAIRO_MUTEX_INIT (&scaled_font->mutex);
 
     scaled_font->surface_backend = NULL;
diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c
index 82e3bfc..e1f263b 100644
--- a/src/cairo-win32-font.c
+++ b/src/cairo-win32-font.c
@@ -283,11 +283,13 @@ _win32_scaled_font_create (LOGFONTW     
     cairo_matrix_multiply (&scale, font_matrix, ctm);
     _compute_transform (f, &scale);
 
-    _cairo_scaled_font_init (&f->base, font_face,
-			     font_matrix, ctm, options,
-			     &cairo_win32_scaled_font_backend);
+    status = _cairo_scaled_font_init (&f->base, font_face,
+				      font_matrix, ctm, options,
+				      &cairo_win32_scaled_font_backend);
+
+    if (status == CAIRO_STATUS_SUCCESS)
+	status = _cairo_win32_scaled_font_set_metrics (f);
 
-    status = _cairo_win32_scaled_font_set_metrics (f);
     if (status) {
 	cairo_scaled_font_destroy (&f->base);
 	return NULL;
diff-tree fd8c1e4dc851dd4ce8f84a3e47abdc4906c83b0f (from 0f0ed88ee26f22c1b0e0ec7c95b8a258d137dde4)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 16:43:50 2007 -0700

    Fix cairo_scaled_font_create to return a nil scaled font, not NULL

diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index a4754f7..6b51e7f 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -478,7 +478,7 @@ cairo_scaled_font_create (cairo_font_fac
 
     font_map = _cairo_scaled_font_map_lock ();
     if (font_map == NULL)
-	return NULL;
+	return (cairo_scaled_font_t *)&_cairo_scaled_font_nil;
 
     _cairo_scaled_font_init_key (&key, font_face,
 				 font_matrix, ctm, options);
@@ -517,7 +517,7 @@ cairo_scaled_font_create (cairo_font_fac
 							 ctm, options, &scaled_font);
 	if (status) {
 	    _cairo_scaled_font_map_unlock ();
-	    return NULL;
+	    return (cairo_scaled_font_t *)&_cairo_scaled_font_nil;
 	}
 
 	status = _cairo_hash_table_insert (font_map->hash_table,
@@ -530,7 +530,7 @@ cairo_scaled_font_create (cairo_font_fac
 	     * hash table. */
 	    _cairo_scaled_font_fini (scaled_font);
 	    free (scaled_font);
-	    return NULL;
+	    return (cairo_scaled_font_t *)&_cairo_scaled_font_nil;
 	}
     }
 
diff-tree 0f0ed88ee26f22c1b0e0ec7c95b8a258d137dde4 (from 381f0bcafc86cefa665368cbbe2026adda1d98c9)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 23:01:55 2007 -0700

    paginated: Add missing error check for _cairo_surface_show_page
    
    Fixing this uncovered a leak of a CAIRO_INT_STATUS_UNSUPPORTED value
    up to cairo_show_page, (and similarly to cairo_copy_page). There was
    really no good reason for _cairo_surface_show_page and
    _cairo_surface_copy_page to be returning cairo_int_status_t. Fix
    this by simply handling the UNSUPPORTED return at the surface layer
    instead of the gstate layer.

diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index c07ce30..c17d9d7 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -1067,29 +1067,13 @@ BAIL:
 cairo_status_t
 _cairo_gstate_copy_page (cairo_gstate_t *gstate)
 {
-    cairo_int_status_t status;
-
-    status = _cairo_surface_copy_page (gstate->target);
-
-    /* It's fine if some surfaces just don't support this. */
-    if (status == CAIRO_INT_STATUS_UNSUPPORTED)
-	return CAIRO_STATUS_SUCCESS;
-
-    return status;
+    return _cairo_surface_copy_page (gstate->target);
 }
 
 cairo_status_t
 _cairo_gstate_show_page (cairo_gstate_t *gstate)
 {
-    cairo_int_status_t status;
-
-    status = _cairo_surface_show_page (gstate->target);
-
-    /* It's fine if some surfaces just don't support this. */
-    if (status == CAIRO_INT_STATUS_UNSUPPORTED)
-	return CAIRO_STATUS_SUCCESS;
-
-    return status;
+    return _cairo_surface_show_page (gstate->target);
 }
 
 static void
diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index fd524ae..f788dc2 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -336,7 +336,9 @@ _cairo_paginated_surface_show_page (void
 
     _paint_page (surface);
 
-    _cairo_surface_show_page (surface->target);
+    status = _cairo_surface_show_page (surface->target);
+    if (status)
+	return status;
 
     cairo_surface_destroy (surface->meta);
 
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index e3d4c0e..c6f64eb 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -1434,10 +1434,7 @@ _cairo_surface_composite_trapezoids (cai
 							  traps, num_traps);
 }
 
-/* _copy_page and _show_page are unique among _cairo_surface functions
- * in that they will actually return CAIRO_INT_STATUS_UNSUPPORTED
- * rather than performing any fallbacks. */
-cairo_int_status_t
+cairo_status_t
 _cairo_surface_copy_page (cairo_surface_t *surface)
 {
     assert (! surface->is_snapshot);
@@ -1448,16 +1445,14 @@ _cairo_surface_copy_page (cairo_surface_
     if (surface->finished)
 	return CAIRO_STATUS_SURFACE_FINISHED;
 
+    /* It's fine if some backends don't implement copy_page */
     if (surface->backend->copy_page == NULL)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+	return CAIRO_STATUS_SUCCESS;
 
     return surface->backend->copy_page (surface);
 }
 
-/* _show_page and _copy_page are unique among _cairo_surface functions
- * in that they will actually return CAIRO_INT_STATUS_UNSUPPORTED
- * rather than performing any fallbacks. */
-cairo_int_status_t
+cairo_status_t
 _cairo_surface_show_page (cairo_surface_t *surface)
 {
     assert (! surface->is_snapshot);
@@ -1468,8 +1463,9 @@ _cairo_surface_show_page (cairo_surface_
     if (surface->finished)
 	return CAIRO_STATUS_SURFACE_FINISHED;
 
+    /* It's fine if some backends don't implement show_page */
     if (surface->backend->show_page == NULL)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+	return CAIRO_STATUS_SUCCESS;
 
     return surface->backend->show_page (surface);
 }
diff --git a/src/cairoint.h b/src/cairoint.h
index 8c215eb..6f1d3c7 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1952,10 +1952,10 @@ _cairo_surface_composite_trapezoids (cai
 				     cairo_trapezoid_t	*traps,
 				     int		ntraps);
 
-cairo_private cairo_int_status_t
+cairo_private cairo_status_t
 _cairo_surface_copy_page (cairo_surface_t *surface);
 
-cairo_private cairo_int_status_t
+cairo_private cairo_status_t
 _cairo_surface_show_page (cairo_surface_t *surface);
 
 cairo_private cairo_status_t
diff-tree 381f0bcafc86cefa665368cbbe2026adda1d98c9 (from 41911002d754f187618ab310ab93c85c4b038943)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 16:33:34 2007 -0700

    paginated: Add missing error check for _cairo_surface_get_extents

diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index f9ca1af..fd524ae 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -517,7 +517,9 @@ _cairo_paginated_surface_snapshot (void 
     cairo_rectangle_int16_t extents;
     cairo_surface_t *surface;
 
-    _cairo_surface_get_extents (other->target, &extents);
+    status = _cairo_surface_get_extents (other->target, &extents);
+    if (status)
+	return (cairo_surface_t*) &_cairo_surface_nil;
 
     surface = _cairo_paginated_surface_create_image_surface (other,
 							     extents.width,
diff-tree 41911002d754f187618ab310ab93c85c4b038943 (from d954e4c1488c6478852dcc02641e66df1d4e9317)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 16:32:09 2007 -0700

    test-meta-surface.c: Fix memory leak on error recovery path.

diff --git a/src/test-meta-surface.c b/src/test-meta-surface.c
index b0e422b..e2f6a09 100644
--- a/src/test-meta-surface.c
+++ b/src/test-meta-surface.c
@@ -313,8 +313,10 @@ _test_meta_surface_snapshot (void *abstr
 					    extents.height);
 
     status = _cairo_meta_surface_replay (other->meta, surface);
-    if (status)
-	return (cairo_surface_t*) &_cairo_surface_nil;
+    if (status) {
+	cairo_surface_destroy (surface);
+	surface = (cairo_surface_t*) &_cairo_surface_nil;
+    }
 
     return surface;
 #endif
diff-tree d954e4c1488c6478852dcc02641e66df1d4e9317 (from c011c37ba086f0c8d0dac6437318822927543955)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 16:31:21 2007 -0700

    Fix indentation of CLEANUP_IMAGE label.

diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index 3124b43..f9ca1af 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -277,7 +277,7 @@ _paint_page (cairo_paginated_surface_t *
 
 	cairo_pattern_destroy (pattern);
 
-CLEANUP_IMAGE:
+     CLEANUP_IMAGE:
 	cairo_surface_destroy (image);
     }
     else
diff-tree c011c37ba086f0c8d0dac6437318822927543955 (from e73a55ad3cc30b0ea69379b12283515523015751)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 16:30:43 2007 -0700

    paginated: Fix missing errors checks for _cairo_meta_surface_replay

diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index e6702b7..3124b43 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -244,11 +244,12 @@ _paint_page (cairo_paginated_surface_t *
 					       surface->width, surface->height);
 
     surface->backend->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_ANALYZE);
-    _cairo_meta_surface_replay (surface->meta, analysis);
+    status = _cairo_meta_surface_replay (surface->meta, analysis);
     surface->backend->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_RENDER);
 
-    if (analysis->status) {
-	status = analysis->status;
+    if (status || analysis->status) {
+	if (status == CAIRO_STATUS_SUCCESS)
+	    status = analysis->status;
 	cairo_surface_destroy (analysis);
 	return status;
     }
@@ -495,6 +496,7 @@ _cairo_paginated_surface_show_glyphs (vo
 static cairo_surface_t *
 _cairo_paginated_surface_snapshot (void *abstract_other)
 {
+    cairo_status_t status;
     cairo_paginated_surface_t *other = abstract_other;
 
     /* XXX: Just making a snapshot of other->meta is what we really
@@ -521,7 +523,11 @@ _cairo_paginated_surface_snapshot (void 
 							     extents.width,
 							     extents.height);
 
-    _cairo_meta_surface_replay (other->meta, surface);
+    status = _cairo_meta_surface_replay (other->meta, surface);
+    if (status) {
+	cairo_surface_destroy (surface);
+	surface = (cairo_surface_t*) &_cairo_surface_nil;
+    }
 
     return surface;
 #endif
diff-tree e73a55ad3cc30b0ea69379b12283515523015751 (from 97b8fd8117160cfea9864c81cbb8a06b321618f1)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 14:17:42 2007 -0700

    cairo-truetype-subset: Fix missing error propagation

diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c
index 461ed71..e8137a7 100644
--- a/src/cairo-truetype-subset.c
+++ b/src/cairo-truetype-subset.c
@@ -505,8 +505,11 @@ cairo_truetype_font_write_glyf_table (ca
         font->glyphs[i].location = next - start_offset;
 
 	status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
-	if (status)
+	if (status) {
+	    font->status = status;
 	    break;
+	}
+
         if (size != 0) {
             font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
                                                 TT_TAG_glyf, begin, buffer, &size);
diff-tree 97b8fd8117160cfea9864c81cbb8a06b321618f1 (from 84639e563ddfbd70ca48dcde4d3631418fd1cd82)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 14:16:01 2007 -0700

    cairo-truetype-subset: Check resturn value from _cairo_array_append and propagate

diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c
index dd8357e..461ed71 100644
--- a/src/cairo-truetype-subset.c
+++ b/src/cairo-truetype-subset.c
@@ -320,16 +320,24 @@ cairo_truetype_font_align_output (cairo_
     return aligned;
 }
 
-static void
+static cairo_status_t
 cairo_truetype_font_check_boundary (cairo_truetype_font_t *font,
 				    unsigned long          boundary)
 {
+    cairo_status_t status;
+
     if (boundary - font->last_offset > SFNT_STRING_MAX_LENGTH)
     {
-        _cairo_array_append(&font->string_offsets, &font->last_boundary);
+        status = _cairo_array_append (&font->string_offsets,
+				      &font->last_boundary);
+	if (status)
+	    return status;
+
         font->last_offset = font->last_boundary;
     }
     font->last_boundary = boundary;
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static int
@@ -487,7 +495,13 @@ cairo_truetype_font_write_glyf_table (ca
 	size = end - begin;
 
         next = cairo_truetype_font_align_output (font);
-        cairo_truetype_font_check_boundary (font, next);
+
+        status = cairo_truetype_font_check_boundary (font, next);
+	if (status) {
+	    font->status = status;
+	    break;
+	}
+
         font->glyphs[i].location = next - start_offset;
 
 	status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
@@ -774,6 +788,7 @@ cairo_truetype_font_generate (cairo_true
 			      const unsigned long   **string_offsets,
 			      unsigned long          *num_strings)
 {
+    cairo_status_t status;
     unsigned long start, end, next;
     uint32_t checksum, *checksum_location;
     unsigned int i;
@@ -793,7 +808,12 @@ cairo_truetype_font_generate (cairo_true
 	next = cairo_truetype_font_align_output (font);
 	cairo_truetype_font_update_entry (font, truetype_tables[i].pos, truetype_tables[i].tag,
 					start, end);
-        cairo_truetype_font_check_boundary (font, next);
+        status = cairo_truetype_font_check_boundary (font, next);
+	if (status) {
+	    font->status = status;
+	    goto fail;
+	}
+
 	start = next;
     }
 
diff-tree 84639e563ddfbd70ca48dcde4d3631418fd1cd82 (from 866b2296b4a8b347011f1c8ae2e0f3a987a29d0c)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 14:11:43 2007 -0700

    test-meta-surface: Add missing check for error from _cairo_surface_get_extents

diff --git a/src/test-meta-surface.c b/src/test-meta-surface.c
index 1c5bad0..b0e422b 100644
--- a/src/test-meta-surface.c
+++ b/src/test-meta-surface.c
@@ -303,7 +303,9 @@ _test_meta_surface_snapshot (void *abstr
     cairo_rectangle_int16_t extents;
     cairo_surface_t *surface;
 
-    _cairo_surface_get_extents (other->image, &extents);
+    status = _cairo_surface_get_extents (other->image, &extents);
+    if (status)
+	return (cairo_surface_t*) &_cairo_surface_nil;
 
     surface = cairo_surface_create_similar (other->image,
 					    CAIRO_CONTENT_COLOR_ALPHA,
diff-tree 866b2296b4a8b347011f1c8ae2e0f3a987a29d0c (from ec1fc931257ff90fe190c52ed0a3bed9f218c350)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 14:09:56 2007 -0700

    test-meta-surface: Add missing checks for errors from _cairo_meta_surface_replay

diff --git a/src/test-meta-surface.c b/src/test-meta-surface.c
index d686881..1c5bad0 100644
--- a/src/test-meta-surface.c
+++ b/src/test-meta-surface.c
@@ -144,11 +144,14 @@ static cairo_int_status_t
 _test_meta_surface_show_page (void *abstract_surface)
 {
     test_meta_surface_t *surface = abstract_surface;
+    cairo_status_t status;
 
     if (surface->image_reflects_meta)
 	return CAIRO_STATUS_SUCCESS;
 
-    _cairo_meta_surface_replay (surface->meta, surface->image);
+    status = _cairo_meta_surface_replay (surface->meta, surface->image);
+    if (status)
+	return status;
 
     surface->image_reflects_meta = TRUE;
 
@@ -280,6 +283,7 @@ static cairo_surface_t *
 _test_meta_surface_snapshot (void *abstract_other)
 {
     test_meta_surface_t *other = abstract_other;
+    cairo_status_t status;
 
     /* XXX: Just making a snapshot of other->meta is what we really
      * want. But this currently triggers a bug somewhere (the "mask"
@@ -306,7 +310,9 @@ _test_meta_surface_snapshot (void *abstr
 					    extents.width,
 					    extents.height);
 
-    _cairo_meta_surface_replay (other->meta, surface);
+    status = _cairo_meta_surface_replay (other->meta, surface);
+    if (status)
+	return (cairo_surface_t*) &_cairo_surface_nil;
 
     return surface;
 #endif
diff-tree ec1fc931257ff90fe190c52ed0a3bed9f218c350 (from 3d21037a8fb69bde0765871f53fe461ac397367e)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 13:59:42 2007 -0700

    Add missing error check of return value of _cairo_path_fixed_close_path

diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 2b43c0f..fa18ffd 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -1750,7 +1750,7 @@ _decompose_glyph_outline (FT_Face		  fac
 
     FT_GlyphSlot glyph;
     cairo_path_fixed_t *path;
-    cairo_status_t status;
+    cairo_status_t status, status2;
 
     path = _cairo_path_fixed_create ();
     if (!path)
@@ -1764,7 +1764,9 @@ _decompose_glyph_outline (FT_Face		  fac
     if (FT_Outline_Decompose (&glyph->outline, &outline_funcs, path))
 	status = CAIRO_STATUS_NO_MEMORY;
 
-    _cairo_path_fixed_close_path (path);
+    status2 = _cairo_path_fixed_close_path (path);
+    if (status == CAIRO_STATUS_SUCCESS)
+	status = status2;
 
     if (status == CAIRO_STATUS_SUCCESS)
 	*pathp = path;
diff-tree 3d21037a8fb69bde0765871f53fe461ac397367e (from 2f468677160080e9dd1db52a2ad7ca4adbf48149)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 13:57:41 2007 -0700

    Add assertion check to quiet warn_unused_result warning.
    
    This is a somewhat useful internal consistency check.

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 69199f8..bfee1c7 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -1322,6 +1322,7 @@ _cairo_xlib_surface_composite (cairo_ope
     cairo_int_status_t		status;
     composite_operation_t       operation;
     int				itx, ity;
+    cairo_bool_t		is_integer_translation;
 
     if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -1414,7 +1415,10 @@ _cairo_xlib_surface_composite (cairo_ope
 	status = _cairo_xlib_surface_ensure_gc (dst);
 	if (status)
 	    goto BAIL;
-	_cairo_matrix_is_integer_translation (&src_attr.matrix, &itx, &ity);
+	is_integer_translation = _cairo_matrix_is_integer_translation (&src_attr.matrix,
+								       &itx, &ity);
+	/* This is a pre-condition for DO_XTILE. */
+	assert (is_integer_translation);
 
 	XSetTSOrigin (dst->dpy, dst->gc,
 		      - (itx + src_attr.x_offset), - (ity + src_attr.y_offset));
diff-tree 2f468677160080e9dd1db52a2ad7ca4adbf48149 (from cc6c115e3c5b931be4ab0210ce7f8cecaccf6241)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 13:53:58 2007 -0700

    Rename _cairo_pdf_surface_emit_toUnicode_stream to eliminate StudlyCaps
    
    Obviously, the new name is _cairo_pdf_surface_emit_to_unicode_stream which
    is consistent with the to_unicode_stream identifiers already existing in
    the implementation.

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 3b84cfd..ddb1bce 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -1658,8 +1658,8 @@ _cairo_pdf_surface_write_pages (cairo_pd
 }
 
 static cairo_pdf_resource_t
-_cairo_pdf_surface_emit_toUnicode_stream (cairo_pdf_surface_t		*surface,
-                                          cairo_scaled_font_subset_t	*font_subset)
+_cairo_pdf_surface_emit_to_unicode_stream (cairo_pdf_surface_t		*surface,
+					   cairo_scaled_font_subset_t	*font_subset)
 {
     const cairo_scaled_font_backend_t *backend;
     cairo_pdf_resource_t stream;
@@ -1781,7 +1781,7 @@ _cairo_pdf_surface_emit_cff_font_subset 
 				 "endobj\r\n");
     free (compressed);
 
-    to_unicode_stream = _cairo_pdf_surface_emit_toUnicode_stream (surface, font_subset);
+    to_unicode_stream = _cairo_pdf_surface_emit_to_unicode_stream (surface, font_subset);
 
     descriptor = _cairo_pdf_surface_new_object (surface);
     _cairo_output_stream_printf (surface->output,
@@ -1890,7 +1890,7 @@ _cairo_pdf_surface_emit_type1_font (cair
 				 "endobj\r\n");
     free (compressed);
 
-    to_unicode_stream = _cairo_pdf_surface_emit_toUnicode_stream (surface, font_subset);
+    to_unicode_stream = _cairo_pdf_surface_emit_to_unicode_stream (surface, font_subset);
 
     descriptor = _cairo_pdf_surface_new_object (surface);
     _cairo_output_stream_printf (surface->output,
@@ -2041,7 +2041,7 @@ _cairo_pdf_surface_emit_truetype_font_su
 				 "endobj\r\n");
     free (compressed);
 
-    to_unicode_stream = _cairo_pdf_surface_emit_toUnicode_stream (surface, font_subset);
+    to_unicode_stream = _cairo_pdf_surface_emit_to_unicode_stream (surface, font_subset);
 
     descriptor = _cairo_pdf_surface_new_object (surface);
     _cairo_output_stream_printf (surface->output,
@@ -2357,7 +2357,7 @@ _cairo_pdf_surface_emit_type3_font_subse
 
     free (glyphs);
 
-    to_unicode_stream = _cairo_pdf_surface_emit_toUnicode_stream (surface, font_subset);
+    to_unicode_stream = _cairo_pdf_surface_emit_to_unicode_stream (surface, font_subset);
 
     subset_resource = _cairo_pdf_surface_new_object (surface);
     matrix = font_subset->scaled_font->scale;
diff-tree cc6c115e3c5b931be4ab0210ce7f8cecaccf6241 (from 8873928f09a78d3e6e8e57d5d4e0b94cf1f78ab7)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 13:51:46 2007 -0700

    PDF: Check return value of _cairo_output_stream_destroy and propagate

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 2118973..3b84cfd 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -151,7 +151,7 @@ _cairo_pdf_surface_open_stream (cairo_pd
                                 cairo_bool_t             compressed,
 				const char		*fmt,
 				...) CAIRO_PRINTF_FORMAT(3, 4);
-static void
+static cairo_status_t
 _cairo_pdf_surface_close_stream (cairo_pdf_surface_t	*surface);
 
 static void
@@ -502,16 +502,17 @@ _cairo_pdf_surface_open_stream (cairo_pd
     return surface->current_stream.self;
 }
 
-static void
+static cairo_status_t
 _cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface)
 {
+    cairo_status_t status = CAIRO_STATUS_SUCCESS;
     long length;
 
     if (! surface->current_stream.active)
-	return;
+	return CAIRO_STATUS_SUCCESS;
 
     if (surface->current_stream.compressed) {
-        _cairo_output_stream_destroy (surface->output);
+        status = _cairo_output_stream_destroy (surface->output);
         surface->output = surface->current_stream.old_output;
         _cairo_output_stream_printf (surface->output,
                                      "\r\n");
@@ -533,17 +534,19 @@ _cairo_pdf_surface_close_stream (cairo_p
 				 length);
 
     surface->current_stream.active = FALSE;
+
+    return status;
 }
 
 static cairo_status_t
 _cairo_pdf_surface_finish (void *abstract_surface)
 {
-    cairo_status_t status;
+    cairo_status_t status, status2;
     cairo_pdf_surface_t *surface = abstract_surface;
     long offset;
     cairo_pdf_resource_t info, catalog;
 
-    _cairo_pdf_surface_close_stream (surface);
+    status = _cairo_pdf_surface_close_stream (surface);
 
     _cairo_pdf_surface_emit_font_subsets (surface);
 
@@ -569,7 +572,9 @@ _cairo_pdf_surface_finish (void *abstrac
 				 "%%%%EOF\r\n",
 				 offset);
 
-    status = _cairo_output_stream_destroy (surface->output);
+    status2 = _cairo_output_stream_destroy (surface->output);
+    if (status == CAIRO_STATUS_SUCCESS)
+	status = status2;
 
     _cairo_array_fini (&surface->objects);
     _cairo_array_fini (&surface->pages);
@@ -588,10 +593,10 @@ _cairo_pdf_surface_finish (void *abstrac
     return status;
 }
 
-static void
+static cairo_status_t
 _cairo_pdf_surface_pause_content_stream (cairo_pdf_surface_t *surface)
 {
-    _cairo_pdf_surface_close_stream (surface);
+    return _cairo_pdf_surface_close_stream (surface);
 }
 
 static void
@@ -716,7 +721,7 @@ _cairo_pdf_surface_emit_smask (cairo_pdf
 						  image->width, image->height);
     _cairo_output_stream_write (surface->output, alpha_compressed, alpha_compressed_size);
     _cairo_output_stream_printf (surface->output, "\r\n");
-    _cairo_pdf_surface_close_stream (surface);
+    status = _cairo_pdf_surface_close_stream (surface);
 
     free (alpha_compressed);
  CLEANUP_ALPHA:
@@ -830,7 +835,7 @@ _cairo_pdf_surface_emit_image (cairo_pdf
 
     _cairo_output_stream_write (surface->output, compressed, compressed_size);
     _cairo_output_stream_printf (surface->output, "\r\n");
-    _cairo_pdf_surface_close_stream (surface);
+    status = _cairo_pdf_surface_close_stream (surface);
 
  CLEANUP_COMPRESSED:
     free (compressed);
@@ -883,7 +888,9 @@ _cairo_pdf_surface_emit_surface_pattern 
 
     /* XXX: Should do something clever here for PDF source surfaces ? */
 
-    _cairo_pdf_surface_pause_content_stream (surface);
+    status = _cairo_pdf_surface_pause_content_stream (surface);
+    if (status)
+	return status;
 
     status = _cairo_pattern_acquire_surface ((cairo_pattern_t *)pattern,
 					     (cairo_surface_t *)surface,
@@ -1008,7 +1015,7 @@ _cairo_pdf_surface_emit_surface_pattern 
 				 image->width, image->height,
 				 image_resource.id);
 
-    _cairo_pdf_surface_close_stream (surface);
+    status = _cairo_pdf_surface_close_stream (surface);
 
     _cairo_pdf_surface_resume_content_stream (surface);
 
@@ -1194,7 +1201,9 @@ _cairo_pdf_surface_emit_linear_pattern (
     cairo_matrix_t p2u;
     cairo_status_t status;
 
-    _cairo_pdf_surface_pause_content_stream (surface);
+    status = _cairo_pdf_surface_pause_content_stream (surface);
+    if (status)
+	return status;
 
     function = _cairo_pdf_surface_emit_pattern_stops (surface, &pattern->base);
     if (function.id == 0)
@@ -1260,7 +1269,9 @@ _cairo_pdf_surface_emit_radial_pattern (
     cairo_matrix_t p2u;
     cairo_status_t status;
 
-    _cairo_pdf_surface_pause_content_stream (surface);
+    status = _cairo_pdf_surface_pause_content_stream (surface);
+    if (status)
+	return status;
 
     function = _cairo_pdf_surface_emit_pattern_stops (surface, &pattern->base);
     if (function.id == 0)
@@ -1653,6 +1664,7 @@ _cairo_pdf_surface_emit_toUnicode_stream
     const cairo_scaled_font_backend_t *backend;
     cairo_pdf_resource_t stream;
     unsigned int i;
+    cairo_status_t status;
 
     if (font_subset->to_unicode == NULL) {
         stream.id = 0;
@@ -1720,7 +1732,9 @@ _cairo_pdf_surface_emit_toUnicode_stream
                                 "end\r\n"
                                  "end\r\n");
 
-    _cairo_pdf_surface_close_stream (surface);
+    status = _cairo_pdf_surface_close_stream (surface);
+    if (status)
+	stream.id = 0;
 
     return stream;
 }
@@ -2156,9 +2170,7 @@ _cairo_pdf_surface_emit_outline_glyph (c
     _cairo_output_stream_printf (surface->output,
 				 " f");
 
-    _cairo_pdf_surface_close_stream (surface);
-
-    return CAIRO_STATUS_SUCCESS;
+    return _cairo_pdf_surface_close_stream (surface);
 }
 
 static cairo_int_status_t
@@ -2235,7 +2247,7 @@ _cairo_pdf_surface_emit_bitmap_glyph (ca
     _cairo_output_stream_printf (surface->output,
 				 "\r\nEI\r\n");
 
-    _cairo_pdf_surface_close_stream (surface);
+    status = _cairo_pdf_surface_close_stream (surface);
 
     if (image != scaled_glyph->surface)
 	cairo_surface_destroy (&image->base);
@@ -2513,7 +2525,9 @@ _cairo_pdf_surface_write_page (cairo_pdf
 	surface->has_clip = FALSE;
     }
 
-    _cairo_pdf_surface_close_stream (surface);
+    status = _cairo_pdf_surface_close_stream (surface);
+    if (status)
+	return status;
 
     page = _cairo_pdf_surface_new_object (surface);
     _cairo_output_stream_printf (surface->output,
diff-tree 8873928f09a78d3e6e8e57d5d4e0b94cf1f78ab7 (from ab5eccbbf6cc361e864e0d75c0299cf7b5d6122d)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 13:40:04 2007 -0700

    PS: Add missing error checks for _cairo_output_stream_destroy

diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index c08ecef..0260996 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -836,7 +836,8 @@ _cairo_ps_surface_create_for_stream_inte
 					    &cairo_ps_surface_paginated_backend);
 
  CLEANUP_OUTPUT_STREAM:
-    _cairo_output_stream_destroy (surface->stream);
+    status = _cairo_output_stream_destroy (surface->stream);
+    /* Ignore status---we're already on a failure path. */
  CLEANUP_TMPFILE:
     fclose (surface->tmpfile);
  CLEANUP_SURFACE:
@@ -1561,7 +1562,7 @@ _cairo_ps_surface_emit_image (cairo_ps_s
 	    cairo_image_surface_t *image,
 	    const char		  *name)
 {
-    cairo_status_t status;
+    cairo_status_t status, status2;
     unsigned char *rgb, *compressed;
     unsigned long rgb_size, compressed_size;
     cairo_surface_t *opaque;
@@ -1654,8 +1655,12 @@ _cairo_ps_surface_emit_image (cairo_ps_s
 
     _cairo_output_stream_write (base85_stream, compressed, compressed_size);
 
-    _cairo_output_stream_destroy (base85_stream);
-    _cairo_output_stream_destroy (string_array_stream);
+    status = _cairo_output_stream_destroy (base85_stream);
+    status2 = _cairo_output_stream_destroy (string_array_stream);
+    if (status == CAIRO_STATUS_SUCCESS)
+	status = status2;
+    if (status)
+	goto bail3;
 
     _cairo_output_stream_printf (surface->stream,
 				 "] def\n");
@@ -1687,6 +1692,7 @@ _cairo_ps_surface_emit_image (cairo_ps_s
 
     status = CAIRO_STATUS_SUCCESS;
 
+ bail3:
     free (compressed);
  bail2:
     free (rgb);
diff-tree ab5eccbbf6cc361e864e0d75c0299cf7b5d6122d (from 7a0ae5b7057798106b5e1a82431178f6c5f148e7)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 13:28:48 2007 -0700

    Make _cairo_clip_reset void
    
    Yet another unconditionally successful function---so it's easier to return nothing.

diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h
index 6b557a4..e7190cf 100644
--- a/src/cairo-clip-private.h
+++ b/src/cairo-clip-private.h
@@ -92,7 +92,7 @@ _cairo_clip_init_deep_copy (cairo_clip_t
                             cairo_clip_t    *other,
                             cairo_surface_t *target);
 
-cairo_private cairo_status_t
+cairo_private void
 _cairo_clip_reset (cairo_clip_t *clip);
 
 cairo_private cairo_status_t
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index a9f1c32..6e52ab2 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -96,7 +96,7 @@ _cairo_clip_init_copy (cairo_clip_t *cli
     return CAIRO_STATUS_SUCCESS;
 }
 
-cairo_status_t
+void
 _cairo_clip_reset (cairo_clip_t *clip)
 {
     /* destroy any existing clip-region artifacts */
@@ -117,8 +117,6 @@ _cairo_clip_reset (cairo_clip_t *clip)
 
     _cairo_clip_path_destroy (clip->path);
     clip->path = NULL;
-
-    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index aa4cd80..c07ce30 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -1191,7 +1191,9 @@ _cairo_gstate_fill_extents (cairo_gstate
 cairo_status_t
 _cairo_gstate_reset_clip (cairo_gstate_t *gstate)
 {
-    return _cairo_clip_reset (&gstate->clip);
+    _cairo_clip_reset (&gstate->clip);
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 cairo_status_t
diff --git a/src/cairo-meta-surface.c b/src/cairo-meta-surface.c
index 8ef9ec0..56c702c 100644
--- a/src/cairo-meta-surface.c
+++ b/src/cairo-meta-surface.c
@@ -756,7 +756,7 @@ _cairo_meta_surface_replay (cairo_surfac
 	    /* XXX Meta surface clipping is broken and requires some
 	     * cairo-gstate.c rewriting.  Work around it for now. */
 	    if (dev_path == NULL)
-		status = _cairo_clip_reset (&clip);
+		_cairo_clip_reset (&clip);
 	    else
 		status = _cairo_clip_clip (&clip, dev_path,
 					   command->intersect_clip_path.fill_rule,
diff-tree 7a0ae5b7057798106b5e1a82431178f6c5f148e7 (from b82e595449e6eebbe6024454aaaaee31e6c43c73)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Apr 10 21:09:36 2007 +0100

    Disable warnings for cairo_*_reference functions.
    
    This class of functions modify their argument and return it as a
    *convenience* for the caller. For example, within cairo a common idiom is:
    
        cairo_object_reference (new);
        cairo_object_unreference (this->obj);
        this->obj = new;
    
    which updates the member to the new object irrespective of whether the
    new object is the same as the one being replaced. Other issues arise
    with subtypes, as the return type is the parent's and so require more
    complicated handling to compile cleanly.
    
    Disabling the warning is therefore preferred over adding code which
    decreases readibility and reduces maintainability. We need to make the
    compiler work for us, not against us...

diff --git a/src/cairoint.h b/src/cairoint.h
index 7375abf..8c215eb 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -73,13 +73,13 @@
 CAIRO_BEGIN_DECLS
 
 #if __GNUC__ >= 3 && defined(__ELF__) && !defined(__sun)
-# define slim_hidden_proto(name)	slim_hidden_proto1(name, slim_hidden_int_name(name))
-# define slim_hidden_def(name)		slim_hidden_def1(name, slim_hidden_int_name(name))
+# define slim_hidden_proto(name)		slim_hidden_proto1(name, slim_hidden_int_name(name)) cairo_private
+# define slim_hidden_proto_no_warn(name)	slim_hidden_proto1(name, slim_hidden_int_name(name)) cairo_private_no_warn
+# define slim_hidden_def(name)			slim_hidden_def1(name, slim_hidden_int_name(name))
 # define slim_hidden_int_name(name) INT_##name
 # define slim_hidden_proto1(name, internal)				\
   extern __typeof (name) name						\
-	__asm__ (slim_hidden_asmname (internal))			\
-	cairo_private
+	__asm__ (slim_hidden_asmname (internal))
 # define slim_hidden_def1(name, internal)				\
   extern __typeof (name) EXT_##name __asm__(slim_hidden_asmname(name))	\
 	__attribute__((__alias__(slim_hidden_asmname(internal))))
@@ -89,8 +89,9 @@ CAIRO_BEGIN_DECLS
 # define slim_hidden_asmname(name)	slim_hidden_asmname1(name)
 # define slim_hidden_asmname1(name)	slim_hidden_ulp #name
 #else
-# define slim_hidden_proto(name)	int _cairo_dummy_prototype(void)
-# define slim_hidden_def(name)		int _cairo_dummy_prototype(void)
+# define slim_hidden_proto(name)		int _cairo_dummy_prototype(void)
+# define slim_hidden_proto_no_warn(name)	int _cairo_dummy_prototype(void)
+# define slim_hidden_def(name)			int _cairo_dummy_prototype(void)
 #endif
 
 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
@@ -103,10 +104,13 @@ CAIRO_BEGIN_DECLS
 /* slim_internal.h */
 #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) && !defined(__sun)
 #define cairo_private			__attribute__((__visibility__("hidden"),__warn_unused_result__))
+#define cairo_private_no_warn		__attribute__((__visibility__("hidden")))
 #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
 #define cairo_private			__hidden CAIRO_WARN_UNUSED_RESULT
+#define cairo_private_no_warn		__hidden
 #else /* not gcc >= 3.3 and not Sun Studio >= 8 */
 #define cairo_private			CAIRO_WARN_UNUSED_RESULT
+#define cairo_private_no_warn		
 #endif
 
 #define cairo_warn CAIRO_WARN_UNUSED_RESULT
@@ -1591,7 +1595,7 @@ cairo_private void
 _cairo_unscaled_font_init (cairo_unscaled_font_t               *font,
 			   const cairo_unscaled_font_backend_t *backend);
 
-cairo_private cairo_unscaled_font_t *
+cairo_private_no_warn cairo_unscaled_font_t *
 _cairo_unscaled_font_reference (cairo_unscaled_font_t *font);
 
 cairo_private void
@@ -2468,7 +2472,7 @@ slim_hidden_proto (cairo_curve_to);
 slim_hidden_proto (cairo_destroy);
 slim_hidden_proto (cairo_fill_preserve);
 slim_hidden_proto (cairo_font_face_destroy);
-slim_hidden_proto (cairo_font_face_reference);
+slim_hidden_proto_no_warn (cairo_font_face_reference);
 slim_hidden_proto (cairo_font_options_create);
 slim_hidden_proto (cairo_font_options_destroy);
 slim_hidden_proto (cairo_font_options_equal);
@@ -2507,7 +2511,7 @@ slim_hidden_proto (cairo_pattern_create_
 slim_hidden_proto (cairo_pattern_destroy);
 slim_hidden_proto (cairo_pattern_get_extend);
 slim_hidden_proto (cairo_pattern_get_type);
-slim_hidden_proto (cairo_pattern_reference);
+slim_hidden_proto_no_warn (cairo_pattern_reference);
 slim_hidden_proto (cairo_pattern_set_matrix);
 slim_hidden_proto (cairo_pattern_status);
 slim_hidden_proto (cairo_pop_group);
@@ -2526,7 +2530,7 @@ slim_hidden_proto (cairo_scaled_font_get
 slim_hidden_proto (cairo_scaled_font_get_font_matrix);
 slim_hidden_proto (cairo_scaled_font_get_font_options);
 slim_hidden_proto (cairo_scaled_font_glyph_extents);
-slim_hidden_proto (cairo_scaled_font_reference);
+slim_hidden_proto_no_warn (cairo_scaled_font_reference);
 slim_hidden_proto (cairo_set_operator);
 slim_hidden_proto (cairo_set_source);
 slim_hidden_proto (cairo_set_source_surface);
@@ -2540,7 +2544,7 @@ slim_hidden_proto (cairo_surface_get_dev
 slim_hidden_proto (cairo_surface_get_font_options);
 slim_hidden_proto (cairo_surface_get_type);
 slim_hidden_proto (cairo_surface_mark_dirty_rectangle);
-slim_hidden_proto (cairo_surface_reference);
+slim_hidden_proto_no_warn (cairo_surface_reference);
 slim_hidden_proto (cairo_surface_set_device_offset);
 slim_hidden_proto (cairo_surface_set_fallback_resolution);
 slim_hidden_proto (cairo_surface_status);
diff-tree b82e595449e6eebbe6024454aaaaee31e6c43c73 (from b0a256aaf3f0fd4491a28fca797aef1ef4b1251d)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Apr 9 15:31:28 2007 +0100

    pixman region operations can fail, propagate the error.
    
    Copying the clip region could fail, add error returns and propagate up
    the call stack.

diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h
index fbcb352..6b557a4 100644
--- a/src/cairo-clip-private.h
+++ b/src/cairo-clip-private.h
@@ -84,10 +84,10 @@ struct _cairo_clip {
 cairo_private void
 _cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target);
 
-cairo_private void
+cairo_private cairo_status_t
 _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other);
 
-cairo_private void
+cairo_private cairo_status_t
 _cairo_clip_init_deep_copy (cairo_clip_t    *clip,
                             cairo_clip_t    *other,
                             cairo_surface_t *target);
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index f7fd1e2..a9f1c32 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -67,7 +67,7 @@ _cairo_clip_init (cairo_clip_t *clip, ca
     clip->path = NULL;
 }
 
-void
+cairo_status_t
 _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
 {
     clip->mode = other->mode;
@@ -80,13 +80,20 @@ _cairo_clip_init_copy (cairo_clip_t *cli
     pixman_region_init (&clip->region);
 
     if (other->has_region) {
-        pixman_region_copy (&clip->region, &other->region);
+	if (pixman_region_copy (&clip->region, &other->region) !=
+		PIXMAN_REGION_STATUS_SUCCESS) {
+	    pixman_region_fini (&clip->region);
+	    cairo_surface_destroy (clip->surface);
+	    return CAIRO_STATUS_NO_MEMORY;
+	}
         clip->has_region = TRUE;
     } else {
         clip->has_region = FALSE;
     }
 
     clip->path = _cairo_clip_path_reference (other->path);
+    
+    return CAIRO_STATUS_SUCCESS;
 }
 
 cairo_status_t
@@ -342,18 +349,20 @@ _cairo_clip_intersect_region (cairo_clip
     status = CAIRO_STATUS_SUCCESS;
 
     if (!clip->has_region) {
-        pixman_region_copy (&clip->region, &region);
-        clip->has_region = TRUE;
+        if (pixman_region_copy (&clip->region, &region) ==
+		PIXMAN_REGION_STATUS_SUCCESS)
+	    clip->has_region = TRUE;
     } else {
 	pixman_region16_t intersection;
         pixman_region_init (&intersection);
 
-	if (PIXMAN_REGION_STATUS_SUCCESS ==
-            pixman_region_intersect (&intersection, &clip->region, &region)) {
-            pixman_region_copy (&clip->region, &intersection);
-        } else {
-            status = CAIRO_STATUS_NO_MEMORY;
-        }
+	if (PIXMAN_REGION_STATUS_SUCCESS !=
+		pixman_region_intersect (&intersection,
+		                         &clip->region,
+		                         &region) ||
+	    PIXMAN_REGION_STATUS_SUCCESS !=
+		pixman_region_copy (&clip->region, &intersection))
+	    status = CAIRO_STATUS_NO_MEMORY;
 
         pixman_region_fini (&intersection);
     }
@@ -544,7 +553,7 @@ _cairo_clip_path_reapply_clip_path (cair
                                 clip_path->antialias);
 }
 
-void
+cairo_status_t
 _cairo_clip_init_deep_copy (cairo_clip_t    *clip,
                             cairo_clip_t    *other,
                             cairo_surface_t *target)
@@ -556,17 +565,21 @@ _cairo_clip_init_deep_copy (cairo_clip_t
          * whatever the right handling is happen */
     } else {
         if (other->has_region) {
-            pixman_region_copy (&clip->region, &other->region);
-            clip->has_region = TRUE;
+            if (pixman_region_copy (&clip->region, &other->region) !=
+		    PIXMAN_REGION_STATUS_SUCCESS)
+		goto BAIL;
+	    clip->has_region = TRUE;
         }
 
         if (other->surface) {
-            _cairo_surface_clone_similar (target, other->surface,
+            if (_cairo_surface_clone_similar (target, other->surface,
 					  other->surface_rect.x,
 					  other->surface_rect.y,
 					  other->surface_rect.width,
 					  other->surface_rect.height,
-					  &clip->surface);
+					  &clip->surface) !=
+		    CAIRO_STATUS_SUCCESS)
+		goto BAIL;
             clip->surface_rect = other->surface_rect;
         }
 
@@ -574,6 +587,16 @@ _cairo_clip_init_deep_copy (cairo_clip_t
             _cairo_clip_path_reapply_clip_path (clip, other->path);
         }
     }
+
+    return CAIRO_STATUS_SUCCESS;
+
+BAIL:
+    if (clip->has_region)
+	pixman_region_fini (&clip->region);
+    if (clip->surface)
+	cairo_surface_destroy (clip->surface);
+
+    return CAIRO_STATUS_NO_MEMORY;
 }
 
 const cairo_rectangle_list_t _cairo_rectangles_nil =
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 6137373..aa4cd80 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -129,7 +129,9 @@ _cairo_gstate_init_copy (cairo_gstate_t 
 
     _cairo_font_options_init_copy (&gstate->font_options , &other->font_options);
 
-    _cairo_clip_init_copy (&gstate->clip, &other->clip);
+    status = _cairo_clip_init_copy (&gstate->clip, &other->clip);
+    if (status)
+	return status;
 
     gstate->target = cairo_surface_reference (other->target);
     /* parent_target is always set to NULL; it's only ever set by redirect_target */
@@ -299,9 +301,11 @@ _cairo_gstate_recursive_apply_clip_path 
  * original #cairo_t target, the clip will be INVALID after this call,
  * and the caller should either recreate or reset the clip.
  **/
-void
+cairo_status_t
 _cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child)
 {
+    cairo_status_t status;
+
     /* If this gstate is already redirected, this is an error; we need a
      * new gstate to be able to redirect */
     assert (gstate->parent_target == NULL);
@@ -317,13 +321,17 @@ _cairo_gstate_redirect_target (cairo_gst
     gstate->target = cairo_surface_reference (child);
 
     _cairo_clip_reset (&gstate->clip);
-    _cairo_clip_init_deep_copy (&gstate->clip, &gstate->next->clip, child);
+    status = _cairo_clip_init_deep_copy (&gstate->clip, &gstate->next->clip, child);
+    if (status)
+	return status;
 
     /* The clip is in surface backend coordinates for the previous target;
      * translate it into the child's backend coordinates. */
     _cairo_clip_translate (&gstate->clip,
                            _cairo_fixed_from_double (child->device_transform.x0 - gstate->parent_target->device_transform.x0),
                            _cairo_fixed_from_double (child->device_transform.y0 - gstate->parent_target->device_transform.y0));
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 /**
diff --git a/src/cairo.c b/src/cairo.c
index 97f264e..abcdaff 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -517,7 +517,7 @@ cairo_push_group_with_content (cairo_t *
     if (cr->status)
 	goto bail;
 
-    _cairo_gstate_redirect_target (cr->gstate, group_surface);
+    status = _cairo_gstate_redirect_target (cr->gstate, group_surface);
 
 bail:
     cairo_surface_destroy (group_surface);
diff --git a/src/cairoint.h b/src/cairoint.h
index c3e64b3..7375abf 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1257,7 +1257,7 @@ _cairo_gstate_restore (cairo_gstate_t **
 cairo_private cairo_bool_t
 _cairo_gstate_is_redirected (cairo_gstate_t *gstate);
 
-cairo_private void
+cairo_private cairo_status_t
 _cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child);
 
 cairo_private cairo_surface_t *
diff-tree b0a256aaf3f0fd4491a28fca797aef1ef4b1251d (from 5303980f82431a9d084177998a68527b60610241)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 13:07:09 2007 -0700

    Change _cairo_dtostr to have a void return type
    
    As previously implemented, there's no essential information in the
    return value from _cairo_dotostr, (the caller can simply use strlen
    to recompute the same value, which is what the only caller is already
    doing).
    
    There would be real information in a return value which would return
    the result from the call to snprintf for the case where the buffer is
    not large enough for the number being printed.

diff --git a/src/cairo-output-stream-private.h b/src/cairo-output-stream-private.h
index 0d5d29c..26c18cb 100644
--- a/src/cairo-output-stream-private.h
+++ b/src/cairo-output-stream-private.h
@@ -107,7 +107,7 @@ _cairo_output_stream_write_hex_string (c
 				       const char *data,
 				       size_t length);
 
-cairo_private int
+cairo_private void
 _cairo_dtostr (char *buffer, size_t size, double d);
 
 cairo_private void
diff --git a/src/cairo-output-stream.c b/src/cairo-output-stream.c
index 960904a..4401c5b 100644
--- a/src/cairo-output-stream.c
+++ b/src/cairo-output-stream.c
@@ -215,8 +215,7 @@ _cairo_output_stream_write_hex_string (c
  * has been relicensed under the LGPL/MPL dual license for inclusion
  * into cairo (see COPYING). -- Kristian Høgsberg <krh at redhat.com>
  */
-
-int
+void
 _cairo_dtostr (char *buffer, size_t size, double d)
 {
     struct lconv *locale_data;
@@ -259,8 +258,6 @@ _cairo_dtostr (char *buffer, size_t size
 	    p--;
 	}
     }
-
-    return p + 1 - buffer;
 }
 
 enum {
diff --git a/src/cairoint.h b/src/cairoint.h
index 991c73e..c3e64b3 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -2460,9 +2460,6 @@ _cairo_utf8_to_utf16 (const unsigned cha
 cairo_private void
 _cairo_error (cairo_status_t status);
 
-cairo_private int
-_cairo_dtostr (char *buffer, size_t size, double d);
-
 /* Avoid unnecessary PLT entries.  */
 slim_hidden_proto (cairo_clip_preserve);
 slim_hidden_proto (cairo_close_path);
diff-tree 5303980f82431a9d084177998a68527b60610241 (from 97a69bc82e023d139d997ef69c7eba50d2708686)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 12:56:56 2007 -0700

    _cairo_output_stream_vprintf: Add assertion to detect internal inconsitency
    
    This will catch any inconsistency between the length of a single
    format specifier and the fixed size of the single_fmt buffer.

diff --git a/src/cairo-output-stream.c b/src/cairo-output-stream.c
index 3da7c74..960904a 100644
--- a/src/cairo-output-stream.c
+++ b/src/cairo-output-stream.c
@@ -279,7 +279,9 @@ void
 _cairo_output_stream_vprintf (cairo_output_stream_t *stream,
 			      const char *fmt, va_list ap)
 {
-    char buffer[512], single_fmt[32];
+#define SINGLE_FMT_BUFFER_SIZE 32
+    char buffer[512], single_fmt[SINGLE_FMT_BUFFER_SIZE];
+    int single_fmt_length;
     char *p;
     const char *f, *start;
     int length_modifier;
@@ -315,9 +317,15 @@ _cairo_output_stream_vprintf (cairo_outp
 	    f++;
 	}
 
+	/* The only format strings exist in the cairo implementation
+	 * itself. So there's an internal consistency problem if any
+	 * of them is larger than our format buffer size. */
+	single_fmt_length = f - start + 1;
+	assert (single_fmt_length + 1 <= SINGLE_FMT_BUFFER_SIZE);
+
 	/* Reuse the format string for this conversion. */
-	memcpy (single_fmt, start, f + 1 - start);
-	single_fmt[f + 1 - start] = '\0';
+	memcpy (single_fmt, start, single_fmt_length);
+	single_fmt[single_fmt_length] = '\0';
 
 	/* Flush contents of buffer before snprintf()'ing into it. */
 	_cairo_output_stream_write (stream, buffer, p - buffer);
diff-tree 97a69bc82e023d139d997ef69c7eba50d2708686 (from 5c95800cded4e906baf8ddd10bfb4abc59151b13)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 12:13:27 2007 -0700

    Fix mis-indented _cairo_dtostr

diff --git a/src/cairo-output-stream.c b/src/cairo-output-stream.c
index cdf7d1d..3da7c74 100644
--- a/src/cairo-output-stream.c
+++ b/src/cairo-output-stream.c
@@ -219,48 +219,48 @@ _cairo_output_stream_write_hex_string (c
 int
 _cairo_dtostr (char *buffer, size_t size, double d)
 {
-  struct lconv *locale_data;
-  const char *decimal_point;
-  int decimal_point_len;
-  char *p;
-  int decimal_len;
-
-  /* Omit the minus sign from negative zero. */
-  if (d == 0.0)
-      d = 0.0;
-
-  snprintf (buffer, size, "%f", d);
-
-  locale_data = localeconv ();
-  decimal_point = locale_data->decimal_point;
-  decimal_point_len = strlen (decimal_point);
-
-  assert (decimal_point_len != 0);
-  p = buffer;
-
-  if (*p == '+' || *p == '-')
-      p++;
-
-  while (isdigit (*p))
-      p++;
-
-  if (strncmp (p, decimal_point, decimal_point_len) == 0) {
-      *p = '.';
-      decimal_len = strlen (p + decimal_point_len);
-      memmove (p + 1, p + decimal_point_len, decimal_len);
-      p[1 + decimal_len] = 0;
-
-      /* Remove trailing zeros and decimal point if possible. */
-      for (p = p + decimal_len; *p == '0'; p--)
-	  *p = 0;
-
-      if (*p == '.') {
-	  *p = 0;
-	  p--;
-      }
-  }
+    struct lconv *locale_data;
+    const char *decimal_point;
+    int decimal_point_len;
+    char *p;
+    int decimal_len;
+
+    /* Omit the minus sign from negative zero. */
+    if (d == 0.0)
+	d = 0.0;
+
+    snprintf (buffer, size, "%f", d);
+
+    locale_data = localeconv ();
+    decimal_point = locale_data->decimal_point;
+    decimal_point_len = strlen (decimal_point);
+
+    assert (decimal_point_len != 0);
+    p = buffer;
+
+    if (*p == '+' || *p == '-')
+	p++;
+
+    while (isdigit (*p))
+	p++;
+
+    if (strncmp (p, decimal_point, decimal_point_len) == 0) {
+	*p = '.';
+	decimal_len = strlen (p + decimal_point_len);
+	memmove (p + 1, p + decimal_point_len, decimal_len);
+	p[1 + decimal_len] = 0;
+
+	/* Remove trailing zeros and decimal point if possible. */
+	for (p = p + decimal_len; *p == '0'; p--)
+	    *p = 0;
+
+	if (*p == '.') {
+	    *p = 0;
+	    p--;
+	}
+    }
 
-  return p + 1 - buffer;
+    return p + 1 - buffer;
 }
 
 enum {
diff-tree 5c95800cded4e906baf8ddd10bfb4abc59151b13 (from 57188b4dcbcc2625dfc1817f8fe3b8ffeade5dc5)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 12:13:10 2007 -0700

    Fix mis-indented _cairo_traps_init_box

diff --git a/src/cairo-traps.c b/src/cairo-traps.c
index d9d57ad..f2b5ccb 100644
--- a/src/cairo-traps.c
+++ b/src/cairo-traps.c
@@ -87,26 +87,26 @@ cairo_status_t
 _cairo_traps_init_box (cairo_traps_t *traps,
 		       cairo_box_t   *box)
 {
-  _cairo_traps_init (traps);
+    _cairo_traps_init (traps);
 
-  traps->status = _cairo_traps_grow (traps);
-  if (traps->status)
-    return traps->status;
+    traps->status = _cairo_traps_grow (traps);
+    if (traps->status)
+	return traps->status;
 
-  traps->num_traps = 1;
+    traps->num_traps = 1;
 
-  traps->traps[0].top = box->p1.y;
-  traps->traps[0].bottom = box->p2.y;
-  traps->traps[0].left.p1 = box->p1;
-  traps->traps[0].left.p2.x = box->p1.x;
-  traps->traps[0].left.p2.y = box->p2.y;
-  traps->traps[0].right.p1.x = box->p2.x;
-  traps->traps[0].right.p1.y = box->p1.y;
-  traps->traps[0].right.p2 = box->p2;
+    traps->traps[0].top = box->p1.y;
+    traps->traps[0].bottom = box->p2.y;
+    traps->traps[0].left.p1 = box->p1;
+    traps->traps[0].left.p2.x = box->p1.x;
+    traps->traps[0].left.p2.y = box->p2.y;
+    traps->traps[0].right.p1.x = box->p2.x;
+    traps->traps[0].right.p1.y = box->p1.y;
+    traps->traps[0].right.p2 = box->p2;
 
-  traps->extents = *box;
+    traps->extents = *box;
 
-  return traps->status;
+    return traps->status;
 }
 
 cairo_status_t
diff-tree 57188b4dcbcc2625dfc1817f8fe3b8ffeade5dc5 (from 67bc608603b9baf8de8bcd2fedcf8ec315432a37)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 12:06:09 2007 -0700

    Fix cairo_traps_t status handling
    
    Add a _cairo_traps_status function and use it instead of adding
    error checks to callers of _cairo_traps_add_trap and
    _cairo_traps_add_trap_from_points, (both of which are now given
    a void return type).

diff --git a/src/cairo-bentley-ottmann.c b/src/cairo-bentley-ottmann.c
index a952837..bbae875 100644
--- a/src/cairo-bentley-ottmann.c
+++ b/src/cairo-bentley-ottmann.c
@@ -1065,7 +1065,6 @@ _cairo_bo_edge_end_trap (cairo_bo_edge_t
 			 cairo_bo_traps_t	*bo_traps)
 {
     cairo_fixed_t fixed_top, fixed_bot;
-    cairo_status_t status = CAIRO_STATUS_SUCCESS;
     cairo_bo_trap_t *trap = left->deferred_trap;
     cairo_bo_edge_t *right;
 
@@ -1107,11 +1106,11 @@ _cairo_bo_edge_end_trap (cairo_bo_edge_t
 	    left_bot.x != right_bot.x ||
 	    left_bot.y != right_bot.y)
 	{
-	    status = _cairo_traps_add_trap_from_points (bo_traps->traps,
-							fixed_top,
-							fixed_bot,
-							left_top, left_bot,
-							right_top, right_bot);
+	    _cairo_traps_add_trap_from_points (bo_traps->traps,
+					       fixed_top,
+					       fixed_bot,
+					       left_top, left_bot,
+					       right_top, right_bot);
 
 #if DEBUG_PRINT_STATE
 	    printf ("Deferred trap: left=(%08x, %08x)-(%08x,%08x) "
@@ -1125,7 +1124,8 @@ _cairo_bo_edge_end_trap (cairo_bo_edge_t
 
     _cairo_freelist_free (&bo_traps->freelist, trap);
     left->deferred_trap = NULL;
-    return status;
+
+    return _cairo_traps_status (bo_traps->traps);
 }
 
 /* Start a new trapezoid at the given top y coordinate, whose edges
diff --git a/src/cairo-traps.c b/src/cairo-traps.c
index 2f34169..d9d57ad 100644
--- a/src/cairo-traps.c
+++ b/src/cairo-traps.c
@@ -43,7 +43,7 @@
 static cairo_status_t
 _cairo_traps_grow (cairo_traps_t *traps);
 
-static cairo_status_t
+static void
 _cairo_traps_add_trap (cairo_traps_t *traps, cairo_fixed_t top, cairo_fixed_t bottom,
 		       cairo_line_t *left, cairo_line_t *right);
 
@@ -109,23 +109,29 @@ _cairo_traps_init_box (cairo_traps_t *tr
   return traps->status;
 }
 
-static cairo_status_t
+cairo_status_t
+_cairo_traps_status (cairo_traps_t *traps)
+{
+    return traps->status;
+}
+
+static void
 _cairo_traps_add_trap (cairo_traps_t *traps, cairo_fixed_t top, cairo_fixed_t bottom,
 		       cairo_line_t *left, cairo_line_t *right)
 {
     cairo_trapezoid_t *trap;
 
     if (traps->status)
-	return traps->status;
+	return;
 
     if (top == bottom) {
-	return CAIRO_STATUS_SUCCESS;
+	return;
     }
 
     if (traps->num_traps >= traps->traps_size) {
 	traps->status = _cairo_traps_grow (traps);
 	if (traps->status)
-	    return traps->status;
+	    return;
     }
 
     trap = &traps->traps[traps->num_traps];
@@ -157,11 +163,9 @@ _cairo_traps_add_trap (cairo_traps_t *tr
 	traps->extents.p2.x = right->p2.x;
 
     traps->num_traps++;
-
-    return traps->status;
 }
 
-cairo_status_t
+void
 _cairo_traps_add_trap_from_points (cairo_traps_t *traps, cairo_fixed_t top, cairo_fixed_t bottom,
 				   cairo_point_t left_p1, cairo_point_t left_p2,
 				   cairo_point_t right_p1, cairo_point_t right_p2)
@@ -170,7 +174,7 @@ _cairo_traps_add_trap_from_points (cairo
     cairo_line_t right;
 
     if (traps->status)
-	return traps->status;
+	return;
 
     left.p1 = left_p1;
     left.p2 = left_p2;
@@ -178,7 +182,7 @@ _cairo_traps_add_trap_from_points (cairo
     right.p1 = right_p1;
     right.p2 = right_p2;
 
-    return _cairo_traps_add_trap (traps, top, bottom, &left, &right);
+    _cairo_traps_add_trap (traps, top, bottom, &left, &right);
 }
 
 /* make room for at least one more trap */
diff --git a/src/cairoint.h b/src/cairoint.h
index c6b9e40..991c73e 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -2297,6 +2297,9 @@ _cairo_traps_init_box (cairo_traps_t *tr
 cairo_private void
 _cairo_traps_fini (cairo_traps_t *traps);
 
+cairo_private cairo_status_t
+_cairo_traps_status (cairo_traps_t *traps);
+
 cairo_private void
 _cairo_traps_translate (cairo_traps_t *traps, int x, int y);
 
@@ -2311,7 +2314,7 @@ _cairo_traps_tessellate_polygon (cairo_t
 				 cairo_polygon_t *poly,
 				 cairo_fill_rule_t fill_rule);
 
-cairo_private cairo_status_t
+cairo_private void
 _cairo_traps_add_trap_from_points (cairo_traps_t *traps, cairo_fixed_t top, cairo_fixed_t bottom,
 				   cairo_point_t left_p1, cairo_point_t left_p2,
 				   cairo_point_t right_p1, cairo_point_t right_p2);
diff-tree 67bc608603b9baf8de8bcd2fedcf8ec315432a37 (from b1086caf3b108b0df19f70a2b6df161ad51bb280)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 11:11:32 2007 -0700

    Add missing error checking to _trace_mask_to_path
    
    Note: It looks like it would be convenient to shove a status value
    into cairo_path_fixed_t to reduce this sequence of error checks.
    But I tried that first, and it actually makes things worse overall
    due to many things like _cairo_path_fixed_move_to called by
    cairo_move_to where the result must be immediately checked anyway.
    So I've already rejected that approach.

diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 4b976c5..a4754f7 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -1178,6 +1178,42 @@ _scaled_glyph_path_close_path (void *abs
     return _cairo_path_fixed_close_path (closure->path);
 }
 
+/* Add a single-device-unit rectangle to a path. */
+static cairo_status_t
+_add_unit_rectangle_to_path (cairo_path_fixed_t *path, int x, int y)
+{
+    cairo_status_t status;
+
+    status = _cairo_path_fixed_move_to (path,
+					_cairo_fixed_from_int (x),
+					_cairo_fixed_from_int (y));
+    if (status)
+	return status;
+
+    status = _cairo_path_fixed_rel_line_to (path,
+					    _cairo_fixed_from_int (1),
+					    _cairo_fixed_from_int (0));
+    if (status)
+	return status;
+
+    status = _cairo_path_fixed_rel_line_to (path,
+					    _cairo_fixed_from_int (0),
+					    _cairo_fixed_from_int (1));
+    if (status)
+	return status;
+
+    status = _cairo_path_fixed_rel_line_to (path,
+					    _cairo_fixed_from_int (-1),
+					    _cairo_fixed_from_int (0));
+    if (status)
+	return status;
+
+    status = _cairo_path_fixed_close_path (path);
+    if (status)
+	return status;
+
+    return CAIRO_STATUS_SUCCESS;
+}
 
 /**
  * _trace_mask_to_path:
@@ -1200,6 +1236,7 @@ static cairo_status_t
 _trace_mask_to_path (cairo_image_surface_t *mask,
 		     cairo_path_fixed_t *path)
 {
+    cairo_status_t status;
     cairo_image_surface_t *a1_mask;
     unsigned char *row, *byte_ptr, byte;
     int rows, cols, bytes_per_row;
@@ -1222,19 +1259,10 @@ _trace_mask_to_path (cairo_image_surface
 	    byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte_ptr);
 	    for (bit = 7; bit >= 0 && x < a1_mask->width; bit--, x++) {
 		if (byte & (1 << bit)) {
-		    _cairo_path_fixed_move_to (path,
-					       _cairo_fixed_from_int (x + xoff),
-					       _cairo_fixed_from_int (y + yoff));
-		    _cairo_path_fixed_rel_line_to (path,
-						   _cairo_fixed_from_int (1),
-						   _cairo_fixed_from_int (0));
-		    _cairo_path_fixed_rel_line_to (path,
-						   _cairo_fixed_from_int (0),
-						   _cairo_fixed_from_int (1));
-		    _cairo_path_fixed_rel_line_to (path,
-						   _cairo_fixed_from_int (-1),
-						   _cairo_fixed_from_int (0));
-		    _cairo_path_fixed_close_path (path);
+		    status = _add_unit_rectangle_to_path (path,
+							  x + xoff, y + yoff);
+		    if (status)
+			return status;
 		}
 	    }
 	}
diff-tree b1086caf3b108b0df19f70a2b6df161ad51bb280 (from bff45ec9f90b5949a8ffa19cb03c140a08119e4d)
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Apr 10 10:45:15 2007 -0700

    Add a status field to cairo_polygon_t
    
    Now, the functions to add new data to a polygon all become void,
    and there's a new _cairo_polygon_status call to query the status
    at the end of a sequence of operations.
    
    With this change, we fix many callerswhich were previously not
    checking the return values of _cairo_polygon functions by adding
    only a single call to _cairo_polygon_status rathern than several
    new checks.

diff --git a/src/cairo-path-fill.c b/src/cairo-path-fill.c
index d2a9118..2542029 100644
--- a/src/cairo-path-fill.c
+++ b/src/cairo-path-fill.c
@@ -88,37 +88,28 @@ _cairo_filler_fini (cairo_filler_t *fill
 static cairo_status_t
 _cairo_filler_move_to (void *closure, cairo_point_t *point)
 {
-    cairo_status_t status;
     cairo_filler_t *filler = closure;
     cairo_polygon_t *polygon = &filler->polygon;
 
-    status = _cairo_polygon_close (polygon);
-    if (status)
-	return status;
-
-    status = _cairo_polygon_move_to (polygon, point);
-    if (status)
-	return status;
+    _cairo_polygon_close (polygon);
+    _cairo_polygon_move_to (polygon, point);
 
     filler->current_point = *point;
 
-    return CAIRO_STATUS_SUCCESS;
+    return _cairo_polygon_status (&filler->polygon);
 }
 
 static cairo_status_t
 _cairo_filler_line_to (void *closure, cairo_point_t *point)
 {
-    cairo_status_t status;
     cairo_filler_t *filler = closure;
     cairo_polygon_t *polygon = &filler->polygon;
 
-    status = _cairo_polygon_line_to (polygon, point);
-    if (status)
-	return status;
+    _cairo_polygon_line_to (polygon, point);
 
     filler->current_point = *point;
 
-    return CAIRO_STATUS_SUCCESS;
+    return _cairo_polygon_status (&filler->polygon);
 }
 
 static cairo_status_t
@@ -142,11 +133,8 @@ _cairo_filler_curve_to (void *closure,
     if (status)
 	goto CLEANUP_SPLINE;
 
-    for (i = 1; i < spline.num_points; i++) {
-	status = _cairo_polygon_line_to (polygon, &spline.points[i]);
-	if (status)
-	    break;
-    }
+    for (i = 1; i < spline.num_points; i++)
+	_cairo_polygon_line_to (polygon, &spline.points[i]);
 
   CLEANUP_SPLINE:
     _cairo_spline_fini (&spline);
@@ -159,15 +147,12 @@ _cairo_filler_curve_to (void *closure,
 static cairo_status_t
 _cairo_filler_close_path (void *closure)
 {
-    cairo_status_t status;
     cairo_filler_t *filler = closure;
     cairo_polygon_t *polygon = &filler->polygon;
 
-    status = _cairo_polygon_close (polygon);
-    if (status)
-	return status;
+    _cairo_polygon_close (polygon);
 
-    return CAIRO_STATUS_SUCCESS;
+    return _cairo_polygon_status (polygon);
 }
 
 static cairo_int_status_t
@@ -201,7 +186,8 @@ _cairo_path_fixed_fill_to_traps (cairo_p
     if (status)
 	goto BAIL;
 
-    status = _cairo_polygon_close (&filler.polygon);
+    _cairo_polygon_close (&filler.polygon);
+    status = _cairo_polygon_status (&filler.polygon);
     if (status)
 	goto BAIL;
 
diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c
index c5a8342..d9f7ed2 100644
--- a/src/cairo-path-stroke.c
+++ b/src/cairo-path-stroke.c
@@ -441,8 +441,14 @@ _cairo_stroker_add_cap (cairo_stroker_t 
 	_cairo_polygon_line_to (&polygon, &occw);
 	_cairo_polygon_line_to (&polygon, &f->ccw);
 	_cairo_polygon_close (&polygon);
+	status = _cairo_polygon_status (&polygon);
+
+	if (status == CAIRO_STATUS_SUCCESS) {
+	    status = _cairo_bentley_ottmann_tessellate_polygon (stroker->traps,
+								&polygon,
+								CAIRO_FILL_RULE_WINDING);
+	}
 
-	status = _cairo_bentley_ottmann_tessellate_polygon (stroker->traps, &polygon, CAIRO_FILL_RULE_WINDING);
 	_cairo_polygon_fini (&polygon);
 
 	return status;
diff --git a/src/cairo-pen.c b/src/cairo-pen.c
index c532019..ec9eb7a 100644
--- a/src/cairo-pen.c
+++ b/src/cairo-pen.c
@@ -399,9 +399,8 @@ _cairo_pen_stroke_spline_half (cairo_pen
     while (i != stop) {
 	hull_point.x = point[i].x + pen->vertices[active].point.x;
 	hull_point.y = point[i].y + pen->vertices[active].point.y;
-	status = _cairo_polygon_line_to (polygon, &hull_point);
-	if (status)
-	    return status;
+
+	_cairo_polygon_line_to (polygon, &hull_point);
 
 	if (i + step == stop)
 	    slope = final_slope;
@@ -452,9 +451,11 @@ _cairo_pen_stroke_spline (cairo_pen_t		*
     if (status)
 	goto BAIL;
 
-    status = _cairo_polygon_close (&polygon);
+    _cairo_polygon_close (&polygon);
+    status = _cairo_polygon_status (&polygon);
     if (status)
 	goto BAIL;
+
     status = _cairo_bentley_ottmann_tessellate_polygon (traps, &polygon, CAIRO_FILL_RULE_WINDING);
 BAIL:
     _cairo_polygon_fini (&polygon);
diff --git a/src/cairo-polygon.c b/src/cairo-polygon.c
index 1eb09ec..e9fc78b 100644
--- a/src/cairo-polygon.c
+++ b/src/cairo-polygon.c
@@ -44,6 +44,8 @@ _cairo_polygon_grow (cairo_polygon_t *po
 void
 _cairo_polygon_init (cairo_polygon_t *polygon)
 {
+    polygon->status = CAIRO_STATUS_SUCCESS;
+
     polygon->num_edges = 0;
 
     polygon->edges_size = 0;
@@ -65,6 +67,12 @@ _cairo_polygon_fini (cairo_polygon_t *po
     polygon->has_current_point = FALSE;
 }
 
+cairo_status_t
+_cairo_polygon_status (cairo_polygon_t *polygon)
+{
+    return polygon->status;
+}
+
 /* make room for at least one more edge */
 static cairo_status_t
 _cairo_polygon_grow (cairo_polygon_t *polygon)
@@ -102,22 +110,22 @@ _cairo_polygon_grow (cairo_polygon_t *po
     return CAIRO_STATUS_SUCCESS;
 }
 
-cairo_status_t
+void
 _cairo_polygon_add_edge (cairo_polygon_t *polygon, cairo_point_t *p1, cairo_point_t *p2)
 {
-    cairo_status_t status;
     cairo_edge_t *edge;
 
+    if (polygon->status)
+	return;
+
     /* drop horizontal edges */
-    if (p1->y == p2->y) {
+    if (p1->y == p2->y)
 	goto DONE;
-    }
 
     if (polygon->num_edges >= polygon->edges_size) {
-	status = _cairo_polygon_grow (polygon);
-	if (status) {
-	    return status;
-	}
+	polygon->status = _cairo_polygon_grow (polygon);
+	if (polygon->status)
+	    return;
     }
 
     edge = &polygon->edges[polygon->num_edges];
@@ -134,48 +142,46 @@ _cairo_polygon_add_edge (cairo_polygon_t
     polygon->num_edges++;
 
   DONE:
-    return _cairo_polygon_move_to (polygon, p2);
+    _cairo_polygon_move_to (polygon, p2);
 }
 
-cairo_status_t
+void
 _cairo_polygon_move_to (cairo_polygon_t *polygon, cairo_point_t *point)
 {
+    if (polygon->status)
+	return;
+
     if (! polygon->has_current_point)
 	polygon->first_point = *point;
+
     polygon->current_point = *point;
     polygon->has_current_point = TRUE;
-
-    return CAIRO_STATUS_SUCCESS;
 }
 
-cairo_status_t
+void
 _cairo_polygon_line_to (cairo_polygon_t *polygon, cairo_point_t *point)
 {
-    cairo_status_t status;
+    if (polygon->status)
+	return;
 
     if (polygon->has_current_point) {
-	status = _cairo_polygon_add_edge (polygon, &polygon->current_point, point);
+	_cairo_polygon_add_edge (polygon, &polygon->current_point, point);
     } else {
-	status = _cairo_polygon_move_to (polygon, point);
+	_cairo_polygon_move_to (polygon, point);
     }
-
-    return status;
 }
 
-cairo_status_t
+void
 _cairo_polygon_close (cairo_polygon_t *polygon)
 {
-    cairo_status_t status;
+    if (polygon->status)
+	return;
 
     if (polygon->has_current_point) {
-	status = _cairo_polygon_add_edge (polygon,
-					  &polygon->current_point,
-					  &polygon->first_point);
-	if (status)
-	    return status;
+	_cairo_polygon_add_edge (polygon,
+				 &polygon->current_point,
+				 &polygon->first_point);
 
 	polygon->has_current_point = FALSE;
     }
-
-    return CAIRO_STATUS_SUCCESS;
 }
diff --git a/src/cairoint.h b/src/cairoint.h
index fba0ab9..c6b9e40 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -347,6 +347,8 @@ typedef struct _cairo_edge {
 } cairo_edge_t;
 
 typedef struct _cairo_polygon {
+    cairo_status_t status;
+
     cairo_point_t first_point;
     cairo_point_t current_point;
     cairo_bool_t has_current_point;
@@ -2219,15 +2221,18 @@ cairo_private void
 _cairo_polygon_fini (cairo_polygon_t *polygon);
 
 cairo_private cairo_status_t
+_cairo_polygon_status (cairo_polygon_t *polygon);
+
+cairo_private void
 _cairo_polygon_add_edge (cairo_polygon_t *polygon, cairo_point_t *p1, cairo_point_t *p2);
 
-cairo_private cairo_status_t
+cairo_private void
 _cairo_polygon_move_to (cairo_polygon_t *polygon, cairo_point_t *point);
 
-cairo_private cairo_status_t
+cairo_private void
 _cairo_polygon_line_to (cairo_polygon_t *polygon, cairo_point_t *point);
 
-cairo_private cairo_status_t
+cairo_private void
 _cairo_polygon_close (cairo_polygon_t *polygon);
 
 /* cairo_spline.c */
diff-tree bff45ec9f90b5949a8ffa19cb03c140a08119e4d (from 01955a6e82ee28dd1377a3f2242aa2ddeebadac9)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Apr 9 17:44:12 2007 -0700

    Invert condition to more intuitive form.
    
    The idiom for checking the return value of malloc is:
    
    	if (pointer == NULL) { ... }
    
    rather than:
    
    	if (pointer != NULL) { ... }

diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 5c51aa2..ce61600 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -297,10 +297,11 @@ _cairo_pattern_create_solid (const cairo
 	/* None cached, need to create a new pattern. */
 	pattern = malloc (sizeof (cairo_solid_pattern_t));
     }
-    if (pattern != NULL)
-	_cairo_pattern_init_solid (pattern, color);
-    else
+
+    if (pattern == NULL)
 	pattern = (cairo_solid_pattern_t *) &_cairo_pattern_nil;
+    else
+	_cairo_pattern_init_solid (pattern, color);
 
     return &pattern->base;
 }
diff-tree 01955a6e82ee28dd1377a3f2242aa2ddeebadac9 (from d317e8175de04c73c4a1f84db4a7e5354411ca06)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Apr 9 17:42:04 2007 -0700

    Rename ARRAY_LEN to ARRAY_LENGTH
    
    Yet another victim in my hunt against abbreviations within cairo's implementation.

diff --git a/src/cairo-arc.c b/src/cairo-arc.c
index 377da84..89e6ce1 100644
--- a/src/cairo-arc.c
+++ b/src/cairo-arc.c
@@ -87,7 +87,7 @@ _arc_max_angle_for_tolerance_normalized 
 	{ M_PI / 10.0,  1.73863223499021216974e-08 },
 	{ M_PI / 11.0,  9.81410988043554039085e-09 },
     };
-    int table_size = ARRAY_LEN (table);
+    int table_size = ARRAY_LENGTH (table);
 
     for (i = 0; i < table_size; i++)
 	if (table[i].error < tolerance)
diff --git a/src/cairo-atsui-font.c b/src/cairo-atsui-font.c
index 79113d8..8aca207 100644
--- a/src/cairo-atsui-font.c
+++ b/src/cairo-atsui-font.c
@@ -116,7 +116,7 @@ _cairo_atsui_font_face_scaled_font_creat
     ATSUStyle style;
 
     err = ATSUCreateStyle (&style);
-    err = ATSUSetAttributes(style, ARRAY_LEN (styleTags),
+    err = ATSUSetAttributes(style, ARRAY_LENGTH (styleTags),
                             styleTags, styleSizes, styleValues);
 
     return _cairo_atsui_font_create_scaled (&font_face->base, font_face->font_id, style,
@@ -372,7 +372,7 @@ _cairo_atsui_font_create_toy(cairo_toy_f
 	ByteCount styleSizes[] =
 	    { sizeof(Boolean), sizeof(Boolean), sizeof(ATSUFontID) };
 
-	err = ATSUSetAttributes(style, ARRAY_LEN (styleTags),
+	err = ATSUSetAttributes(style, ARRAY_LENGTH (styleTags),
 				styleTags, styleSizes, styleValues);
     }
 
diff --git a/src/cairo-bentley-ottmann.c b/src/cairo-bentley-ottmann.c
index 4c551f6..a952837 100644
--- a/src/cairo-bentley-ottmann.c
+++ b/src/cairo-bentley-ottmann.c
@@ -1794,7 +1794,7 @@ main (void)
     unsigned int i, num_random;
     test_t *test;
 
-    for (i = 0; i < ARRAY_LEN (tests); i++) {
+    for (i = 0; i < ARRAY_LENGTH (tests); i++) {
 	test = &tests[i];
 	run_test (test->name, test->edges, test->num_edges);
     }
diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c
index 1cdedee..ab61ae2 100644
--- a/src/cairo-cff-subset.c
+++ b/src/cairo-cff-subset.c
@@ -895,7 +895,7 @@ cairo_cff_font_read_font (cairo_cff_font
     cairo_int_status_t status;
     unsigned int i;
 
-    for (i = 0; i < ARRAY_LEN (font_read_funcs); i++) {
+    for (i = 0; i < ARRAY_LENGTH (font_read_funcs); i++) {
         status = font_read_funcs[i] (font);
         if (status)
             return status;
@@ -955,7 +955,7 @@ cairo_cff_font_subset_dict_strings (cair
     cairo_status_t status;
     unsigned int i;
 
-    for (i = 0; i < ARRAY_LEN (dict_strings); i++) {
+    for (i = 0; i < ARRAY_LENGTH (dict_strings); i++) {
         status = cairo_cff_font_subset_dict_string (font, dict, dict_strings[i]);
         if (status)
             return status;
@@ -1316,7 +1316,7 @@ cairo_cff_font_write_subset (cairo_cff_f
     cairo_int_status_t status;
     unsigned int i;
 
-    for (i = 0; i < ARRAY_LEN (font_write_funcs); i++) {
+    for (i = 0; i < ARRAY_LENGTH (font_write_funcs); i++) {
         status = font_write_funcs[i] (font);
         if (status)
             return status;
diff --git a/src/cairo-hash.c b/src/cairo-hash.c
index b55e7fb..9934375 100644
--- a/src/cairo-hash.c
+++ b/src/cairo-hash.c
@@ -115,7 +115,7 @@ static const cairo_hash_table_arrangemen
     { 268435456,	590559793,	590559791	}
 };
 
-#define NUM_HASH_TABLE_ARRANGEMENTS ARRAY_LEN (hash_table_arrangements)
+#define NUM_HASH_TABLE_ARRANGEMENTS ARRAY_LENGTH (hash_table_arrangements)
 
 struct _cairo_hash_table {
     cairo_hash_keys_equal_func_t keys_equal;
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 719067c..5c51aa2 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -286,7 +286,7 @@ _cairo_pattern_create_solid (const cairo
 
     if (solid_pattern_cache.size) {
 	int i = --solid_pattern_cache.size %
-	    ARRAY_LEN (solid_pattern_cache.patterns);
+	    ARRAY_LENGTH (solid_pattern_cache.patterns);
 	pattern = solid_pattern_cache.patterns[i];
 	solid_pattern_cache.patterns[i] = NULL;
     }
@@ -312,7 +312,7 @@ _cairo_pattern_reset_static_data (void)
 
     CAIRO_MUTEX_LOCK (_cairo_pattern_solid_cache_lock);
 
-    for (i = 0; i < MIN (ARRAY_LEN (solid_pattern_cache.patterns), solid_pattern_cache.size); i++) {
+    for (i = 0; i < MIN (ARRAY_LENGTH (solid_pattern_cache.patterns), solid_pattern_cache.size); i++) {
 	free (solid_pattern_cache.patterns[i]);
 	solid_pattern_cache.patterns[i] = NULL;
     }
@@ -632,7 +632,7 @@ cairo_pattern_destroy (cairo_pattern_t *
 	CAIRO_MUTEX_LOCK (_cairo_pattern_solid_cache_lock);
 
 	i = solid_pattern_cache.size++ %
-	    ARRAY_LEN (solid_pattern_cache.patterns);
+	    ARRAY_LENGTH (solid_pattern_cache.patterns);
 	/* swap an old pattern for this 'cache-hot' pattern */
 	if (solid_pattern_cache.patterns[i])
 	    free (solid_pattern_cache.patterns[i]);
@@ -725,7 +725,7 @@ _cairo_pattern_gradient_grow (cairo_grad
 {
     pixman_gradient_stop_t *new_stops;
     int old_size = pattern->stops_size;
-    int embedded_size = ARRAY_LEN (pattern->stops_embedded);
+    int embedded_size = ARRAY_LENGTH (pattern->stops_embedded);
     int new_size = 2 * MAX (old_size, 4);
 
     /* we have a local buffer at pattern->stops_embedded.  try to fulfill the request
diff --git a/src/cairo-polygon.c b/src/cairo-polygon.c
index c79eedc..1eb09ec 100644
--- a/src/cairo-polygon.c
+++ b/src/cairo-polygon.c
@@ -71,7 +71,7 @@ _cairo_polygon_grow (cairo_polygon_t *po
 {
     cairo_edge_t *new_edges;
     int old_size = polygon->edges_size;
-    int embedded_size = ARRAY_LEN (polygon->edges_embedded);
+    int embedded_size = ARRAY_LENGTH (polygon->edges_embedded);
     int new_size = 2 * MAX (old_size, 16);
 
     /* we have a local buffer at polygon->edges_embedded.  try to fulfill the request
diff --git a/src/cairo-spline.c b/src/cairo-spline.c
index b63ac57..bf87770 100644
--- a/src/cairo-spline.c
+++ b/src/cairo-spline.c
@@ -81,7 +81,7 @@ _cairo_spline_init (cairo_spline_t *spli
 	_cairo_slope_init (&spline->final_slope, &spline->a, &spline->d);
 
     spline->points = spline->points_embedded;
-    spline->points_size = ARRAY_LEN (spline->points_embedded);
+    spline->points_size = ARRAY_LENGTH (spline->points_embedded);
     spline->num_points = 0;
 
     return CAIRO_STATUS_SUCCESS;
@@ -94,7 +94,7 @@ _cairo_spline_fini (cairo_spline_t *spli
 	free (spline->points);
 
     spline->points = spline->points_embedded;
-    spline->points_size = ARRAY_LEN (spline->points_embedded);
+    spline->points_size = ARRAY_LENGTH (spline->points_embedded);
     spline->num_points = 0;
 }
 
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 93d4f46..e3d4c0e 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -1180,7 +1180,7 @@ _cairo_surface_fill_region (cairo_surfac
 	return CAIRO_STATUS_SUCCESS;
 
     rects = stack_rects;
-    if (num_rects > ARRAY_LEN (stack_rects)) {
+    if (num_rects > ARRAY_LENGTH (stack_rects)) {
 	rects = malloc (sizeof (cairo_rectangle_int16_t) * num_rects);
 	if (!rects)
 	    return CAIRO_STATUS_NO_MEMORY;
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 7d217a9..70dce46 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -59,7 +59,7 @@ static const cairo_svg_version_t _cairo_
     CAIRO_SVG_VERSION_1_2
 };
 
-#define CAIRO_SVG_VERSION_LAST ARRAY_LEN (_cairo_svg_versions)
+#define CAIRO_SVG_VERSION_LAST ARRAY_LENGTH (_cairo_svg_versions)
 
 static cairo_bool_t
 _cairo_svg_version_has_page_set_support (cairo_svg_version_t version)
diff --git a/src/cairo-traps.c b/src/cairo-traps.c
index 2fa4f66..2f34169 100644
--- a/src/cairo-traps.c
+++ b/src/cairo-traps.c
@@ -187,7 +187,7 @@ _cairo_traps_grow (cairo_traps_t *traps)
 {
     cairo_trapezoid_t *new_traps;
     int old_size = traps->traps_size;
-    int embedded_size = ARRAY_LEN (traps->traps_embedded);
+    int embedded_size = ARRAY_LENGTH (traps->traps_embedded);
     int new_size = 2 * MAX (old_size, 16);
 
     /* we have a local buffer at traps->traps_embedded.  try to fulfill the request
diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c
index 262912e..dd8357e 100644
--- a/src/cairo-truetype-subset.c
+++ b/src/cairo-truetype-subset.c
@@ -703,7 +703,7 @@ cairo_truetype_font_write_offset_table (
     unsigned short search_range, entry_selector, range_shift;
     int num_tables;
 
-    num_tables = ARRAY_LEN (truetype_tables);
+    num_tables = ARRAY_LENGTH (truetype_tables);
     search_range = 1;
     entry_selector = 0;
     while (search_range * 2 <= num_tables) {
@@ -722,7 +722,7 @@ cairo_truetype_font_write_offset_table (
     /* Allocate space for the table directory. Each directory entry
      * will be filled in by cairo_truetype_font_update_entry() after
      * the table is written. */
-    table_buffer_length = ARRAY_LEN (truetype_tables) * 16;
+    table_buffer_length = ARRAY_LENGTH (truetype_tables) * 16;
     status = cairo_truetype_font_allocate_write_buffer (font, table_buffer_length,
 						      &table_buffer);
     if (status)
@@ -785,7 +785,7 @@ cairo_truetype_font_generate (cairo_true
     end = start;
 
     end = 0;
-    for (i = 0; i < ARRAY_LEN (truetype_tables); i++) {
+    for (i = 0; i < ARRAY_LENGTH (truetype_tables); i++) {
 	if (truetype_tables[i].write (font, truetype_tables[i].tag))
 	    goto fail;
 
diff --git a/src/cairoint.h b/src/cairoint.h
index c537a00..fba0ab9 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -153,8 +153,8 @@ CAIRO_BEGIN_DECLS
 #define M_PI 3.14159265358979323846
 #endif
 
-#undef  ARRAY_LEN
-#define ARRAY_LEN(__array) ((int) (sizeof (__array) / sizeof (__array[0])))
+#undef  ARRAY_LENGTH
+#define ARRAY_LENGTH(__array) ((int) (sizeof (__array) / sizeof (__array[0])))
 
 /* Size in bytes of buffer to use off the stack per functions.
  * Mostly used by text functions.  For larger allocations, they'll
diff-tree d317e8175de04c73c4a1f84db4a7e5354411ca06 (from 9a33dab96988b94940a917921accc1bf19960a53)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Apr 9 17:38:17 2007 -0700

    Prefer FALSE over 0 for initializing a cairo_bool_t value

diff --git a/src/cairo.c b/src/cairo.c
index 9ba5241..97f264e 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -2164,7 +2164,7 @@ cairo_bool_t
 cairo_in_stroke (cairo_t *cr, double x, double y)
 {
     cairo_status_t status;
-    cairo_bool_t inside = 0;
+    cairo_bool_t inside = FALSE;
 
     if (cr->status)
 	return 0;
@@ -2197,7 +2197,7 @@ cairo_bool_t
 cairo_in_fill (cairo_t *cr, double x, double y)
 {
     cairo_status_t status;
-    cairo_bool_t inside = 0;
+    cairo_bool_t inside = FALSE;
 
     if (cr->status)
 	return 0;
diff-tree 9a33dab96988b94940a917921accc1bf19960a53 (from 4bfc8c98ccf29fc11d11ee35996be9aab5a63f36)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Apr 9 17:37:30 2007 -0700

    Fix an incorrectly indented condition

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 5b8d3ef..69199f8 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -2934,8 +2934,8 @@ _cairo_xlib_surface_show_glyphs (void   
                                                  0, 0, 1, 1,
                                                  (cairo_surface_t **) &src,
                                                  &attributes);
-    if (status)
-        goto BAIL0;
+	if (status)
+	    goto BAIL0;
     } else {
         cairo_rectangle_int16_t glyph_extents;
 
diff-tree 4bfc8c98ccf29fc11d11ee35996be9aab5a63f36 (from bd98295100ce84a9dfffd16bc6e50ef0ced4d4bc)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Apr 9 17:36:41 2007 -0700

    ATSUI: Fix broken error checks for NULL surface
    
    The cairo_image_surface_create function never returns NULL so
    the previous error checks would never have triggered. The correct
    approach is to check the result of cairo_surface_status().

diff --git a/src/cairo-atsui-font.c b/src/cairo-atsui-font.c
index b5b783c..79113d8 100644
--- a/src/cairo-atsui-font.c
+++ b/src/cairo-atsui-font.c
@@ -680,8 +680,9 @@ _cairo_atsui_scaled_font_init_glyph_surf
 
     if (theGlyph == kATSDeletedGlyphcode) {
 	surface = (cairo_image_surface_t *)cairo_image_surface_create (CAIRO_FORMAT_A8, 2, 2);
-	if (!surface)
-	    return CAIRO_STATUS_NO_MEMORY;
+	if (cairo_surface_status (surface))
+	    return cairo_surface_status (surface);
+
 	_cairo_scaled_glyph_set_surface (scaled_glyph,
 					 &base,
 					 surface);
@@ -746,8 +747,8 @@ _cairo_atsui_scaled_font_init_glyph_surf
 
     /* create the glyph mask surface */
     surface = (cairo_image_surface_t *)cairo_image_surface_create (format, bbox.size.width, bbox.size.height);
-    if (!surface)
-	return CAIRO_STATUS_NO_MEMORY;
+    if (cairo_surface_status (surface))
+	return cairo_surface_status (surface);
 
     /* Create a CGBitmapContext for the dest surface for drawing into */
     {
diff-tree bd98295100ce84a9dfffd16bc6e50ef0ced4d4bc (from a7d8e52cc4be2376429f567abc2be853da7d5fbc)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Apr 9 17:30:06 2007 -0700

    Add a couple of missing newline characters
    
    A return statement that's not at the end of a function really needs
    a line of whitespace after it.

diff --git a/src/cairo-bentley-ottmann.c b/src/cairo-bentley-ottmann.c
index 204b925..4c551f6 100644
--- a/src/cairo-bentley-ottmann.c
+++ b/src/cairo-bentley-ottmann.c
@@ -1275,6 +1275,7 @@ _cairo_bentley_ottmann_tessellate_bo_edg
     status = _cairo_bo_event_queue_init (&event_queue, edges, num_edges);
     if (status)
 	return status;
+
     _cairo_bo_sweep_line_init (&sweep_line);
     _cairo_bo_traps_init (&bo_traps, traps, xmin, ymin, xmax, ymax);
 
diff --git a/src/cairo-type1-fallback.c b/src/cairo-type1-fallback.c
index 3db3531..a8f88df 100644
--- a/src/cairo-type1-fallback.c
+++ b/src/cairo-type1-fallback.c
@@ -643,6 +643,7 @@ cairo_type1_font_write (cairo_type1_font
     status = cairo_type1_font_write_header (font, name);
     if (status)
 	return status;
+
     font->header_size = _cairo_output_stream_get_position (font->output);
 
     status = cairo_type1_font_write_private_dict (font, name);
diff-tree a7d8e52cc4be2376429f567abc2be853da7d5fbc (from 7c97696af98a6dab9e0c5cdc72ff08c19892c95f)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Apr 9 17:24:18 2007 -0700

    Cleanup multi-line if condition
    
    The standard idiom of assigning to a local status variable looks much,
    much nicer here.

diff --git a/src/cairo-path.c b/src/cairo-path.c
index 3add107..cf2dd4d 100644
--- a/src/cairo-path.c
+++ b/src/cairo-path.c
@@ -136,6 +136,7 @@ _cairo_path_count (cairo_path_t		*path,
 		   double		 tolerance,
 		   cairo_bool_t		 flatten)
 {
+    cairo_status_t status;
     cpc_t cpc;
 
     cpc.count = 0;
@@ -143,15 +144,16 @@ _cairo_path_count (cairo_path_t		*path,
     cpc.current_point.x = 0;
     cpc.current_point.y = 0;
 
-    if (_cairo_path_fixed_interpret (path_fixed,
-				     CAIRO_DIRECTION_FORWARD,
-				     _cpc_move_to,
-				     _cpc_line_to,
-				     flatten ?
-				     _cpc_curve_to_flatten :
-				     _cpc_curve_to,
-				     _cpc_close_path,
-				     &cpc) != CAIRO_STATUS_SUCCESS)
+    status = _cairo_path_fixed_interpret (path_fixed,
+					  CAIRO_DIRECTION_FORWARD,
+					  _cpc_move_to,
+					  _cpc_line_to,
+					  flatten ?
+					  _cpc_curve_to_flatten :
+					  _cpc_curve_to,
+					  _cpc_close_path,
+					  &cpc);
+    if (status)
 	return 0;
 
     return cpc.count;
diff-tree 7c97696af98a6dab9e0c5cdc72ff08c19892c95f (from 93776772edbadeab90ea199a115750310be91e4e)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Apr 9 17:16:30 2007 -0700

    Make _cairo_path_bounder_add_point void
    
    Yet another function that cannot fail under any circumstances.

diff --git a/src/cairo-path-bounds.c b/src/cairo-path-bounds.c
index 48b4393..5b60cf1 100644
--- a/src/cairo-path-bounds.c
+++ b/src/cairo-path-bounds.c
@@ -51,7 +51,7 @@ _cairo_path_bounder_init (cairo_path_bou
 static void
 _cairo_path_bounder_fini (cairo_path_bounder_t *bounder);
 
-static cairo_status_t
+static void
 _cairo_path_bounder_add_point (cairo_path_bounder_t *bounder, cairo_point_t *point);
 
 static cairo_status_t
@@ -81,7 +81,7 @@ _cairo_path_bounder_fini (cairo_path_bou
     bounder->has_point = 0;
 }
 
-static cairo_status_t
+static void
 _cairo_path_bounder_add_point (cairo_path_bounder_t *bounder, cairo_point_t *point)
 {
     if (bounder->has_point) {
@@ -104,8 +104,6 @@ _cairo_path_bounder_add_point (cairo_pat
 
 	bounder->has_point = 1;
     }
-
-    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
diff-tree 93776772edbadeab90ea199a115750310be91e4e (from d5b35d7d7666634f1f98d6c0141a2a29976e7e2f)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Apr 9 17:15:33 2007 -0700

    Make _cairo_matrix_compute_scale_factors void
    
    Yet another function that cannot fail under any circumstances.

diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c
index 75c27b2..40828f0 100644
--- a/src/cairo-matrix.c
+++ b/src/cairo-matrix.c
@@ -495,7 +495,7 @@ _cairo_matrix_compute_determinant (const
 }
 
 /* Compute the amount that each basis vector is scaled by. */
-cairo_status_t
+void
 _cairo_matrix_compute_scale_factors (const cairo_matrix_t *matrix,
 				     double *sx, double *sy, int x_major)
 {
@@ -535,8 +535,6 @@ _cairo_matrix_compute_scale_factors (con
 	    *sy = major;
 	}
     }
-
-    return CAIRO_STATUS_SUCCESS;
 }
 
 cairo_bool_t
diff --git a/src/cairoint.h b/src/cairoint.h
index 0042307..c537a00 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -2260,7 +2260,7 @@ _cairo_matrix_transform_bounding_box (co
 cairo_private void
 _cairo_matrix_compute_determinant (const cairo_matrix_t *matrix, double *det);
 
-cairo_private cairo_status_t
+cairo_private void
 _cairo_matrix_compute_scale_factors (const cairo_matrix_t *matrix,
 				     double *sx, double *sy, int x_major);
 
diff-tree d5b35d7d7666634f1f98d6c0141a2a29976e7e2f (from 9077da99abd163ebd0c52e8375e6f40ce60cf7d2)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Apr 9 17:12:11 2007 -0700

    Make _cairo_pen_init_empty void
    
    Yet another function that cannot fail under any circumstances.

diff --git a/src/cairo-pen.c b/src/cairo-pen.c
index 0d18782..c532019 100644
--- a/src/cairo-pen.c
+++ b/src/cairo-pen.c
@@ -45,15 +45,13 @@ _cairo_pen_compute_slopes (cairo_pen_t *
 static cairo_status_t
 _cairo_pen_stroke_spline_half (cairo_pen_t *pen, cairo_spline_t *spline, cairo_direction_t dir, cairo_polygon_t *polygon);
 
-cairo_status_t
+void
 _cairo_pen_init_empty (cairo_pen_t *pen)
 {
     pen->radius = 0;
     pen->tolerance = 0;
     pen->vertices = NULL;
     pen->num_vertices = 0;
-
-    return CAIRO_STATUS_SUCCESS;
 }
 
 cairo_status_t
diff --git a/src/cairoint.h b/src/cairoint.h
index d33a048..0042307 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -2176,7 +2176,7 @@ _cairo_pen_init (cairo_pen_t	*pen,
 		 double		 tolerance,
 		 cairo_matrix_t	*ctm);
 
-cairo_private cairo_status_t
+cairo_private void
 _cairo_pen_init_empty (cairo_pen_t *pen);
 
 cairo_private cairo_status_t
diff-tree 9077da99abd163ebd0c52e8375e6f40ce60cf7d2 (from 628ec8eb91fb246b8a44be3451163a5d8592a860)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Apr 9 17:09:51 2007 -0700

    Make _cairo_gstate_user_to_device (and friends) void.
    
    This is just multiplication after all, so there's nothing that can fail.
    And we can get rid of a lot of useless error-checking code this way.
    The corrected functions are:
    
    	_cairo_gstate_user_to_device
    	_cairo_gstate_user_to_device_distance
    	_cairo_gstate_device_to_user
    	_cairo_gstate_device_to_user_distance

diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index cc45145..6137373 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -690,38 +690,30 @@ _cairo_gstate_identity_matrix (cairo_gst
     cairo_matrix_init_identity (&gstate->ctm_inverse);
 }
 
-cairo_status_t
+void
 _cairo_gstate_user_to_device (cairo_gstate_t *gstate, double *x, double *y)
 {
     cairo_matrix_transform_point (&gstate->ctm, x, y);
-
-    return CAIRO_STATUS_SUCCESS;
 }
 
-cairo_status_t
+void
 _cairo_gstate_user_to_device_distance (cairo_gstate_t *gstate,
 				       double *dx, double *dy)
 {
     cairo_matrix_transform_distance (&gstate->ctm, dx, dy);
-
-    return CAIRO_STATUS_SUCCESS;
 }
 
-cairo_status_t
+void
 _cairo_gstate_device_to_user (cairo_gstate_t *gstate, double *x, double *y)
 {
     cairo_matrix_transform_point (&gstate->ctm_inverse, x, y);
-
-    return CAIRO_STATUS_SUCCESS;
 }
 
-cairo_status_t
+void
 _cairo_gstate_device_to_user_distance (cairo_gstate_t *gstate,
 				       double *dx, double *dy)
 {
     cairo_matrix_transform_distance (&gstate->ctm_inverse, dx, dy);
-
-    return CAIRO_STATUS_SUCCESS;
 }
 
 void
diff --git a/src/cairo.c b/src/cairo.c
index fedeaf0..9ba5241 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -1280,14 +1280,10 @@ cairo_identity_matrix (cairo_t *cr)
 void
 cairo_user_to_device (cairo_t *cr, double *x, double *y)
 {
-    cairo_status_t status;
-
     if (cr->status)
 	return;
 
-    status = _cairo_gstate_user_to_device (cr->gstate, x, y);
-    if (status)
-	_cairo_set_error (cr, status);
+    _cairo_gstate_user_to_device (cr->gstate, x, y);
 }
 
 /**
@@ -1304,14 +1300,10 @@ cairo_user_to_device (cairo_t *cr, doubl
 void
 cairo_user_to_device_distance (cairo_t *cr, double *dx, double *dy)
 {
-    cairo_status_t status;
-
     if (cr->status)
 	return;
 
-    status = _cairo_gstate_user_to_device_distance (cr->gstate, dx, dy);
-    if (status)
-	_cairo_set_error (cr, status);
+    _cairo_gstate_user_to_device_distance (cr->gstate, dx, dy);
 }
 
 /**
@@ -1327,14 +1319,10 @@ cairo_user_to_device_distance (cairo_t *
 void
 cairo_device_to_user (cairo_t *cr, double *x, double *y)
 {
-    cairo_status_t status;
-
     if (cr->status)
 	return;
 
-    status = _cairo_gstate_device_to_user (cr->gstate, x, y);
-    if (status)
-	_cairo_set_error (cr, status);
+    _cairo_gstate_device_to_user (cr->gstate, x, y);
 }
 
 /**
@@ -1351,14 +1339,10 @@ cairo_device_to_user (cairo_t *cr, doubl
 void
 cairo_device_to_user_distance (cairo_t *cr, double *dx, double *dy)
 {
-    cairo_status_t status;
-
     if (cr->status)
 	return;
 
-    status = _cairo_gstate_device_to_user_distance (cr->gstate, dx, dy);
-    if (status)
-	_cairo_set_error (cr, status);
+    _cairo_gstate_device_to_user_distance (cr->gstate, dx, dy);
 }
 
 /**
@@ -1678,13 +1662,12 @@ cairo_rel_move_to (cairo_t *cr, double d
     if (cr->status)
 	return;
 
-    status = _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy);
-    if (status == CAIRO_STATUS_SUCCESS) {
-	dx_fixed = _cairo_fixed_from_double (dx);
-	dy_fixed = _cairo_fixed_from_double (dy);
+    _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy);
 
-	status = _cairo_path_fixed_rel_move_to (cr->path, dx_fixed, dy_fixed);
-    }
+    dx_fixed = _cairo_fixed_from_double (dx);
+    dy_fixed = _cairo_fixed_from_double (dy);
+
+    status = _cairo_path_fixed_rel_move_to (cr->path, dx_fixed, dy_fixed);
     if (status)
 	_cairo_set_error (cr, status);
 }
@@ -1716,13 +1699,12 @@ cairo_rel_line_to (cairo_t *cr, double d
     if (cr->status)
 	return;
 
-    status = _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy);
-    if (status == CAIRO_STATUS_SUCCESS) {
-	dx_fixed = _cairo_fixed_from_double (dx);
-	dy_fixed = _cairo_fixed_from_double (dy);
+    _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy);
 
-	status = _cairo_path_fixed_rel_line_to (cr->path, dx_fixed, dy_fixed);
-    }
+    dx_fixed = _cairo_fixed_from_double (dx);
+    dy_fixed = _cairo_fixed_from_double (dy);
+
+    status = _cairo_path_fixed_rel_line_to (cr->path, dx_fixed, dy_fixed);
     if (status)
 	_cairo_set_error (cr, status);
 }
@@ -1768,15 +1750,9 @@ cairo_rel_curve_to (cairo_t *cr,
     if (cr->status)
 	return;
 
-    status = _cairo_gstate_user_to_device_distance (cr->gstate, &dx1, &dy1);
-    if (status)
-	goto BAIL;
-    status = _cairo_gstate_user_to_device_distance (cr->gstate, &dx2, &dy2);
-    if (status)
-	goto BAIL;
-    status = _cairo_gstate_user_to_device_distance (cr->gstate, &dx3, &dy3);
-    if (status)
-	goto BAIL;
+    _cairo_gstate_user_to_device_distance (cr->gstate, &dx1, &dy1);
+    _cairo_gstate_user_to_device_distance (cr->gstate, &dx2, &dy2);
+    _cairo_gstate_user_to_device_distance (cr->gstate, &dx3, &dy3);
 
     dx1_fixed = _cairo_fixed_from_double (dx1);
     dy1_fixed = _cairo_fixed_from_double (dy1);
@@ -1791,10 +1767,8 @@ cairo_rel_curve_to (cairo_t *cr,
 					     dx1_fixed, dy1_fixed,
 					     dx2_fixed, dy2_fixed,
 					     dx3_fixed, dy3_fixed);
-    if (status) {
-BAIL:
+    if (status)
 	_cairo_set_error (cr, status);
-    }
 }
 
 /**
diff --git a/src/cairoint.h b/src/cairoint.h
index 4f64f79..d33a048 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1347,16 +1347,16 @@ _cairo_gstate_set_matrix (cairo_gstate_t
 cairo_private void
 _cairo_gstate_identity_matrix (cairo_gstate_t *gstate);
 
-cairo_private cairo_status_t
+cairo_private void
 _cairo_gstate_user_to_device (cairo_gstate_t *gstate, double *x, double *y);
 
-cairo_private cairo_status_t
+cairo_private void
 _cairo_gstate_user_to_device_distance (cairo_gstate_t *gstate, double *dx, double *dy);
 
-cairo_private cairo_status_t
+cairo_private void
 _cairo_gstate_device_to_user (cairo_gstate_t *gstate, double *x, double *y);
 
-cairo_private cairo_status_t
+cairo_private void
 _cairo_gstate_device_to_user_distance (cairo_gstate_t *gstate, double *dx, double *dy);
 
 cairo_private void
diff-tree 628ec8eb91fb246b8a44be3451163a5d8592a860 (from 90803eca0fa8d49c54c465580707009aae382d28)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Apr 9 17:03:29 2007 -0700

    Make _cairo_gstate_identity_matrix void
    
    Now that we have the warn_unused_result attribute enabled, (thanks
    Chris!), it's actually harmful to have a function return an
    uncoditional value of CAIRO_STATUS_SUCCESS. The harm is that
    it would force lots of unnecessary error-checking paths that
    just add clutter.
    
    It is much better to simply give a function that cannot fail
    a return type of void.

diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 6a61987..cc45145 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -62,7 +62,6 @@ cairo_status_t
 _cairo_gstate_init (cairo_gstate_t  *gstate,
 		    cairo_surface_t *target)
 {
-    cairo_status_t status;
     gstate->next = NULL;
 
     gstate->op = CAIRO_GSTATE_OPERATOR_DEFAULT;
@@ -89,9 +88,7 @@ _cairo_gstate_init (cairo_gstate_t  *gst
     gstate->parent_target = NULL;
     gstate->original_target = cairo_surface_reference (target);
 
-    status = _cairo_gstate_identity_matrix (gstate);
-    if (status)
-	return status;
+    _cairo_gstate_identity_matrix (gstate);
     gstate->source_ctm_inverse = gstate->ctm_inverse;
 
     gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK);
@@ -684,15 +681,13 @@ _cairo_gstate_set_matrix (cairo_gstate_t
     return CAIRO_STATUS_SUCCESS;
 }
 
-cairo_status_t
+void
 _cairo_gstate_identity_matrix (cairo_gstate_t *gstate)
 {
     _cairo_gstate_unset_scaled_font (gstate);
 
     cairo_matrix_init_identity (&gstate->ctm);
     cairo_matrix_init_identity (&gstate->ctm_inverse);
-
-    return CAIRO_STATUS_SUCCESS;
 }
 
 cairo_status_t
diff --git a/src/cairo.c b/src/cairo.c
index 290e644..fedeaf0 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -1261,14 +1261,10 @@ cairo_set_matrix (cairo_t	       *cr,
 void
 cairo_identity_matrix (cairo_t *cr)
 {
-    cairo_status_t status;
-
     if (cr->status)
 	return;
 
-    status = _cairo_gstate_identity_matrix (cr->gstate);
-    if (status)
-	_cairo_set_error (cr, status);
+    _cairo_gstate_identity_matrix (cr->gstate);
 }
 
 /**
diff --git a/src/cairoint.h b/src/cairoint.h
index 5e62529..4f64f79 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1344,7 +1344,7 @@ cairo_private cairo_status_t
 _cairo_gstate_set_matrix (cairo_gstate_t       *gstate,
 			  const cairo_matrix_t *matrix);
 
-cairo_private cairo_status_t
+cairo_private void
 _cairo_gstate_identity_matrix (cairo_gstate_t *gstate);
 
 cairo_private cairo_status_t
diff-tree 90803eca0fa8d49c54c465580707009aae382d28 (from 4456ecbf2694f0b71a431353e0dea0515b72926b)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Apr 4 11:17:23 2007 +0100

    Implement clone_surface for test-fallback-surface.
    
    A few tests were failing due to clip_init_deep_copy() not being able to
    clone the target surface. Before propagating the failure, this was being
    silently ignored.
    
    Copy the simple implementation from cairo-image-surface.

diff --git a/src/test-fallback-surface.c b/src/test-fallback-surface.c
index 628373c..0b06dc1 100644
--- a/src/test-fallback-surface.c
+++ b/src/test-fallback-surface.c
@@ -169,6 +169,26 @@ _test_fallback_surface_release_dest_imag
 				       image_extra);
 }
 
+static cairo_status_t
+_test_fallback_surface_clone_similar (void		  *abstract_surface,
+				      cairo_surface_t     *src,
+				      int                  src_x,
+				      int                  src_y,
+				      int                  width,
+				      int                  height,
+				      cairo_surface_t    **clone_out)
+{
+    test_fallback_surface_t *surface = abstract_surface;
+
+    if (src->backend == surface->base.backend) {
+	*clone_out = cairo_surface_reference (src);
+
+	return CAIRO_STATUS_SUCCESS;
+    }
+
+    return CAIRO_INT_STATUS_UNSUPPORTED;
+}
+
 static cairo_int_status_t
 _test_fallback_surface_get_extents (void		            *abstract_surface,
 				    cairo_rectangle_int16_t *rectangle)
@@ -186,7 +206,7 @@ const cairo_surface_backend_t test_fallb
     _test_fallback_surface_release_source_image,
     _test_fallback_surface_acquire_dest_image,
     _test_fallback_surface_release_dest_image,
-    NULL, /* clone_similar */
+    _test_fallback_surface_clone_similar,
     NULL, /* composite */
     NULL, /* fill_rectangles */
     NULL, /* composite_trapezoids */
diff-tree 4456ecbf2694f0b71a431353e0dea0515b72926b (from cd2394c076e2f6b14a9a3281461026b811692f2e)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 23:40:31 2007 +0100

    Fix detection of FcFini().
    
    It is customary to check for a FontConfig function in the FontConfig
    library rather than the FreeType library.

diff --git a/configure.in b/configure.in
index be3a423..f267c22 100644
--- a/configure.in
+++ b/configure.in
@@ -436,7 +436,7 @@ FREETYPE_MIN_VERSION=8.0.2
 CAIRO_BACKEND_ENABLE(ft, FreeType font, freetype, FT_FONT, auto, [
   ft_REQUIRES="fontconfig"
   PKG_CHECK_MODULES(FONTCONFIG, $ft_REQUIRES,
-		    [_CHECK_FUNCS_WITH_FLAGS(FcFini, $ft_CFLAGS, $ft_LIBS)],
+		    [_CHECK_FUNCS_WITH_FLAGS(FcFini, [$FONTCONFIG_CFLAGS], [$FONTCONFIG_LIBS])],
 		    [AC_MSG_RESULT(no); use_ft="no (requires fontconfig"])
 
   if test "x$use_ft" = "xyes"; then
diff-tree cd2394c076e2f6b14a9a3281461026b811692f2e (from ac33953a81114dddc25ceb57f6df57e01d4d937b)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Apr 3 21:50:15 2007 +0100

    Free the bitmap->buffer on failure
    
    Currently if the ownership of the bitmap->buffer is passed to
    _get_bitmap_surface() then the status of the buffer is inconsistent
    should the function detect an error (i.e. CAIRO_STATUS_NO_MEMORY).
    Fix it up that should we encounter an error and we own the buffer then
    we always free it on behalf of the caller.

diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 0d14e98..2b43c0f 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -819,8 +819,11 @@ _get_bitmap_surface (FT_Bitmap		     *bi
 	    stride = bitmap->pitch;
 	    stride_rgba = (width_rgba * 4 + 3) & ~3;
 	    data_rgba = calloc (1, stride_rgba * height);
-	    if (data_rgba == NULL)
+	    if (data_rgba == NULL) {
+		if (own_buffer)
+		    free (bitmap->buffer);
 		return CAIRO_STATUS_NO_MEMORY;
+	    }
 
 	    os = 1;
 	    switch (font_options->subpixel_order) {
@@ -885,6 +888,8 @@ _get_bitmap_surface (FT_Bitmap		     *bi
     case FT_PIXEL_MODE_GRAY4:
 	/* These could be triggered by very rare types of TrueType fonts */
     default:
+	if (own_buffer)
+	    free (bitmap->buffer);
 	return CAIRO_STATUS_NO_MEMORY;
     }
 
diff-tree ac33953a81114dddc25ceb57f6df57e01d4d937b (from ce1651f1ea57b53ad91f5115524d33f6424d5797)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 23:37:29 2007 +0100

    Correct handling of a malloc failure during pattern_create_in_error()
    
    Confusion had been introduced as to who provided the fixup after
    the malloc failed which resulted in a NULL deference whilst checking for
    an erroneous pattern in _cairo_pattern_create_in_error.

diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 7d5da62..719067c 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -277,8 +277,8 @@ static struct {
     int size;
 } solid_pattern_cache;
 
-static cairo_pattern_t *
-_cairo_pattern_create_solid_from_cache (const cairo_color_t *color)
+cairo_pattern_t *
+_cairo_pattern_create_solid (const cairo_color_t *color)
 {
     cairo_solid_pattern_t *pattern = NULL;
 
@@ -299,22 +299,12 @@ _cairo_pattern_create_solid_from_cache (
     }
     if (pattern != NULL)
 	_cairo_pattern_init_solid (pattern, color);
+    else
+	pattern = (cairo_solid_pattern_t *) &_cairo_pattern_nil;
 
     return &pattern->base;
 }
 
-cairo_pattern_t *
-_cairo_pattern_create_solid (const cairo_color_t *color)
-{
-    cairo_pattern_t *pattern;
-
-    pattern = _cairo_pattern_create_solid_from_cache (color);
-    if (pattern == NULL)
-	return (cairo_pattern_t *) &_cairo_pattern_nil.base;
-
-    return pattern;
-}
-
 void
 _cairo_pattern_reset_static_data (void)
 {
@@ -336,10 +326,8 @@ _cairo_pattern_create_in_error (cairo_st
 {
     cairo_pattern_t *pattern;
 
-    pattern = _cairo_pattern_create_solid_from_cache (_cairo_stock_color (CAIRO_STOCK_BLACK));
-    if (cairo_pattern_status (pattern))
-	return pattern;
-
+    pattern = _cairo_pattern_create_solid (_cairo_stock_color (CAIRO_STOCK_BLACK));
+    /* no-op on a pattern already in error i.e the _cairo_pattern_nil */
     _cairo_pattern_set_error (pattern, status);
 
     return pattern;
diff-tree ce1651f1ea57b53ad91f5115524d33f6424d5797 (from bd99507f15dd8a2d162f13e691cc5f8d71795577)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Apr 3 16:53:17 2007 +0100

    Free the pixman_image if we fail to wrap it with a surface.

diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 3062533..ccfe4d9 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -241,6 +241,9 @@ _cairo_image_surface_create_with_masks (
 
     surface = _cairo_image_surface_create_for_pixman_image (pixman_image,
 							    cairo_format);
+    if (cairo_surface_status (surface)) {
+	pixman_image_destroy (pixman_image);
+    }
 
     return surface;
 }
@@ -315,6 +318,9 @@ cairo_image_surface_create (cairo_format
     }
 
     surface = _cairo_image_surface_create_for_pixman_image (pixman_image, format);
+    if (cairo_surface_status (surface)) {
+	pixman_image_destroy (pixman_image);
+    }
 
     return surface;
 }
@@ -395,6 +401,9 @@ cairo_image_surface_create_for_data (uns
     }
 
     surface = _cairo_image_surface_create_for_pixman_image (pixman_image, format);
+    if (cairo_surface_status (surface)) {
+	pixman_image_destroy (pixman_image);
+    }
 
     return surface;
 }
diff-tree bd99507f15dd8a2d162f13e691cc5f8d71795577 (from b2280c5ac25e752c4462acdc8d2ded916fce7c34)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Mar 30 14:00:50 2007 +0100

    Initialise cairo_spline_t to use its embedded buffer.
    
    Currently the code defaults to setting its points to NULL and fixing it up
    on the first add_point() to use the embedded buffer. Skip this extra step
    by initialising points to the embedded buffer.

diff --git a/src/cairo-spline.c b/src/cairo-spline.c
index 42151aa..b63ac57 100644
--- a/src/cairo-spline.c
+++ b/src/cairo-spline.c
@@ -80,9 +80,9 @@ _cairo_spline_init (cairo_spline_t *spli
     else
 	_cairo_slope_init (&spline->final_slope, &spline->a, &spline->d);
 
+    spline->points = spline->points_embedded;
+    spline->points_size = ARRAY_LEN (spline->points_embedded);
     spline->num_points = 0;
-    spline->points_size = 0;
-    spline->points = NULL;
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -90,11 +90,11 @@ _cairo_spline_init (cairo_spline_t *spli
 void
 _cairo_spline_fini (cairo_spline_t *spline)
 {
-    if (spline->points && spline->points != spline->points_embedded)
+    if (spline->points != spline->points_embedded)
 	free (spline->points);
 
-    spline->points = NULL;
-    spline->points_size = 0;
+    spline->points = spline->points_embedded;
+    spline->points_size = ARRAY_LEN (spline->points_embedded);
     spline->num_points = 0;
 }
 
@@ -104,17 +104,8 @@ _cairo_spline_grow (cairo_spline_t *spli
 {
     cairo_point_t *new_points;
     int old_size = spline->points_size;
-    int embedded_size = ARRAY_LEN (spline->points_embedded);
     int new_size = 2 * MAX (old_size, 16);
 
-    /* we have a local buffer at spline->points_embedded.  try to fulfill the request
-     * from there. */
-    if (old_size < embedded_size) {
-	spline->points = spline->points_embedded;
-	spline->points_size = embedded_size;
-	return CAIRO_STATUS_SUCCESS;
-    }
-
     assert (spline->num_points <= spline->points_size);
 
     if (spline->points == spline->points_embedded) {
@@ -284,9 +275,8 @@ _cairo_spline_decompose (cairo_spline_t 
 {
     cairo_status_t status;
 
-    if (spline->points_size) {
-	_cairo_spline_fini (spline);
-    }
+    /* reset the spline, but keep the buffer */
+    spline->num_points = 0;
 
     status = _cairo_spline_decompose_into (spline, tolerance * tolerance, spline);
     if (status)
diff-tree b2280c5ac25e752c4462acdc8d2ded916fce7c34 (from 14ac5dd78b38aaaa118e8ac39fa50f485bff516d)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Mar 30 11:24:18 2007 +0100

    Do not overwrite cr->status
    
    The idiom for cairo.c is to do
        cr->status = _cairo_op ();
        if (cr->status) _cairo_set_error (cr, cr->status);
    
    Unfortunately a trivial mistake for a _cairo_op () is to call a cairo_op ()
    and forget to check cr->status but return CAIRO_STATUS_SUCCESS which will
    mask the earlier error.
    
    Obviously this is a bug in the lower level but the impact can be reduced
    by chaning cairo.c to use a local status variable for its return:
        cairo_status_t status = _cairo_op ();
        if (status) _cairo_set_error (cr, cr->status);

diff --git a/src/cairo.c b/src/cairo.c
index c39d6e3..290e644 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -579,7 +579,7 @@ cairo_pop_group (cairo_t *cr)
 
     group_pattern = cairo_pattern_create_for_surface (group_surface);
     if (!group_pattern) {
-        cr->status = CAIRO_STATUS_NO_MEMORY;
+	_cairo_set_error (cr, CAIRO_STATUS_NO_MEMORY);
         goto done;
     }
 
@@ -646,12 +646,14 @@ slim_hidden_def(cairo_pop_group_to_sourc
 void
 cairo_set_operator (cairo_t *cr, cairo_operator_t op)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_set_operator (cr->gstate, op);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_set_operator (cr->gstate, op);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 slim_hidden_def (cairo_set_operator);
 
@@ -790,6 +792,8 @@ slim_hidden_def (cairo_set_source_surfac
 void
 cairo_set_source (cairo_t *cr, cairo_pattern_t *source)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
@@ -803,9 +807,9 @@ cairo_set_source (cairo_t *cr, cairo_pat
 	return;
     }
 
-    cr->status = _cairo_gstate_set_source (cr->gstate, source);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_set_source (cr->gstate, source);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 slim_hidden_def (cairo_set_source);
 
@@ -844,14 +848,16 @@ cairo_get_source (cairo_t *cr)
 void
 cairo_set_tolerance (cairo_t *cr, double tolerance)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
     _cairo_restrict_value (&tolerance, CAIRO_TOLERANCE_MINIMUM, tolerance);
 
-    cr->status = _cairo_gstate_set_tolerance (cr->gstate, tolerance);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_set_tolerance (cr->gstate, tolerance);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -870,12 +876,14 @@ cairo_set_tolerance (cairo_t *cr, double
 void
 cairo_set_antialias (cairo_t *cr, cairo_antialias_t antialias)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_set_antialias (cr->gstate, antialias);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_set_antialias (cr->gstate, antialias);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -892,12 +900,14 @@ cairo_set_antialias (cairo_t *cr, cairo_
 void
 cairo_set_fill_rule (cairo_t *cr, cairo_fill_rule_t fill_rule)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_set_fill_rule (cr->gstate, fill_rule);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_set_fill_rule (cr->gstate, fill_rule);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -929,14 +939,16 @@ cairo_set_fill_rule (cairo_t *cr, cairo_
 void
 cairo_set_line_width (cairo_t *cr, double width)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
     _cairo_restrict_value (&width, 0.0, width);
 
-    cr->status = _cairo_gstate_set_line_width (cr->gstate, width);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_set_line_width (cr->gstate, width);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -956,12 +968,14 @@ cairo_set_line_width (cairo_t *cr, doubl
 void
 cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_set_line_cap (cr->gstate, line_cap);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_set_line_cap (cr->gstate, line_cap);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -981,12 +995,14 @@ cairo_set_line_cap (cairo_t *cr, cairo_l
 void
 cairo_set_line_join (cairo_t *cr, cairo_line_join_t line_join)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_set_line_join (cr->gstate, line_join);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_set_line_join (cr->gstate, line_join);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -1027,13 +1043,15 @@ cairo_set_dash (cairo_t	     *cr,
 		int	      num_dashes,
 		double	      offset)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_set_dash (cr->gstate,
-					 dashes, num_dashes, offset);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_set_dash (cr->gstate,
+				     dashes, num_dashes, offset);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -1101,12 +1119,14 @@ cairo_get_dash (cairo_t *cr,
 void
 cairo_set_miter_limit (cairo_t *cr, double limit)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_set_miter_limit (cr->gstate, limit);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_set_miter_limit (cr->gstate, limit);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -1124,12 +1144,14 @@ cairo_set_miter_limit (cairo_t *cr, doub
 void
 cairo_translate (cairo_t *cr, double tx, double ty)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_translate (cr->gstate, tx, ty);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_translate (cr->gstate, tx, ty);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -1146,12 +1168,14 @@ cairo_translate (cairo_t *cr, double tx,
 void
 cairo_scale (cairo_t *cr, double sx, double sy)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_scale (cr->gstate, sx, sy);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_scale (cr->gstate, sx, sy);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 slim_hidden_def (cairo_scale);
 
@@ -1170,12 +1194,14 @@ slim_hidden_def (cairo_scale);
 void
 cairo_rotate (cairo_t *cr, double angle)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_rotate (cr->gstate, angle);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_rotate (cr->gstate, angle);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -1191,12 +1217,14 @@ void
 cairo_transform (cairo_t	      *cr,
 		 const cairo_matrix_t *matrix)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_transform (cr->gstate, matrix);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_transform (cr->gstate, matrix);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -1211,12 +1239,14 @@ void
 cairo_set_matrix (cairo_t	       *cr,
 		  const cairo_matrix_t *matrix)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_set_matrix (cr->gstate, matrix);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_set_matrix (cr->gstate, matrix);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -1231,12 +1261,14 @@ cairo_set_matrix (cairo_t	       *cr,
 void
 cairo_identity_matrix (cairo_t *cr)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_identity_matrix (cr->gstate);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_identity_matrix (cr->gstate);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -1252,12 +1284,14 @@ cairo_identity_matrix (cairo_t *cr)
 void
 cairo_user_to_device (cairo_t *cr, double *x, double *y)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_user_to_device (cr->gstate, x, y);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_user_to_device (cr->gstate, x, y);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -1274,12 +1308,14 @@ cairo_user_to_device (cairo_t *cr, doubl
 void
 cairo_user_to_device_distance (cairo_t *cr, double *dx, double *dy)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_user_to_device_distance (cr->gstate, dx, dy);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_user_to_device_distance (cr->gstate, dx, dy);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -1295,12 +1331,14 @@ cairo_user_to_device_distance (cairo_t *
 void
 cairo_device_to_user (cairo_t *cr, double *x, double *y)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_device_to_user (cr->gstate, x, y);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_device_to_user (cr->gstate, x, y);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -1317,12 +1355,14 @@ cairo_device_to_user (cairo_t *cr, doubl
 void
 cairo_device_to_user_distance (cairo_t *cr, double *dx, double *dy)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_device_to_user_distance (cr->gstate, dx, dy);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_device_to_user_distance (cr->gstate, dx, dy);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -1354,6 +1394,7 @@ slim_hidden_def(cairo_new_path);
 void
 cairo_move_to (cairo_t *cr, double x, double y)
 {
+    cairo_status_t status;
     cairo_fixed_t x_fixed, y_fixed;
 
     if (cr->status)
@@ -1363,9 +1404,9 @@ cairo_move_to (cairo_t *cr, double x, do
     x_fixed = _cairo_fixed_from_double (x);
     y_fixed = _cairo_fixed_from_double (y);
 
-    cr->status = _cairo_path_fixed_move_to (cr->path, x_fixed, y_fixed);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_path_fixed_move_to (cr->path, x_fixed, y_fixed);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 slim_hidden_def(cairo_move_to);
 
@@ -1412,6 +1453,7 @@ cairo_new_sub_path (cairo_t *cr)
 void
 cairo_line_to (cairo_t *cr, double x, double y)
 {
+    cairo_status_t status;
     cairo_fixed_t x_fixed, y_fixed;
 
     if (cr->status)
@@ -1421,9 +1463,9 @@ cairo_line_to (cairo_t *cr, double x, do
     x_fixed = _cairo_fixed_from_double (x);
     y_fixed = _cairo_fixed_from_double (y);
 
-    cr->status = _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 slim_hidden_def (cairo_line_to);
 
@@ -1452,6 +1494,7 @@ cairo_curve_to (cairo_t *cr,
 		double x2, double y2,
 		double x3, double y3)
 {
+    cairo_status_t status;
     cairo_fixed_t x1_fixed, y1_fixed;
     cairo_fixed_t x2_fixed, y2_fixed;
     cairo_fixed_t x3_fixed, y3_fixed;
@@ -1472,12 +1515,12 @@ cairo_curve_to (cairo_t *cr,
     x3_fixed = _cairo_fixed_from_double (x3);
     y3_fixed = _cairo_fixed_from_double (y3);
 
-    cr->status = _cairo_path_fixed_curve_to (cr->path,
-					     x1_fixed, y1_fixed,
-					     x2_fixed, y2_fixed,
-					     x3_fixed, y3_fixed);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_path_fixed_curve_to (cr->path,
+					 x1_fixed, y1_fixed,
+					 x2_fixed, y2_fixed,
+					 x3_fixed, y3_fixed);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 slim_hidden_def (cairo_curve_to);
 
@@ -1600,13 +1643,17 @@ cairo_arc_to (cairo_t *cr,
 	      double x2, double y2,
 	      double radius)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_arc_to (cr->gstate,
-				       x1, y1,
-				       x2, y2,
-				       radius);
+    status = _cairo_gstate_arc_to (cr->gstate,
+				   x1, y1,
+				   x2, y2,
+				   radius);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 */
 
@@ -1793,12 +1840,14 @@ cairo_rectangle (cairo_t *cr,
 void
 cairo_stroke_to_path (cairo_t *cr)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_stroke_path (cr->gstate);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_stroke_path (cr->gstate);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 */
 
@@ -1831,12 +1880,14 @@ cairo_stroke_to_path (cairo_t *cr)
 void
 cairo_close_path (cairo_t *cr)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_path_fixed_close_path (cr->path);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_path_fixed_close_path (cr->path);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 slim_hidden_def(cairo_close_path);
 
@@ -1850,12 +1901,14 @@ slim_hidden_def(cairo_close_path);
 void
 cairo_paint (cairo_t *cr)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_paint (cr->gstate);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_paint (cr->gstate);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 slim_hidden_def (cairo_paint);
 
@@ -1873,6 +1926,7 @@ void
 cairo_paint_with_alpha (cairo_t *cr,
 			double   alpha)
 {
+    cairo_status_t status;
     cairo_color_t color;
     cairo_pattern_union_t pattern;
 
@@ -1891,9 +1945,9 @@ cairo_paint_with_alpha (cairo_t *cr,
     _cairo_color_init_rgba (&color, 1., 1., 1., alpha);
     _cairo_pattern_init_solid (&pattern.solid, &color);
 
-    cr->status = _cairo_gstate_mask (cr->gstate, &pattern.base);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_mask (cr->gstate, &pattern.base);
+    if (status)
+	_cairo_set_error (cr, status);
 
     _cairo_pattern_fini (&pattern.base);
 }
@@ -1912,6 +1966,8 @@ void
 cairo_mask (cairo_t         *cr,
 	    cairo_pattern_t *pattern)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
@@ -1925,9 +1981,9 @@ cairo_mask (cairo_t         *cr,
 	return;
     }
 
-    cr->status = _cairo_gstate_mask (cr->gstate, pattern);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_mask (cr->gstate, pattern);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 slim_hidden_def (cairo_mask);
 
@@ -2021,12 +2077,14 @@ cairo_stroke (cairo_t *cr)
 void
 cairo_stroke_preserve (cairo_t *cr)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_stroke (cr->gstate, cr->path);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_stroke (cr->gstate, cr->path);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 slim_hidden_def(cairo_stroke_preserve);
 
@@ -2062,12 +2120,14 @@ cairo_fill (cairo_t *cr)
 void
 cairo_fill_preserve (cairo_t *cr)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_fill (cr->gstate, cr->path);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_fill (cr->gstate, cr->path);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 slim_hidden_def(cairo_fill_preserve);
 
@@ -2083,12 +2143,14 @@ slim_hidden_def(cairo_fill_preserve);
 void
 cairo_copy_page (cairo_t *cr)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_copy_page (cr->gstate);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_copy_page (cr->gstate);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -2101,12 +2163,14 @@ cairo_copy_page (cairo_t *cr)
 void
 cairo_show_page (cairo_t *cr)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_show_page (cr->gstate);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_show_page (cr->gstate);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -2129,16 +2193,17 @@ cairo_show_page (cairo_t *cr)
 cairo_bool_t
 cairo_in_stroke (cairo_t *cr, double x, double y)
 {
-    cairo_bool_t inside;
+    cairo_status_t status;
+    cairo_bool_t inside = 0;
 
     if (cr->status)
 	return 0;
 
-    cr->status = _cairo_gstate_in_stroke (cr->gstate,
-					  cr->path,
-					  x, y, &inside);
-    if (cr->status)
-	return 0;
+    status = _cairo_gstate_in_stroke (cr->gstate,
+				      cr->path,
+				      x, y, &inside);
+    if (status)
+	_cairo_set_error (cr, status);
 
     return inside;
 }
@@ -2161,18 +2226,17 @@ cairo_in_stroke (cairo_t *cr, double x, 
 cairo_bool_t
 cairo_in_fill (cairo_t *cr, double x, double y)
 {
-    cairo_bool_t inside;
+    cairo_status_t status;
+    cairo_bool_t inside = 0;
 
     if (cr->status)
 	return 0;
 
-    cr->status = _cairo_gstate_in_fill (cr->gstate,
-					cr->path,
-					x, y, &inside);
-    if (cr->status) {
-	_cairo_set_error (cr, cr->status);
-	return 0;
-    }
+    status = _cairo_gstate_in_fill (cr->gstate,
+				    cr->path,
+				    x, y, &inside);
+    if (status)
+	_cairo_set_error (cr, status);
 
     return inside;
 }
@@ -2199,14 +2263,16 @@ void
 cairo_stroke_extents (cairo_t *cr,
                       double *x1, double *y1, double *x2, double *y2)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_stroke_extents (cr->gstate,
-					       cr->path,
-					       x1, y1, x2, y2);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_stroke_extents (cr->gstate,
+					   cr->path,
+					   x1, y1, x2, y2);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -2229,14 +2295,16 @@ void
 cairo_fill_extents (cairo_t *cr,
                     double *x1, double *y1, double *x2, double *y2)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_fill_extents (cr->gstate,
-					     cr->path,
-					     x1, y1, x2, y2);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_fill_extents (cr->gstate,
+					 cr->path,
+					 x1, y1, x2, y2);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -2294,12 +2362,14 @@ cairo_clip (cairo_t *cr)
 void
 cairo_clip_preserve (cairo_t *cr)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_clip (cr->gstate, cr->path);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_clip (cr->gstate, cr->path);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 slim_hidden_def(cairo_clip_preserve);
 
@@ -2322,12 +2392,14 @@ slim_hidden_def(cairo_clip_preserve);
 void
 cairo_reset_clip (cairo_t *cr)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_reset_clip (cr->gstate);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_reset_clip (cr->gstate);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -2348,12 +2420,14 @@ cairo_clip_extents (cairo_t *cr,
 		    double *x1, double *y1,
 		    double *x2, double *y2)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_clip_extents (cr->gstate, x1, y1, x2, y2);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_clip_extents (cr->gstate, x1, y1, x2, y2);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 static cairo_rectangle_list_t *
@@ -2419,12 +2493,14 @@ cairo_select_font_face (cairo_t         
 			cairo_font_slant_t    slant,
 			cairo_font_weight_t   weight)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_select_font_face (cr->gstate, family, slant, weight);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_select_font_face (cr->gstate, family, slant, weight);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -2439,12 +2515,14 @@ void
 cairo_font_extents (cairo_t              *cr,
 		    cairo_font_extents_t *extents)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_get_font_extents (cr->gstate, extents);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_get_font_extents (cr->gstate, extents);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -2460,12 +2538,14 @@ void
 cairo_set_font_face (cairo_t           *cr,
 		     cairo_font_face_t *font_face)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_set_font_face (cr->gstate, font_face);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_set_font_face (cr->gstate, font_face);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -2489,14 +2569,15 @@ cairo_set_font_face (cairo_t           *
 cairo_font_face_t *
 cairo_get_font_face (cairo_t *cr)
 {
+    cairo_status_t status;
     cairo_font_face_t *font_face;
 
     if (cr->status)
 	return (cairo_font_face_t*) &_cairo_font_face_nil;
 
-    cr->status = _cairo_gstate_get_font_face (cr->gstate, &font_face);
-    if (cr->status) {
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_get_font_face (cr->gstate, &font_face);
+    if (status) {
+	_cairo_set_error (cr, status);
 	return (cairo_font_face_t*) &_cairo_font_face_nil;
     }
 
@@ -2517,12 +2598,14 @@ cairo_get_font_face (cairo_t *cr)
 void
 cairo_set_font_size (cairo_t *cr, double size)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_set_font_size (cr->gstate, size);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_set_font_size (cr->gstate, size);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -2542,12 +2625,14 @@ void
 cairo_set_font_matrix (cairo_t		    *cr,
 		       const cairo_matrix_t *matrix)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_set_font_matrix (cr->gstate, matrix);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_set_font_matrix (cr->gstate, matrix);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -2579,12 +2664,14 @@ void
 cairo_set_font_options (cairo_t                    *cr,
 			const cairo_font_options_t *options)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_set_font_options (cr->gstate, options);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_set_font_options (cr->gstate, options);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -2622,29 +2709,31 @@ void
 cairo_set_scaled_font (cairo_t                   *cr,
 		       const cairo_scaled_font_t *scaled_font)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = scaled_font->status;
-    if (cr->status)
+    status = scaled_font->status;
+    if (status)
         goto BAIL;
 
-    cr->status = _cairo_gstate_set_font_face (cr->gstate, scaled_font->font_face);
-    if (cr->status)
+    status = _cairo_gstate_set_font_face (cr->gstate, scaled_font->font_face);
+    if (status)
         goto BAIL;
 
-    cr->status = _cairo_gstate_set_font_matrix (cr->gstate, &scaled_font->font_matrix);
-    if (cr->status)
+    status = _cairo_gstate_set_font_matrix (cr->gstate, &scaled_font->font_matrix);
+    if (status)
         goto BAIL;
 
-    cr->status = _cairo_gstate_set_font_options (cr->gstate, &scaled_font->options);
-    if (cr->status)
+    status = _cairo_gstate_set_font_options (cr->gstate, &scaled_font->options);
+    if (status)
         goto BAIL;
 
     return;
 
 BAIL:
-    _cairo_set_error (cr, cr->status);
+    _cairo_set_error (cr, status);
 }
 
 /**
@@ -2670,14 +2759,15 @@ BAIL:
 cairo_scaled_font_t *
 cairo_get_scaled_font (cairo_t *cr)
 {
+    cairo_status_t status;
     cairo_scaled_font_t *scaled_font;
 
     if (cr->status)
 	return (cairo_scaled_font_t *)&_cairo_scaled_font_nil;
 
-    cr->status = _cairo_gstate_get_scaled_font (cr->gstate, &scaled_font);
-    if (cr->status) {
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_get_scaled_font (cr->gstate, &scaled_font);
+    if (status) {
+	_cairo_set_error (cr, status);
 	return (cairo_scaled_font_t *)&_cairo_scaled_font_nil;
     }
 
@@ -2709,6 +2799,7 @@ cairo_text_extents (cairo_t             
 		    const char		 *utf8,
 		    cairo_text_extents_t *extents)
 {
+    cairo_status_t status;
     cairo_glyph_t *glyphs = NULL;
     int num_glyphs;
     double x, y;
@@ -2728,23 +2819,23 @@ cairo_text_extents (cairo_t             
 
     cairo_get_current_point (cr, &x, &y);
 
-    cr->status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8,
-					       x, y,
-					       &glyphs, &num_glyphs);
+    status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8,
+					   x, y,
+					   &glyphs, &num_glyphs);
 
-    if (cr->status) {
+    if (status) {
 	if (glyphs)
 	    free (glyphs);
-	_cairo_set_error (cr, cr->status);
+	_cairo_set_error (cr, status);
 	return;
     }
 
-    cr->status = _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs, extents);
+    status = _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs, extents);
     if (glyphs)
 	free (glyphs);
 
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -2771,13 +2862,15 @@ cairo_glyph_extents (cairo_t            
 		     int                    num_glyphs,
 		     cairo_text_extents_t   *extents)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs,
-					      extents);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs,
+					  extents);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -2811,6 +2904,7 @@ void
 cairo_show_text (cairo_t *cr, const char *utf8)
 {
     cairo_text_extents_t extents;
+    cairo_status_t status;
     cairo_glyph_t *glyphs = NULL, *last_glyph;
     int num_glyphs;
     double x, y;
@@ -2823,24 +2917,24 @@ cairo_show_text (cairo_t *cr, const char
 
     cairo_get_current_point (cr, &x, &y);
 
-    cr->status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8,
+    status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8,
 					       x, y,
 					       &glyphs, &num_glyphs);
-    if (cr->status)
+    if (status)
 	goto BAIL;
 
     if (num_glyphs == 0)
 	return;
 
-    cr->status = _cairo_gstate_show_glyphs (cr->gstate, glyphs, num_glyphs);
-    if (cr->status)
+    status = _cairo_gstate_show_glyphs (cr->gstate, glyphs, num_glyphs);
+    if (status)
 	goto BAIL;
 
     last_glyph = &glyphs[num_glyphs - 1];
-    cr->status = _cairo_gstate_glyph_extents (cr->gstate,
-					      last_glyph, 1,
-					      &extents);
-    if (cr->status)
+    status = _cairo_gstate_glyph_extents (cr->gstate,
+					  last_glyph, 1,
+					  &extents);
+    if (status)
 	goto BAIL;
 
     x = last_glyph->x + extents.x_advance;
@@ -2851,8 +2945,8 @@ cairo_show_text (cairo_t *cr, const char
     if (glyphs)
 	free (glyphs);
 
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -2868,15 +2962,17 @@ cairo_show_text (cairo_t *cr, const char
 void
 cairo_show_glyphs (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
     if (num_glyphs == 0)
 	return;
 
-    cr->status = _cairo_gstate_show_glyphs (cr->gstate, glyphs, num_glyphs);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_show_glyphs (cr->gstate, glyphs, num_glyphs);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -2906,6 +3002,7 @@ cairo_show_glyphs (cairo_t *cr, const ca
 void
 cairo_text_path  (cairo_t *cr, const char *utf8)
 {
+    cairo_status_t status;
     cairo_text_extents_t extents;
     cairo_glyph_t *glyphs = NULL, *last_glyph;
     int num_glyphs;
@@ -2916,29 +3013,29 @@ cairo_text_path  (cairo_t *cr, const cha
 
     cairo_get_current_point (cr, &x, &y);
 
-    cr->status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8,
-					       x, y,
-					       &glyphs, &num_glyphs);
+    status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8,
+					   x, y,
+					   &glyphs, &num_glyphs);
 
-    if (cr->status)
+    if (status)
 	goto BAIL;
 
     if (num_glyphs == 0)
 	return;
 
-    cr->status = _cairo_gstate_glyph_path (cr->gstate,
-					   glyphs, num_glyphs,
-					   cr->path);
+    status = _cairo_gstate_glyph_path (cr->gstate,
+				       glyphs, num_glyphs,
+				       cr->path);
 
-    if (cr->status)
+    if (status)
 	goto BAIL;
 
     last_glyph = &glyphs[num_glyphs - 1];
-    cr->status = _cairo_gstate_glyph_extents (cr->gstate,
-					      last_glyph, 1,
-					      &extents);
+    status = _cairo_gstate_glyph_extents (cr->gstate,
+					  last_glyph, 1,
+					  &extents);
 
-    if (cr->status)
+    if (status)
 	goto BAIL;
 
     x = last_glyph->x + extents.x_advance;
@@ -2949,8 +3046,8 @@ cairo_text_path  (cairo_t *cr, const cha
     if (glyphs)
 	free (glyphs);
 
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -2966,14 +3063,16 @@ cairo_text_path  (cairo_t *cr, const cha
 void
 cairo_glyph_path (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
-    cr->status = _cairo_gstate_glyph_path (cr->gstate,
-					   glyphs, num_glyphs,
-					   cr->path);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_gstate_glyph_path (cr->gstate,
+				       glyphs, num_glyphs,
+				       cr->path);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -3300,6 +3399,8 @@ void
 cairo_append_path (cairo_t		*cr,
 		   const cairo_path_t	*path)
 {
+    cairo_status_t status;
+
     if (cr->status)
 	return;
 
@@ -3322,9 +3423,9 @@ cairo_append_path (cairo_t		*cr,
 	return;
     }
 
-    cr->status = _cairo_path_append_to_context (path, cr);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_path_append_to_context (path, cr);
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
diff-tree 14ac5dd78b38aaaa118e8ac39fa50f485bff516d (from b823e2f68ff613b2c4f537aba6bbbcf413412eb2)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 23:11:57 2007 +0100

    Return the correct status from _cairo_pen_stroke_spline().
    
    The return value is shared before the normal cleanup and error paths,
    so do not simply return a hard-coded CAIRO_STATUS_SUCCESS.

diff --git a/src/cairo-pen.c b/src/cairo-pen.c
index 1bc096b..0d18782 100644
--- a/src/cairo-pen.c
+++ b/src/cairo-pen.c
@@ -461,5 +461,5 @@ _cairo_pen_stroke_spline (cairo_pen_t		*
 BAIL:
     _cairo_polygon_fini (&polygon);
 
-    return CAIRO_STATUS_SUCCESS;
+    return status;
 }
diff-tree b823e2f68ff613b2c4f537aba6bbbcf413412eb2 (from 4a624b8e8b0a14dd03e551b28257d8a54b9ee6f6)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 23:09:31 2007 +0100

    cairo-xlib-surface - propagate status returns.
    
    These were found during a cairo_static pass on an alternative branch...
    
    A critical one in particular was setting the have added glyph flag to
    TRUE even if _cairo_xlib_surface_add_glyph() fails. This can cause an
    application crash due to a RenderBadGlyph error later when the scaled
    font is cleaned and we attempt to remove the glyph.

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 5c25c06..5b8d3ef 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -889,6 +889,7 @@ _cairo_xlib_surface_clone_similar (void	
 {
     cairo_xlib_surface_t *surface = abstract_surface;
     cairo_xlib_surface_t *clone;
+    cairo_status_t status;
 
     if (src->backend == surface->base.backend ) {
 	cairo_xlib_surface_t *xlib_src = (cairo_xlib_surface_t *)src;
@@ -910,8 +911,12 @@ _cairo_xlib_surface_clone_similar (void	
 	if (clone->base.status)
 	    return CAIRO_STATUS_NO_MEMORY;
 
-	_draw_image_surface (clone, image_src, src_x, src_y,
-			     width, height, src_x, src_y);
+	status = _draw_image_surface (clone, image_src, src_x, src_y,
+			              width, height, src_x, src_y);
+	if (status) {
+	    cairo_surface_destroy (&clone->base);
+	    return status;
+	}
 
 	*clone_out = &clone->base;
 
@@ -1042,15 +1047,17 @@ _cairo_xlib_surface_set_attributes (cair
 
     switch (attributes->extend) {
     case CAIRO_EXTEND_NONE:
-	_cairo_xlib_surface_set_repeat (surface, 0);
+	status = _cairo_xlib_surface_set_repeat (surface, 0);
 	break;
     case CAIRO_EXTEND_REPEAT:
-	_cairo_xlib_surface_set_repeat (surface, 1);
+	status = _cairo_xlib_surface_set_repeat (surface, 1);
 	break;
     case CAIRO_EXTEND_REFLECT:
     case CAIRO_EXTEND_PAD:
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+	status = CAIRO_INT_STATUS_UNSUPPORTED;
     }
+    if (status)
+	return status;
 
     status = _cairo_xlib_surface_set_filter (surface, attributes->filter);
     if (status)
@@ -2318,14 +2325,17 @@ _cairo_xlib_surface_font_init (Display		
 {
     cairo_xlib_surface_font_private_t	*font_private;
 
+    font_private = malloc (sizeof (cairo_xlib_surface_font_private_t));
+    if (!font_private)
+	return CAIRO_STATUS_NO_MEMORY;
+
     if (!_cairo_xlib_add_close_display_hook (dpy,
 		_cairo_xlib_surface_remove_scaled_font,
-		scaled_font, scaled_font))
+		scaled_font, scaled_font)) {
+	free (font_private);
 	return CAIRO_STATUS_NO_MEMORY;
+    }
 
-    font_private = malloc (sizeof (cairo_xlib_surface_font_private_t));
-    if (!font_private)
-	return CAIRO_STATUS_NO_MEMORY;
 
     font_private->dpy = dpy;
     font_private->format = format;
@@ -2815,7 +2825,11 @@ _cairo_xlib_surface_emit_glyphs (cairo_x
 
 	/* Send unsent glyphs to the server */
 	if (scaled_glyph->surface_private == NULL) {
-	    _cairo_xlib_surface_add_glyph (dst->dpy, scaled_font, scaled_glyph);
+	    status = _cairo_xlib_surface_add_glyph (dst->dpy,
+		                                    scaled_font,
+						    scaled_glyph);
+	    if (status)
+		return status;
 	    scaled_glyph->surface_private = (void *) 1;
 	}
 
@@ -2951,9 +2965,13 @@ _cairo_xlib_surface_show_glyphs (void   
     if (status)
         goto BAIL1;
 
-    _cairo_xlib_surface_emit_glyphs (dst,
-	                             (cairo_xlib_glyph_t *) glyphs, num_glyphs,
-				     scaled_font, op, src, &attributes);
+    status = _cairo_xlib_surface_emit_glyphs (dst,
+	                                      (cairo_xlib_glyph_t *) glyphs,
+					      num_glyphs,
+					      scaled_font,
+					      op,
+					      src,
+					      &attributes);
 
   BAIL1:
     if (src)
diff-tree 4a624b8e8b0a14dd03e551b28257d8a54b9ee6f6 (from 1cdb54f8835446b23769b7771445201a9b5d165e)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Mar 29 13:36:07 2007 +0100

    Remove the entry if we return an error code during _cair_hash_table_insert.
    
    Previously if we detected an error during resize we would report a
    failure to insert the entry into the hash table having already done so.

diff --git a/src/cairo-hash.c b/src/cairo-hash.c
index 31de811..b55e7fb 100644
--- a/src/cairo-hash.c
+++ b/src/cairo-hash.c
@@ -481,8 +481,12 @@ _cairo_hash_table_insert (cairo_hash_tab
     hash_table->live_entries++;
 
     status = _cairo_hash_table_resize (hash_table);
-    if (status)
+    if (status) {
+	/* abort the insert... */
+	*entry = DEAD_ENTRY;
+	hash_table->live_entries--;
 	return status;
+    }
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -561,6 +565,9 @@ _cairo_hash_table_foreach (cairo_hash_ta
      * the table may need resizing. Just do this every time
      * as the check is inexpensive.
      */
-    if (--hash_table->iterating == 0)
+    if (--hash_table->iterating == 0) {
+	/* Should we fail to shrink the hash table, it is left unaltered,
+	 * and we don't need to propagate the error status. */
 	_cairo_hash_table_resize (hash_table);
+    }
 }
diff-tree 1cdb54f8835446b23769b7771445201a9b5d165e (from a1331fb043051ac10f8555b2ad2fe85183db96df)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Mar 29 09:11:21 2007 +0100

    Reorder cleanup cairo_xlib_surface_show_glyphs()
    
    _cairo_pattern_release_surface() asserts that it is passed a pattern
    surface. This itself is bad as breaks the symmetry with
    _cairo_pattern_acquire_surface under() error conditions, however reorder
    the cleanup to avoid this assertion.

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 5914c37..5c25c06 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -2920,6 +2920,8 @@ _cairo_xlib_surface_show_glyphs (void   
                                                  0, 0, 1, 1,
                                                  (cairo_surface_t **) &src,
                                                  &attributes);
+    if (status)
+        goto BAIL0;
     } else {
         cairo_rectangle_int16_t glyph_extents;
 
@@ -2928,38 +2930,38 @@ _cairo_xlib_surface_show_glyphs (void   
                                                           num_glyphs,
                                                           &glyph_extents);
         if (status)
-	    goto BAIL;
+	    goto BAIL0;
 
         status = _cairo_pattern_acquire_surface (src_pattern, &dst->base,
                                                  glyph_extents.x, glyph_extents.y,
                                                  glyph_extents.width, glyph_extents.height,
                                                  (cairo_surface_t **) &src,
                                                  &attributes);
+        if (status)
+	    goto BAIL0;
     }
 
-    if (status)
-        goto BAIL;
-
     operation = _recategorize_composite_operation (dst, op, src, &attributes, TRUE);
     if (operation == DO_UNSUPPORTED) {
 	status = CAIRO_INT_STATUS_UNSUPPORTED;
-	goto BAIL;
+	goto BAIL1;
     }
 
     status = _cairo_xlib_surface_set_attributes (src, &attributes);
     if (status)
-        goto BAIL;
+        goto BAIL1;
 
-    _cairo_xlib_surface_emit_glyphs (dst, (cairo_xlib_glyph_t *) glyphs, num_glyphs,
+    _cairo_xlib_surface_emit_glyphs (dst,
+	                             (cairo_xlib_glyph_t *) glyphs, num_glyphs,
 				     scaled_font, op, src, &attributes);
 
-  BAIL:
-    _cairo_scaled_font_thaw_cache (scaled_font);
-
+  BAIL1:
     if (src)
         _cairo_pattern_release_surface (src_pattern, &src->base, &attributes);
     if (src_pattern == &solid_pattern.base)
 	_cairo_pattern_fini (&solid_pattern.base);
+  BAIL0:
+    _cairo_scaled_font_thaw_cache (scaled_font);
 
     return status;
 }
diff-tree a1331fb043051ac10f8555b2ad2fe85183db96df (from 1237eedff3d557b94db9c940fd8de48be9ba41ba)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Mar 28 19:32:25 2007 +0100

    Detect failure to allocate glyphs during _cairo_scaled_font_init()
    
    If _cairo_cache_create fails, return CAIRO_STATUS_NO_MEMORY.

diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index abf475e..4b976c5 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -351,6 +351,12 @@ _cairo_scaled_font_init (cairo_scaled_fo
 			 const cairo_font_options_t	   *options,
 			 const cairo_scaled_font_backend_t *backend)
 {
+    scaled_font->glyphs = _cairo_cache_create (_cairo_scaled_glyph_keys_equal,
+					       _cairo_scaled_glyph_destroy,
+					       max_glyphs_cached_per_font);
+    if (scaled_font->glyphs == NULL)
+	return CAIRO_STATUS_NO_MEMORY;
+
     scaled_font->ref_count = 1;
 
     _cairo_user_data_array_init (&scaled_font->user_data);
@@ -365,9 +371,6 @@ _cairo_scaled_font_init (cairo_scaled_fo
 			   &scaled_font->ctm);
 
     CAIRO_MUTEX_INIT (&scaled_font->mutex);
-    scaled_font->glyphs = _cairo_cache_create (_cairo_scaled_glyph_keys_equal,
-					       _cairo_scaled_glyph_destroy,
-					       max_glyphs_cached_per_font);
 
     scaled_font->surface_backend = NULL;
     scaled_font->surface_private = NULL;
diff-tree 1237eedff3d557b94db9c940fd8de48be9ba41ba (from ea4945850ae3ce3614bcadc0fa413eb836344430)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 22:56:43 2007 +0100

    Check for error whilst trying to advance along a text string.
    
    The text perf-case tries to fill the region with a single text string,
    but fails to detect when the current point does not advance due to an
    error. This causes the perf-case to enter an infinite loop, so we break
    out when the cairo_status() has been set.

diff --git a/perf/text.c b/perf/text.c
index de5e0cd..efe7d91 100644
--- a/perf/text.c
+++ b/perf/text.c
@@ -40,14 +40,14 @@ do_text (cairo_t *cr, int width, int hei
 	cairo_move_to (cr, 0, i * 10);
 	cairo_show_text (cr, text + i);
 	cairo_get_current_point (cr, &x, &y);
-	while (x < width) {
+	while (x < width && cairo_status (cr) == CAIRO_STATUS_SUCCESS) {
 	    cairo_show_text (cr, text);
 	    cairo_get_current_point (cr, &x, &y);
 	}
 	i++;
 	if (i >= len)
 	    i = 0;
-    } while (y < height);
+    } while (y < height && cairo_status (cr) == CAIRO_STATUS_SUCCESS);
 
     cairo_perf_timer_stop ();
 
diff-tree ea4945850ae3ce3614bcadc0fa413eb836344430 (from 751976970bb0ec9b810c1f58a05d53b7bfb7d90f)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Mar 16 20:04:26 2007 +0000

    Avoid using substituted surfaces for xlib operations.
    
    Detect when a substitute image surface is returned for a solid pattern,
    and avoid mixed image/xlib composite operations. This can happen for example
    if there is a resource allocation failure during creating a similar surface.

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index ff5cdfe..5914c37 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -1217,7 +1217,12 @@ _recategorize_composite_operation (cairo
 {
     cairo_bool_t is_integer_translation =
 	_cairo_matrix_is_integer_translation (&src_attr->matrix, NULL, NULL);
-    cairo_bool_t needs_alpha_composite =
+    cairo_bool_t needs_alpha_composite;
+
+    if (!_cairo_surface_is_xlib (&src->base))
+	return DO_UNSUPPORTED;
+
+    needs_alpha_composite =
 	_operator_needs_alpha_composite (op, _surface_has_alpha (src));
 
     if (!have_mask &&
diff-tree 751976970bb0ec9b810c1f58a05d53b7bfb7d90f (from c6055dc349c3f96e8d6f0e4166540871a59cb0e2)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Mar 16 19:35:02 2007 +0000

    Handle failure to allocate a GC.

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 7f1392d..ff5cdfe 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -51,7 +51,7 @@ typedef int (*cairo_xlib_error_func_t) (
 
 typedef struct _cairo_xlib_surface cairo_xlib_surface_t;
 
-static void
+static cairo_status_t
 _cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface);
 
 static void
@@ -587,22 +587,27 @@ _get_image_surface (cairo_xlib_surface_t
 	 * retry, but to keep things simple, we just create a
 	 * temporary pixmap
 	 */
-	Pixmap pixmap = XCreatePixmap (surface->dpy,
+	Pixmap pixmap;
+	cairo_status_t status = _cairo_xlib_surface_ensure_gc (surface);
+	if (status)
+	    return status;
+
+	pixmap = XCreatePixmap (surface->dpy,
 				       surface->drawable,
 				       x2 - x1, y2 - y1,
 				       surface->depth);
-	_cairo_xlib_surface_ensure_gc (surface);
-
-	XCopyArea (surface->dpy, surface->drawable, pixmap, surface->gc,
-		   x1, y1, x2 - x1, y2 - y1, 0, 0);
+	if (pixmap) {
+	    XCopyArea (surface->dpy, surface->drawable, pixmap, surface->gc,
+		       x1, y1, x2 - x1, y2 - y1, 0, 0);
 
-	ximage = XGetImage (surface->dpy,
-			    pixmap,
-			    0, 0,
-			    x2 - x1, y2 - y1,
-			    AllPlanes, ZPixmap);
+	    ximage = XGetImage (surface->dpy,
+				pixmap,
+				0, 0,
+				x2 - x1, y2 - y1,
+				AllPlanes, ZPixmap);
 
-	XFreePixmap (surface->dpy, pixmap);
+	    XFreePixmap (surface->dpy, pixmap);
+	}
     }
     if (!ximage)
 	return CAIRO_STATUS_NO_MEMORY;
@@ -731,18 +736,23 @@ _cairo_xlib_surface_ensure_dst_picture (
 
 }
 
-static void
+static cairo_status_t
 _cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface)
 {
     XGCValues gcv;
 
     if (surface->gc)
-	return;
+	return CAIRO_STATUS_SUCCESS;
 
     gcv.graphics_exposures = False;
     surface->gc = XCreateGC (surface->dpy, surface->drawable,
 			     GCGraphicsExposures, &gcv);
+    if (!surface->gc)
+	return CAIRO_STATUS_NO_MEMORY;
+
     _cairo_xlib_surface_set_gc_clip_rects (surface);
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
@@ -758,6 +768,7 @@ _draw_image_surface (cairo_xlib_surface_
     XImage ximage;
     unsigned int bpp, alpha, red, green, blue;
     int native_byte_order = _native_byte_order_lsb () ? LSBFirst : MSBFirst;
+    cairo_status_t status;
 
     pixman_format_get_masks (pixman_image_get_format (image->pixman_image),
 			     &bpp, &alpha, &red, &green, &blue);
@@ -780,7 +791,9 @@ _draw_image_surface (cairo_xlib_surface_
 
     XInitImage (&ximage);
 
-    _cairo_xlib_surface_ensure_gc (surface);
+    status = _cairo_xlib_surface_ensure_gc (surface);
+    if (status)
+	return status;
     XPutImage(surface->dpy, surface->drawable, surface->gc,
 	      &ximage, src_x, src_y, dst_x, dst_y,
 	      width, height);
@@ -1364,7 +1377,9 @@ _cairo_xlib_surface_composite (cairo_ope
 	break;
 
     case DO_XCOPYAREA:
-	_cairo_xlib_surface_ensure_gc (dst);
+	status = _cairo_xlib_surface_ensure_gc (dst);
+	if (status)
+	    goto BAIL;
 	XCopyArea (dst->dpy,
 		   src->drawable,
 		   dst->drawable,
@@ -1384,7 +1399,9 @@ _cairo_xlib_surface_composite (cairo_ope
 	 * _recategorize_composite_operation.
 	 */
 
-	_cairo_xlib_surface_ensure_gc (dst);
+	status = _cairo_xlib_surface_ensure_gc (dst);
+	if (status)
+	    goto BAIL;
 	_cairo_matrix_is_integer_translation (&src_attr.matrix, &itx, &ity);
 
 	XSetTSOrigin (dst->dpy, dst->gc,
diff-tree c6055dc349c3f96e8d6f0e4166540871a59cb0e2 (from 65de47d8bc7865c6bf6318fd7bd861acf4e4af05)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 22:50:44 2007 +0100

    Reset cairo_scaled_font_map after freeing.
    
    Along the error path the global font map was freed but not reset,
    causing segfaults on any subsequent use of a cairo_scaled_font_t.

diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 963c060..abf475e 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -211,6 +211,7 @@ _cairo_scaled_font_map_lock (void)
 
  CLEANUP_SCALED_FONT_MAP:
     free (cairo_scaled_font_map);
+    cairo_scaled_font_map = NULL;
  CLEANUP_MUTEX_LOCK:
     CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_map_mutex);
     return NULL;
diff-tree 65de47d8bc7865c6bf6318fd7bd861acf4e4af05 (from b4cb0306b4415f2ddf0acd84043b72c8b8485726)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 22:47:19 2007 +0100

    cairo-bentley-ottmann - check init for failure
    
    This was found during a cairo_static pass on an alternative branch...
    Add the trivial error propagation for _cairo_bo_event_queue_init()

diff --git a/src/cairo-bentley-ottmann.c b/src/cairo-bentley-ottmann.c
index ee8c0af..204b925 100644
--- a/src/cairo-bentley-ottmann.c
+++ b/src/cairo-bentley-ottmann.c
@@ -1262,7 +1262,7 @@ _cairo_bentley_ottmann_tessellate_bo_edg
 					    cairo_fixed_t	ymax,
 					    int			*num_intersections)
 {
-    cairo_status_t status = CAIRO_STATUS_SUCCESS;
+    cairo_status_t status;
     int intersection_count = 0;
     cairo_bo_event_queue_t event_queue;
     cairo_bo_sweep_line_t sweep_line;
@@ -1272,7 +1272,9 @@ _cairo_bentley_ottmann_tessellate_bo_edg
     cairo_bo_edge_t *left, *right;
     cairo_bo_edge_t *edge1, *edge2;
 
-    _cairo_bo_event_queue_init (&event_queue, edges, num_edges);
+    status = _cairo_bo_event_queue_init (&event_queue, edges, num_edges);
+    if (status)
+	return status;
     _cairo_bo_sweep_line_init (&sweep_line);
     _cairo_bo_traps_init (&bo_traps, traps, xmin, ymin, xmax, ymax);
 
diff-tree b4cb0306b4415f2ddf0acd84043b72c8b8485726 (from b29d78dda169ee58b82cdbd04e3af2eedcc58edd)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Mar 28 15:55:06 2007 +0100

    cairo-type1-fallback - propagate error returns
    
    Add status returns in order to propagate a matrix inversion failure
    up through the call stack.

diff --git a/src/cairo-type1-fallback.c b/src/cairo-type1-fallback.c
index eef0d73..3db3531 100644
--- a/src/cairo-type1-fallback.c
+++ b/src/cairo-type1-fallback.c
@@ -464,18 +464,21 @@ fail:
     return status;
 }
 
-static void
+static cairo_status_t
 cairo_type1_font_write_header (cairo_type1_font_t *font,
                                const char         *name)
 {
     cairo_matrix_t matrix;
+    cairo_status_t status;
     unsigned int i;
     const char spaces[50] = "                                                  ";
 
     matrix = font->type1_scaled_font->scale;
     matrix.xy = -matrix.xy;
     matrix.yy = -matrix.yy;
-    cairo_matrix_invert (&matrix);
+    status = cairo_matrix_invert (&matrix);
+    if (status)
+	return status;
 
     _cairo_output_stream_printf (font->output,
                                  "%%!FontType1-1.1 %s 1.0\n"
@@ -512,6 +515,8 @@ cairo_type1_font_write_header (cairo_typ
                                  "readonly def\n"
                                  "currentdict end\n"
                                  "currentfile eexec\n");
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
@@ -635,7 +640,9 @@ cairo_type1_font_write (cairo_type1_font
 {
     cairo_int_status_t status;
 
-    cairo_type1_font_write_header (font, name);
+    status = cairo_type1_font_write_header (font, name);
+    if (status)
+	return status;
     font->header_size = _cairo_output_stream_get_position (font->output);
 
     status = cairo_type1_font_write_private_dict (font, name);
@@ -673,14 +680,18 @@ cairo_type1_font_generate (cairo_type1_f
     return CAIRO_STATUS_SUCCESS;
 }
 
-static void
+static cairo_status_t
 cairo_type1_font_destroy (cairo_type1_font_t *font)
 {
+    cairo_status_t status;
+
     free (font->widths);
     cairo_scaled_font_destroy (font->type1_scaled_font);
     _cairo_array_fini (&font->contents);
-    _cairo_output_stream_destroy (font->output);
+    status = _cairo_output_stream_destroy (font->output);
     free (font);
+
+    return status;
 }
 
 static cairo_status_t
@@ -746,14 +757,14 @@ _cairo_type1_fallback_init_internal (cai
     type1_subset->data_length = font->data_size;
     type1_subset->trailer_length = font->trailer_size;
 
-    cairo_type1_font_destroy (font);
-    return CAIRO_STATUS_SUCCESS;
+    return cairo_type1_font_destroy (font);
 
  fail3:
     free (type1_subset->widths);
  fail2:
     free (type1_subset->base_font);
  fail1:
+    /* status is already set, ignore further errors */
     cairo_type1_font_destroy (font);
 
     return status;
diff-tree b29d78dda169ee58b82cdbd04e3af2eedcc58edd (from 3f7ca6ef5b09263607ff2f9862950393815c5d2c)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Mar 28 15:43:37 2007 +0100

    cairo-svg-surface - propagate some error returns
    
    Add status returns to functions in order to propagate an error up
    the call stack.
    
    For the emit_*_pattern we add a new status return even when when
    the functon return CAIRO_STATUS_SUCCESS unconditionally in order for
    the caller to handle all cases in a consistent manner.

diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 1c885d1..7d217a9 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -707,14 +707,21 @@ _cairo_svg_document_emit_font_subset (ca
     }
 }
 
-static void
+static cairo_status_t
 _cairo_svg_document_emit_font_subsets (cairo_svg_document_t *document)
 {
-    _cairo_scaled_font_subsets_foreach_scaled (document->font_subsets,
-                                               _cairo_svg_document_emit_font_subset,
-                                               document);
+    cairo_status_t status;
+
+    status = _cairo_scaled_font_subsets_foreach_scaled (document->font_subsets,
+                                                        _cairo_svg_document_emit_font_subset,
+                                                        document);
+    if (status)
+	return status;
+
     _cairo_scaled_font_subsets_destroy (document->font_subsets);
     document->font_subsets = NULL;
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_bool_t cairo_svg_force_fallbacks = FALSE;
@@ -1162,7 +1169,7 @@ _cairo_svg_surface_emit_operator (cairo_
 	_cairo_output_stream_printf (output, "comp-op: %s; ", op_str[op]);
 }
 
-static void
+static cairo_status_t
 _cairo_svg_surface_emit_solid_pattern (cairo_svg_surface_t	    *surface,
 		    cairo_solid_pattern_t   *pattern,
 		    cairo_output_stream_t   *style,
@@ -1176,9 +1183,11 @@ _cairo_svg_surface_emit_solid_pattern (c
 				 pattern->color.green * 100.0,
 				 pattern->color.blue * 100.0,
 				 pattern->color.alpha);
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
-static void
+static cairo_status_t
 _cairo_svg_surface_emit_surface_pattern (cairo_svg_surface_t	*surface,
 		      cairo_surface_pattern_t	*pattern,
 		      cairo_output_stream_t     *style,
@@ -1195,6 +1204,8 @@ _cairo_svg_surface_emit_surface_pattern 
 				 "%s: url(#pattern%d);",
 				 is_stroke ? "color" : "fill",
 				 pattern_id);
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static void
@@ -1376,7 +1387,7 @@ _cairo_svg_surface_emit_pattern_extend (
     }
 }
 
-static void
+static cairo_status_t
 _cairo_svg_surface_emit_linear_pattern (cairo_svg_surface_t    *surface,
 		     cairo_linear_pattern_t *pattern,
 		     cairo_output_stream_t  *style,
@@ -1418,9 +1429,11 @@ _cairo_svg_surface_emit_linear_pattern (
 				 document->linear_pattern_id);
 
     document->linear_pattern_id++;
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
-static void
+static cairo_status_t
 _cairo_svg_surface_emit_radial_pattern (cairo_svg_surface_t    *surface,
 		     cairo_radial_pattern_t *pattern,
 		     cairo_output_stream_t  *style,
@@ -1432,6 +1445,7 @@ _cairo_svg_surface_emit_radial_pattern (
     double x0, y0, x1, y1, r0, r1;
     double fx, fy;
     cairo_bool_t reverse_stops;
+    cairo_status_t status;
     pixman_circle_t *c0, *c1;
 
     extend = pattern->base.base.extend;
@@ -1454,7 +1468,9 @@ _cairo_svg_surface_emit_radial_pattern (
     r1 = _cairo_fixed_to_double (c1->radius);
 
     p2u = pattern->base.base.matrix;
-    cairo_matrix_invert (&p2u);
+    status = cairo_matrix_invert (&p2u);
+    if (status)
+	return status;
 
     if (pattern->gradient.c1.radius == pattern->gradient.c2.radius) {
 	_cairo_output_stream_printf (document->xml_node_defs,
@@ -1585,29 +1601,28 @@ _cairo_svg_surface_emit_radial_pattern (
 				 document->radial_pattern_id);
 
     document->radial_pattern_id++;
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
-static void
+static cairo_status_t
 _cairo_svg_surface_emit_pattern (cairo_svg_surface_t *surface, cairo_pattern_t *pattern,
 	      cairo_output_stream_t *output, cairo_bool_t is_stroke)
 {
     switch (pattern->type) {
     case CAIRO_PATTERN_TYPE_SOLID:
-	_cairo_svg_surface_emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern, output, is_stroke);
-	break;
+	return _cairo_svg_surface_emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern, output, is_stroke);
 
     case CAIRO_PATTERN_TYPE_SURFACE:
-	_cairo_svg_surface_emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern, output, is_stroke);
-	break;
+	return _cairo_svg_surface_emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern, output, is_stroke);
 
     case CAIRO_PATTERN_TYPE_LINEAR:
-	_cairo_svg_surface_emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern, output, is_stroke);
-	break;
+	return _cairo_svg_surface_emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern, output, is_stroke);
 
     case CAIRO_PATTERN_TYPE_RADIAL:
-	_cairo_svg_surface_emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern, output, is_stroke);
-	break;
+	return _cairo_svg_surface_emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern, output, is_stroke);
     }
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_int_status_t
@@ -2127,7 +2142,10 @@ _cairo_svg_document_finish (cairo_svg_do
 				 document->width, document->height,
 				 _cairo_svg_internal_version_strings [document->svg_version]);
 
-    _cairo_svg_document_emit_font_subsets (document);
+    status = _cairo_svg_document_emit_font_subsets (document);
+    if (status)
+	return status;
+
     if (_cairo_memory_stream_length (document->xml_node_glyphs) > 0 ||
 	_cairo_memory_stream_length (document->xml_node_defs) > 0) {
 	_cairo_output_stream_printf (output, "<defs>\n");
diff-tree 3f7ca6ef5b09263607ff2f9862950393815c5d2c (from 67f13b3518c5fc98d1e3fb184bc6c2f5ea96f4c9)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Mar 28 14:57:44 2007 +0100

    cairo-pen - cairo_pen_init() can fail propagate its error.
    
    Add status returns in order to propagate an intialisation failure
    back up the call chain.

diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c
index 7b61152..c5a8342 100644
--- a/src/cairo-path-stroke.c
+++ b/src/cairo-path-stroke.c
@@ -67,7 +67,7 @@ typedef struct cairo_stroker {
 } cairo_stroker_t;
 
 /* private functions */
-static void
+static cairo_status_t
 _cairo_stroker_init (cairo_stroker_t		*stroker,
 		     cairo_stroke_style_t	*stroke_style,
 		     cairo_matrix_t		*ctm,
@@ -148,7 +148,7 @@ _cairo_stroker_step_dash (cairo_stroker_
     }
 }
 
-static void
+static cairo_status_t
 _cairo_stroker_init (cairo_stroker_t		*stroker,
 		     cairo_stroke_style_t	*stroke_style,
 		     cairo_matrix_t		*ctm,
@@ -156,15 +156,18 @@ _cairo_stroker_init (cairo_stroker_t		*s
 		     double			 tolerance,
 		     cairo_traps_t		*traps)
 {
+    cairo_status_t status;
     stroker->style = stroke_style;
     stroker->ctm = ctm;
     stroker->ctm_inverse = ctm_inverse;
     stroker->tolerance = tolerance;
     stroker->traps = traps;
 
-    _cairo_pen_init (&stroker->pen,
-		     stroke_style->line_width / 2.0,
-		     tolerance, ctm);
+    status = _cairo_pen_init (&stroker->pen,
+		              stroke_style->line_width / 2.0,
+			      tolerance, ctm);
+    if (status)
+	return status;
 
     stroker->has_current_face = FALSE;
     stroker->has_first_face = FALSE;
@@ -174,6 +177,8 @@ _cairo_stroker_init (cairo_stroker_t		*s
 	_cairo_stroker_start_dash (stroker);
     else
 	stroker->dashed = FALSE;
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static void
@@ -984,9 +989,11 @@ _cairo_path_fixed_stroke_to_traps (cairo
     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
 	return status;
 
-    _cairo_stroker_init (&stroker, stroke_style,
-			 ctm, ctm_inverse, tolerance,
-			 traps);
+    status = _cairo_stroker_init (&stroker, stroke_style,
+			          ctm, ctm_inverse, tolerance,
+				  traps);
+    if (status)
+	return status;
 
     if (stroker.style->dash)
 	status = _cairo_path_fixed_interpret (path,
diff-tree 67f13b3518c5fc98d1e3fb184bc6c2f5ea96f4c9 (from 293122279fd87098a00386bb4c9310f3fc1bb373)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 21:54:41 2007 +0100

    cairo-bentley-ottmann/skip-list - catch and propagate out-of-memory errors
    
    The skip list inserts could return NULL indicating an out-of-memory error.
    In order to handle this, propagate the error up the call stack.

diff --git a/src/cairo-bentley-ottmann.c b/src/cairo-bentley-ottmann.c
index 873bfd6..ee8c0af 100644
--- a/src/cairo-bentley-ottmann.c
+++ b/src/cairo-bentley-ottmann.c
@@ -137,6 +137,7 @@ typedef struct _cairo_bo_sweep_line {
     int32_t current_y;
 } cairo_bo_sweep_line_t;
 
+
 static inline int
 _cairo_bo_point32_compare (cairo_bo_point32_t const *a,
 			   cairo_bo_point32_t const *b)
@@ -692,13 +693,16 @@ _cairo_bo_event_init (cairo_bo_event_t		
     event->point = point;
 }
 
-static void
+static cairo_status_t
 _cairo_bo_event_queue_insert (cairo_bo_event_queue_t *queue,
 			      cairo_bo_event_t	     *event)
 {
+    cairo_status_t status = CAIRO_STATUS_SUCCESS;
     /* Don't insert if there's already an equivalent intersection event in the queue. */
-    _cairo_skip_list_insert (&queue->intersection_queue, event,
-		      event->type == CAIRO_BO_EVENT_TYPE_INTERSECTION);
+    if (_cairo_skip_list_insert (&queue->intersection_queue, event,
+		      event->type == CAIRO_BO_EVENT_TYPE_INTERSECTION) == NULL)
+	status = CAIRO_STATUS_NO_MEMORY;
+    return status;
 }
 
 static void
@@ -796,7 +800,7 @@ _cairo_bo_event_queue_fini (cairo_bo_eve
 	free (event_queue->sorted_startstop_event_ptrs);
 }
 
-static void
+static cairo_status_t
 _cairo_bo_event_queue_insert_if_intersect_below_current_y (cairo_bo_event_queue_t	*event_queue,
 							   cairo_bo_edge_t	*left,
 							   cairo_bo_edge_t	*right)
@@ -806,7 +810,7 @@ _cairo_bo_event_queue_insert_if_intersec
     cairo_bo_event_t event;
 
     if (left == NULL || right == NULL)
-	return;
+	return CAIRO_STATUS_SUCCESS;
 
     /* The names "left" and "right" here are correct descriptions of
      * the order of the two edges within the active edge list. So if a
@@ -814,13 +818,13 @@ _cairo_bo_event_queue_insert_if_intersec
      * that the intersection of these two segments has oalready
      * occurred before the current sweep line position. */
     if (_slope_compare (left, right) < 0)
-	return;
+	return CAIRO_STATUS_SUCCESS;
 
     status = _cairo_bo_edge_intersect (left, right, &intersection);
     if (status == CAIRO_BO_STATUS_PARALLEL ||
 	status == CAIRO_BO_STATUS_NO_INTERSECTION)
     {
-	return;
+	return CAIRO_STATUS_SUCCESS;
     }
 
     _cairo_bo_event_init (&event,
@@ -828,7 +832,7 @@ _cairo_bo_event_queue_insert_if_intersec
 			  left, right,
 			  intersection);
 
-    _cairo_bo_event_queue_insert (event_queue, &event);
+    return _cairo_bo_event_queue_insert (event_queue, &event);
 }
 
 static void
@@ -848,7 +852,7 @@ _cairo_bo_sweep_line_fini (cairo_bo_swee
     _cairo_skip_list_fini (&sweep_line->active_edges);
 }
 
-static void
+static cairo_status_t
 _cairo_bo_sweep_line_insert (cairo_bo_sweep_line_t	*sweep_line,
 			     cairo_bo_edge_t		*edge)
 {
@@ -858,6 +862,8 @@ _cairo_bo_sweep_line_insert (cairo_bo_sw
 
     sweep_line_elt = _cairo_skip_list_insert (&sweep_line->active_edges, &edge,
 				       1 /* unique inserts*/);
+    if (sweep_line_elt == NULL)
+	return CAIRO_STATUS_NO_MEMORY;
 
     next_elt = sweep_line_elt->elt.next[0];
     if (next_elt)
@@ -876,6 +882,8 @@ _cairo_bo_sweep_line_insert (cairo_bo_sw
     *next_of_prev = edge;
 
     edge->sweep_line_elt = sweep_line_elt;
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static void
@@ -1296,7 +1304,9 @@ _cairo_bentley_ottmann_tessellate_bo_edg
 	case CAIRO_BO_EVENT_TYPE_START:
 	    edge = event->e1;
 
-	    _cairo_bo_sweep_line_insert (&sweep_line, edge);
+	    status = _cairo_bo_sweep_line_insert (&sweep_line, edge);
+	    if (status)
+		goto unwind;
 	    /* Cache the insert position for use in pass 2.
 	    event->e2 = Sortlist::prev (sweep_line, edge);
 	    */
@@ -1304,9 +1314,13 @@ _cairo_bentley_ottmann_tessellate_bo_edg
 	    left = edge->prev;
 	    right = edge->next;
 
-	    _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, edge);
+	    status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, edge);
+	    if (status)
+		goto unwind;
 
-	    _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, edge, right);
+	    status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, edge, right);
+	    if (status)
+		goto unwind;
 
 #if DEBUG_PRINT_STATE
 	    print_state ("After processing start", &event_queue, &sweep_line);
@@ -1326,7 +1340,9 @@ _cairo_bentley_ottmann_tessellate_bo_edg
 	    if (status)
 		goto unwind;
 
-	    _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, right);
+	    status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, right);
+	    if (status)
+		goto unwind;
 
 #if DEBUG_PRINT_STATE
 	    print_state ("After processing stop", &event_queue, &sweep_line);
@@ -1354,11 +1370,15 @@ _cairo_bentley_ottmann_tessellate_bo_edg
 
 	    /* after the swap e2 is left of e1 */
 
-	    _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue,
+	    status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue,
 								       left, edge2);
+	    if (status)
+		goto unwind;
 
-	    _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue,
+	    status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue,
 								       edge1, right);
+	    if (status)
+		goto unwind;
 
 #if DEBUG_PRINT_STATE
 	    print_state ("After processing intersection", &event_queue, &sweep_line);
diff --git a/src/cairo-skiplist.c b/src/cairo-skiplist.c
index c8a3018..d493731 100644
--- a/src/cairo-skiplist.c
+++ b/src/cairo-skiplist.c
@@ -345,6 +345,8 @@ _cairo_skip_list_insert (cairo_skip_list
     }
 
     data_and_elt = alloc_node_for_level (list, level);
+    if (data_and_elt == NULL)
+	return NULL;
     memcpy (data_and_elt, data, list->data_size);
     elt = (skip_elt_t *) (data_and_elt + list->data_size);
 
diff-tree 293122279fd87098a00386bb4c9310f3fc1bb373 (from 2f2bff038cb0e59865a0405b19da4805213d718e)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 21:50:48 2007 +0100

    cairo-path-stroke - add trivial missing status checks
    
    Propagate the error status.

diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c
index 09bafbf..7b61152 100644
--- a/src/cairo-path-stroke.c
+++ b/src/cairo-path-stroke.c
@@ -205,6 +205,7 @@ _cairo_stroker_join (cairo_stroker_t *st
 {
     int			clockwise = _cairo_stroker_face_clockwise (out, in);
     cairo_point_t	*inpt, *outpt;
+    cairo_status_t status;
 
     if (in->cw.x == out->cw.x
 	&& in->cw.y == out->cw.y
@@ -231,13 +232,21 @@ _cairo_stroker_join (cairo_stroker_t *st
 
 	tri[0] = in->point;
 	if (clockwise) {
-	    _cairo_pen_find_active_ccw_vertex_index (pen, &in->dev_vector, &start);
+	    status = _cairo_pen_find_active_ccw_vertex_index (pen, &in->dev_vector, &start);
+	    if (status)
+		return status;
 	    step = -1;
-	    _cairo_pen_find_active_ccw_vertex_index (pen, &out->dev_vector, &stop);
+	    status = _cairo_pen_find_active_ccw_vertex_index (pen, &out->dev_vector, &stop);
+	    if (status)
+		return status;
 	} else {
-	    _cairo_pen_find_active_cw_vertex_index (pen, &in->dev_vector, &start);
+	    status = _cairo_pen_find_active_cw_vertex_index (pen, &in->dev_vector, &start);
+	    if (status)
+		return status;
 	    step = +1;
-	    _cairo_pen_find_active_cw_vertex_index (pen, &out->dev_vector, &stop);
+	    status = _cairo_pen_find_active_cw_vertex_index (pen, &out->dev_vector, &stop);
+	    if (status)
+		return status;
 	}
 
 	i = start;
@@ -245,7 +254,9 @@ _cairo_stroker_join (cairo_stroker_t *st
 	while (i != stop) {
 	    tri[2] = in->point;
 	    _translate_point (&tri[2], &pen->vertices[i].point);
-	    _cairo_traps_tessellate_triangle (stroker->traps, tri);
+	    status = _cairo_traps_tessellate_triangle (stroker->traps, tri);
+	    if (status)
+		return status;
 	    tri[1] = tri[2];
 	    i += step;
 	    if (i < 0)
@@ -378,17 +389,23 @@ _cairo_stroker_add_cap (cairo_stroker_t 
 	cairo_pen_t *pen = &stroker->pen;
 
 	slope = f->dev_vector;
-	_cairo_pen_find_active_cw_vertex_index (pen, &slope, &start);
+	status = _cairo_pen_find_active_cw_vertex_index (pen, &slope, &start);
+	if (status)
+	    return status;
 	slope.dx = -slope.dx;
 	slope.dy = -slope.dy;
-	_cairo_pen_find_active_cw_vertex_index (pen, &slope, &stop);
+	status = _cairo_pen_find_active_cw_vertex_index (pen, &slope, &stop);
+	if (status)
+	    return status;
 
 	tri[0] = f->point;
 	tri[1] = f->cw;
 	for (i=start; i != stop; i = (i+1) % pen->num_vertices) {
 	    tri[2] = f->point;
 	    _translate_point (&tri[2], &pen->vertices[i].point);
-	    _cairo_traps_tessellate_triangle (stroker->traps, tri);
+	    status = _cairo_traps_tessellate_triangle (stroker->traps, tri);
+	    if (status)
+		return status;
 	    tri[1] = tri[2];
 	}
 	tri[2] = f->ccw;
diff-tree 2f2bff038cb0e59865a0405b19da4805213d718e (from 79424fc64640db4b518eaf4a23477f1bbc26db5a)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 21:47:01 2007 +0100

    buffer-diff - check for any errors whilst writing the png
    
    Propagate any errors from writing out the png.

diff --git a/test/buffer-diff.c b/test/buffer-diff.c
index d111b23..abb7e33 100644
--- a/test/buffer-diff.c
+++ b/test/buffer-diff.c
@@ -339,6 +339,7 @@ image_diff_core (const char *filename_a,
 
     compare_surfaces (surface_a, surface_b, surface_diff, result);
 
+    status = CAIRO_STATUS_SUCCESS;
     if (result->pixels_changed) {
 	FILE *png_file;
 
@@ -347,7 +348,7 @@ image_diff_core (const char *filename_a,
 	else
 	    png_file = stdout;
 
-	cairo_surface_write_to_png_stream (surface_diff, stdio_write_func, png_file);
+	status = cairo_surface_write_to_png_stream (surface_diff, stdio_write_func, png_file);
 
 	if (png_file != stdout)
 	    fclose (png_file);
@@ -360,7 +361,7 @@ image_diff_core (const char *filename_a,
     cairo_surface_destroy (surface_b);
     cairo_surface_destroy (surface_diff);
 
-    return CAIRO_STATUS_SUCCESS;
+    return status;
 }
 
 cairo_status_t
diff-tree 79424fc64640db4b518eaf4a23477f1bbc26db5a (from a34a32fd99145733df9290f7c72bf7d9759e212b)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 21:45:58 2007 +0100

    cairo - add missing status checks
    
    Add a few missing status checks and set the error on the context when
    applicable.

diff --git a/src/cairo.c b/src/cairo.c
index bf61596..c39d6e3 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -189,6 +189,7 @@ cairo_t *
 cairo_create (cairo_surface_t *target)
 {
     cairo_t *cr;
+    cairo_status_t status;
 
     cr = malloc (sizeof (cairo_t));
     if (cr == NULL)
@@ -201,14 +202,18 @@ cairo_create (cairo_surface_t *target)
     _cairo_user_data_array_init (&cr->user_data);
 
     cr->gstate = cr->gstate_tail;
-    _cairo_gstate_init (cr->gstate, target);
+    status = _cairo_gstate_init (cr->gstate, target);
 
     _cairo_path_fixed_init (cr->path);
 
     if (target == NULL) {
-	_cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER);
+	/* override status with user error */
+	status = CAIRO_STATUS_NULL_POINTER;
     }
 
+    if (status)
+	_cairo_set_error (cr, status);
+
     return cr;
 }
 slim_hidden_def (cairo_create);
@@ -483,9 +488,11 @@ cairo_push_group_with_content (cairo_t *
 
     parent_surface = _cairo_gstate_get_target (cr->gstate);
     /* Get the extents that we'll use in creating our new group surface */
-    _cairo_surface_get_extents (parent_surface, &extents);
+    status = _cairo_surface_get_extents (parent_surface, &extents);
+    if (status)
+	goto bail;
     status = _cairo_clip_intersect_to_rectangle (_cairo_gstate_get_clip (cr->gstate), &extents);
-    if (status != CAIRO_STATUS_SUCCESS)
+    if (status)
 	goto bail;
 
     group_surface = cairo_surface_create_similar (_cairo_gstate_get_target (cr->gstate),
@@ -563,7 +570,7 @@ cairo_pop_group (cairo_t *cr)
     /* We need to save group_surface before we restore; we don't need
      * to reference parent_target and original_target, since the
      * gstate will still hold refs to them once we restore. */
-    cairo_surface_reference (group_surface);
+    group_surface = cairo_surface_reference (group_surface);
 
     cairo_restore (cr);
 
@@ -1623,17 +1630,20 @@ void
 cairo_rel_move_to (cairo_t *cr, double dx, double dy)
 {
     cairo_fixed_t dx_fixed, dy_fixed;
+    cairo_status_t status;
 
     if (cr->status)
 	return;
 
-    _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy);
-    dx_fixed = _cairo_fixed_from_double (dx);
-    dy_fixed = _cairo_fixed_from_double (dy);
+    status = _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy);
+    if (status == CAIRO_STATUS_SUCCESS) {
+	dx_fixed = _cairo_fixed_from_double (dx);
+	dy_fixed = _cairo_fixed_from_double (dy);
 
-    cr->status = _cairo_path_fixed_rel_move_to (cr->path, dx_fixed, dy_fixed);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+	status = _cairo_path_fixed_rel_move_to (cr->path, dx_fixed, dy_fixed);
+    }
+    if (status)
+	_cairo_set_error (cr, status);
 }
 
 /**
@@ -1658,17 +1668,20 @@ void
 cairo_rel_line_to (cairo_t *cr, double dx, double dy)
 {
     cairo_fixed_t dx_fixed, dy_fixed;
+    cairo_status_t status;
 
     if (cr->status)
 	return;
 
-    _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy);
-    dx_fixed = _cairo_fixed_from_double (dx);
-    dy_fixed = _cairo_fixed_from_double (dy);
+    status = _cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy);
+    if (status == CAIRO_STATUS_SUCCESS) {
+	dx_fixed = _cairo_fixed_from_double (dx);
+	dy_fixed = _cairo_fixed_from_double (dy);
 
-    cr->status = _cairo_path_fixed_rel_line_to (cr->path, dx_fixed, dy_fixed);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+	status = _cairo_path_fixed_rel_line_to (cr->path, dx_fixed, dy_fixed);
+    }
+    if (status)
+	_cairo_set_error (cr, status);
 }
 slim_hidden_def(cairo_rel_line_to);
 
@@ -1707,13 +1720,20 @@ cairo_rel_curve_to (cairo_t *cr,
     cairo_fixed_t dx1_fixed, dy1_fixed;
     cairo_fixed_t dx2_fixed, dy2_fixed;
     cairo_fixed_t dx3_fixed, dy3_fixed;
+    cairo_status_t status;
 
     if (cr->status)
 	return;
 
-    _cairo_gstate_user_to_device_distance (cr->gstate, &dx1, &dy1);
-    _cairo_gstate_user_to_device_distance (cr->gstate, &dx2, &dy2);
-    _cairo_gstate_user_to_device_distance (cr->gstate, &dx3, &dy3);
+    status = _cairo_gstate_user_to_device_distance (cr->gstate, &dx1, &dy1);
+    if (status)
+	goto BAIL;
+    status = _cairo_gstate_user_to_device_distance (cr->gstate, &dx2, &dy2);
+    if (status)
+	goto BAIL;
+    status = _cairo_gstate_user_to_device_distance (cr->gstate, &dx3, &dy3);
+    if (status)
+	goto BAIL;
 
     dx1_fixed = _cairo_fixed_from_double (dx1);
     dy1_fixed = _cairo_fixed_from_double (dy1);
@@ -1724,12 +1744,14 @@ cairo_rel_curve_to (cairo_t *cr,
     dx3_fixed = _cairo_fixed_from_double (dx3);
     dy3_fixed = _cairo_fixed_from_double (dy3);
 
-    cr->status = _cairo_path_fixed_rel_curve_to (cr->path,
-						 dx1_fixed, dy1_fixed,
-						 dx2_fixed, dy2_fixed,
-						 dx3_fixed, dy3_fixed);
-    if (cr->status)
-	_cairo_set_error (cr, cr->status);
+    status = _cairo_path_fixed_rel_curve_to (cr->path,
+					     dx1_fixed, dy1_fixed,
+					     dx2_fixed, dy2_fixed,
+					     dx3_fixed, dy3_fixed);
+    if (status) {
+BAIL:
+	_cairo_set_error (cr, status);
+    }
 }
 
 /**
diff-tree a34a32fd99145733df9290f7c72bf7d9759e212b (from d2efadc84d0716498cec0510916f5375fbb7acf0)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 21:36:42 2007 +0100

    cairo-type1-fallback - check for an error during cleanup
    
    The cleanup path is shared between the error path and the true path, and
    so any error along it can not be ignored.

diff --git a/src/cairo-type1-fallback.c b/src/cairo-type1-fallback.c
index a183b28..eef0d73 100644
--- a/src/cairo-type1-fallback.c
+++ b/src/cairo-type1-fallback.c
@@ -558,6 +558,7 @@ cairo_type1_font_write_private_dict (cai
                                      const char         *name)
 {
     cairo_int_status_t status;
+    cairo_status_t status2;
     cairo_output_stream_t *encrypted_output;
 
     font->eexec_key = CAIRO_TYPE1_PRIVATE_DICT_KEY;
@@ -597,10 +598,10 @@ cairo_type1_font_write_private_dict (cai
                                  "dup /FontName get exch definefont pop\n"
                                  "mark currentfile closefile\n");
 
-    if (status == CAIRO_STATUS_SUCCESS)
-	status = _cairo_output_stream_get_status (encrypted_output);
   fail:
-    _cairo_output_stream_destroy (encrypted_output);
+    status2 = _cairo_output_stream_destroy (encrypted_output);
+    if (status == CAIRO_STATUS_SUCCESS)
+	status = status2;
 
     return status;
 }
diff-tree d2efadc84d0716498cec0510916f5375fbb7acf0 (from 02264b40f5ab4831e52c0ad156471045c62c9e85)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 21:35:28 2007 +0100

    cairo-svg-surface - propagate error returns
    
    Add a couple of missing checks for error statues.

diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 703017a..1c885d1 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -447,7 +447,8 @@ _cairo_svg_surface_store_page (cairo_svg
     for (i = 0; i < page.clip_level; i++)
 	_cairo_output_stream_printf (page.xml_node, "</g>\n");
 
-    _cairo_array_append (&surface->page_set, &page);
+    if (_cairo_array_append (&surface->page_set, &page) != CAIRO_STATUS_SUCCESS)
+	return NULL;
 
     return _cairo_array_index (&surface->page_set, surface->page_set.num_elements - 1);
 }
@@ -776,7 +777,7 @@ _cairo_svg_surface_create_similar (void	
 static cairo_status_t
 _cairo_svg_surface_finish (void *abstract_surface)
 {
-    cairo_status_t status;
+    cairo_status_t status, status2;
     cairo_svg_surface_t *surface = abstract_surface;
     cairo_svg_document_t *document = surface->document;
     cairo_svg_page_t *page;
@@ -787,11 +788,15 @@ _cairo_svg_surface_finish (void *abstrac
     else
 	status = CAIRO_STATUS_SUCCESS;
 
-    _cairo_output_stream_destroy (surface->xml_node);
+    status2 = _cairo_output_stream_destroy (surface->xml_node);
+    if (status == CAIRO_STATUS_SUCCESS)
+	status = status2;
 
     for (i = 0; i < surface->page_set.num_elements; i++) {
 	page = _cairo_array_index (&surface->page_set, i);
-	_cairo_output_stream_destroy (page->xml_node);
+	status2 = _cairo_output_stream_destroy (page->xml_node);
+	if (status == CAIRO_STATUS_SUCCESS)
+	    status = status2;
     }
     _cairo_array_fini (&surface->page_set);
 
@@ -941,7 +946,9 @@ _cairo_svg_surface_emit_composite_image_
 	return status;
 
     p2u = pattern->base.matrix;
-    cairo_matrix_invert (&p2u);
+    status = cairo_matrix_invert (&p2u);
+    if (status)
+	return status;
 
     if (pattern_id != invalid_pattern_id) {
 	_cairo_output_stream_printf (output,
@@ -1075,15 +1082,18 @@ _cairo_svg_surface_emit_composite_meta_p
     cairo_svg_document_t *document = surface->document;
     cairo_meta_surface_t *meta_surface;
     cairo_matrix_t p2u;
+    cairo_status_t status;
     int id;
 
+    p2u = pattern->base.matrix;
+    status = cairo_matrix_invert (&p2u);
+    if (status)
+	return status;
+
     meta_surface = (cairo_meta_surface_t *) pattern->surface;
 
     id = _cairo_svg_surface_emit_meta_surface (document, meta_surface);
 
-    p2u = pattern->base.matrix;
-    cairo_matrix_invert (&p2u);
-
     if (pattern_id != invalid_pattern_id) {
 	_cairo_output_stream_printf (output,
 				     "<pattern id=\"pattern%d\" "
@@ -1375,6 +1385,12 @@ _cairo_svg_surface_emit_linear_pattern (
     cairo_svg_document_t *document = surface->document;
     double x0, y0, x1, y1;
     cairo_matrix_t p2u;
+    cairo_status_t status;
+
+    p2u = pattern->base.base.matrix;
+    status = cairo_matrix_invert (&p2u);
+    if (status)
+	return status;
 
     x0 = _cairo_fixed_to_double (pattern->gradient.p1.x);
     y0 = _cairo_fixed_to_double (pattern->gradient.p1.y);
@@ -1389,8 +1405,6 @@ _cairo_svg_surface_emit_linear_pattern (
 				 x0, y0, x1, y1);
 
     _cairo_svg_surface_emit_pattern_extend (document->xml_node_defs, &pattern->base.base),
-    p2u = pattern->base.base.matrix;
-    cairo_matrix_invert (&p2u);
     _cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", ">\n", &p2u);
 
     _cairo_svg_surface_emit_pattern_stops (document->xml_node_defs ,&pattern->base, 0.0, FALSE, FALSE);
diff-tree 02264b40f5ab4831e52c0ad156471045c62c9e85 (from 76b27fb0e81cc557c7348f6ba98b72552d781aed)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 21:34:25 2007 +0100

    cairo-surface-fallback - propagate error returns
    
    _cairo_surface_composite() can fail so check for and error return and
    propagate.

diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index 581d312..a504826 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -454,8 +454,11 @@ _composite_trap_region (cairo_clip_t    
 				       extents->width, extents->height);
 
     /* Restore the original clip if we modified it temporarily. */
-    if (num_rects >1)
-	_cairo_surface_set_clip (dst, clip);
+    if (num_rects > 1) {
+	cairo_status_t status2 = _cairo_surface_set_clip (dst, clip);
+	if (status == CAIRO_STATUS_SUCCESS)
+	    status = status2;
+    }
 
     if (clip_surface)
       _cairo_pattern_fini (&mask.base);
@@ -992,17 +995,21 @@ _cairo_surface_fallback_snapshot (cairo_
 
     _cairo_pattern_init_for_surface (&pattern.surface, &image->base);
 
-    _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
-			      &pattern.base,
-			      NULL,
-			      snapshot,
-			      0, 0,
-			      0, 0,
-			      0, 0,
-			      image->width,
-			      image->height);
+    status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
+			               &pattern.base,
+				       NULL,
+				       snapshot,
+				       0, 0,
+				       0, 0,
+				       0, 0,
+				       image->width,
+				       image->height);
 
     _cairo_pattern_fini (&pattern.base);
+    if (status) {
+	cairo_surface_destroy (snapshot);
+	return (cairo_surface_t *) &_cairo_surface_nil;
+    }
 
     _cairo_surface_release_source_image (surface,
 					 image, &image_extra);
@@ -1171,13 +1178,14 @@ _cairo_surface_fallback_composite_trapez
 	traps = offset_traps;
     }
 
-    _cairo_surface_composite_trapezoids (op, pattern,
-					 &state.image->base,
-					 antialias,
-					 src_x, src_y,
-					 dst_x - state.image_rect.x,
-					 dst_y - state.image_rect.y,
-					 width, height, traps, num_traps);
+    status = _cairo_surface_composite_trapezoids (op, pattern,
+					          &state.image->base,
+						  antialias,
+						  src_x, src_y,
+						  dst_x - state.image_rect.x,
+						  dst_y - state.image_rect.y,
+						  width, height,
+						  traps, num_traps);
     if (offset_traps)
 	free (offset_traps);
 
diff-tree 76b27fb0e81cc557c7348f6ba98b72552d781aed (from 619425a8b3bff79fb453f4b84e3a8e75db369b40)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 21:33:00 2007 +0100

    cairo-ps-surface - add a couple of status checks
    
    Handle a couple more error returns.

diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 52efc83..c08ecef 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -297,7 +297,7 @@ _cairo_ps_surface_emit_path (cairo_ps_su
 			     cairo_line_cap_t	    line_cap)
 {
     cairo_output_stream_t *word_wrap;
-    cairo_status_t status;
+    cairo_status_t status, status2;
     ps_path_info_t path_info;
 
     word_wrap = _word_wrap_stream_create (stream, 79);
@@ -315,7 +315,9 @@ _cairo_ps_surface_emit_path (cairo_ps_su
 
     if (status == CAIRO_STATUS_SUCCESS)
 	status = _cairo_output_stream_get_status (word_wrap);
-    _cairo_output_stream_destroy (word_wrap);
+    status2 = _cairo_output_stream_destroy (word_wrap);
+    if (status == CAIRO_STATUS_SUCCESS)
+	status = status2;
 
     return status;
 }
@@ -1201,7 +1203,7 @@ cairo_ps_surface_dsc_begin_page_setup (c
 static cairo_status_t
 _cairo_ps_surface_finish (void *abstract_surface)
 {
-    cairo_status_t status;
+    cairo_status_t status, status2;
     cairo_ps_surface_t *surface = abstract_surface;
     int i, num_comments;
     char **comments;
@@ -1214,16 +1216,13 @@ _cairo_ps_surface_finish (void *abstract
 
     _cairo_ps_surface_emit_footer (surface);
 
-    _cairo_output_stream_close (surface->stream);
-    status = _cairo_output_stream_get_status (surface->stream);
-    _cairo_output_stream_destroy (surface->stream);
+    status = _cairo_output_stream_destroy (surface->stream);
 
     fclose (surface->tmpfile);
 
-    _cairo_output_stream_close (surface->final_stream);
+    status2 = _cairo_output_stream_destroy (surface->final_stream);
     if (status == CAIRO_STATUS_SUCCESS)
-	status = _cairo_output_stream_get_status (surface->final_stream);
-    _cairo_output_stream_destroy (surface->final_stream);
+	status = status2;
 
     num_comments = _cairo_array_num_elements (&surface->dsc_header_comments);
     comments = _cairo_array_index (&surface->dsc_header_comments, 0);
@@ -1588,20 +1587,29 @@ _cairo_ps_surface_emit_image (cairo_ps_s
 
 	_cairo_pattern_init_for_surface (&pattern.surface, &image->base);
 
-	_cairo_surface_fill_rectangle (opaque,
-				       CAIRO_OPERATOR_SOURCE,
-				       CAIRO_COLOR_WHITE,
-				       0, 0, image->width, image->height);
-
-	_cairo_surface_composite (CAIRO_OPERATOR_OVER,
-				  &pattern.base,
-				  NULL,
-				  opaque,
-				  0, 0,
-				  0, 0,
-				  0, 0,
-				  image->width,
-				  image->height);
+	status = _cairo_surface_fill_rectangle (opaque,
+				                CAIRO_OPERATOR_SOURCE,
+						CAIRO_COLOR_WHITE,
+						0, 0,
+					       	image->width, image->height);
+	if (status) {
+	    _cairo_pattern_fini (&pattern.base);
+	    goto bail0;
+	}
+
+	status = _cairo_surface_composite (CAIRO_OPERATOR_OVER,
+				           &pattern.base,
+					   NULL,
+					   opaque,
+					   0, 0,
+					   0, 0,
+					   0, 0,
+					   image->width,
+					   image->height);
+	if (status) {
+	    _cairo_pattern_fini (&pattern.base);
+	    goto bail0;
+	}
 
 	_cairo_pattern_fini (&pattern.base);
 	opaque_image = (cairo_image_surface_t *) opaque;
diff-tree 619425a8b3bff79fb453f4b84e3a8e75db369b40 (from 4b195779a465f69b035e9fd6695ef5c137a6b342)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 21:29:19 2007 +0100

    cairo-polygon - trivial propagation of error status
    
    _cairo_polygon_move_to() returns an error status so use it.

diff --git a/src/cairo-polygon.c b/src/cairo-polygon.c
index bba9e93..c79eedc 100644
--- a/src/cairo-polygon.c
+++ b/src/cairo-polygon.c
@@ -134,9 +134,7 @@ _cairo_polygon_add_edge (cairo_polygon_t
     polygon->num_edges++;
 
   DONE:
-    _cairo_polygon_move_to (polygon, p2);
-
-    return CAIRO_STATUS_SUCCESS;
+    return _cairo_polygon_move_to (polygon, p2);
 }
 
 cairo_status_t
@@ -153,12 +151,12 @@ _cairo_polygon_move_to (cairo_polygon_t 
 cairo_status_t
 _cairo_polygon_line_to (cairo_polygon_t *polygon, cairo_point_t *point)
 {
-    cairo_status_t status = CAIRO_STATUS_SUCCESS;
+    cairo_status_t status;
 
     if (polygon->has_current_point) {
 	status = _cairo_polygon_add_edge (polygon, &polygon->current_point, point);
     } else {
-	_cairo_polygon_move_to (polygon, point);
+	status = _cairo_polygon_move_to (polygon, point);
     }
 
     return status;
diff-tree 4b195779a465f69b035e9fd6695ef5c137a6b342 (from 66d3e252025cf7f8a624fad83bffa1488a98910d)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 21:28:25 2007 +0100

    cairo-pen - trivial propagation of error status
    
    Add a couple of missing checks for error statuses and correct the
    error path cleanup for _cairo_pen_stroke_spline().

diff --git a/src/cairo-pen.c b/src/cairo-pen.c
index 1af8c36..1bc096b 100644
--- a/src/cairo-pen.c
+++ b/src/cairo-pen.c
@@ -135,6 +135,7 @@ cairo_status_t
 _cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *point, int num_points)
 {
     cairo_pen_vertex_t *vertices;
+    cairo_status_t status;
     int num_vertices;
     int i;
 
@@ -150,7 +151,9 @@ _cairo_pen_add_points (cairo_pen_t *pen,
     for (i=0; i < num_points; i++)
 	pen->vertices[pen->num_vertices-num_points+i].point = point[i];
 
-    _cairo_hull_compute (pen->vertices, &pen->num_vertices);
+    status = _cairo_hull_compute (pen->vertices, &pen->num_vertices);
+    if (status)
+	return status;
 
     _cairo_pen_compute_slopes (pen);
 
@@ -388,7 +391,11 @@ _cairo_pen_stroke_spline_half (cairo_pen
 	final_slope.dy = -final_slope.dy;
     }
 
-    _cairo_pen_find_active_cw_vertex_index (pen, &initial_slope, &active);
+    status = _cairo_pen_find_active_cw_vertex_index (pen,
+	                                             &initial_slope,
+						     &active);
+    if (status)
+	return status;
 
     i = start;
     while (i != stop) {
@@ -437,18 +444,21 @@ _cairo_pen_stroke_spline (cairo_pen_t		*
 
     status = _cairo_spline_decompose (spline, tolerance);
     if (status)
-	return status;
+	goto BAIL;
 
     status = _cairo_pen_stroke_spline_half (pen, spline, CAIRO_DIRECTION_FORWARD, &polygon);
     if (status)
-	return status;
+	goto BAIL;
 
     status = _cairo_pen_stroke_spline_half (pen, spline, CAIRO_DIRECTION_REVERSE, &polygon);
     if (status)
-	return status;
+	goto BAIL;
 
-    _cairo_polygon_close (&polygon);
-    _cairo_bentley_ottmann_tessellate_polygon (traps, &polygon, CAIRO_FILL_RULE_WINDING);
+    status = _cairo_polygon_close (&polygon);
+    if (status)
+	goto BAIL;
+    status = _cairo_bentley_ottmann_tessellate_polygon (traps, &polygon, CAIRO_FILL_RULE_WINDING);
+BAIL:
     _cairo_polygon_fini (&polygon);
 
     return CAIRO_STATUS_SUCCESS;
diff-tree 66d3e252025cf7f8a624fad83bffa1488a98910d (from b32a5b1dc6d66a4477fb8df1461821a27192600f)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 21:26:33 2007 +0100

    cairo-pdf-surface - propagate error status
    
    Catch and propagate any error status.

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index a5b18c5..2118973 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -900,7 +900,9 @@ _cairo_pdf_surface_emit_surface_pattern 
     if (status)
 	goto BAIL;
 
-    _cairo_surface_get_extents (&surface->base, &surface_extents);
+    status = _cairo_surface_get_extents (&surface->base, &surface_extents);
+    if (status)
+	goto BAIL;
 
     switch (extend) {
     /* We implement EXTEND_PAD like EXTEND_NONE for now */
@@ -1256,6 +1258,7 @@ _cairo_pdf_surface_emit_radial_pattern (
     cairo_pdf_resource_t function, pattern_resource, alpha;
     double x0, y0, x1, y1, r0, r1;
     cairo_matrix_t p2u;
+    cairo_status_t status;
 
     _cairo_pdf_surface_pause_content_stream (surface);
 
@@ -1264,7 +1267,9 @@ _cairo_pdf_surface_emit_radial_pattern (
 	return CAIRO_STATUS_NO_MEMORY;
 
     p2u = pattern->base.base.matrix;
-    cairo_matrix_invert (&p2u);
+    status = cairo_matrix_invert (&p2u);
+    if (status)
+	return status;
 
     x0 = _cairo_fixed_to_double (pattern->gradient.c1.x);
     y0 = _cairo_fixed_to_double (pattern->gradient.c1.y);
@@ -1825,11 +1830,11 @@ _cairo_pdf_surface_emit_cff_font_subset 
     font.font_id = font_subset->font_id;
     font.subset_id = font_subset->subset_id;
     font.subset_resource = subset_resource;
-    _cairo_array_append (&surface->fonts, &font);
+    status = _cairo_array_append (&surface->fonts, &font);
 
     _cairo_cff_subset_fini (&subset);
 
-    return CAIRO_STATUS_SUCCESS;
+    return status;
 }
 
 static cairo_status_t
@@ -1934,9 +1939,7 @@ _cairo_pdf_surface_emit_type1_font (cair
     font.font_id = font_subset->font_id;
     font.subset_id = font_subset->subset_id;
     font.subset_resource = subset_resource;
-    _cairo_array_append (&surface->fonts, &font);
-
-    return CAIRO_STATUS_SUCCESS;
+    return _cairo_array_append (&surface->fonts, &font);
 }
 
 #if CAIRO_HAS_FT_FONT
@@ -2105,11 +2108,11 @@ _cairo_pdf_surface_emit_truetype_font_su
     font.font_id = font_subset->font_id;
     font.subset_id = font_subset->subset_id;
     font.subset_resource = subset_resource;
-    _cairo_array_append (&surface->fonts, &font);
+    status = _cairo_array_append (&surface->fonts, &font);
 
     _cairo_truetype_subset_fini (&subset);
 
-    return CAIRO_STATUS_SUCCESS;
+    return status;
 }
 
 static cairo_int_status_t
@@ -2390,9 +2393,7 @@ _cairo_pdf_surface_emit_type3_font_subse
     font.font_id = font_subset->font_id;
     font.subset_id = font_subset->subset_id;
     font.subset_resource = subset_resource;
-    _cairo_array_append (&surface->fonts, &font);
-
-    return CAIRO_STATUS_SUCCESS;
+    return _cairo_array_append (&surface->fonts, &font);
 }
 
 static void
diff-tree b32a5b1dc6d66a4477fb8df1461821a27192600f (from fd49bbb4b21b73247b4d391c2cb1b028a596f6eb)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 21:25:46 2007 +0100

    cairo-pattern - propagate status
    
    Catch, cleanup and propagate after an error return.

diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 80acdad..7d5da62 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -1191,7 +1191,11 @@ _cairo_pattern_acquire_surface_for_gradi
     pixman_image_set_filter (pixman_image, PIXMAN_FILTER_BILINEAR);
 
     _cairo_matrix_to_pixman_matrix (&pattern->base.matrix, &pixman_transform);
-    pixman_image_set_transform (pixman_image, &pixman_transform);
+    if (pixman_image_set_transform (pixman_image, &pixman_transform)) {
+	cairo_surface_destroy (&image->base);
+	pixman_image_destroy (pixman_image);
+	return CAIRO_STATUS_NO_MEMORY;
+    }
 
     switch (pattern->base.extend) {
     case CAIRO_EXTEND_NONE:
@@ -1755,7 +1759,9 @@ _cairo_pattern_get_extents (cairo_patter
 	    return status;
 
 	imatrix = pattern->matrix;
-	cairo_matrix_invert (&imatrix);
+	status = cairo_matrix_invert (&imatrix);
+	if (status)
+	    return status;
 
 	/* XXX Use _cairo_matrix_transform_bounding_box here */
 	for (sy = 0; sy <= 1; sy++) {
diff-tree fd49bbb4b21b73247b4d391c2cb1b028a596f6eb (from 814830f63b72f69198e92564c53f2683e5bda269)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 21:24:59 2007 +0100

    cairo-path - check for failure during _cairo_path_fixed_interpret
    
    Catch an error return from _cairo_path_fixed_interpret() and return
    it. Similary check for an error code in cairo_status() before returning
    success.

diff --git a/src/cairo-path.c b/src/cairo-path.c
index ff44191..3add107 100644
--- a/src/cairo-path.c
+++ b/src/cairo-path.c
@@ -143,15 +143,16 @@ _cairo_path_count (cairo_path_t		*path,
     cpc.current_point.x = 0;
     cpc.current_point.y = 0;
 
-    _cairo_path_fixed_interpret (path_fixed,
-				 CAIRO_DIRECTION_FORWARD,
-				 _cpc_move_to,
-				 _cpc_line_to,
-				 flatten ?
-				 _cpc_curve_to_flatten :
-				 _cpc_curve_to,
-				 _cpc_close_path,
-				 &cpc);
+    if (_cairo_path_fixed_interpret (path_fixed,
+				     CAIRO_DIRECTION_FORWARD,
+				     _cpc_move_to,
+				     _cpc_line_to,
+				     flatten ?
+				     _cpc_curve_to_flatten :
+				     _cpc_curve_to,
+				     _cpc_close_path,
+				     &cpc) != CAIRO_STATUS_SUCCESS)
+	return 0;
 
     return cpc.count;
 }
@@ -307,12 +308,13 @@ _cpp_close_path (void *closure)
     return CAIRO_STATUS_SUCCESS;
 }
 
-static void
+static cairo_status_t
 _cairo_path_populate (cairo_path_t		*path,
 		      cairo_path_fixed_t	*path_fixed,
 		      cairo_gstate_t		*gstate,
 		      cairo_bool_t		 flatten)
 {
+    cairo_status_t status;
     cpp_t cpp;
 
     cpp.data = path->data;
@@ -320,18 +322,22 @@ _cairo_path_populate (cairo_path_t		*pat
     cpp.current_point.x = 0;
     cpp.current_point.y = 0;
 
-    _cairo_path_fixed_interpret (path_fixed,
-				 CAIRO_DIRECTION_FORWARD,
-				 _cpp_move_to,
-				 _cpp_line_to,
-				 flatten ?
-				 _cpp_curve_to_flatten :
-				 _cpp_curve_to,
-				 _cpp_close_path,
-				 &cpp);
+    status = _cairo_path_fixed_interpret (path_fixed,
+				          CAIRO_DIRECTION_FORWARD,
+					  _cpp_move_to,
+					  _cpp_line_to,
+					  flatten ?
+					  _cpp_curve_to_flatten :
+					  _cpp_curve_to,
+					  _cpp_close_path,
+					  &cpp);
+    if (status)
+	return status;
 
     /* Sanity check the count */
     assert (cpp.data - path->data == path->num_data);
+
+    return status;
 }
 
 cairo_path_t *
@@ -371,10 +377,8 @@ _cairo_path_create_internal (cairo_path_
 	return (cairo_path_t*) &_cairo_path_nil;
     }
 
-    path->status = CAIRO_STATUS_SUCCESS;
-
-    _cairo_path_populate (path, path_fixed,
-			  gstate, flatten);
+    path->status = _cairo_path_populate (path, path_fixed,
+			                 gstate, flatten);
 
     return path;
 }
@@ -463,6 +467,7 @@ _cairo_path_append_to_context (const cai
 {
     int i;
     cairo_path_data_t *p;
+    cairo_status_t status;
 
     for (i=0; i < path->num_data; i += path->data[i].header.length) {
 	p = &path->data[i];
@@ -495,6 +500,10 @@ _cairo_path_append_to_context (const cai
 	default:
 	    return CAIRO_STATUS_INVALID_PATH_DATA;
 	}
+
+	status = cairo_status (cr);
+	if (status)
+	    return status;
     }
 
     return CAIRO_STATUS_SUCCESS;
diff-tree 814830f63b72f69198e92564c53f2683e5bda269 (from 7ab1f62c60141d5c0e989d55f4a49537a6b52c4d)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 21:22:56 2007 +0100

    cairo-path-fill - trivial missing unused result
    
    Actually assign the result that is tested on the next line...

diff --git a/src/cairo-path-fill.c b/src/cairo-path-fill.c
index b1b7a12..d2a9118 100644
--- a/src/cairo-path-fill.c
+++ b/src/cairo-path-fill.c
@@ -138,7 +138,7 @@ _cairo_filler_curve_to (void *closure,
     if (status == CAIRO_INT_STATUS_DEGENERATE)
 	return CAIRO_STATUS_SUCCESS;
 
-    _cairo_spline_decompose (&spline, filler->tolerance);
+    status = _cairo_spline_decompose (&spline, filler->tolerance);
     if (status)
 	goto CLEANUP_SPLINE;
 
diff-tree 7ab1f62c60141d5c0e989d55f4a49537a6b52c4d (from 78c0d62ba7c650a6dc8137e6d1375e21f9477c2b)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 21:21:49 2007 +0100

    cairo-paginated-surface - fix up the trivial unused result
    
    Check for status returns and propagate, cleaning up as necessary.

diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index c8e4612..e6702b7 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -201,15 +201,22 @@ _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_surface_get_extents (surface->target, &extents);
+    status = _cairo_surface_get_extents (surface->target, &extents);
+    if (status)
+	return status;
 
     image = _cairo_paginated_surface_create_image_surface (surface,
 							   extents.width,
 							   extents.height);
 
-    _cairo_meta_surface_replay (surface->meta, image);
+    status = _cairo_meta_surface_replay (surface->meta, image);
+    if (status) {
+	cairo_surface_destroy (image);
+	return status;
+    }
 
     *image_out = (cairo_image_surface_t*) image;
     *image_extra = NULL;
@@ -257,26 +264,29 @@ _paint_page (cairo_paginated_surface_t *
 							       surface->height * y_scale);
 	_cairo_surface_set_device_scale (image, x_scale, y_scale);
 
-	_cairo_meta_surface_replay (surface->meta, image);
+	status = _cairo_meta_surface_replay (surface->meta, image);
+	if (status)
+	    goto CLEANUP_IMAGE;
 
 	pattern = cairo_pattern_create_for_surface (image);
 	cairo_matrix_init_scale (&matrix, x_scale, y_scale);
 	cairo_pattern_set_matrix (pattern, &matrix);
 
-	_cairo_surface_paint (surface->target, CAIRO_OPERATOR_SOURCE, pattern);
+	status = _cairo_surface_paint (surface->target, CAIRO_OPERATOR_SOURCE, pattern);
 
 	cairo_pattern_destroy (pattern);
 
+CLEANUP_IMAGE:
 	cairo_surface_destroy (image);
     }
     else
     {
-	_cairo_meta_surface_replay (surface->meta, surface->target);
+	status = _cairo_meta_surface_replay (surface->meta, surface->target);
     }
 
     cairo_surface_destroy (analysis);
 
-    return CAIRO_STATUS_SUCCESS;
+    return status;
 }
 
 static cairo_status_t
diff-tree 78c0d62ba7c650a6dc8137e6d1375e21f9477c2b (from 75cc5e04d5b854a1eefe116c2be4a3c2bb21d6ac)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 21:20:42 2007 +0100

    cairo-meta-surface - propagate trivial status return
    
    _cairo_path_fixed_init_copy() could fail so propagate it's status.

diff --git a/src/cairo-meta-surface.c b/src/cairo-meta-surface.c
index 457bfe2..8ef9ec0 100644
--- a/src/cairo-meta-surface.c
+++ b/src/cairo-meta-surface.c
@@ -668,7 +668,9 @@ _cairo_meta_surface_replay (cairo_surfac
 
 	dev_path = _cairo_command_get_path (command);
 	if (dev_path && has_device_transform) {
-	    _cairo_path_fixed_init_copy (&path_copy, dev_path);
+	    status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
+	    if (status)
+		break;
 	    _cairo_path_fixed_device_transform (&path_copy, device_transform);
 	    dev_path = &path_copy;
 	}
diff-tree 75cc5e04d5b854a1eefe116c2be4a3c2bb21d6ac (from dee9a53029bd3e42c60a855edfb54591bf1782b5)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 21:19:49 2007 +0100

    cairo-image-surface - propagate error returns from pixman.
    
    pixman does occasionally return an error - in such circumstances we
    should propagate it.

diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 6279012..3062533 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -690,7 +690,8 @@ _cairo_image_surface_set_matrix (cairo_i
 
     _cairo_matrix_to_pixman_matrix (matrix, &pixman_transform);
 
-    pixman_image_set_transform (surface->pixman_image, &pixman_transform);
+    if (pixman_image_set_transform (surface->pixman_image, &pixman_transform))
+	return CAIRO_STATUS_NO_MEMORY;
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -1047,7 +1048,8 @@ _cairo_image_surface_set_clip_region (vo
 {
     cairo_image_surface_t *surface = (cairo_image_surface_t *) abstract_surface;
 
-    pixman_image_set_clip_region (surface->pixman_image, region);
+    if (pixman_image_set_clip_region (surface->pixman_image, region))
+	return CAIRO_STATUS_NO_MEMORY;
 
     surface->has_clip = region != NULL;
 
diff-tree dee9a53029bd3e42c60a855edfb54591bf1782b5 (from de264af2c659b32c8bc71060da85037ac7e1d44f)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 21:18:30 2007 +0100

    cairo-gstate - fix the trivial unchecked returns
    
    Check for an error return and propagate.

diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 41da4f4..6a61987 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -62,6 +62,7 @@ cairo_status_t
 _cairo_gstate_init (cairo_gstate_t  *gstate,
 		    cairo_surface_t *target)
 {
+    cairo_status_t status;
     gstate->next = NULL;
 
     gstate->op = CAIRO_GSTATE_OPERATOR_DEFAULT;
@@ -88,7 +89,9 @@ _cairo_gstate_init (cairo_gstate_t  *gst
     gstate->parent_target = NULL;
     gstate->original_target = cairo_surface_reference (target);
 
-    _cairo_gstate_identity_matrix (gstate);
+    status = _cairo_gstate_identity_matrix (gstate);
+    if (status)
+	return status;
     gstate->source_ctm_inverse = gstate->ctm_inverse;
 
     gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK);
@@ -403,7 +406,7 @@ _cairo_gstate_set_source (cairo_gstate_t
     if (source->status)
 	return source->status;
 
-    cairo_pattern_reference (source);
+    source = cairo_pattern_reference (source);
     cairo_pattern_destroy (gstate->source);
     gstate->source = source;
     gstate->source_ctm_inverse = gstate->ctm_inverse;
@@ -648,13 +651,16 @@ _cairo_gstate_transform (cairo_gstate_t	
 			 const cairo_matrix_t *matrix)
 {
     cairo_matrix_t tmp;
+    cairo_status_t status;
 
     _cairo_gstate_unset_scaled_font (gstate);
 
     tmp = *matrix;
     cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm);
 
-    cairo_matrix_invert (&tmp);
+    status = cairo_matrix_invert (&tmp);
+    if (status)
+	return status;
     cairo_matrix_multiply (&gstate->ctm_inverse, &gstate->ctm_inverse, &tmp);
 
     return CAIRO_STATUS_SUCCESS;
@@ -1255,12 +1261,15 @@ _cairo_gstate_select_font_face (cairo_gs
 				cairo_font_weight_t   weight)
 {
     cairo_font_face_t *font_face;
+    cairo_status_t status;
 
     font_face = _cairo_toy_font_face_create (family, slant, weight);
     if (font_face->status)
 	return font_face->status;
 
-    _cairo_gstate_set_font_face (gstate, font_face);
+    status = _cairo_gstate_set_font_face (gstate, font_face);
+    if (status)
+	return status;
     cairo_font_face_destroy (font_face);
 
     return CAIRO_STATUS_SUCCESS;
diff-tree de264af2c659b32c8bc71060da85037ac7e1d44f (from 14c8dfb0b9bcc26a02057e5636d8bf35c3b4ef29)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 21:17:26 2007 +0100

    cairo-ft-font - handle trivial failures
    
    Catch the status return, cleanup and propagate the error.

diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 0da7d67..0d14e98 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -1158,24 +1158,33 @@ _transform_glyph_bitmap (cairo_matrix_t 
 
     /* Initialize it to empty
      */
-    _cairo_surface_fill_rectangle (image, CAIRO_OPERATOR_CLEAR,
-				   CAIRO_COLOR_TRANSPARENT,
-				   0, 0,
-				   width, height);
+    status = _cairo_surface_fill_rectangle (image, CAIRO_OPERATOR_CLEAR,
+				            CAIRO_COLOR_TRANSPARENT,
+					    0, 0,
+					    width, height);
+    if (status) {
+	cairo_surface_destroy (image);
+	return status;
+    }
 
     /* Draw the original bitmap transformed into the new bitmap
      */
     _cairo_pattern_init_for_surface (&pattern, &(*surface)->base);
     cairo_pattern_set_matrix (&pattern.base, &transformed_to_original);
 
-    _cairo_surface_composite (CAIRO_OPERATOR_OVER,
-			      &pattern.base, NULL, image,
-			      0, 0, 0, 0, 0, 0,
-			      width,
-			      height);
+    status = _cairo_surface_composite (CAIRO_OPERATOR_OVER,
+			               &pattern.base, NULL, image,
+				       0, 0, 0, 0, 0, 0,
+				       width,
+				       height);
 
     _cairo_pattern_fini (&pattern.base);
 
+    if (status) {
+	cairo_surface_destroy (image);
+	return status;
+    }
+
     /* Now update the cache entry for the new bitmap, recomputing
      * the origin based on the final transform.
      */
@@ -1425,6 +1434,7 @@ _cairo_ft_scaled_font_create (cairo_ft_u
     FT_Face face;
     FT_Size_Metrics *metrics;
     cairo_font_extents_t fs_metrics;
+    cairo_status_t status;
 
     face = _cairo_ft_unscaled_font_lock_face (unscaled);
     if (!face)
@@ -1445,10 +1455,15 @@ _cairo_ft_scaled_font_create (cairo_ft_u
     _cairo_font_options_init_copy (&scaled_font->ft_options.base, options);
     _cairo_ft_options_merge (&scaled_font->ft_options, &ft_options);
 
-    _cairo_scaled_font_init (&scaled_font->base,
-			     font_face,
-			     font_matrix, ctm, options,
-			     &cairo_ft_scaled_font_backend);
+    status = _cairo_scaled_font_init (&scaled_font->base,
+			              font_face,
+				      font_matrix, ctm, options,
+				      &cairo_ft_scaled_font_backend);
+    if (status) {
+	free (scaled_font);
+	_cairo_ft_unscaled_font_unlock_face (unscaled);
+	return NULL;
+    }
 
     _cairo_ft_unscaled_font_set_scale (unscaled,
 				       &scaled_font->base.scale);
@@ -1624,8 +1639,10 @@ _move_to (FT_Vector *to, void *closure)
     x = _cairo_fixed_from_26_6 (to->x);
     y = _cairo_fixed_from_26_6 (to->y);
 
-    _cairo_path_fixed_close_path (path);
-    _cairo_path_fixed_move_to (path, x, y);
+    if (_cairo_path_fixed_close_path (path) != CAIRO_STATUS_SUCCESS)
+	return 1;
+    if (_cairo_path_fixed_move_to (path, x, y) != CAIRO_STATUS_SUCCESS)
+	return 1;
 
     return 0;
 }
@@ -1639,7 +1656,8 @@ _line_to (FT_Vector *to, void *closure)
     x = _cairo_fixed_from_26_6 (to->x);
     y = _cairo_fixed_from_26_6 (to->y);
 
-    _cairo_path_fixed_line_to (path, x, y);
+    if (_cairo_path_fixed_line_to (path, x, y) != CAIRO_STATUS_SUCCESS)
+	return 1;
 
     return 0;
 }
@@ -1655,7 +1673,9 @@ _conic_to (FT_Vector *control, FT_Vector
     cairo_fixed_t x3, y3;
     cairo_point_t conic;
 
-    _cairo_path_fixed_get_current_point (path, &x0, &y0);
+    if (_cairo_path_fixed_get_current_point (path, &x0, &y0) !=
+	    CAIRO_STATUS_SUCCESS)
+	return 1;
 
     conic.x = _cairo_fixed_from_26_6 (control->x);
     conic.y = _cairo_fixed_from_26_6 (control->y);
@@ -1669,10 +1689,11 @@ _conic_to (FT_Vector *control, FT_Vector
     x2 = x3 + 2.0/3.0 * (conic.x - x3);
     y2 = y3 + 2.0/3.0 * (conic.y - y3);
 
-    _cairo_path_fixed_curve_to (path,
-				x1, y1,
-				x2, y2,
-				x3, y3);
+    if (_cairo_path_fixed_curve_to (path,
+				    x1, y1,
+				    x2, y2,
+				    x3, y3) != CAIRO_STATUS_SUCCESS)
+	return 1;
 
     return 0;
 }
@@ -1695,10 +1716,11 @@ _cubic_to (FT_Vector *control1, FT_Vecto
     x2 = _cairo_fixed_from_26_6 (to->x);
     y2 = _cairo_fixed_from_26_6 (to->y);
 
-    _cairo_path_fixed_curve_to (path,
-				x0, y0,
-				x1, y1,
-				x2, y2);
+    if (_cairo_path_fixed_curve_to (path,
+				    x0, y0,
+				    x1, y1,
+				    x2, y2) != CAIRO_STATUS_SUCCESS)
+	return 1;
 
     return 0;
 }
@@ -1723,6 +1745,7 @@ _decompose_glyph_outline (FT_Face		  fac
 
     FT_GlyphSlot glyph;
     cairo_path_fixed_t *path;
+    cairo_status_t status;
 
     path = _cairo_path_fixed_create ();
     if (!path)
@@ -1730,15 +1753,18 @@ _decompose_glyph_outline (FT_Face		  fac
 
     glyph = face->glyph;
 
+    status = CAIRO_STATUS_SUCCESS;
     /* Font glyphs have an inverted Y axis compared to cairo. */
     FT_Outline_Transform (&glyph->outline, &invert_y);
-    FT_Outline_Decompose (&glyph->outline, &outline_funcs, path);
+    if (FT_Outline_Decompose (&glyph->outline, &outline_funcs, path))
+	status = CAIRO_STATUS_NO_MEMORY;
 
     _cairo_path_fixed_close_path (path);
 
-    *pathp = path;
+    if (status == CAIRO_STATUS_SUCCESS)
+	*pathp = path;
 
-    return CAIRO_STATUS_SUCCESS;
+    return status;
 }
 
 /*
diff-tree 14c8dfb0b9bcc26a02057e5636d8bf35c3b4ef29 (from 274c20c27a094c05afa62579cacb5749013abd60)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Apr 9 15:03:34 2007 +0100

    cairo-clip - handle trivial pixman failures
    
    Detect the simple cases when pixman returns an error, ie an OOM
    condition, and propagate the error status.

diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index ea4ada3..f7fd1e2 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -195,6 +195,8 @@ cairo_status_t
 _cairo_clip_intersect_to_region (cairo_clip_t      *clip,
 				 pixman_region16_t *region)
 {
+    pixman_region_status_t pixman_status;
+
     if (!clip)
 	return CAIRO_STATUS_SUCCESS;
 
@@ -202,8 +204,11 @@ _cairo_clip_intersect_to_region (cairo_c
 	/* Intersect clip path into region. */
     }
 
-    if (clip->has_region)
-	pixman_region_intersect (region, &clip->region, region);
+    if (clip->has_region) {
+	pixman_status = pixman_region_intersect (region, &clip->region, region);
+	if (pixman_status != PIXMAN_REGION_STATUS_SUCCESS)
+	    return CAIRO_STATUS_NO_MEMORY;
+    }
 
     if (clip->surface) {
 	cairo_status_t status = CAIRO_STATUS_SUCCESS;
@@ -625,10 +630,11 @@ _cairo_clip_copy_rectangle_list (cairo_c
         }
     } else {
         cairo_rectangle_int16_t extents;
-        _cairo_surface_get_extents (_cairo_gstate_get_target (gstate), &extents);
-        if (!_cairo_clip_rect_to_user(gstate, extents.x, extents.y,
-                                      extents.width, extents.height,
-                                      rectangles)) {
+        if (_cairo_surface_get_extents (_cairo_gstate_get_target (gstate),
+		                        &extents) != CAIRO_STATUS_SUCCESS ||
+		!_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;
diff-tree 274c20c27a094c05afa62579cacb5749013abd60 (from 46eab95698e101e41407778eda22089b508a8984)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 21:14:09 2007 +0100

    cairo-boilerplate - handle failure to set user data
    
    After failing to set the user data on a surface, clean up and return NULL.

diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c
index 6a1acb8..e277f1c 100644
--- a/boilerplate/cairo-boilerplate.c
+++ b/boilerplate/cairo-boilerplate.c
@@ -1062,7 +1062,15 @@ create_ps_surface (const char			 *name,
 	ptc->target = NULL;
     }
 
-    cairo_surface_set_user_data (surface, &ps_closure_key, ptc, NULL);
+    if (cairo_surface_set_user_data (surface,
+	       	                     &ps_closure_key,
+				     ptc,
+				     NULL) != CAIRO_STATUS_SUCCESS) {
+	cairo_surface_destroy (surface);
+	free (ptc->filename);
+	free (ptc);
+	return NULL;
+    }
 
     return surface;
 }
diff-tree 46eab95698e101e41407778eda22089b508a8984 (from 9da86e4a386505288c3a933f30583abf7706c950)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Apr 8 20:50:08 2007 +0100

    Add attribute(warn_unused_result)
    
    This adds a compiler check that the function result is used by the caller
    and enables it by default for all cairo_private functions and for public
    API that returns a cairo_status_t.
    
    It has been discussed that to extend the warnings to all functions, a
    new function type could been introduced to cover static functions:
    cairo_static. This has not been done at the present time in order to
    minimise the churn and focus on the more common errors.
    
    In order to reduce the warning spew generated by gcc for invalid use of
    this attribute, -Wno-attributes is added to CFLAGS. This has the
    unfortunate side-effect of masking future warnings for all attributes -
    be warned!

diff --git a/configure.in b/configure.in
index e625fc5..be3a423 100644
--- a/configure.in
+++ b/configure.in
@@ -623,7 +623,8 @@ MAYBE_WARN="-Wall -Wextra \
 -Wpacked -Wswitch-enum -Wmissing-format-attribute \
 -Wstrict-aliasing=2 -Winit-self -Wunsafe-loop-optimizations \
 -Wdeclaration-after-statement -Wold-style-definition \
--Wno-missing-field-initializers -Wno-unused-parameter"
+-Wno-missing-field-initializers -Wno-unused-parameter \
+-Wno-attributes"
 
 
 # invalidate cached value if MAYBE_WARN has changed
@@ -844,9 +845,19 @@ AC_CONFIG_COMMANDS([src/cairo-features.h
 # define CAIRO_END_DECLS
 #endif
 
+#if    __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+#define CAIRO_WARN_UNUSED_RESULT 		\
+  __attribute__((__warn_unused_result__))
+#else
+#define CAIRO_WARN_UNUSED_RESULT
+#endif /* __GNUC__ */
+
 #ifndef cairo_public
 # define cairo_public
 #endif
+#ifndef cairo_public_warn
+# define cairo_public_warn CAIRO_WARN_UNUSED_RESULT
+#endif
 
 #define CAIRO_VERSION_MAJOR $CAIRO_VERSION_MAJOR
 #define CAIRO_VERSION_MINOR $CAIRO_VERSION_MINOR
diff --git a/pixman/configure.in b/pixman/configure.in
index c9cdae8..4cbb5ba 100644
--- a/pixman/configure.in
+++ b/pixman/configure.in
@@ -45,7 +45,8 @@ WARN_CFLAGS=""
 if test "x$GCC" = "xyes"; then
 	WARN_CFLAGS="-Wall -Wpointer-arith -Wstrict-prototypes \
 	-Wmissing-prototypes -Wmissing-declarations \
-	-Wnested-externs -fno-strict-aliasing"
+	-Wnested-externs -fno-strict-aliasing \
+	-Wno-attributes"
 fi
 
 AC_SUBST(WARN_CFLAGS)
diff --git a/pixman/src/pixman.h b/pixman/src/pixman.h
index 5c12127..779e305 100644
--- a/pixman/src/pixman.h
+++ b/pixman/src/pixman.h
@@ -100,7 +100,7 @@ SOFTWARE.
 #include "pixman-remap.h"
 
 #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) && !defined(__sun__)
-#define pixman_private		__attribute__((__visibility__("hidden")))
+#define pixman_private		__attribute__((__visibility__("hidden"),__warn_unused_result__))
 #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
 #define pixman_private		__hidden
 #else /* not gcc >= 3.3 and not Sun Studio >= 8 */
diff --git a/src/cairo.h b/src/cairo.h
index a80efde..5fc05e3 100644
--- a/src/cairo.h
+++ b/src/cairo.h
@@ -313,7 +313,7 @@ cairo_public void *
 cairo_get_user_data (cairo_t			 *cr,
 		     const cairo_user_data_key_t *key);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_set_user_data (cairo_t			 *cr,
 		     const cairo_user_data_key_t *key,
 		     void			 *user_data,
@@ -972,7 +972,7 @@ cairo_font_options_copy (const cairo_fon
 cairo_public void
 cairo_font_options_destroy (cairo_font_options_t *options);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_font_options_status (cairo_font_options_t *options);
 
 cairo_public void
@@ -1088,7 +1088,7 @@ cairo_font_face_destroy (cairo_font_face
 cairo_public unsigned int
 cairo_font_face_get_reference_count (cairo_font_face_t *font_face);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_font_face_status (cairo_font_face_t *font_face);
 
 /**
@@ -1141,7 +1141,7 @@ cairo_public void *
 cairo_font_face_get_user_data (cairo_font_face_t	   *font_face,
 			       const cairo_user_data_key_t *key);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_font_face_set_user_data (cairo_font_face_t	   *font_face,
 			       const cairo_user_data_key_t *key,
 			       void			   *user_data,
@@ -1164,7 +1164,7 @@ cairo_scaled_font_destroy (cairo_scaled_
 cairo_public unsigned int
 cairo_scaled_font_get_reference_count (cairo_scaled_font_t *scaled_font);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_scaled_font_status (cairo_scaled_font_t *scaled_font);
 
 cairo_public cairo_font_type_t
@@ -1174,7 +1174,7 @@ cairo_public void *
 cairo_scaled_font_get_user_data (cairo_scaled_font_t         *scaled_font,
 				 const cairo_user_data_key_t *key);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_scaled_font_set_user_data (cairo_scaled_font_t         *scaled_font,
 				 const cairo_user_data_key_t *key,
 				 void                        *user_data,
@@ -1392,7 +1392,7 @@ cairo_path_destroy (cairo_path_t *path);
 
 /* Error status queries */
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_status (cairo_t *cr);
 
 cairo_public const char *
@@ -1418,7 +1418,7 @@ cairo_surface_destroy (cairo_surface_t *
 cairo_public unsigned int
 cairo_surface_get_reference_count (cairo_surface_t *surface);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_surface_status (cairo_surface_t *surface);
 
 /**
@@ -1482,11 +1482,11 @@ cairo_surface_get_content (cairo_surface
 
 #if CAIRO_HAS_PNG_FUNCTIONS
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_surface_write_to_png (cairo_surface_t	*surface,
 			    const char		*filename);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_surface_write_to_png_stream (cairo_surface_t	*surface,
 				   cairo_write_func_t	write_func,
 				   void			*closure);
@@ -1497,7 +1497,7 @@ cairo_public void *
 cairo_surface_get_user_data (cairo_surface_t		 *surface,
 			     const cairo_user_data_key_t *key);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_surface_set_user_data (cairo_surface_t		 *surface,
 			     const cairo_user_data_key_t *key,
 			     void			 *user_data,
@@ -1642,14 +1642,14 @@ cairo_pattern_destroy (cairo_pattern_t *
 cairo_public unsigned int
 cairo_pattern_get_reference_count (cairo_pattern_t *pattern);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_pattern_status (cairo_pattern_t *pattern);
 
 cairo_public void *
 cairo_pattern_get_user_data (cairo_pattern_t		 *pattern,
 			     const cairo_user_data_key_t *key);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_pattern_set_user_data (cairo_pattern_t		 *pattern,
 			     const cairo_user_data_key_t *key,
 			     void			 *user_data,
@@ -1758,32 +1758,32 @@ cairo_pattern_set_filter (cairo_pattern_
 cairo_public cairo_filter_t
 cairo_pattern_get_filter (cairo_pattern_t *pattern);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_pattern_get_rgba (cairo_pattern_t *pattern,
 			double *red, double *green,
 			double *blue, double *alpha);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_pattern_get_surface (cairo_pattern_t *pattern,
 			   cairo_surface_t **surface);
 
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_pattern_get_color_stop_rgba (cairo_pattern_t *pattern,
 				   int index, double *offset,
 				   double *red, double *green,
 				   double *blue, double *alpha);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_pattern_get_color_stop_count (cairo_pattern_t *pattern,
 				    int *count);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_pattern_get_linear_points (cairo_pattern_t *pattern,
 				 double *x0, double *y0,
 				 double *x1, double *y1);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_pattern_get_radial_circles (cairo_pattern_t *pattern,
 				  double *x0, double *y0, double *r0,
 				  double *x1, double *y1, double *r1);
@@ -1820,7 +1820,7 @@ cairo_matrix_scale (cairo_matrix_t *matr
 cairo_public void
 cairo_matrix_rotate (cairo_matrix_t *matrix, double radians);
 
-cairo_public cairo_status_t
+cairo_public_warn cairo_status_t
 cairo_matrix_invert (cairo_matrix_t *matrix);
 
 cairo_public void
diff --git a/src/cairoint.h b/src/cairoint.h
index 77eda90..5e62529 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -102,13 +102,15 @@ CAIRO_BEGIN_DECLS
 
 /* slim_internal.h */
 #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) && !defined(__sun)
-#define cairo_private		__attribute__((__visibility__("hidden")))
+#define cairo_private			__attribute__((__visibility__("hidden"),__warn_unused_result__))
 #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
-#define cairo_private		__hidden
+#define cairo_private			__hidden CAIRO_WARN_UNUSED_RESULT
 #else /* not gcc >= 3.3 and not Sun Studio >= 8 */
-#define cairo_private
+#define cairo_private			CAIRO_WARN_UNUSED_RESULT
 #endif
 
+#define cairo_warn CAIRO_WARN_UNUSED_RESULT
+
 /* This macro allow us to deprecate a function by providing an alias
    for the old function name to the new function name. With this
    macro, binary compatibility is preserved. The macro only works on
diff --git a/src/check-headers.sh b/src/check-headers.sh
index 1d0ebf8..2ac74fd 100755
--- a/src/check-headers.sh
+++ b/src/check-headers.sh
@@ -12,7 +12,7 @@ xargs grep -B 1 '^cairo_.*[ 	]\+(' |
 awk '
 /^--$/ { context=""; public=0; next; }
 /:cairo_.*[ 	]+\(/ { if (!public) {print context; print; print "--";} next; }
-/-cairo_public[ 	]/ {public=1;}
+/-cairo_public.*[ 	]/ {public=1;}
 { context=$0; }
 ' |
 sed 's/[.]h-/.h:/' |


More information about the cairo-commit mailing list