b=383960: Upgrade cairo to 1.4.10: Cairo 1.4.10
authorvladimir@pobox.com
Sat, 30 Jun 2007 00:45:16 -0700
changeset 2964 d7088c1fdd68202d71fbfa26a97a2b9fbcb9c0fe
parent 2963 f47e4090747a5b3ce5b2dc15d22e13c0d9caa1a7
child 2965 6adab9c10fb1d7cdebb40fb5f03ffff375fddcf3
push idunknown
push userunknown
push dateunknown
bugs383960
milestone1.9a6pre
b=383960: Upgrade cairo to 1.4.10: Cairo 1.4.10
configure.in
gfx/cairo/README
gfx/cairo/cairo/src/Makefile.in
gfx/cairo/cairo/src/cairo-analysis-surface-private.h
gfx/cairo/cairo/src/cairo-analysis-surface.c
gfx/cairo/cairo/src/cairo-arc.c
gfx/cairo/cairo/src/cairo-atsui-font.c
gfx/cairo/cairo/src/cairo-base85-stream.c
gfx/cairo/cairo/src/cairo-bentley-ottmann.c
gfx/cairo/cairo/src/cairo-cache-private.h
gfx/cairo/cairo/src/cairo-cache.c
gfx/cairo/cairo/src/cairo-cff-subset.c
gfx/cairo/cairo/src/cairo-clip-private.h
gfx/cairo/cairo/src/cairo-clip.c
gfx/cairo/cairo/src/cairo-color.c
gfx/cairo/cairo/src/cairo-debug.c
gfx/cairo/cairo/src/cairo-deflate-stream.c
gfx/cairo/cairo/src/cairo-directfb-surface.c
gfx/cairo/cairo/src/cairo-directfb.h
gfx/cairo/cairo/src/cairo-features.h.in
gfx/cairo/cairo/src/cairo-font-face.c
gfx/cairo/cairo/src/cairo-font-options.c
gfx/cairo/cairo/src/cairo-font.c
gfx/cairo/cairo/src/cairo-freelist-private.h
gfx/cairo/cairo/src/cairo-freelist.c
gfx/cairo/cairo/src/cairo-ft-font.c
gfx/cairo/cairo/src/cairo-glitz-surface.c
gfx/cairo/cairo/src/cairo-gstate.c
gfx/cairo/cairo/src/cairo-hash-private.h
gfx/cairo/cairo/src/cairo-hash.c
gfx/cairo/cairo/src/cairo-image-surface.c
gfx/cairo/cairo/src/cairo-matrix.c
gfx/cairo/cairo/src/cairo-meta-surface.c
gfx/cairo/cairo/src/cairo-mutex-list-private.h
gfx/cairo/cairo/src/cairo-mutex-private.h
gfx/cairo/cairo/src/cairo-mutex-type-private.h
gfx/cairo/cairo/src/cairo-mutex.c
gfx/cairo/cairo/src/cairo-os2-surface.c
gfx/cairo/cairo/src/cairo-output-stream-private.h
gfx/cairo/cairo/src/cairo-output-stream.c
gfx/cairo/cairo/src/cairo-paginated-private.h
gfx/cairo/cairo/src/cairo-paginated-surface-private.h
gfx/cairo/cairo/src/cairo-paginated-surface.c
gfx/cairo/cairo/src/cairo-path-bounds.c
gfx/cairo/cairo/src/cairo-path-fill.c
gfx/cairo/cairo/src/cairo-path-fixed.c
gfx/cairo/cairo/src/cairo-path-stroke.c
gfx/cairo/cairo/src/cairo-path.c
gfx/cairo/cairo/src/cairo-pattern.c
gfx/cairo/cairo/src/cairo-pdf-surface-private.h
gfx/cairo/cairo/src/cairo-pdf-surface.c
gfx/cairo/cairo/src/cairo-pen.c
gfx/cairo/cairo/src/cairo-platform.h
gfx/cairo/cairo/src/cairo-png.c
gfx/cairo/cairo/src/cairo-polygon.c
gfx/cairo/cairo/src/cairo-ps-surface-private.h
gfx/cairo/cairo/src/cairo-ps-surface.c
gfx/cairo/cairo/src/cairo-quartz-private.h
gfx/cairo/cairo/src/cairo-quartz-surface.c
gfx/cairo/cairo/src/cairo-region.c
gfx/cairo/cairo/src/cairo-rename.h
gfx/cairo/cairo/src/cairo-scaled-font-private.h
gfx/cairo/cairo/src/cairo-scaled-font-subsets-private.h
gfx/cairo/cairo/src/cairo-scaled-font-subsets.c
gfx/cairo/cairo/src/cairo-scaled-font.c
gfx/cairo/cairo/src/cairo-skiplist-private.h
gfx/cairo/cairo/src/cairo-skiplist.c
gfx/cairo/cairo/src/cairo-spline.c
gfx/cairo/cairo/src/cairo-surface-fallback.c
gfx/cairo/cairo/src/cairo-surface-private.h
gfx/cairo/cairo/src/cairo-surface.c
gfx/cairo/cairo/src/cairo-svg-surface-private.h
gfx/cairo/cairo/src/cairo-svg-surface.c
gfx/cairo/cairo/src/cairo-traps.c
gfx/cairo/cairo/src/cairo-truetype-subset.c
gfx/cairo/cairo/src/cairo-type1-fallback.c
gfx/cairo/cairo/src/cairo-type1-subset.c
gfx/cairo/cairo/src/cairo-types-private.h
gfx/cairo/cairo/src/cairo-unicode.c
gfx/cairo/cairo/src/cairo-wideint-private.h
gfx/cairo/cairo/src/cairo-win32-font.c
gfx/cairo/cairo/src/cairo-win32-private.h
gfx/cairo/cairo/src/cairo-win32-surface.c
gfx/cairo/cairo/src/cairo-win32.h
gfx/cairo/cairo/src/cairo-xcb-surface.c
gfx/cairo/cairo/src/cairo-xlib-display.c
gfx/cairo/cairo/src/cairo-xlib-private.h
gfx/cairo/cairo/src/cairo-xlib-screen.c
gfx/cairo/cairo/src/cairo-xlib-surface-private.h
gfx/cairo/cairo/src/cairo-xlib-surface.c
gfx/cairo/cairo/src/cairo-xlib-xrender.h
gfx/cairo/cairo/src/cairo.c
gfx/cairo/cairo/src/cairo.h
gfx/cairo/cairo/src/cairoint.h
gfx/cairo/cairo/src/filterpublic.awk
gfx/cairo/cairo/src/test-fallback-surface.c
gfx/cairo/cairo/src/test-meta-surface.c
gfx/cairo/cairo/src/test-paginated-surface.c
gfx/cairo/libpixman/src/fbcompose.c
gfx/cairo/libpixman/src/fbedge.c
gfx/cairo/libpixman/src/fbmmx.c
gfx/cairo/libpixman/src/fbmmx.h
gfx/cairo/libpixman/src/fbpict.c
gfx/cairo/libpixman/src/fbpict.h
gfx/cairo/libpixman/src/fbtrap.c
gfx/cairo/libpixman/src/icblt.c
gfx/cairo/libpixman/src/icbltone.c
gfx/cairo/libpixman/src/iccolor.c
gfx/cairo/libpixman/src/icformat.c
gfx/cairo/libpixman/src/icimage.c
gfx/cairo/libpixman/src/icimage.h
gfx/cairo/libpixman/src/icpixels.c
gfx/cairo/libpixman/src/icrect.c
gfx/cairo/libpixman/src/icstipple.c
gfx/cairo/libpixman/src/ictransform.c
gfx/cairo/libpixman/src/ictrap.c
gfx/cairo/libpixman/src/ictri.c
gfx/cairo/libpixman/src/icutil.c
gfx/cairo/libpixman/src/pixman-remap.h
gfx/cairo/libpixman/src/pixman-xserver-compat.h
gfx/cairo/libpixman/src/pixman.h
gfx/cairo/libpixman/src/pixmanint.h
gfx/cairo/libpixman/src/pixregion.c
gfx/cairo/libpixman/src/pixregionint.h
gfx/cairo/libpixman/src/renderedge.c
--- a/configure.in
+++ b/configure.in
@@ -6963,16 +6963,17 @@ if test "$MOZ_SVG" -o "$MOZ_ENABLE_CANVA
 
        # For now we assume that we will have a uint64_t available through
        # one of the above headers or mozstdint.h.
        AC_DEFINE(HAVE_UINT64_T)
 
        # Define macros for cairo-features.h
        if test "$MOZ_X11"; then
            XLIB_SURFACE_FEATURE="#define CAIRO_HAS_XLIB_SURFACE 1"
+           XLIB_XRENDER_SURFACE_FEATURE="#define CAIRO_HAS_XLIB_XRENDER_SURFACE 1"
            PS_SURFACE_FEATURE="#define CAIRO_HAS_PS_SURFACE 1"
            PDF_SURFACE_FEATURE="#define CAIRO_HAS_PDF_SURFACE 1"
            FT_FONT_FEATURE="#define CAIRO_HAS_FT_FONT 1"
            MOZ_ENABLE_CAIRO_FT=1
            CAIRO_FT_CFLAGS="$FT2_CFLAGS"
        fi
        if test "$MOZ_WIDGET_TOOLKIT" = "mac" -o "$MOZ_WIDGET_TOOLKIT" = "cocoa"; then
            QUARTZ_SURFACE_FEATURE="#define CAIRO_HAS_QUARTZ_SURFACE 1"
@@ -7009,16 +7010,17 @@ if test "$MOZ_SVG" -o "$MOZ_ENABLE_CANVA
        fi
 
        PNG_FUNCTIONS_FEATURE="#define CAIRO_HAS_PNG_FUNCTIONS 1"
 
        AC_SUBST(PS_SURFACE_FEATURE)
        AC_SUBST(PDF_SURFACE_FEATURE)
        AC_SUBST(SVG_SURFACE_FEATURE)
        AC_SUBST(XLIB_SURFACE_FEATURE)
+       AC_SUBST(XLIB_XRENDER_SURFACE_FEATURE)
        AC_SUBST(QUARTZ_SURFACE_FEATURE)
        AC_SUBST(NQUARTZ_SURFACE_FEATURE)
        AC_SUBST(XCB_SURFACE_FEATURE)
        AC_SUBST(WIN32_SURFACE_FEATURE)
        AC_SUBST(OS2_SURFACE_FEATURE)
        AC_SUBST(BEOS_SURFACE_FEATURE)
        AC_SUBST(GLITZ_SURFACE_FEATURE)
        AC_SUBST(DIRECTFB_SURFACE_FEATURE)
--- a/gfx/cairo/README
+++ b/gfx/cairo/README
@@ -2,27 +2,25 @@ Snapshots of cairo and glitz for mozilla
 
 We only include the relevant parts of each release (generally, src/*.[ch]),
 as we have Makefile.in's that integrate into the Mozilla build system.  For
 documentation and similar, please see the official tarballs at
 http://www.cairographics.org/.
 
 VERSIONS:
 
-  cairo (1.4.2)
+  cairo (1.4.10)
   glitz 0.5.2 (cvs - 2006-01-10)
 
 ***** NOTE FOR VISUAL C++ 6.0 *****
 
 VC6 is not supported.  Please upgrade to VC8.
 
 ==== Patches ====
 
-All patches in the cairo tree are surrounded by "MOZILLA_CAIRO_NOT_DEFINED" (which should NOT be defined).
-
 Some specific things:
 
 max-font-size.patch: Clamp freetype font size to 1000 to avoid overflow issues
 
 fbcompose-bandaid.patch: Disable "optimized" code in non-MMX case due to bugs
 
 quartz-glyph-rounding.patch: Round glyph positions, not advances, to float
 
--- a/gfx/cairo/cairo/src/Makefile.in
+++ b/gfx/cairo/cairo/src/Makefile.in
@@ -65,26 +65,27 @@ CSRCS   = \
         cairo-array.c \
         cairo-bentley-ottmann.c \
         cairo-cache.c \
         cairo-clip.c \
         cairo-color.c \
         cairo-debug.c \
         cairo-deflate-stream.c \
         cairo-fixed.c \
-        cairo-font.c \
+        cairo-font-face.c \
         cairo-font-options.c \
         cairo-freelist.c \
         cairo-gstate.c \
         cairo-hash.c \
         cairo-hull.c \
         cairo-image-surface.c \
         cairo-lzw.c \
         cairo-matrix.c \
         cairo-meta-surface.c \
+        cairo-mutex.c \
         cairo-operator.c \
         cairo-output-stream.c \
         cairo-paginated-surface.c \
         cairo-path.c \
         cairo-path-bounds.c \
         cairo-path-fill.c \
         cairo-path-fixed.c \
         cairo-path-stroke.c \
@@ -149,17 +150,18 @@ endif
 
 ifdef BUILD_CAIRO_SVG
 CSRCS	+= cairo-svg-surface.c
 EXPORTS += cairo-svg.h
 endif
 
 ifdef MOZ_X11
 CSRCS   += cairo-xlib-surface.c \
-	   cairo-xlib-screen.c
+	   cairo-xlib-screen.c \
+	   cairo-xlib-display.c
 EXPORTS += cairo-xlib.h cairo-xlib-xrender.h
 endif
 
 ifdef MOZ_ENABLE_CAIRO_FT
 CSRCS   += cairo-ft-font.c
 EXPORTS += cairo-ft.h
 OS_INCLUDES += $(CAIRO_FT_CFLAGS)
 endif
--- a/gfx/cairo/cairo/src/cairo-analysis-surface-private.h
+++ b/gfx/cairo/cairo/src/cairo-analysis-surface-private.h
@@ -1,10 +1,9 @@
-/* $Id: cairo-analysis-surface-private.h,v 1.6 2007/06/11 00:01:29 vladimir%pobox.com Exp $
- *
+/*
  * Copyright © 2005 Keith Packard
  *
  * This library is free software; you can redistribute it and/or
  * modify it either under the terms of the GNU Lesser General Public
  * License version 2.1 as published by the Free Software Foundation
  * (the "LGPL") or, at your option, under the terms of the Mozilla
  * Public License Version 1.1 (the "MPL"). If you do not alter this
  * notice, a recipient may use your version of this file under either
--- a/gfx/cairo/cairo/src/cairo-analysis-surface.c
+++ b/gfx/cairo/cairo/src/cairo-analysis-surface.c
@@ -30,17 +30,17 @@
  *
  * Contributor(s):
  *      Keith Packard <keithp@keithp.com>
  */
 
 #include "cairoint.h"
 
 #include "cairo-analysis-surface-private.h"
-#include "cairo-paginated-surface-private.h"
+#include "cairo-paginated-private.h"
 
 typedef struct {
     cairo_surface_t base;
     int width;
     int height;
 
     cairo_surface_t	*target;
 
--- a/gfx/cairo/cairo/src/cairo-arc.c
+++ b/gfx/cairo/cairo/src/cairo-arc.c
@@ -29,16 +29,18 @@
  *
  * The Initial Developer of the Original Code is University of Southern
  * California.
  *
  * Contributor(s):
  *	Carl D. Worth <cworth@cworth.org>
  */
 
+#include "cairoint.h"
+
 #include "cairo-arc-private.h"
 
 /* Spline deviation from the circle in radius would be given by:
 
 	error = sqrt (x**2 + y**2) - 1
 
    A simpler error function to work with is:
 
@@ -80,17 +82,17 @@ static double
 	{ M_PI / 5.0,   1.11281001494389081528e-06 },
 	{ M_PI / 6.0,   3.72662000942734705475e-07 },
 	{ M_PI / 7.0,   1.47783685574284411325e-07 },
 	{ M_PI / 8.0,   6.63240432022601149057e-08 },
 	{ M_PI / 9.0,   3.2715520137536980553e-08 },
 	{ M_PI / 10.0,  1.73863223499021216974e-08 },
 	{ M_PI / 11.0,  9.81410988043554039085e-09 },
     };
-    int table_size = (sizeof (table) / sizeof (table[0]));
+    int table_size = ARRAY_LENGTH (table);
 
     for (i = 0; i < table_size; i++)
 	if (table[i].error < tolerance)
 	    return table[i].angle;
 
     ++i;
     do {
 	angle = M_PI / i++;
--- a/gfx/cairo/cairo/src/cairo-atsui-font.c
+++ b/gfx/cairo/cairo/src/cairo-atsui-font.c
@@ -29,21 +29,20 @@
  * The Original Code is the cairo graphics library.
  *
  * The Initial Developer of the Original Code is Calum Robinson
  *
  * Contributor(s):
  *  Calum Robinson <calumr@mac.com>
  */
 
-#include <stdlib.h>
-#include <math.h>
+#include "cairoint.h"
+
+#include "cairo.h"
 #include "cairo-atsui.h"
-#include "cairoint.h"
-#include "cairo.h"
 #include "cairo-quartz-private.h"
 
 /*
  * FixedToFloat/FloatToFixed are 10.3+ SDK items - include definitions
  * here so we can use older SDKs.
  */
 #ifndef FixedToFloat
 #define fixed1              ((Fixed) 0x00010000L)
@@ -112,30 +111,42 @@ static cairo_status_t
     cairo_atsui_font_face_t *font_face = abstract_face;
     OSStatus err;
     ATSUAttributeTag styleTags[] = { kATSUFontTag };
     ATSUAttributeValuePtr styleValues[] = { &font_face->font_id };
     ByteCount styleSizes[] = {  sizeof(ATSUFontID) };
     ATSUStyle style;
 
     err = ATSUCreateStyle (&style);
-    err = ATSUSetAttributes(style,
-                            sizeof(styleTags) / sizeof(styleTags[0]),
+    err = ATSUSetAttributes(style, ARRAY_LENGTH (styleTags),
                             styleTags, styleSizes, styleValues);
 
     return _cairo_atsui_font_create_scaled (&font_face->base, font_face->font_id, style,
 					    font_matrix, ctm, options, font);
 }
 
 static const cairo_font_face_backend_t _cairo_atsui_font_face_backend = {
     CAIRO_FONT_TYPE_ATSUI,
     _cairo_atsui_font_face_destroy,
     _cairo_atsui_font_face_scaled_font_create
 };
 
+/**
+ * cairo_atsui_font_face_create_for_atsu_font_id
+ * @font_id: an ATSUFontID for the font.
+ *
+ * Creates a new font for the ATSUI font backend based on an
+ * #ATSUFontID. This font can then be used with
+ * cairo_set_font_face() or cairo_scaled_font_create().
+ *
+ * Return value: a newly created #cairo_font_face_t. Free with
+ *  cairo_font_face_destroy() when you are done using it.
+ *
+ * Since: 1.4
+ **/
 cairo_font_face_t *
 cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id)
 {
   cairo_atsui_font_face_t *font_face;
 
   font_face = malloc (sizeof (cairo_atsui_font_face_t));
   if (!font_face) {
     _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -144,24 +155,16 @@ cairo_atsui_font_face_create_for_atsu_fo
 
   font_face->font_id = font_id;
 
     _cairo_font_face_init (&font_face->base, &_cairo_atsui_font_face_backend);
 
     return &font_face->base;
 }
 
-static CGAffineTransform
-CGAffineTransformMakeWithCairoFontScale(const cairo_matrix_t *scale)
-{
-    return CGAffineTransformMake(scale->xx, scale->yx,
-                                 scale->xy, scale->yy,
-                                 0, 0);
-}
-
 static ATSUStyle
 CreateSizedCopyOfStyle(ATSUStyle inStyle, 
 		       const Fixed *theSize, 
 		       const CGAffineTransform *theTransform)
 {
     ATSUStyle style;
     OSStatus err;
     const ATSUAttributeTag theFontStyleTags[] = { kATSUSizeTag, 
@@ -227,18 +230,23 @@ static cairo_status_t
     cairo_status_t status;
     double xscale = 1.0;
     double yscale = 1.0;
 
     font = malloc(sizeof(cairo_atsui_font_t));
     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);
     font->font_matrix = CGAffineTransformMake (1., 0.,
 					       0., yscale/xscale,
 					       0., 0.);
     font->size = FloatToFixed (xscale);
 
@@ -369,18 +377,17 @@ static cairo_status_t
 
     {
 	ATSUAttributeTag styleTags[] =
 	    { kATSUQDItalicTag, kATSUQDBoldfaceTag, kATSUFontTag };
 	ATSUAttributeValuePtr styleValues[] = { &isItalic, &isBold, &fontID };
 	ByteCount styleSizes[] =
 	    { sizeof(Boolean), sizeof(Boolean), sizeof(ATSUFontID) };
 
-	err = ATSUSetAttributes(style,
-				sizeof(styleTags) / sizeof(styleTags[0]),
+	err = ATSUSetAttributes(style, ARRAY_LENGTH (styleTags),
 				styleTags, styleSizes, styleValues);
     }
 
     return _cairo_atsui_font_create_scaled (&toy_face->base, fontID, style,
 					    font_matrix, ctm, options, font_out);
 }
 
 static void
@@ -392,83 +399,33 @@ static void
         return;
 
     if (font->style)
         ATSUDisposeStyle(font->style);
     if (font->unscaled_style)
         ATSUDisposeStyle(font->unscaled_style);
 }
 
-static
-OSStatus _move_to_for_metrics (const Float32Point *point, void *callback_data)
-{
-    CGMutablePathRef path = callback_data;
-
-    CGPathMoveToPoint (path, &CGAffineTransformIdentity,
-			   point->x, point->y);
-    return noErr;
-}
-
-static
-OSStatus _line_to_for_metrics(const Float32Point *point, void *callback_data)
-{
-    CGMutablePathRef path = callback_data;
-
-    CGPathAddLineToPoint (path, &CGAffineTransformIdentity,
-			   point->x, point->y);
-    return noErr;
-}
-
-static
-OSStatus _curve_to_for_metrics (const Float32Point *point1,
-				const Float32Point *point2,
-				const Float32Point *point3,
-				void *callback_data)
-{
-    CGMutablePathRef path = callback_data;
-
-    CGPathAddCurveToPoint (path, &CGAffineTransformIdentity,
-			   point1->x, point1->y,
-			   point2->x, point2->y,
-			   point3->x, point3->y);
-    return noErr;
-}
-
-static
-OSStatus _close_path_for_metrics(void *callback_data)
-{
-    CGMutablePathRef path = callback_data;
-
-    CGPathCloseSubpath (path);
-    return noErr;
-}
-
 static GlyphID 
 _cairo_atsui_scaled_glyph_index (cairo_scaled_glyph_t *scaled_glyph) {
     unsigned long index = _cairo_scaled_glyph_index (scaled_glyph);
     if (index > 0xffff) 
 	return kATSDeletedGlyphcode;
     return index;
 }
 
 static cairo_status_t
 _cairo_atsui_font_init_glyph_metrics (cairo_atsui_font_t *scaled_font,
 				      cairo_scaled_glyph_t *scaled_glyph)
 {
     cairo_text_extents_t extents = {0, 0, 0, 0, 0, 0};
-    OSStatus err, callback_err;
+    OSStatus err;
     ATSGlyphScreenMetrics metricsH;
-    static ATSCubicMoveToUPP moveProc = NULL;
-    static ATSCubicLineToUPP lineProc = NULL;
-    static ATSCubicCurveToUPP curveProc = NULL;
-    static ATSCubicClosePathUPP closePathProc = NULL;
-    CGMutablePathRef path;
     GlyphID theGlyph = _cairo_atsui_scaled_glyph_index (scaled_glyph);
     double xscale, yscale;
-    CGRect rect;
 
     if (theGlyph == kATSDeletedGlyphcode) {
 	_cairo_scaled_glyph_set_metrics (scaled_glyph,
 					 &scaled_font->base,
 					 &extents);
 	return CAIRO_STATUS_SUCCESS;
     }
 
@@ -484,51 +441,25 @@ static cairo_status_t
     /* Scale down to font units.*/
     _cairo_matrix_compute_scale_factors (&scaled_font->base.scale,
 					 &xscale, &yscale, 1);
     xscale = 1.0/xscale;
     yscale = 1.0/yscale;
 
     extents.x_advance = metricsH.deviceAdvance.x * xscale;
     extents.y_advance = 0;
-
-    if (moveProc == NULL) {
-        moveProc = NewATSCubicMoveToUPP (_move_to_for_metrics);
-        lineProc = NewATSCubicLineToUPP (_line_to_for_metrics);
-        curveProc = NewATSCubicCurveToUPP (_curve_to_for_metrics);
-        closePathProc = NewATSCubicClosePathUPP (_close_path_for_metrics);
-    }
-
-    path = CGPathCreateMutable ();
-
-    /* The callback error contains any error our functions returned.
-     * Its only meaningful if err != noErr, and we don't currently
-     * use it for anything.
-     */
-    err = ATSUGlyphGetCubicPaths (scaled_font->style, theGlyph,
-				  moveProc, lineProc, curveProc, closePathProc,
-				  (void *)path, &callback_err);
-
-    if (err != noErr) {
-	CGPathRelease (path);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
-
-    rect = CGPathGetBoundingBox (path);
-
-    extents.x_bearing = rect.origin.x * xscale;
-    extents.y_bearing = rect.origin.y * yscale;
-    extents.width = rect.size.width * xscale;
-    extents.height = rect.size.height * yscale;
+    
+    extents.x_bearing = metricsH.topLeft.x * xscale;
+    extents.y_bearing = -metricsH.topLeft.y * yscale;
+    extents.width = metricsH.width * xscale;
+    extents.height = metricsH.height * yscale;
 
     _cairo_scaled_glyph_set_metrics (scaled_glyph,
 				     &scaled_font->base,
 				     &extents);
-    CGPathRelease (path);
-
     return CAIRO_STATUS_SUCCESS;
 }
 
 static OSStatus
 _move_to (const Float32Point *point,
 	  void *callback_data)
 {
     cairo_atsui_scaled_path_t *scaled_path = callback_data;
@@ -662,54 +593,63 @@ static cairo_status_t
 static cairo_status_t
 _cairo_atsui_scaled_font_init_glyph_surface (cairo_atsui_font_t *scaled_font,
 					     cairo_scaled_glyph_t *scaled_glyph)
 {
     OSStatus err;
     CGContextRef drawingContext;
     cairo_image_surface_t *surface;
     cairo_format_t format;
+    cairo_status_t status;
 
     ATSFontRef atsFont;
     CGFontRef cgFont;
     cairo_scaled_font_t base = scaled_font->base;
     cairo_font_extents_t extents = base.extents;
 
     GlyphID theGlyph = _cairo_atsui_scaled_glyph_index (scaled_glyph);
     ATSGlyphScreenMetrics metricsH;
     double left, bottom, width, height;
     double xscale, yscale;
     CGRect bbox;
     CGAffineTransform transform;
 
 
     if (theGlyph == kATSDeletedGlyphcode) {
 	surface = (cairo_image_surface_t *)cairo_image_surface_create (CAIRO_FORMAT_A8, 2, 2);
-	if (!surface)
-	    return CAIRO_STATUS_NO_MEMORY;
+	status = cairo_surface_status ((cairo_surface_t *)surface);
+	if (status)
+	    return status;
+
 	_cairo_scaled_glyph_set_surface (scaled_glyph,
 					 &base,
 					 surface);
 	return CAIRO_STATUS_SUCCESS;
     }
 
     /* Compute a box to contain the glyph mask. The vertical
-     * sizes come from the font extents; extra pixels are 
+     * sizes come from the font extents; extra pixels are
      * added to account for fractional sizes.
      */
     height = extents.ascent + extents.descent + 2.0;
     bottom = -extents.descent - 1.0;
 
+    _cairo_matrix_compute_scale_factors (&base.scale,
+					&xscale, &yscale, 1);
+    bbox = CGRectApplyAffineTransform (CGRectMake (1.0, bottom, 1.0, height), CGAffineTransformMakeScale(xscale, yscale));
+    bottom = CGRectGetMinY (bbox);
+    height = bbox.size.height;
+
     /* Horizontal sizes come from the glyph typographic metrics.
      * It is possible that this might result in clipped text
      * in fonts where the typographic bounds don't cover the ink.
      * The width is recalculated, since metricsH.width is rounded.
      */
     err = ATSUGlyphGetScreenMetrics (scaled_font->style,
-				     1, &theGlyph, 0, false, 
+				     1, &theGlyph, 0, false,
 				     false, &metricsH);    
     left = metricsH.sideBearing.x - 1.0;
     width = metricsH.deviceAdvance.x 
 	- metricsH.sideBearing.x 
 	+ metricsH.otherSideBearing.x + 2.0;
 
     /* The xy and yx components are negated because the y-axis
      * is flipped into the cairo system then flipped back, ie:
@@ -738,18 +678,19 @@ static cairo_status_t
     left = CGRectGetMinX (bbox);
     bottom = CGRectGetMinY (bbox);
 
     /* XXX should we select format based on antialiasing flags, as ft does? */
     format = CAIRO_FORMAT_A8;
 
     /* 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;
+    status = cairo_surface_status ((cairo_surface_t *)surface);
+    if (status)
+	return status;
 
     /* Create a CGBitmapContext for the dest surface for drawing into */
     {
 	CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray ();
     
 	drawingContext = CGBitmapContextCreate (surface->data,
 						surface->width,
 						surface->height,
--- a/gfx/cairo/cairo/src/cairo-base85-stream.c
+++ b/gfx/cairo/cairo/src/cairo-base85-stream.c
@@ -110,17 +110,17 @@ static cairo_status_t
 
 cairo_output_stream_t *
 _cairo_base85_stream_create (cairo_output_stream_t *output)
 {
     cairo_base85_stream_t *stream;
 
     stream = malloc (sizeof (cairo_base85_stream_t));
     if (stream == NULL)
-	return (cairo_output_stream_t *) &cairo_output_stream_nil;
+	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
 
     _cairo_output_stream_init (&stream->base,
 			       _cairo_base85_stream_write,
 			       _cairo_base85_stream_close);
     stream->output = output;
     stream->pending = 0;
 
     return &stream->base;
--- a/gfx/cairo/cairo/src/cairo-bentley-ottmann.c
+++ b/gfx/cairo/cairo/src/cairo-bentley-ottmann.c
@@ -132,16 +132,17 @@ typedef struct _cairo_bo_event_queue {
 /* This structure extends cairo_skip_list_t, which must come first. */
 typedef struct _cairo_bo_sweep_line {
     cairo_skip_list_t active_edges;
     cairo_bo_edge_t *head;
     cairo_bo_edge_t *tail;
     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)
 {
     int cmp = a->y - b->y;
     if (cmp) return cmp;
     return a->x - b->x;
 }
@@ -687,23 +688,26 @@ static void
 		      cairo_bo_point32_t	 point)
 {
     event->type = type;
     event->e1 = e1;
     event->e2 = e2;
     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
 _cairo_bo_event_queue_delete (cairo_bo_event_queue_t *queue,
 			      cairo_bo_event_t	     *event)
 {
     if (CAIRO_BO_EVENT_TYPE_INTERSECTION == event->type)
 	_cairo_skip_list_delete_given ( &queue->intersection_queue, &event->elt );
@@ -745,26 +749,24 @@ static cairo_status_t
 		    sizeof (cairo_bo_event_t));
     if (0 == num_edges)
 	return CAIRO_STATUS_SUCCESS;
 
     /* The skip_elt_t field of a cairo_bo_event_t isn't used for start
      * or stop events, so this allocation is safe.  XXX: make the
      * event type a union so it doesn't always contain the skip
      * elt? */
-    events = malloc (num_events * sizeof(cairo_bo_event_t));
-    sorted_event_ptrs = malloc (num_events * sizeof(cairo_bo_event_t*));
-    if (!events || !sorted_event_ptrs) {
-	if (events) free(events);
-	if (sorted_event_ptrs) free(sorted_event_ptrs);
+    events = malloc (num_events * (sizeof (cairo_bo_event_t) + sizeof(cairo_bo_event_t*)));
+    if (events == NULL)
 	return CAIRO_STATUS_NO_MEMORY;
-    }
+
+    sorted_event_ptrs = (cairo_bo_event_t **) (events + num_events);
     event_queue->startstop_events = events;
     event_queue->sorted_startstop_event_ptrs = sorted_event_ptrs;
-    event_queue->num_startstop_events = (unsigned)(num_events);
+    event_queue->num_startstop_events = num_events;
     event_queue->next_startstop_event_index = 0;
 
     for (i = 0; i < num_edges; i++) {
 	sorted_event_ptrs[2*i] = &events[2*i];
 	sorted_event_ptrs[2*i+1] = &events[2*i+1];
 
 	/* Initialize "middle" to top */
 	edges[i].middle = edges[i].top;
@@ -787,53 +789,51 @@ static cairo_status_t
 }
 
 static void
 _cairo_bo_event_queue_fini (cairo_bo_event_queue_t *event_queue)
 {
     _cairo_skip_list_fini (&event_queue->intersection_queue);
     if (event_queue->startstop_events)
 	free (event_queue->startstop_events);
-    if (event_queue->sorted_startstop_event_ptrs)
-	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)
 {
     cairo_bo_status_t status;
     cairo_bo_point32_t intersection;
     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
      * slope comparison also puts left less than right, then we know
      * 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,
 			  CAIRO_BO_EVENT_TYPE_INTERSECTION,
 			  left, right,
 			  intersection);
 
-    _cairo_bo_event_queue_insert (event_queue, &event);
+    return _cairo_bo_event_queue_insert (event_queue, &event);
 }
 
 static void
 _cairo_bo_sweep_line_init (cairo_bo_sweep_line_t *sweep_line)
 {
     _cairo_skip_list_init (&sweep_line->active_edges,
 		    _sweep_line_elt_compare,
 		    sizeof (sweep_line_elt_t));
@@ -843,26 +843,28 @@ static void
 }
 
 static void
 _cairo_bo_sweep_line_fini (cairo_bo_sweep_line_t *sweep_line)
 {
     _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)
 {
     skip_elt_t *next_elt;
     sweep_line_elt_t *sweep_line_elt;
     cairo_bo_edge_t **prev_of_next, **next_of_prev;
 
     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)
 	prev_of_next = & (SKIP_ELT_TO_EDGE (next_elt)->prev);
     else
 	prev_of_next = &sweep_line->tail;
 
     if (*prev_of_next)
@@ -871,16 +873,18 @@ static void
 	next_of_prev = &sweep_line->head;
 
     edge->prev = *prev_of_next;
     edge->next = *next_of_prev;
     *prev_of_next = edge;
     *next_of_prev = edge;
 
     edge->sweep_line_elt = sweep_line_elt;
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static void
 _cairo_bo_sweep_line_delete (cairo_bo_sweep_line_t	*sweep_line,
 			     cairo_bo_edge_t	*edge)
 {
     cairo_bo_edge_t **left_next, **right_prev;
 
@@ -1052,17 +1056,16 @@ print_state (const char			*msg,
 /* Adds the trapezoid, if any, of the left edge to the cairo_traps_t
  * of bo_traps. */
 static cairo_status_t
 _cairo_bo_edge_end_trap (cairo_bo_edge_t	*left,
 			 int32_t		bot,
 			 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;
 
     if (!trap)
 	return CAIRO_STATUS_SUCCESS;
 
      /* If the right edge of the trapezoid stopped earlier than the
       * left edge, then cut the trapezoid bottom early. */
@@ -1094,35 +1097,36 @@ static cairo_status_t
 	 * TODO: need a real collinearity test here for the cases
 	 * where the trapezoid is degenerate, yet the top and bottom
 	 * coordinates aren't equal.  */
 	if (left_top.x != right_top.x ||
 	    left_top.y != right_top.y ||
 	    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) "
 		    "right=(%08x,%08x)-(%08x,%08x) top=%08x, bot=%08x\n",
 		    left->top.x, left->top.y, left->bottom.x, left->bottom.y,
 		    right->top.x, right->top.y, right->bottom.x, right->bottom.y,
 		    trap->top, bot);
 #endif
 	}
     }
 
     _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
  * are `edge' and `edge->next'. If `edge' already has a trapezoid,
  * then either add it to the traps in `bo_traps', if the trapezoid's
  * right edge differs from `edge->next', or do nothing if the new
  * trapezoid would be a continuation of the existing one. */
 static cairo_status_t
@@ -1249,27 +1253,30 @@ static cairo_status_t
 					    cairo_fill_rule_t	 fill_rule,
 					    cairo_traps_t	*traps,
 					    cairo_fixed_t	xmin,
 					    cairo_fixed_t	ymin,
 					    cairo_fixed_t	xmax,
 					    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;
     cairo_bo_traps_t bo_traps;
     cairo_bo_event_t *event, event_saved;
     cairo_bo_edge_t *edge;
     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);
 
 #if DEBUG_PRINT_STATE
     print_state ("After initializing", &event_queue, &sweep_line);
 #endif
 
     while (1)
@@ -1291,27 +1298,33 @@ static cairo_status_t
 	event_saved = *event;
 	_cairo_bo_event_queue_delete (&event_queue, event);
 	event = &event_saved;
 
 	switch (event->type) {
 	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);
 	    */
 
 	    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);
 #endif
 	    _cairo_bo_sweep_line_validate (&sweep_line);
 
 	    break;
 	case CAIRO_BO_EVENT_TYPE_STOP:
@@ -1321,17 +1334,19 @@ static cairo_status_t
 	    right = edge->next;
 
 	    _cairo_bo_sweep_line_delete (&sweep_line, edge);
 
 	    status = _cairo_bo_edge_end_trap (edge, edge->bottom.y, &bo_traps);
 	    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);
 #endif
 	    _cairo_bo_sweep_line_validate (&sweep_line);
 
 	    break;
 	case CAIRO_BO_EVENT_TYPE_INTERSECTION:
@@ -1349,21 +1364,25 @@ static cairo_status_t
 
 	    left = edge1->prev;
 	    right = edge2->next;
 
 	    _cairo_bo_sweep_line_swap (&sweep_line, edge1, edge2);
 
 	    /* 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);
 #endif
 	    _cairo_bo_sweep_line_validate (&sweep_line);
 
 	    break;
 	}
@@ -1397,30 +1416,35 @@ update_minmax(cairo_fixed_t *inout_min,
 
 cairo_status_t
 _cairo_bentley_ottmann_tessellate_polygon (cairo_traps_t	*traps,
 					   cairo_polygon_t	*polygon,
 					   cairo_fill_rule_t	 fill_rule)
 {
     int intersections;
     cairo_status_t status;
+    cairo_bo_edge_t stack_edges[CAIRO_STACK_BUFFER_SIZE / sizeof (cairo_bo_edge_t)];
     cairo_bo_edge_t *edges;
     cairo_fixed_t xmin = 0x7FFFFFFF;
     cairo_fixed_t ymin = 0x7FFFFFFF;
     cairo_fixed_t xmax = -0x80000000;
     cairo_fixed_t ymax = -0x80000000;
     int num_bo_edges;
     int i;
 
     if (0 == polygon->num_edges)
 	return CAIRO_STATUS_SUCCESS;
 
-    edges = malloc (polygon->num_edges * sizeof (cairo_bo_edge_t));
-    if (edges == NULL)
-	return CAIRO_STATUS_NO_MEMORY;
+    if (polygon->num_edges < ARRAY_LENGTH (stack_edges)) {
+	edges = stack_edges;
+    } else {
+	edges = malloc (polygon->num_edges * sizeof (cairo_bo_edge_t));
+	if (edges == NULL)
+	    return CAIRO_STATUS_NO_MEMORY;
+    }
 
     /* Figure out the bounding box of the input coordinates and
      * validate that we're not given invalid polygon edges. */
     for (i = 0; i < polygon->num_edges; i++) {
 	update_minmax (&xmin, &xmax, polygon->edges[i].edge.p1.x);
 	update_minmax (&ymin, &ymax, polygon->edges[i].edge.p1.y);
 	update_minmax (&xmin, &xmax, polygon->edges[i].edge.p2.x);
 	update_minmax (&ymin, &ymax, polygon->edges[i].edge.p2.y);
@@ -1490,17 +1514,18 @@ cairo_status_t
      * passes of the Bentley-Ottmann algorithm. It would merely
      * require storing the results of each pass into a temporary
      * cairo_traps_t. */
     status = _cairo_bentley_ottmann_tessellate_bo_edges (edges, num_bo_edges,
 							 fill_rule, traps,
 							 xmin, ymin, xmax, ymax,
 							 &intersections);
 
-    free (edges);
+    if (edges != stack_edges)
+	free (edges);
 
     return status;
 }
 
 #if 0
 static cairo_bool_t
 edges_have_an_intersection_quadratic (cairo_bo_edge_t	*edges,
 				      int		 num_edges)
@@ -1766,17 +1791,17 @@ run_test (const char		*test_name,
 int
 main (void)
 {
     char random_name[] = "random-XX";
     cairo_bo_edge_t random_edges[MAX_RANDOM], *edge;
     unsigned int i, num_random;
     test_t *test;
 
-    for (i = 0; i < sizeof (tests) / sizeof (tests[0]); i++) {
+    for (i = 0; i < ARRAY_LENGTH (tests); i++) {
 	test = &tests[i];
 	run_test (test->name, test->edges, test->num_edges);
     }
 
     for (num_random = 0; num_random < MAX_RANDOM; num_random++) {
 	srand (0);
 	for (i = 0; i < num_random; i++) {
 	    do {
--- a/gfx/cairo/cairo/src/cairo-cache-private.h
+++ b/gfx/cairo/cairo/src/cairo-cache-private.h
@@ -34,17 +34,17 @@
  *      Keith Packard <keithp@keithp.com>
  *	Graydon Hoare <graydon@redhat.com>
  *	Carl Worth <cworth@cworth.org>
  */
 
 #ifndef CAIRO_CACHE_PRIVATE_H
 #define CAIRO_CACHE_PRIVATE_H
 
-typedef struct _cairo_cache cairo_cache_t;
+#include "cairo-types-private.h"
 
 /**
  * cairo_cache_entry_t:
  *
  * A #cairo_cache_entry_t contains both a key and a value for
  * cairo_cache_t. User-derived types for cairo_cache_entry_t must
  * have a cairo_cache_entry_t as their first field. For example:
  *
--- a/gfx/cairo/cairo/src/cairo-cache.c
+++ b/gfx/cairo/cairo/src/cairo-cache.c
@@ -33,27 +33,16 @@
  * Contributor(s):
  *      Keith Packard <keithp@keithp.com>
  *	Graydon Hoare <graydon@redhat.com>
  *	Carl Worth <cworth@cworth.org>
  */
 
 #include "cairoint.h"
 
-struct _cairo_cache {
-    cairo_hash_table_t *hash_table;
-
-    cairo_destroy_func_t entry_destroy;
-
-    unsigned long max_size;
-    unsigned long size;
-
-    int freeze_count;
-};
-
 static void
 _cairo_cache_remove (cairo_cache_t	 *cache,
 		     cairo_cache_entry_t *entry);
 
 static void
 _cairo_cache_shrink_to_accommodate (cairo_cache_t *cache,
 				   unsigned long  additional);
 
--- a/gfx/cairo/cairo/src/cairo-cff-subset.c
+++ b/gfx/cairo/cairo/src/cairo-cff-subset.c
@@ -32,39 +32,44 @@
  * Contributor(s):
  *	Adrian Johnson <ajohnson@redneon.com>
  *      Eugeniy Meshcheryakov <eugen@debian.org>
  */
 
 #include "cairoint.h"
 #include "cairo-scaled-font-subsets-private.h"
 #include "cairo-truetype-subset-private.h"
+#include <string.h>
 
 /* CFF Dict Operators. If the high byte is 0 the command is encoded
  * with a single byte. */
 #define BASEFONTNAME_OP  0x0c16
+#define CIDCOUNT_OP      0x0c22
 #define CHARSET_OP       0x000f
 #define CHARSTRINGS_OP   0x0011
 #define COPYRIGHT_OP     0x0c00
 #define ENCODING_OP      0x0010
 #define FAMILYNAME_OP    0x0003
+#define FDARRAY_OP       0x0c24
+#define FDSELECT_OP      0x0c25
+#define FONTBBOX_OP      0x0005
 #define FONTNAME_OP      0x0c26
 #define FULLNAME_OP      0x0002
 #define LOCAL_SUB_OP     0x0013
 #define NOTICE_OP        0x0001
 #define POSTSCRIPT_OP    0x0c15
 #define PRIVATE_OP       0x0012
 #define ROS_OP           0x0c1e
+#define UNIQUEID_OP      0x000d
 #define VERSION_OP       0x0000
 #define WEIGHT_OP        0x0004
+#define XUID_OP          0x000e
 
 #define NUM_STD_STRINGS 391
 
-#define ARRAY_LENGTH(a) ( (sizeof (a)) / (sizeof ((a)[0])) )
-
 typedef struct _cff_header {
     uint8_t major;
     uint8_t minor;
     uint8_t header_size;
     uint8_t offset_size;
 } cff_header_t;
 
 typedef struct _cff_index_element {
@@ -77,23 +82,16 @@ typedef struct _cff_dict_operator {
     cairo_hash_entry_t base;
 
     unsigned short operator;
     unsigned char *operand;
     int            operand_length;
     int            operand_offset;
 } cff_dict_operator_t;
 
-typedef struct _cff_charset {
-    cairo_bool_t         is_builtin;
-    const uint16_t      *sids;
-    const unsigned char *data;
-    int                  length;
-} cff_charset_t;
-
 typedef struct _cairo_cff_font {
 
     cairo_scaled_font_subset_t *scaled_font_subset;
     const cairo_scaled_font_backend_t *backend;
 
     /* Font Data */
     unsigned char       *data;
     unsigned long        data_length;
@@ -103,24 +101,33 @@ typedef struct _cairo_cff_font {
     char                *font_name;
     cairo_hash_table_t  *top_dict;
     cairo_hash_table_t  *private_dict;
     cairo_array_t        strings_index;
     cairo_array_t        charstrings_index;
     cairo_array_t        global_sub_index;
     cairo_array_t        local_sub_index;
     int                  num_glyphs;
-    cff_charset_t        charset;
-    int                  charset_offset;
+    cairo_bool_t         is_cid;
+
+    /* CID Font Data */
+    int                 *fdselect;
+    unsigned int         num_fontdicts;
+    cairo_hash_table_t **fd_dict;
+    cairo_hash_table_t **fd_private_dict;
+    cairo_array_t       *fd_local_sub_index;
 
     /* Subsetted Font Data */
     char                *subset_font_name;
     cairo_array_t        charstrings_subset_index;
     cairo_array_t        strings_subset_index;
-    cairo_array_t        charset_subset;
+    int                 *fdselect_subset;
+    unsigned int         num_subset_fontdicts;
+    int                 *fd_subset_map;
+    int                 *private_dict_offset;
     cairo_array_t        output;
 
     /* Subset Metrics */
     int                 *widths;
     int                  x_min, y_min, x_max, y_max;
     int                  ascent, descent;
 
 } cairo_cff_font_t;
@@ -342,17 +349,16 @@ cff_index_write (cairo_array_t *index, c
 
     for (i = 0; i < num_elem; i++) {
         element = _cairo_array_index (index, i);
         offset += element->length;
         encode_index_offset (buf, offset_size, offset);
         status = _cairo_array_append_multiple (output, buf, offset_size);
         if (status)
             return status;
-
     }
 
     for (i = 0; i < num_elem; i++) {
         element = _cairo_array_index (index, i);
         status = _cairo_array_append_multiple (output,
                                                element->data,
                                                element->length);
         if (status)
@@ -369,17 +375,19 @@ cff_index_append (cairo_array_t *index, 
     element.length = length;
     element.is_copy = FALSE;
     element.data = object;
 
     return _cairo_array_append (index, &element);
 }
 
 static cairo_status_t
-cff_index_append_copy (cairo_array_t *index, unsigned char *object , int length)
+cff_index_append_copy (cairo_array_t *index,
+                       const unsigned char *object,
+                       unsigned int length)
 {
     cff_index_element_t element;
 
     element.length = length;
     element.is_copy = TRUE;
     element.data = malloc (element.length);
     if (element.data == NULL)
         return CAIRO_STATUS_NO_MEMORY;
@@ -483,16 +491,31 @@ cff_dict_read (cairo_hash_table_t *dict,
     }
 
 fail:
     _cairo_array_fini (&operands);
 
     return status;
 }
 
+static void
+cff_dict_remove (cairo_hash_table_t *dict, unsigned short operator)
+{
+    cff_dict_operator_t key, *op;
+
+    _cairo_dict_init_key (&key, operator);
+    if (_cairo_hash_table_lookup (dict, &key.base,
+                                  (cairo_hash_entry_t **) &op))
+    {
+        free (op->operand);
+        _cairo_hash_table_remove (dict, (cairo_hash_entry_t *) op);
+        free (op);
+    }
+}
+
 static unsigned char *
 cff_dict_get_operands (cairo_hash_table_t *dict,
                        unsigned short      operator,
                        int                *size)
 {
     cff_dict_operator_t key, *op;
 
     _cairo_dict_init_key (&key, operator);
@@ -558,49 +581,65 @@ cff_dict_get_location (cairo_hash_table_
 }
 
 typedef struct _dict_write_info {
     cairo_array_t *output;
     cairo_status_t status;
 } dict_write_info_t;
 
 static void
-_cairo_dict_collect (void *entry, void *closure)
+cairo_dict_write_operator (cff_dict_operator_t *op, dict_write_info_t *write_info)
 {
-    dict_write_info_t *write_info = closure;
-    cff_dict_operator_t *op = entry;
     unsigned char data;
 
-    if (write_info->status)
-        return;
-
     op->operand_offset = _cairo_array_num_elements (write_info->output);
-    write_info->status = _cairo_array_append_multiple (write_info->output,
-                                                       op->operand,
-                                                       op->operand_length);
+    write_info->status = _cairo_array_append_multiple (write_info->output, op->operand, op->operand_length);
     if (write_info->status)
         return;
 
     if (op->operator & 0xff00) {
         data = op->operator >> 8;
         write_info->status = _cairo_array_append (write_info->output, &data);
         if (write_info->status)
             return;
     }
     data = op->operator & 0xff;
     write_info->status = _cairo_array_append (write_info->output, &data);
 }
 
+static void
+_cairo_dict_collect (void *entry, void *closure)
+{
+    dict_write_info_t   *write_info = closure;
+    cff_dict_operator_t *op = entry;
+
+    if (write_info->status)
+        return;
+
+    /* The ROS operator is handled separately in cff_dict_write() */
+    if (op->operator != ROS_OP)
+        cairo_dict_write_operator (op, write_info);
+}
+
 static cairo_status_t
 cff_dict_write (cairo_hash_table_t *dict, cairo_array_t *output)
 {
     dict_write_info_t write_info;
+    cff_dict_operator_t key, *op;
 
     write_info.output = output;
     write_info.status = CAIRO_STATUS_SUCCESS;
+
+    /* The CFF specification requires that the Top Dict of CID fonts
+     * begin with the ROS operator. */
+    _cairo_dict_init_key (&key, ROS_OP);
+    if (_cairo_hash_table_lookup (dict, &key.base,
+                                  (cairo_hash_entry_t **) &op))
+        cairo_dict_write_operator (op, &write_info);
+
     _cairo_hash_table_foreach (dict, _cairo_dict_collect, &write_info);
 
     return write_info.status;
 }
 
 static void
 cff_dict_fini (cairo_hash_table_t *dict)
 {
@@ -641,42 +680,163 @@ cairo_cff_font_read_name (cairo_cff_font
     status = cff_index_read (&index, &font->current_ptr, font->data_end);
     cff_index_fini (&index);
 
     return status;
 }
 
 static cairo_int_status_t
 cairo_cff_font_read_private_dict (cairo_cff_font_t   *font,
+                                  cairo_hash_table_t *private_dict,
+                                  cairo_array_t      *local_sub_index,
                                   unsigned char      *ptr,
                                   int                 size)
 {
     unsigned char buf[10];
     unsigned char *end_buf;
     int offset;
     int i;
     unsigned char *operand;
     unsigned char *p;
 
-    cff_dict_read (font->private_dict, ptr, size);
-    operand = cff_dict_get_operands (font->private_dict, LOCAL_SUB_OP, &i);
+    cff_dict_read (private_dict, ptr, size);
+    operand = cff_dict_get_operands (private_dict, LOCAL_SUB_OP, &i);
     if (operand) {
         decode_integer (operand, &offset);
         p = ptr + offset;
-        cff_index_read (&font->local_sub_index, &p, font->data_end);
+        cff_index_read (local_sub_index, &p, font->data_end);
 
         /* Use maximum sized encoding to reserve space for later modification. */
         end_buf = encode_integer_max (buf, 0);
-        cff_dict_set_operands (font->private_dict, LOCAL_SUB_OP, buf, end_buf - buf);
+        cff_dict_set_operands (private_dict, LOCAL_SUB_OP, buf, end_buf - buf);
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+cairo_cff_font_read_fdselect (cairo_cff_font_t *font, unsigned char *p)
+{
+    int type, num_ranges, first, last, fd, i, j;
+
+    font->fdselect = calloc (font->num_glyphs, sizeof (int));
+    if (font->fdselect == NULL)
+        return CAIRO_STATUS_NO_MEMORY;
+
+    type = *p++;
+    if (type == 0)
+    {
+        for (i = 0; i < font->num_glyphs; i++)
+            font->fdselect[i] = *p++;
+    } else if (type == 3) {
+        num_ranges = be16_to_cpu( *((uint16_t *)p) );
+        p += 2;
+        for  (i = 0; i < num_ranges; i++)
+        {
+            first = be16_to_cpu( *((uint16_t *)p) );
+            p += 2;
+            fd = *p++;
+            last = be16_to_cpu( *((uint16_t *)p) );
+            for (j = first; j < last; j++)
+                font->fdselect[j] = fd;
+        }
+    } else {
+        return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_int_status_t
+cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr)
+{
+    cairo_array_t index;
+    cff_index_element_t *element;
+    unsigned int i;
+    int size;
+    unsigned char *operand;
+    int offset;
+    cairo_int_status_t status;
+    unsigned char buf[100];
+    unsigned char *end_buf;
+
+    cff_index_init (&index);
+    status = cff_index_read (&index, &ptr, font->data_end);
+    if (status)
+        goto fail;
+
+    font->num_fontdicts = _cairo_array_num_elements (&index);
+
+    font->fd_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts);
+    if (font->fd_dict == NULL) {
+        status = CAIRO_STATUS_NO_MEMORY;
+        goto fail;
+    }
+
+    font->fd_private_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts);
+    if (font->fd_private_dict == NULL) {
+        status = CAIRO_STATUS_NO_MEMORY;
+        goto fail;
+    }
+
+    font->fd_local_sub_index = calloc (sizeof (cairo_array_t), font->num_fontdicts);
+    if (font->fd_local_sub_index == NULL) {
+        status = CAIRO_STATUS_NO_MEMORY;
+        goto fail;
+    }
+
+    for (i = 0; i < font->num_fontdicts; i++) {
+        cff_dict_init (&font->fd_dict[i]);
+        if (font->fd_dict[i] == NULL) {
+            status = CAIRO_STATUS_NO_MEMORY;
+            goto fail;
+        }
+        element = _cairo_array_index (&index, i);
+        status = cff_dict_read (font->fd_dict[i], element->data, element->length);
+        if (status)
+            goto fail;
+
+        operand = cff_dict_get_operands (font->fd_dict[i], PRIVATE_OP, &size);
+        if (operand == NULL) {
+            status = CAIRO_INT_STATUS_UNSUPPORTED;
+            goto fail;
+        }
+        operand = decode_integer (operand, &size);
+        decode_integer (operand, &offset);
+        cff_dict_init (&font->fd_private_dict[i]);
+        if (font->fd_private_dict[i] == NULL) {
+            status = CAIRO_STATUS_NO_MEMORY;
+            goto fail;
+        }
+        cff_index_init (&font->fd_local_sub_index[i]);
+        status = cairo_cff_font_read_private_dict (font,
+                                                   font->fd_private_dict[i],
+                                                   &font->fd_local_sub_index[i],
+                                                   font->data + offset,
+                                                   size);
+        if (status)
+            goto fail;
+        /* Set integer operand to max value to use max size encoding to reserve
+         * space for any value later */
+        end_buf = encode_integer_max (buf, 0);
+        end_buf = encode_integer_max (end_buf, 0);
+        status = cff_dict_set_operands (font->fd_dict[i], PRIVATE_OP, buf, end_buf - buf);
+        if (status)
+            goto fail;
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+
+fail:
+    cff_index_fini (&index);
+
+    return status;
+}
+
+static cairo_int_status_t
 cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
 {
     cairo_array_t index;
     cff_index_element_t *element;
     unsigned char buf[20];
     unsigned char *end_buf;
     unsigned char *operand;
     cairo_int_status_t status;
@@ -685,53 +845,66 @@ cairo_cff_font_read_top_dict (cairo_cff_
     int offset;
 
     cff_index_init (&index);
     status = cff_index_read (&index, &font->current_ptr, font->data_end);
     if (status)
         goto fail;
 
     element = _cairo_array_index (&index, 0);
-    cff_dict_read (font->top_dict, element->data, element->length);
+    status = cff_dict_read (font->top_dict, element->data, element->length);
+    if (status)
+        goto fail;
 
-    /* CID fonts are NYI */
-    if (cff_dict_get_operands (font->top_dict, ROS_OP, &size) != NULL) {
-        status = CAIRO_INT_STATUS_UNSUPPORTED;
-        goto fail;
-    }
+    if (cff_dict_get_operands (font->top_dict, ROS_OP, &size) != NULL)
+        font->is_cid = TRUE;
+    else
+        font->is_cid = FALSE;
 
     operand = cff_dict_get_operands (font->top_dict, CHARSTRINGS_OP, &size);
     decode_integer (operand, &offset);
     p = font->data + offset;
     status = cff_index_read (&font->charstrings_index, &p, font->data_end);
     if (status)
         goto fail;
     font->num_glyphs = _cairo_array_num_elements (&font->charstrings_index);
 
-    operand = cff_dict_get_operands (font->top_dict, PRIVATE_OP, &size);
-    operand = decode_integer (operand, &size);
-    decode_integer (operand, &offset);
-    cairo_cff_font_read_private_dict (font, font->data + offset, size);
+    if (font->is_cid) {
+        operand = cff_dict_get_operands (font->top_dict, FDSELECT_OP, &size);
+        decode_integer (operand, &offset);
+        cairo_cff_font_read_fdselect (font, font->data + offset);
 
-    operand = cff_dict_get_operands (font->top_dict, CHARSET_OP, &size);
-    if (!operand)
-      font->charset_offset = 0;
-    else {
-      decode_integer (operand, &offset);
-      font->charset_offset = offset;
+        operand = cff_dict_get_operands (font->top_dict, FDARRAY_OP, &size);
+        decode_integer (operand, &offset);
+        cairo_cff_font_read_cid_fontdict (font, font->data + offset);
+    } else {
+        operand = cff_dict_get_operands (font->top_dict, PRIVATE_OP, &size);
+        operand = decode_integer (operand, &size);
+        decode_integer (operand, &offset);
+        cairo_cff_font_read_private_dict (font,
+                                          font->private_dict,
+                                          &font->local_sub_index,
+                                          font->data + offset,
+                                          size);
     }
 
     /* Use maximum sized encoding to reserve space for later modification. */
     end_buf = encode_integer_max (buf, 0);
     cff_dict_set_operands (font->top_dict, CHARSTRINGS_OP, buf, end_buf - buf);
-    cff_dict_set_operands (font->top_dict, ENCODING_OP, buf, end_buf - buf);
+    cff_dict_set_operands (font->top_dict, FDSELECT_OP, buf, end_buf - buf);
+    cff_dict_set_operands (font->top_dict, FDARRAY_OP, buf, end_buf - buf);
     cff_dict_set_operands (font->top_dict, CHARSET_OP, buf, end_buf - buf);
-    /* Private has two operands - size and offset */
-    end_buf = encode_integer_max (end_buf, 0);
-    cff_dict_set_operands (font->top_dict, PRIVATE_OP, buf, end_buf - buf);
+
+    cff_dict_remove (font->top_dict, ENCODING_OP);
+    cff_dict_remove (font->top_dict, PRIVATE_OP);
+
+    /* Remove the unique identifier operators as the subsetted font is
+     * not the same is the original font. */
+    cff_dict_remove (font->top_dict, UNIQUEID_OP);
+    cff_dict_remove (font->top_dict, XUID_OP);
 
 fail:
     cff_index_fini (&index);
 
     return status;
 }
 
 static cairo_int_status_t
@@ -741,159 +914,25 @@ cairo_cff_font_read_strings (cairo_cff_f
 }
 
 static cairo_int_status_t
 cairo_cff_font_read_global_subroutines (cairo_cff_font_t *font)
 {
     return cff_index_read (&font->global_sub_index, &font->current_ptr, font->data_end);
 }
 
-static cairo_int_status_t
-cff_charset_read_data (cff_charset_t *charset, const unsigned char *data,
-	const unsigned char *data_end, int num_glyphs)
-{
-    const unsigned char *p = data;
-
-    num_glyphs -= 1; /* do not count .notdef */
-
-    if (p + 1 > data_end)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    switch (*p++) {
-    case 0:
-	if (p + num_glyphs*2 > data_end)
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-	charset->is_builtin = FALSE;
-	charset->data = data;
-	charset->length = num_glyphs * 2 + 1;
-	break;
-    case 1:
-	while (num_glyphs > 0) {
-	    if (p + 3 > data_end)
-		return CAIRO_INT_STATUS_UNSUPPORTED;
-	    num_glyphs -= p[2] + 1;
-	    p += 3;
-	}
-	if (num_glyphs < 0)
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-	charset->is_builtin = FALSE;
-	charset->data = data;
-	charset->length = p - data;
-	break;
-    case 2:
-	while (num_glyphs > 0) {
-	    if (p + 4 > data_end)
-		return CAIRO_INT_STATUS_UNSUPPORTED;
-	    num_glyphs -= be16_to_cpu(*(uint16_t *)(p + 2)) + 1;
-	    p += 4;
-	}
-	if (num_glyphs < 0)
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-	charset->is_builtin = FALSE;
-	charset->data = data;
-	charset->length = p - data;
-	break;
-    default:
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-    }
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static const uint16_t ISOAdobe_charset[] = {
-    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
-    17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
-    31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
-    45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
-    59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
-    73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
-    87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
-    101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
-    112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
-    123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133,
-    134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
-    145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155,
-    156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166,
-    167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177,
-    178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188,
-    189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
-    200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210,
-    211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221,
-    222, 223, 224, 225, 226, 227, 228,
-};
-
-static const uint16_t Expert_charset[] = {
-    1, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 13,
-    14, 15, 99, 239, 240, 241, 242, 243, 244, 245, 246, 247,
-    248, 27, 28, 249, 250, 251, 252, 253, 254, 255, 256, 257,
-    258, 259, 260, 261, 262, 263, 264, 265, 266, 109, 110,
-    267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277,
-    278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288,
-    289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299,
-    300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310,
-    311, 312, 313, 314, 315, 316, 317, 318, 158, 155, 163,
-    319, 320, 321, 322, 323, 324, 325, 326, 150, 164, 169,
-    327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337,
-    338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348,
-    349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359,
-    360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370,
-    371, 372, 373, 374, 375, 376, 377, 378,
-};
-
-static const uint16_t ExpertSubset_charset[] = {
-    1, 231, 232, 235, 236, 237, 238, 13, 14, 15, 99, 239, 240,
-    241, 242, 243, 244, 245, 246, 247, 248, 27, 28, 249, 250,
-    251, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262,
-    263, 264, 265, 266, 109, 110, 267, 268, 269, 270, 272,
-    300, 301, 302, 305, 314, 315, 158, 155, 163, 320, 321,
-    322, 323, 324, 325, 326, 150, 164, 169, 327, 328, 329,
-    330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340,
-    341, 342, 343, 344, 345, 346,
-};
-
-static cairo_int_status_t
-cairo_cff_font_read_charset (cairo_cff_font_t *font)
-{
-    switch (font->charset_offset) {
-    case 0:
-	/* ISOAdobe charset */
-	font->charset.is_builtin = TRUE;
-        font->charset.sids = ISOAdobe_charset;
-        font->charset.length = sizeof (ISOAdobe_charset);
-	return CAIRO_STATUS_SUCCESS;
-    case 1:
-	/* Expert charset */
-	font->charset.is_builtin = TRUE;
-        font->charset.sids = Expert_charset;
-        font->charset.length = sizeof (Expert_charset);
-	return CAIRO_STATUS_SUCCESS;
-    case 2:
-	/* ExpertSubset charset */;
-	font->charset.is_builtin = TRUE;
-        font->charset.sids = ExpertSubset_charset;
-        font->charset.length = sizeof (ExpertSubset_charset);
-	return CAIRO_STATUS_SUCCESS;
-    default:
-	break;
-    }
-    return cff_charset_read_data (&font->charset, font->data + (unsigned)font->charset_offset,
-	    font->data_end, font->num_glyphs);
-}
-
 typedef cairo_int_status_t
 (*font_read_t) (cairo_cff_font_t *font);
 
 static const font_read_t font_read_funcs[] = {
     cairo_cff_font_read_header,
     cairo_cff_font_read_name,
     cairo_cff_font_read_top_dict,
     cairo_cff_font_read_strings,
     cairo_cff_font_read_global_subroutines,
-    /* non-contiguous */
-    cairo_cff_font_read_charset,
 };
 
 static cairo_int_status_t
 cairo_cff_font_read_font (cairo_cff_font_t *font)
 {
     cairo_int_status_t status;
     unsigned int i;
 
@@ -901,16 +940,44 @@ cairo_cff_font_read_font (cairo_cff_font
         status = font_read_funcs[i] (font);
         if (status)
             return status;
     }
 
     return CAIRO_STATUS_SUCCESS;
 }
 
+static void
+cairo_cff_font_set_ros_strings (cairo_cff_font_t *font)
+{
+    unsigned char buf[30];
+    unsigned char *p;
+    int sid1, sid2;
+    const char *registry = "Adobe";
+    const char *ordering = "Identity";
+
+    sid1 = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
+    cff_index_append_copy (&font->strings_subset_index,
+                           (unsigned char *)registry,
+                           strlen(registry));
+
+    sid2 = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
+    cff_index_append_copy (&font->strings_subset_index,
+                           (unsigned char *)ordering,
+                           strlen(ordering));
+
+    p = encode_integer (buf, sid1);
+    p = encode_integer (p, sid2);
+    p = encode_integer (p, 0);
+    cff_dict_set_operands (font->top_dict, ROS_OP, buf, p - buf);
+
+    p = encode_integer (buf, font->scaled_font_subset->num_glyphs);
+    cff_dict_set_operands (font->top_dict, CIDCOUNT_OP, buf, p - buf);
+}
+
 static cairo_status_t
 cairo_cff_font_subset_dict_string(cairo_cff_font_t   *font,
                                   cairo_hash_table_t *dict,
                                   int                 operator)
 {
     int size;
     unsigned char *p;
     int sid;
@@ -962,148 +1029,156 @@ cairo_cff_font_subset_dict_strings (cair
         if (status)
             return status;
     }
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
-cairo_cff_font_subset_strings (cairo_cff_font_t *font)
-{
-    cairo_status_t status;
-
-    status = cairo_cff_font_subset_dict_strings (font, font->top_dict);
-    if (status)
-        return status;
-
-    status = cairo_cff_font_subset_dict_strings (font, font->private_dict);
-
-    return status;
-}
-
-static cairo_status_t
 cairo_cff_font_subset_charstrings (cairo_cff_font_t  *font)
 {
     cff_index_element_t *element;
     unsigned int i;
     cairo_status_t status;
 
-    /* add .notdef */
-    element = _cairo_array_index (&font->charstrings_index, 0);
-    status = cff_index_append (&font->charstrings_subset_index,
-                               element->data,
-                               element->length);
-    if (status)
-        return status;
-
     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
         element = _cairo_array_index (&font->charstrings_index,
                                       font->scaled_font_subset->glyphs[i]);
         status = cff_index_append (&font->charstrings_subset_index,
                                    element->data,
                                    element->length);
         if (status)
             return status;
     }
 
     return CAIRO_STATUS_SUCCESS;
 }
 
-static uint16_t
-cff_sid_from_gid (const cff_charset_t *charset, int gid)
+static cairo_status_t
+cairo_cff_font_subset_fontdict (cairo_cff_font_t  *font)
 {
-    const uint16_t *sids;
-    const unsigned char *p;
-    int prev_glyph;
+    unsigned int i;
+    int fd;
+    int *reverse_map;
+
+    font->fdselect_subset = calloc (font->scaled_font_subset->num_glyphs,
+                                     sizeof (int));
+    if (font->fdselect_subset == NULL)
+        return CAIRO_STATUS_NO_MEMORY;
+
+    font->fd_subset_map = calloc (font->num_fontdicts, sizeof (int));
+    if (font->fd_subset_map == NULL)
+        return CAIRO_STATUS_NO_MEMORY;
 
-    if (charset->is_builtin) {
-        if (gid - 1 < charset->length / 2)
-	    return charset->sids[gid - 1];
+    font->private_dict_offset = calloc (font->num_fontdicts, sizeof (int));
+    if (font->private_dict_offset == NULL)
+        return CAIRO_STATUS_NO_MEMORY;
+
+    reverse_map = calloc (font->num_fontdicts, sizeof (int));
+    if (reverse_map == NULL)
+        return CAIRO_STATUS_NO_MEMORY;
+
+    for (i = 0; i < font->num_fontdicts; i++)
+        reverse_map[i] = -1;
+
+    font->num_subset_fontdicts = 0;
+    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
+        fd = font->fdselect[font->scaled_font_subset->glyphs[i]];
+        if (reverse_map[fd] < 0) {
+            font->fd_subset_map[font->num_subset_fontdicts] = fd;
+            reverse_map[fd] = font->num_subset_fontdicts++;
+        }
+        font->fdselect_subset[i] = reverse_map[fd];
     }
-    else {
-	/* no need to check sizes here, this was done during reading */
-	switch (charset->data[0]) {
-	case 0:
-	    sids = (const uint16_t *)(charset->data + 1);
-	    return be16_to_cpu(sids[gid - 1]);
-	case 1:
-	    prev_glyph = 1;
-	    for (p = charset->data + 1; p < charset->data + charset->length; p += 3) {
-		if (gid <= prev_glyph + p[2]) {
-		    uint16_t sid = be16_to_cpu(*(const uint16_t *)p);
-		    return sid + gid - prev_glyph;
-		}
-		prev_glyph += p[2] + 1;
-	    }
-	    break;
-	case 2:
-	    prev_glyph = 1;
-	    for (p = charset->data + 1; p < charset->data + charset->length; p += 4) {
-		uint16_t nLeft = be16_to_cpu(*(const uint16_t *)(p + 2));
-		if (gid <= prev_glyph + nLeft) {
-		    uint16_t sid = be16_to_cpu(*(const uint16_t *)p);
-		    return sid + gid - prev_glyph;
-		}
-		prev_glyph += nLeft + 1;
-	    }
-	    break;
-	default:
-	    break;
-	}
-    }
-    return 0;
+
+    free (reverse_map);
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
-cairo_cff_font_subset_charset (cairo_cff_font_t  *font)
+cairo_cff_font_create_cid_fontdict (cairo_cff_font_t *font)
 {
+    unsigned char buf[100];
+    unsigned char *end_buf;
+
+    font->num_fontdicts = 1;
+    font->fd_dict = malloc (sizeof (cairo_hash_table_t *));
+    if (font->fd_dict == NULL)
+        return CAIRO_STATUS_NO_MEMORY;
+
+    cff_dict_init (&font->fd_dict[0]);
+
+    font->fd_subset_map = malloc (sizeof (int));
+    if (font->fd_subset_map == NULL)
+        return CAIRO_STATUS_NO_MEMORY;
+
+    font->private_dict_offset = malloc (sizeof (int));
+    if (font->private_dict_offset == NULL)
+        return CAIRO_STATUS_NO_MEMORY;
+
+    font->fd_subset_map[0] = 0;
+    font->num_subset_fontdicts = 1;
+
+    /* Set integer operand to max value to use max size encoding to reserve
+     * space for any value later */
+    end_buf = encode_integer_max (buf, 0);
+    end_buf = encode_integer_max (end_buf, 0);
+    cff_dict_set_operands (font->fd_dict[0], PRIVATE_OP, buf, end_buf - buf);
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+cairo_cff_font_subset_strings (cairo_cff_font_t *font)
+{
+    cairo_status_t status;
     unsigned int i;
 
-    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
-	int gid = font->scaled_font_subset->glyphs[i];
-	uint16_t original_sid = cff_sid_from_gid(&font->charset, gid);
-	uint16_t new_sid;
-	cff_index_element_t *element;
-	cairo_status_t status;
+    status = cairo_cff_font_subset_dict_strings (font, font->top_dict);
+    if (status)
+        return status;
+    if (font->is_cid) {
+        for (i = 0; i < font->num_subset_fontdicts; i++) {
+            status = cairo_cff_font_subset_dict_strings (font, font->fd_dict[font->fd_subset_map[i]]);
+            if (status)
+                return status;
 
-	if (original_sid >= NUM_STD_STRINGS) {
-	    element = _cairo_array_index (&font->strings_index, original_sid - NUM_STD_STRINGS);
-	    new_sid = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
-	    status = cff_index_append (&font->strings_subset_index, element->data, element->length);
-	    if (status)
-		return status;
-	}
-	else
-	    new_sid = original_sid;
+            status = cairo_cff_font_subset_dict_strings (font, font->fd_private_dict[font->fd_subset_map[i]]);
+            if (status)
+                return status;
+        }
+    } else {
+        status = cairo_cff_font_subset_dict_strings (font, font->private_dict);
+    }
 
-	status = _cairo_array_append(&font->charset_subset, &new_sid);
-	if (status)
-	    return status;
-    }
-    return CAIRO_STATUS_SUCCESS;
+    return status;
 }
 
 static cairo_status_t
 cairo_cff_font_subset_font (cairo_cff_font_t  *font)
 {
     cairo_status_t status;
 
-    /* TODO: subset subroutines */
+    cairo_cff_font_set_ros_strings (font);
+
+    status = cairo_cff_font_subset_charstrings (font);
+    if (status)
+        return status;
+
+    if (font->is_cid)
+        cairo_cff_font_subset_fontdict (font);
+    else
+        cairo_cff_font_create_cid_fontdict (font);
 
     status = cairo_cff_font_subset_strings (font);
     if (status)
         return status;
 
-    status = cairo_cff_font_subset_charstrings (font);
-    if (status)
-	return status;
-
-    status = cairo_cff_font_subset_charset (font);
-
     return status;
 }
 
 /* Set the operand of the specified operator in the (already written)
  * top dict to point to the current position in the output
  * array. Operands updated with this function must have previously
  * been encoded with the 5-byte (max) integer encoding. */
 static void
@@ -1207,114 +1282,255 @@ cairo_cff_font_write_strings (cairo_cff_
 
 static cairo_status_t
 cairo_cff_font_write_global_subrs (cairo_cff_font_t  *font)
 {
     return cff_index_write (&font->global_sub_index, &font->output);
 }
 
 static cairo_status_t
-cairo_cff_font_write_encoding (cairo_cff_font_t  *font)
+cairo_cff_font_write_fdselect (cairo_cff_font_t  *font)
 {
-    unsigned char buf[10];
+    unsigned char data;
+    unsigned int i;
+    cairo_int_status_t status;
+
+    cairo_cff_font_set_topdict_operator_to_cur_pos (font, FDSELECT_OP);
+
+    if (font->is_cid) {
+        data = 0;
+        status = _cairo_array_append (&font->output, &data);
+        if (status)
+            return status;
+
+        for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
+            data = font->fdselect_subset[i];
+            status = _cairo_array_append (&font->output, &data);
+            if (status)
+                return status;
+        }
+    } else {
+        unsigned char byte;
+        uint16_t word;
 
-    cairo_cff_font_set_topdict_operator_to_cur_pos (font, ENCODING_OP);
-    buf[0] = 1; /* Format 1 */
-    buf[1] = 1; /* Number of ranges */
-    buf[2] = 0; /* First code in range */
-    /* Codes left in range excluding first */
-    buf[3] = font->scaled_font_subset->num_glyphs - 1;
+        status = _cairo_array_grow_by (&font->output, 9);
+        if (status)
+            return status;
+
+        byte = 3;
+        status = _cairo_array_append (&font->output, &byte);
+        assert (status == CAIRO_STATUS_SUCCESS);
+
+        word = cpu_to_be16 (1);
+        status = _cairo_array_append_multiple (&font->output, &word, 2);
+        assert (status == CAIRO_STATUS_SUCCESS);
 
-    return _cairo_array_append_multiple (&font->output, buf, 4);
+        word = cpu_to_be16 (0);
+        status = _cairo_array_append_multiple (&font->output, &word, 2);
+        assert (status == CAIRO_STATUS_SUCCESS);
+
+        byte = 0;
+        status = _cairo_array_append (&font->output, &byte);
+        assert (status == CAIRO_STATUS_SUCCESS);
+
+        word = cpu_to_be16 (font->scaled_font_subset->num_glyphs);
+        status = _cairo_array_append_multiple (&font->output, &word, 2);
+        assert (status == CAIRO_STATUS_SUCCESS);
+    }
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
 cairo_cff_font_write_charset (cairo_cff_font_t  *font)
 {
-    unsigned char format = 0;
-    unsigned int i;
+    unsigned char byte;
+    uint16_t word;
     cairo_status_t status;
 
     cairo_cff_font_set_topdict_operator_to_cur_pos (font, CHARSET_OP);
-    status = _cairo_array_append (&font->output, &format);
+    status = _cairo_array_grow_by (&font->output, 5);
     if (status)
-	return status;
+        return status;
+
+    byte = 2;
+    status = _cairo_array_append (&font->output, &byte);
+    assert (status == CAIRO_STATUS_SUCCESS);
 
-    for (i = 0; i < (unsigned)_cairo_array_num_elements(&font->charset_subset); i++) {
-	uint16_t sid = cpu_to_be16(*(uint16_t *)_cairo_array_index(&font->charset_subset, i));
-	status = _cairo_array_append_multiple (&font->output, &sid, sizeof(sid));
-	if (status)
-	    return status;
-    }
+    word = cpu_to_be16 (1);
+    status = _cairo_array_append_multiple (&font->output, &word, 2);
+    assert (status == CAIRO_STATUS_SUCCESS);
+
+    word = cpu_to_be16 (font->scaled_font_subset->num_glyphs - 2);
+    status = _cairo_array_append_multiple (&font->output, &word, 2);
+    assert (status == CAIRO_STATUS_SUCCESS);
+
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
 cairo_cff_font_write_charstrings (cairo_cff_font_t  *font)
 {
     cairo_cff_font_set_topdict_operator_to_cur_pos (font, CHARSTRINGS_OP);
 
     return cff_index_write (&font->charstrings_subset_index, &font->output);
 }
 
 static cairo_status_t
-cairo_cff_font_write_private_dict_and_local_sub (cairo_cff_font_t *font)
+cairo_cff_font_write_cid_fontdict (cairo_cff_font_t *font)
 {
-    int offset, private_dict_offset;
+    unsigned int i;
+    cairo_int_status_t status;
+    uint32_t *offset_array;
+    int offset_base;
+    uint16_t count;
+    uint8_t offset_size = 4;
+
+    cairo_cff_font_set_topdict_operator_to_cur_pos (font, FDARRAY_OP);
+    count = cpu_to_be16 (font->num_subset_fontdicts);
+    status = _cairo_array_append_multiple (&font->output, &count, sizeof (uint16_t));
+    if (status)
+        return status;
+    status = _cairo_array_append (&font->output, &offset_size);
+    if (status)
+        return status;
+    status = _cairo_array_allocate (&font->output,
+                                    (font->num_subset_fontdicts + 1)*offset_size,
+                                    (void **) &offset_array);
+    if (status)
+        return status;
+    offset_base = _cairo_array_num_elements (&font->output) - 1;
+    *offset_array++ = cpu_to_be32(1);
+    for (i = 0; i < font->num_subset_fontdicts; i++) {
+        status = cff_dict_write (font->fd_dict[font->fd_subset_map[i]],
+                                 &font->output);
+        if (status)
+            return status;
+        *offset_array++ = cpu_to_be32(_cairo_array_num_elements (&font->output) - offset_base);
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+cairo_cff_font_write_private_dict (cairo_cff_font_t   *font,
+                                   int                 dict_num,
+                                   cairo_hash_table_t *parent_dict,
+                                   cairo_hash_table_t *private_dict)
+{
+    int offset;
     int size;
     unsigned char buf[10];
     unsigned char *buf_end;
     unsigned char *p;
     cairo_status_t status;
 
     /* Write private dict and update offset and size in top dict */
-    private_dict_offset = _cairo_array_num_elements (&font->output);
-    status = cff_dict_write (font->private_dict, &font->output);
+    font->private_dict_offset[dict_num] = _cairo_array_num_elements (&font->output);
+    status = cff_dict_write (private_dict, &font->output);
     if (status)
         return status;
-    size = _cairo_array_num_elements (&font->output) - private_dict_offset;
+    size = _cairo_array_num_elements (&font->output) - font->private_dict_offset[dict_num];
     /* private entry has two operands - size and offset */
     buf_end = encode_integer_max (buf, size);
-    buf_end = encode_integer_max (buf_end, private_dict_offset);
-    offset = cff_dict_get_location (font->top_dict, PRIVATE_OP, &size);
+    buf_end = encode_integer_max (buf_end, font->private_dict_offset[dict_num]);
+    offset = cff_dict_get_location (parent_dict, PRIVATE_OP, &size);
     assert (offset > 0);
     p = _cairo_array_index (&font->output, offset);
     memcpy (p, buf, buf_end - buf);
 
-    if (_cairo_array_num_elements (&font->local_sub_index) > 0) {
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+cairo_cff_font_write_local_sub (cairo_cff_font_t   *font,
+                                int                 dict_num,
+                                cairo_hash_table_t *private_dict,
+                                cairo_array_t      *local_sub_index)
+{
+    int offset;
+    int size;
+    unsigned char buf[10];
+    unsigned char *buf_end;
+    unsigned char *p;
+    cairo_status_t status;
+
+    if (_cairo_array_num_elements (local_sub_index) > 0) {
         /* Write local subroutines and update offset in private
          * dict. Local subroutines offset is relative to start of
          * private dict */
-        offset = _cairo_array_num_elements (&font->output) - private_dict_offset;
+        offset = _cairo_array_num_elements (&font->output) - font->private_dict_offset[dict_num];
         buf_end = encode_integer_max (buf, offset);
-        offset = cff_dict_get_location (font->private_dict, LOCAL_SUB_OP, &size);
+        offset = cff_dict_get_location (private_dict, LOCAL_SUB_OP, &size);
         assert (offset > 0);
         p = _cairo_array_index (&font->output, offset);
         memcpy (p, buf, buf_end - buf);
-        status = cff_index_write (&font->local_sub_index, &font->output);
+        status = cff_index_write (local_sub_index, &font->output);
         if (status)
             return status;
     }
 
     return CAIRO_STATUS_SUCCESS;
 }
 
+
+static cairo_status_t
+cairo_cff_font_write_cid_private_dict_and_local_sub (cairo_cff_font_t  *font)
+{
+    unsigned int i;
+    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
+
+    if (font->is_cid) {
+        for (i = 0; i < font->num_subset_fontdicts; i++) {
+            status = cairo_cff_font_write_private_dict (
+                            font,
+                            i,
+                            font->fd_dict[font->fd_subset_map[i]],
+                            font->fd_private_dict[font->fd_subset_map[i]]);
+            if (status)
+                return status;
+        }
+
+        for (i = 0; i < font->num_subset_fontdicts; i++) {
+            status = cairo_cff_font_write_local_sub (
+                            font,
+                            i,
+                            font->fd_private_dict[font->fd_subset_map[i]],
+                           &font->fd_local_sub_index[font->fd_subset_map[i]]);
+            if (status)
+                return status;
+        }
+    } else {
+        status = cairo_cff_font_write_private_dict (font,
+                                                    0,
+                                                    font->fd_dict[0],
+                                                    font->private_dict);
+        status = cairo_cff_font_write_local_sub (font,
+                                                 0,
+                                                 font->private_dict,
+                                                 &font->local_sub_index);
+    }
+
+    return status;
+}
+
 typedef cairo_status_t
 (*font_write_t) (cairo_cff_font_t *font);
 
 static const font_write_t font_write_funcs[] = {
     cairo_cff_font_write_header,
     cairo_cff_font_write_name,
     cairo_cff_font_write_top_dict,
     cairo_cff_font_write_strings,
     cairo_cff_font_write_global_subrs,
-    cairo_cff_font_write_encoding,
+    cairo_cff_font_write_fdselect,
     cairo_cff_font_write_charset,
     cairo_cff_font_write_charstrings,
-    cairo_cff_font_write_private_dict_and_local_sub,
+    cairo_cff_font_write_cid_fontdict,
+    cairo_cff_font_write_cid_private_dict_and_local_sub,
 };
 
 static cairo_status_t
 cairo_cff_font_write_subset (cairo_cff_font_t *font)
 {
     cairo_int_status_t status;
     unsigned int i;
 
@@ -1368,17 +1584,17 @@ cairo_cff_font_create_set_widths (cairo_
     size = sizeof (tt_hhea_t);
     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
                                                  TT_TAG_hhea, 0,
                                                  (unsigned char*) &hhea, &size);
     if (status)
         return status;
     num_hmetrics = be16_to_cpu (hhea.num_hmetrics);
 
-    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
+    for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
         glyph_index = font->scaled_font_subset->glyphs[i];
         long_entry_size = 2 * sizeof (int16_t);
         short_entry_size = sizeof (int16_t);
         if (glyph_index < num_hmetrics) {
             status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
                                                          TT_TAG_hmtx,
                                                          glyph_index * long_entry_size,
                                                          buf, &short_entry_size);
@@ -1550,17 +1766,23 @@ static cairo_int_status_t
     cff_dict_init (&font->top_dict);
     cff_dict_init (&font->private_dict);
     cff_index_init (&font->strings_index);
     cff_index_init (&font->charstrings_index);
     cff_index_init (&font->global_sub_index);
     cff_index_init (&font->local_sub_index);
     cff_index_init (&font->charstrings_subset_index);
     cff_index_init (&font->strings_subset_index);
-    _cairo_array_init (&font->charset_subset, sizeof(uint16_t));
+    font->fdselect = NULL;
+    font->fd_dict = NULL;
+    font->fd_private_dict = NULL;
+    font->fd_local_sub_index = NULL;
+    font->fdselect_subset = NULL;
+    font->fd_subset_map = NULL;
+    font->private_dict_offset = NULL;
 
     free (name);
     *font_return = font;
 
     return CAIRO_STATUS_SUCCESS;
 
 fail7:
     free (font->data);
@@ -1577,29 +1799,67 @@ fail2:
 fail1:
     free (name);
     return status;
 }
 
 static void
 cairo_cff_font_destroy (cairo_cff_font_t *font)
 {
+    unsigned int i;
+
     free (font->widths);
     free (font->font_name);
     free (font->subset_font_name);
     _cairo_array_fini (&font->output);
     cff_dict_fini (font->top_dict);
     cff_dict_fini (font->private_dict);
     cff_index_fini (&font->strings_index);
     cff_index_fini (&font->charstrings_index);
     cff_index_fini (&font->global_sub_index);
     cff_index_fini (&font->local_sub_index);
     cff_index_fini (&font->charstrings_subset_index);
     cff_index_fini (&font->strings_subset_index);
-    _cairo_array_fini (&font->charset_subset);
+
+    /* If we bailed out early as a result of an error some of the
+     * following cairo_cff_font_t members may still be NULL */
+    if (font->fd_dict) {
+        for (i = 0; i < font->num_fontdicts; i++) {
+            if (font->fd_dict[i])
+                cff_dict_fini (font->fd_dict[i]);
+        }
+        free (font->fd_dict);
+    }
+    if (font->fd_subset_map)
+        free (font->fd_subset_map);
+    if (font->private_dict_offset)
+        free (font->private_dict_offset);
+
+    if (font->is_cid) {
+        if (font->fdselect)
+            free (font->fdselect);
+        if (font->fdselect_subset)
+            free (font->fdselect_subset);
+        if (font->fd_private_dict) {
+            for (i = 0; i < font->num_fontdicts; i++) {
+                if (font->fd_private_dict[i])
+                    cff_dict_fini (font->fd_private_dict[i]);
+            }
+            free (font->fd_private_dict);
+        }
+        if (font->fd_local_sub_index) {
+            for (i = 0; i < font->num_fontdicts; i++)
+                cff_index_fini (&font->fd_local_sub_index[i]);
+            free (font->fd_local_sub_index);
+        }
+    }
+
+    if (font->data)
+        free (font->data);
+
     free (font);
 }
 
 cairo_status_t
 _cairo_cff_subset_init (cairo_cff_subset_t          *cff_subset,
                         const char		    *subset_name,
                         cairo_scaled_font_subset_t  *font_subset)
 {
@@ -1657,8 +1917,220 @@ cairo_status_t
 
 void
 _cairo_cff_subset_fini (cairo_cff_subset_t *subset)
 {
     free (subset->base_font);
     free (subset->widths);
     free (subset->data);
 }
+
+static cairo_int_status_t
+_cairo_cff_font_fallback_create (cairo_scaled_font_subset_t  *scaled_font_subset,
+                                 cairo_cff_font_t           **font_return,
+                                 const char                  *subset_name)
+{
+    cairo_status_t status;
+    cairo_cff_font_t *font;
+
+    font = malloc (sizeof (cairo_cff_font_t));
+    if (font == NULL)
+        return CAIRO_STATUS_NO_MEMORY;
+
+    font->backend = NULL;
+    font->scaled_font_subset = scaled_font_subset;
+
+    _cairo_array_init (&font->output, sizeof (char));
+    status = _cairo_array_grow_by (&font->output, 4096);
+    if (status)
+	goto fail1;
+
+    font->subset_font_name = strdup (subset_name);
+    if (font->subset_font_name == NULL) {
+        status = CAIRO_STATUS_NO_MEMORY;
+	goto fail2;
+    }
+
+    font->font_name = strdup (subset_name);
+    if (font->subset_font_name == NULL) {
+        status = CAIRO_STATUS_NO_MEMORY;
+	goto fail3;
+    }
+
+    font->x_min = 0;
+    font->y_min = 0;
+    font->x_max = 0;
+    font->y_max = 0;
+    font->ascent = 0;
+    font->descent = 0;
+
+    font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int));
+    if (font->widths == NULL) {
+        status = CAIRO_STATUS_NO_MEMORY;
+        goto fail4;
+    }
+
+    font->data_length = 0;
+    font->data = NULL;
+    font->data_end = 0;
+
+    cff_dict_init (&font->top_dict);
+    cff_dict_init (&font->private_dict);
+    cff_index_init (&font->strings_index);
+    cff_index_init (&font->charstrings_index);
+    cff_index_init (&font->global_sub_index);
+    cff_index_init (&font->local_sub_index);
+    cff_index_init (&font->charstrings_subset_index);
+    cff_index_init (&font->strings_subset_index);
+    font->fdselect = NULL;
+    font->fd_dict = NULL;
+    font->fd_private_dict = NULL;
+    font->fd_local_sub_index = NULL;
+    font->fdselect_subset = NULL;
+    font->fd_subset_map = NULL;
+    font->private_dict_offset = NULL;
+
+    *font_return = font;
+
+    return CAIRO_STATUS_SUCCESS;
+
+fail4:
+    free (font->font_name);
+fail3:
+    free (font->subset_font_name);
+fail2:
+    _cairo_array_fini (&font->output);
+fail1:
+    free (font);
+    return status;
+}
+
+static cairo_int_status_t
+cairo_cff_font_fallback_generate (cairo_cff_font_t           *font,
+                                  cairo_type2_charstrings_t  *type2_subset,
+                                  const char                **data,
+                                  unsigned long              *length)
+{
+    cairo_int_status_t status;
+    cff_header_t header;
+    cairo_array_t *charstring;
+    unsigned char buf[40];
+    unsigned char *end_buf;
+    unsigned int i;
+
+    /* Create header */
+    header.major = 1;
+    header.minor = 0;
+    header.header_size = 4;
+    header.offset_size = 4;
+    font->header = &header;
+
+    /* Create Top Dict */
+    font->is_cid = FALSE;
+    end_buf = encode_integer (buf, type2_subset->x_min);
+    end_buf = encode_integer (end_buf, type2_subset->y_min);
+    end_buf = encode_integer (end_buf, type2_subset->x_max);
+    end_buf = encode_integer (end_buf, type2_subset->y_max);
+    cff_dict_set_operands (font->top_dict, FONTBBOX_OP, buf, end_buf - buf);
+    end_buf = encode_integer_max (buf, 0);
+    cff_dict_set_operands (font->top_dict, CHARSTRINGS_OP, buf, end_buf - buf);
+    cff_dict_set_operands (font->top_dict, FDSELECT_OP, buf, end_buf - buf);
+    cff_dict_set_operands (font->top_dict, FDARRAY_OP, buf, end_buf - buf);
+    cff_dict_set_operands (font->top_dict, CHARSET_OP, buf, end_buf - buf);
+    cairo_cff_font_set_ros_strings (font);
+
+    /* Create CID FD dictionary */
+    cairo_cff_font_create_cid_fontdict (font);
+
+    /* Create charstrings */
+    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
+        charstring = _cairo_array_index(&type2_subset->charstrings, i);
+
+        status = cff_index_append (&font->charstrings_subset_index,
+                                   _cairo_array_index (charstring, 0),
+                                   _cairo_array_num_elements (charstring));
+
+        if (status)
+            return status;
+    }
+
+    status = cairo_cff_font_write_subset (font);
+    if (status)
+        return status;
+
+    *data = _cairo_array_index (&font->output, 0);
+    *length = _cairo_array_num_elements (&font->output);
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_status_t
+_cairo_cff_fallback_init (cairo_cff_subset_t          *cff_subset,
+                          const char		      *subset_name,
+                          cairo_scaled_font_subset_t  *font_subset)
+{
+    cairo_cff_font_t *font = NULL; /* squelch bogus compiler warning */
+    cairo_status_t status;
+    const char *data = NULL; /* squelch bogus compiler warning */
+    unsigned long length = 0; /* squelch bogus compiler warning */
+    unsigned int i;
+    cairo_type2_charstrings_t type2_subset;
+
+    status = _cairo_cff_font_fallback_create (font_subset, &font, subset_name);
+    if (status)
+	return status;
+
+    status = _cairo_type2_charstrings_init (&type2_subset, font_subset);
+    if (status)
+	goto fail1;
+
+    status = cairo_cff_font_fallback_generate (font, &type2_subset, &data, &length);
+    if (status)
+	goto fail1;
+
+    cff_subset->base_font = strdup (font->font_name);
+    if (cff_subset->base_font == NULL)
+	goto fail1;
+
+    cff_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
+    if (cff_subset->widths == NULL)
+	goto fail2;
+    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
+        cff_subset->widths[i] = type2_subset.widths[i];
+
+    cff_subset->x_min = type2_subset.x_min;
+    cff_subset->y_min = type2_subset.y_min;
+    cff_subset->x_max = type2_subset.x_max;
+    cff_subset->y_max = type2_subset.y_max;
+    cff_subset->ascent = type2_subset.y_max;
+    cff_subset->descent = type2_subset.y_min;
+
+    _cairo_type2_charstrings_fini (&type2_subset);
+
+    cff_subset->data = malloc (length);
+    if (cff_subset->data == NULL)
+	goto fail3;
+
+    memcpy (cff_subset->data, data, length);
+    cff_subset->data_length = length;
+    cff_subset->data_length = length;
+
+    cairo_cff_font_destroy (font);
+
+    return CAIRO_STATUS_SUCCESS;
+
+ fail3:
+    free (cff_subset->widths);
+ fail2:
+    free (cff_subset->base_font);
+ fail1:
+    cairo_cff_font_destroy (font);
+
+    return status;
+}
+
+void
+_cairo_cff_fallback_fini (cairo_cff_subset_t *subset)
+{
+    free (subset->base_font);
+    free (subset->widths);
+    free (subset->data);
+}
--- a/gfx/cairo/cairo/src/cairo-clip-private.h
+++ b/gfx/cairo/cairo/src/cairo-clip-private.h
@@ -33,17 +33,17 @@
  *	Kristian Høgsberg <krh@redhat.com>
  */
 
 #ifndef CAIRO_CLIP_PRIVATE_H
 #define CAIRO_CLIP_PRIVATE_H
 
 #include "cairo-path-fixed-private.h"
 
-extern cairo_private const cairo_rectangle_list_t _cairo_rectangles_nil;
+extern const cairo_private cairo_rectangle_list_t _cairo_rectangles_nil;
 
 struct _cairo_clip_path {
     unsigned int	ref_count;
     cairo_path_fixed_t	path;
     cairo_fill_rule_t	fill_rule;
     double		tolerance;
     cairo_antialias_t	antialias;
     cairo_clip_path_t	*prev;
@@ -67,39 +67,37 @@ struct _cairo_clip {
     /*
      * Surface clip serial number to store
      * in the surface when this clip is set
      */
     unsigned int serial;
     /*
      * A clip region that can be placed in the surface
      */
-    pixman_region16_t *region;
+    pixman_region16_t region;
+    cairo_bool_t has_region;
     /*
      * If the surface supports path clipping, we store the list of
      * clipping paths that has been set here as a linked list.
      */
     cairo_clip_path_t *path;
 };
 
 cairo_private void
 _cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target);
 
-cairo_private void
-_cairo_clip_fini (cairo_clip_t *clip);
-
-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);
 
-cairo_private cairo_status_t
+cairo_private void
 _cairo_clip_reset (cairo_clip_t *clip);
 
 cairo_private cairo_status_t
 _cairo_clip_clip (cairo_clip_t       *clip,
 		  cairo_path_fixed_t *path,
 		  cairo_fill_rule_t   fill_rule,
 		  double              tolerance,
 		  cairo_antialias_t   antialias,
--- a/gfx/cairo/cairo/src/cairo-clip.c
+++ b/gfx/cairo/cairo/src/cairo-clip.c
@@ -56,74 +56,72 @@ void
     clip->surface = NULL;
     clip->surface_rect.x = 0;
     clip->surface_rect.y = 0;
     clip->surface_rect.width = 0;
     clip->surface_rect.height = 0;
 
     clip->serial = 0;
 
-    clip->region = NULL;
+    pixman_region_init (&clip->region);
+    clip->has_region = FALSE;
 
     clip->path = NULL;
 }
 
-void
-_cairo_clip_fini (cairo_clip_t *clip)
-{
-    cairo_surface_destroy (clip->surface);
-    clip->surface = NULL;
-
-    clip->serial = 0;
-
-    if (clip->region)
-	pixman_region_destroy (clip->region);
-    clip->region = NULL;
-
-    _cairo_clip_path_destroy (clip->path);
-    clip->path = NULL;
-}
-
-void
+cairo_status_t
 _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
 {
     clip->mode = other->mode;
 
     clip->surface = cairo_surface_reference (other->surface);
     clip->surface_rect = other->surface_rect;
 
     clip->serial = other->serial;
 
-    if (other->region == NULL) {
-	clip->region = other->region;
+    pixman_region_init (&clip->region);
+
+    if (other->has_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->region = pixman_region_create ();
-	pixman_region_copy (clip->region, other->region);
+        clip->has_region = FALSE;
     }
 
     clip->path = _cairo_clip_path_reference (other->path);
+    
+    return CAIRO_STATUS_SUCCESS;
 }
 
-cairo_status_t
+void
 _cairo_clip_reset (cairo_clip_t *clip)
 {
     /* destroy any existing clip-region artifacts */
     cairo_surface_destroy (clip->surface);
     clip->surface = NULL;
 
     clip->serial = 0;
 
-    if (clip->region)
-	pixman_region_destroy (clip->region);
-    clip->region = NULL;
+    if (clip->has_region) {
+        /* pixman_region_fini just releases the resources used but
+         * doesn't bother with leaving the region in a valid state.
+         * So pixman_region_init has to be called afterwards. */
+	pixman_region_fini (&clip->region);
+        pixman_region_init (&clip->region);
+
+        clip->has_region = FALSE;
+    }
 
     _cairo_clip_path_destroy (clip->path);
     clip->path = NULL;
-
-    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
 _cairo_clip_path_intersect_to_rectangle (cairo_clip_path_t       *clip_path,
    				         cairo_rectangle_int16_t *rectangle)
 {
     while (clip_path) {
         cairo_status_t status;
@@ -165,78 +163,79 @@ cairo_status_t
         cairo_status_t status;
         
         status = _cairo_clip_path_intersect_to_rectangle (clip->path,
                                                           rectangle);
         if (status)
             return status;
     }
 
-    if (clip->region) {
-	pixman_region16_t *intersection;
+    if (clip->has_region) {
 	cairo_status_t status = CAIRO_STATUS_SUCCESS;
-	pixman_region_status_t pixman_status;
+	pixman_region16_t intersection;
 
-	intersection = _cairo_region_create_from_rectangle (rectangle);
-	if (intersection == NULL)
-	    return CAIRO_STATUS_NO_MEMORY;
+	pixman_region_init_rect (&intersection,
+                                  rectangle->x, rectangle->y,
+                                  rectangle->width, rectangle->height);
 
-	pixman_status = pixman_region_intersect (intersection,
-					  clip->region,
-					  intersection);
-	if (pixman_status == PIXMAN_REGION_STATUS_SUCCESS)
-	    _cairo_region_extents_rectangle (intersection, rectangle);
-	else
+	if (PIXMAN_REGION_STATUS_SUCCESS !=
+            pixman_region_intersect (&intersection, &clip->region,
+                                     &intersection)) {
 	    status = CAIRO_STATUS_NO_MEMORY;
-
-	pixman_region_destroy (intersection);
+	} else {
+            _cairo_region_extents_rectangle (&intersection, rectangle);
+        }
 
-	if (status)
-	    return status;
+        pixman_region_fini (&intersection);
+
+        if (status)
+            return status;
     }
 
     if (clip->surface)
 	_cairo_rectangle_intersect (rectangle, &clip->surface_rect);
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 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;
 
     if (clip->path) {
 	/* Intersect clip path into region. */
     }
 
-    if (clip->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) {
-	pixman_region16_t *clip_rect;
-	pixman_region_status_t pixman_status;
 	cairo_status_t status = CAIRO_STATUS_SUCCESS;
+	pixman_region16_t clip_rect;
 
-	clip_rect = _cairo_region_create_from_rectangle (&clip->surface_rect);
-	if (clip_rect == NULL)
-	    return CAIRO_STATUS_NO_MEMORY;
+        pixman_region_init_rect (&clip_rect,
+                                  clip->surface_rect.x, clip->surface_rect.y,
+                                  clip->surface_rect.width, clip->surface_rect.height);
 
-	pixman_status = pixman_region_intersect (region,
-						 clip_rect,
-						 region);
-	if (pixman_status != PIXMAN_REGION_STATUS_SUCCESS)
+        if (PIXMAN_REGION_STATUS_SUCCESS !=
+            pixman_region_intersect (region, &clip_rect, region))
 	    status = CAIRO_STATUS_NO_MEMORY;
 
-	pixman_region_destroy (clip_rect);
+        pixman_region_fini (&clip_rect);
 
-	if (status)
-	    return status;
+        if (status)
+            return status;
     }
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 /* Combines the region of clip->surface given by extents in
  * device backend coordinates into the given temporary surface,
  * which has its origin at dst_x, dst_y in backend coordinates
@@ -324,52 +323,57 @@ static void
     if (clip_path->ref_count)
 	return;
 
     _cairo_path_fixed_fini (&clip_path->path);
     _cairo_clip_path_destroy (clip_path->prev);
     free (clip_path);
 }
 
-static cairo_status_t
+static cairo_int_status_t
 _cairo_clip_intersect_region (cairo_clip_t    *clip,
 			      cairo_traps_t   *traps,
 			      cairo_surface_t *target)
 {
-    pixman_region16_t *region;
-    cairo_status_t status;
+    pixman_region16_t region;
+    cairo_int_status_t status;
 
     if (clip->mode != CAIRO_CLIP_MODE_REGION)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     status = _cairo_traps_extract_region (traps, &region);
+
     if (status)
 	return status;
 
-    if (region == NULL)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
     status = CAIRO_STATUS_SUCCESS;
-    if (clip->region == NULL) {
-	clip->region = region;
-    } else {
-	pixman_region16_t *intersection = pixman_region_create();
 
-	if (pixman_region_intersect (intersection,
-				     clip->region, region)
-	    == PIXMAN_REGION_STATUS_SUCCESS) {
-	    pixman_region_destroy (clip->region);
-	    clip->region = intersection;
-	} else {
+    if (!clip->has_region) {
+        if (pixman_region_copy (&clip->region, &region) ==
+		PIXMAN_REGION_STATUS_SUCCESS)
+	    clip->has_region = TRUE;
+	else
 	    status = CAIRO_STATUS_NO_MEMORY;
-	}
-	pixman_region_destroy (region);
+    } else {
+	pixman_region16_t intersection;
+        pixman_region_init (&intersection);
+
+	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);
     }
 
     clip->serial = _cairo_surface_allocate_clip_serial (target);
+    pixman_region_fini (&region);
 
     return status;
 }
 
 static cairo_status_t
 _cairo_clip_intersect_mask (cairo_clip_t      *clip,
 			    cairo_traps_t     *traps,
 			    cairo_antialias_t antialias,
@@ -397,24 +401,26 @@ static cairo_status_t
     status = _cairo_surface_get_extents (target, &target_rect);
     if (!status)
 	_cairo_rectangle_intersect (&surface_rect, &target_rect);
 
     surface = _cairo_surface_create_similar_solid (target,
 						   CAIRO_CONTENT_ALPHA,
 						   surface_rect.width,
 						   surface_rect.height,
-						   CAIRO_COLOR_WHITE);
+						   CAIRO_COLOR_WHITE,
+						   NULL);
     if (surface->status)
 	return CAIRO_STATUS_NO_MEMORY;
 
     /* Render the new clipping path into the new mask surface. */
 
     _cairo_traps_translate (traps, -surface_rect.x, -surface_rect.y);
-    _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE);
+    _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE,
+			       CAIRO_CONTENT_COLOR);
 
     status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_IN,
 						  &pattern.base,
 						  surface,
 						  antialias,
 						  0, 0,
 						  0, 0,
 						  surface_rect.width,
@@ -504,18 +510,18 @@ cairo_status_t
     return status;
 }
 
 void
 _cairo_clip_translate (cairo_clip_t  *clip,
                        cairo_fixed_t  tx,
                        cairo_fixed_t  ty)
 {
-    if (clip->region) {
-        pixman_region_translate (clip->region,
+    if (clip->has_region) {
+        pixman_region_translate (&clip->region,
                                  _cairo_fixed_integer_part (tx),
                                  _cairo_fixed_integer_part (ty));
     }
 
     if (clip->surface) {
         clip->surface_rect.x += _cairo_fixed_integer_part (tx);
         clip->surface_rect.y += _cairo_fixed_integer_part (ty);
     }
@@ -544,46 +550,60 @@ static void
 
     _cairo_clip_intersect_path (clip,
                                 &clip_path->path,
                                 clip_path->fill_rule,
                                 clip_path->tolerance,
                                 clip_path->antialias);
 }
 
-void
+cairo_status_t
 _cairo_clip_init_deep_copy (cairo_clip_t    *clip,
                             cairo_clip_t    *other,
                             cairo_surface_t *target)
 {
     _cairo_clip_init (clip, target);
 
     if (other->mode != clip->mode) {
         /* We should reapply the original clip path in this case, and let
          * whatever the right handling is happen */
     } else {
-        if (other->region) {
-            clip->region = pixman_region_create ();
-            pixman_region_copy (clip->region, other->region);
+        if (other->has_region) {
+            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;
         }
 
         if (other->path) {
             _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 =
   { CAIRO_STATUS_NO_MEMORY, NULL, 0 };
 static const cairo_rectangle_list_t _cairo_rectangles_not_representable =
   { CAIRO_STATUS_CLIP_NOT_REPRESENTABLE, NULL, 0 };
 
 static cairo_bool_t
@@ -608,42 +628,46 @@ cairo_private cairo_rectangle_list_t*
 {
     cairo_rectangle_list_t *list;
     cairo_rectangle_t *rectangles;
     int n_boxes;
 
     if (clip->path || clip->surface)
         return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
 
-    n_boxes = clip->region ? pixman_region_num_rects (clip->region) : 1;
+    n_boxes = clip->has_region ? pixman_region_num_rects (&clip->region) : 1;
     rectangles = malloc (sizeof (cairo_rectangle_t)*n_boxes);
     if (rectangles == NULL)
         return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
 
-    if (clip->region) {
+    if (clip->has_region) {
         pixman_box16_t *boxes;
         int i;
         
-        boxes = pixman_region_rects (clip->region);
+        boxes = pixman_region_rects (&clip->region);
         for (i = 0; i < n_boxes; ++i) {
             if (!_cairo_clip_rect_to_user(gstate, boxes[i].x1, boxes[i].y1,
                                           boxes[i].x2 - boxes[i].x1,
                                           boxes[i].y2 - boxes[i].y1,
                                           &rectangles[i])) {
                 free (rectangles);
                 return (cairo_rectangle_list_t*)
                     &_cairo_rectangles_not_representable;
             }
         }
     } 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) {
+            free (rectangles);
+	    return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
+	}
+	if (! _cairo_clip_rect_to_user(gstate, extents.x, extents.y,
+                                          extents.width, extents.height,
+                                          rectangles)) {
             free (rectangles);
             return (cairo_rectangle_list_t*)
                 &_cairo_rectangles_not_representable;
         }
     }
 
     list = malloc (sizeof (cairo_rectangle_list_t));
     if (list == NULL) {
--- a/gfx/cairo/cairo/src/cairo-color.c
+++ b/gfx/cairo/cairo/src/cairo-color.c
@@ -155,8 +155,18 @@ void
 				     double	   *blue,
 				     double	   *alpha)
 {
     *red   = color->red   * color->alpha;
     *green = color->green * color->alpha;
     *blue  = color->blue  * color->alpha;
     *alpha = color->alpha;
 }
+
+cairo_bool_t
+_cairo_color_equal (const cairo_color_t *color_a,
+	            const cairo_color_t *color_b)
+{
+    return color_a->red_short   == color_b->red_short   &&
+           color_a->green_short == color_b->green_short &&
+           color_a->blue_short  == color_b->blue_short  &&
+           color_a->alpha_short == color_b->alpha_short;
+}
--- a/gfx/cairo/cairo/src/cairo-debug.c
+++ b/gfx/cairo/cairo/src/cairo-debug.c
@@ -54,18 +54,16 @@
  * active cairo objects remaining, (ie. the appropriate destroy
  * functions have been called as necessary). If there are active cairo
  * objects, this call is likely to cause a crash, (eg. an assertion
  * failure due to a hash table being destroyed when non-empty).
  **/
 void
 cairo_debug_reset_static_data (void)
 {
-#if CAIRO_HAS_XLIB_SURFACE
-    _cairo_xlib_screen_reset_static_data ();
-#endif
-
     _cairo_font_reset_static_data ();
 
 #if CAIRO_HAS_FT_FONT
     _cairo_ft_font_reset_static_data ();
 #endif
+
+    _cairo_pattern_reset_static_data ();
 }
--- a/gfx/cairo/cairo/src/cairo-deflate-stream.c
+++ b/gfx/cairo/cairo/src/cairo-deflate-stream.c
@@ -114,29 +114,31 @@ static cairo_status_t
 
 cairo_output_stream_t *
 _cairo_deflate_stream_create (cairo_output_stream_t *output)
 {
     cairo_deflate_stream_t *stream;
 
     stream = malloc (sizeof (cairo_deflate_stream_t));
     if (stream == NULL)
-	return (cairo_output_stream_t *) &cairo_output_stream_nil;
+	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
 
     _cairo_output_stream_init (&stream->base,
 			       _cairo_deflate_stream_write,
 			       _cairo_deflate_stream_close);
     stream->output = output;
 
     stream->zlib_stream.zalloc = Z_NULL;
     stream->zlib_stream.zfree  = Z_NULL;
     stream->zlib_stream.opaque  = Z_NULL;
 
-    if (deflateInit (&stream->zlib_stream, Z_DEFAULT_COMPRESSION) != Z_OK)
-	return (cairo_output_stream_t *) &cairo_output_stream_nil;
+    if (deflateInit (&stream->zlib_stream, Z_DEFAULT_COMPRESSION) != Z_OK) {
+	free (stream);
+	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
+    }
 
     stream->zlib_stream.next_in = stream->input_buf;
     stream->zlib_stream.avail_in = 0;
     stream->zlib_stream.next_out = stream->output_buf;
     stream->zlib_stream.avail_out = BUFFER_SIZE;
 
     return &stream->base;
 }
--- a/gfx/cairo/cairo/src/cairo-directfb-surface.c
+++ b/gfx/cairo/cairo/src/cairo-directfb-surface.c
@@ -30,31 +30,27 @@
  * The Initial Developer of the Original Code is University of Southern
  * California.
  *
  * Contributor(s):
  *    Michael Emmel <mike.emmel@gmail.com>
  *    Claudio Ciccani <klan@users.sf.net>
  */
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <assert.h>
+#include "cairoint.h"
+
+#include "cairo-directfb.h"
 
 #include <directfb.h>
 
 #include <direct/types.h>
 #include <direct/debug.h>
 #include <direct/memcpy.h>
 #include <direct/util.h>
 
-#include "cairo-directfb.h"
-#include "cairoint.h"
-
 
 /*
  * Rectangle causes problems (see bugs 361377, 359553, 359243 in Gnome BTS).
  */
 #define DFB_RECTANGLES 0
 
 /*
  * Composite works fine.
@@ -332,17 +328,17 @@ static cairo_status_t
 {   
     void      *data;
     int        pitch;
     IDirectFBSurface *buffer;
     DFBRectangle source_rect;
     cairo_format_t            cairo_format;
     cairo_format = surface->format;    
         
-    if (surface->format == -1) {
+    if (surface->format == (cairo_format_t) -1) {
         if( intrest_rec ) {
             source_rect.x = intrest_rec->x;
             source_rect.y = intrest_rec->y;
             source_rect.w = intrest_rec->width; 
             source_rect.h = intrest_rec->height; 
         }else {
             source_rect.x=0;
             source_rect.y=0;
@@ -1510,16 +1506,27 @@ static cairo_int_status_t
                  dst->dfbsurface->BatchBlit (dst->dfbsurface,
                                          cache->dfbsurface, rects, points, num));
         
     return CAIRO_STATUS_SUCCESS;
 }
 #endif /* DFB_SHOW_GLYPHS */
 
 
+static cairo_bool_t
+_cairo_directfb_surface_is_similar (void *surface_a,
+	                           void *surface_b,
+				   cairo_content_t content)
+{
+    cairo_directfb_surface_t *a = (cairo_directfb_surface_t *) surface_a;
+    cairo_directfb_surface_t *b = (cairo_directfb_surface_t *) surface_b;
+
+    return a->dfb == b->dfb;
+}
+
 static cairo_surface_backend_t cairo_directfb_surface_backend = {
          CAIRO_SURFACE_TYPE_DIRECTFB, /*type*/
         _cairo_directfb_surface_create_similar,/*create_similar*/
         _cairo_directfb_surface_finish, /*finish*/
         _cairo_directfb_surface_acquire_source_image,/*acquire_source_image*/
         _cairo_directfb_surface_release_source_image,/*release_source_image*/
         _cairo_directfb_surface_acquire_dest_image,/*acquire_dest_image*/
         _cairo_directfb_surface_release_dest_image,/*release_dest_image*/ 
@@ -1559,17 +1566,19 @@ static cairo_surface_backend_t cairo_dir
         NULL, /* mask */
         NULL, /* stroke */
         NULL, /* fill */
 #if DFB_SHOW_GLYPHS
         _cairo_directfb_surface_show_glyphs,/*show_glyphs*/
 #else
         NULL, /* show_glyphs */
 #endif
-        NULL /* snapshot */
+        NULL, /* snapshot */
+	_cairo_directfb_surface_is_similar,
+	NULL /* reset */
 };
 
 
 static void
 cairo_directfb_surface_backend_init (IDirectFB *dfb)
 {
     DFBGraphicsDeviceDescription dsc;
     static int                   done = 0;
--- a/gfx/cairo/cairo/src/cairo-directfb.h
+++ b/gfx/cairo/cairo/src/cairo-directfb.h
@@ -36,16 +36,18 @@
 
 #ifndef CAIRO_DIRECTFB_H
 #define CAIRO_DIRECTFB_H
 
 #include <cairo.h>
 
 #ifdef  CAIRO_HAS_DIRECTFB_SURFACE
 
+#include <directfb.h>
+
 CAIRO_BEGIN_DECLS
 
 cairo_public cairo_surface_t *
 cairo_directfb_surface_create (IDirectFB *dfb,IDirectFBSurface *surface);
 
 CAIRO_END_DECLS
 
 #else  /*CAIRO_HAS_DIRECTFB_SURFACE*/
--- a/gfx/cairo/cairo/src/cairo-features.h.in
+++ b/gfx/cairo/cairo/src/cairo-features.h.in
@@ -48,28 +48,30 @@
 #endif
 
 #ifndef cairo_public
 # define cairo_public
 #endif
 
 #define CAIRO_VERSION_MAJOR 1
 #define CAIRO_VERSION_MINOR 4
-#define CAIRO_VERSION_MICRO 2
+#define CAIRO_VERSION_MICRO 10
 
-#define CAIRO_VERSION_STRING "1.4.2"
+#define CAIRO_VERSION_STRING "1.4.10"
 
 @PS_SURFACE_FEATURE@
 
 @PDF_SURFACE_FEATURE@
 
 @SVG_SURFACE_FEATURE@
 
 @XLIB_SURFACE_FEATURE@
 
+@XLIB_XRENDER_SURFACE_FEATURE@
+
 @QUARTZ_SURFACE_FEATURE@
 
 @XCB_SURFACE_FEATURE@
 
 @WIN32_SURFACE_FEATURE@
 
 @OS2_SURFACE_FEATURE@
 
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/cairo/src/cairo-font-face.c
@@ -0,0 +1,519 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2002 University of Southern California
+ * Copyright © 2005 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is University of Southern
+ * California.
+ *
+ * Contributor(s):
+ *	Carl D. Worth <cworth@cworth.org>
+ *      Graydon Hoare <graydon@redhat.com>
+ *      Owen Taylor <otaylor@redhat.com>
+ */
+
+#include "cairoint.h"
+
+/* Forward declare so we can use it as an arbitrary backend for
+ * _cairo_font_face_nil.
+ */
+static const cairo_font_face_backend_t _cairo_toy_font_face_backend;
+
+/* cairo_font_face_t */
+
+const cairo_font_face_t _cairo_font_face_nil = {
+    { 0 },			/* hash_entry */
+    CAIRO_STATUS_NO_MEMORY,	/* status */
+    CAIRO_REF_COUNT_INVALID,	/* ref_count */
+    { 0, 0, 0, NULL },		/* user_data */
+    &_cairo_toy_font_face_backend
+};
+
+void
+_cairo_font_face_init (cairo_font_face_t               *font_face,
+		       const cairo_font_face_backend_t *backend)
+{
+    CAIRO_MUTEX_INITIALIZE ();
+
+    font_face->status = CAIRO_STATUS_SUCCESS;
+    font_face->ref_count = 1;
+    font_face->backend = backend;
+
+    _cairo_user_data_array_init (&font_face->user_data);
+}
+
+/**
+ * cairo_font_face_reference:
+ * @font_face: a #cairo_font_face_t, (may be %NULL in which case this
+ * function does nothing).
+ *
+ * Increases the reference count on @font_face by one. This prevents
+ * @font_face from being destroyed until a matching call to
+ * cairo_font_face_destroy() is made.
+ *
+ * The number of references to a #cairo_font_face_t can be get using
+ * cairo_font_face_get_reference_count().
+ *
+ * Return value: the referenced #cairo_font_face_t.
+ **/
+cairo_font_face_t *
+cairo_font_face_reference (cairo_font_face_t *font_face)
+{
+    if (font_face == NULL || font_face->ref_count == CAIRO_REF_COUNT_INVALID)
+	return font_face;
+
+    CAIRO_MUTEX_LOCK (_cairo_font_face_mutex);
+
+    /* We would normally assert (font_face->ref_count >0) here but we
+     * can't get away with that due to the zombie case as documented
+     * in _cairo_ft_font_face_destroy. */
+
+    font_face->ref_count++;
+
+    CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
+
+    return font_face;
+}
+slim_hidden_def (cairo_font_face_reference);
+
+/**
+ * cairo_font_face_destroy:
+ * @font_face: a #cairo_font_face_t
+ *
+ * Decreases the reference count on @font_face by one. If the result
+ * is zero, then @font_face and all associated resources are freed.
+ * See cairo_font_face_reference().
+ **/
+void
+cairo_font_face_destroy (cairo_font_face_t *font_face)
+{
+    if (font_face == NULL || font_face->ref_count == CAIRO_REF_COUNT_INVALID)
+	return;
+
+    CAIRO_MUTEX_LOCK (_cairo_font_face_mutex);
+
+    assert (font_face->ref_count > 0);
+
+    if (--(font_face->ref_count) > 0) {
+        CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
+	return;
+    }
+
+    CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
+
+    font_face->backend->destroy (font_face);
+
+    /* We allow resurrection to deal with some memory management for the
+     * FreeType backend where cairo_ft_font_face_t and cairo_ft_unscaled_font_t
+     * need to effectively mutually reference each other
+     */
+    if (font_face->ref_count > 0)
+	return;
+
+    _cairo_user_data_array_fini (&font_face->user_data);
+
+    free (font_face);
+}
+slim_hidden_def (cairo_font_face_destroy);
+
+/**
+ * cairo_font_face_get_type:
+ * @font_face: a font face
+ *
+ * This function returns the type of the backend used to create
+ * a font face. See #cairo_font_type_t for available types.
+ *
+ * Return value: The type of @font_face.
+ *
+ * Since: 1.2
+ **/
+cairo_font_type_t
+cairo_font_face_get_type (cairo_font_face_t *font_face)
+{
+    return font_face->backend->type;
+}
+
+/**
+ * cairo_font_face_get_reference_count:
+ * @font_face: a #cairo_font_face_t
+ *
+ * Returns the current reference count of @font_face.
+ *
+ * Return value: the current reference count of @font_face.  If the
+ * object is a nil object, 0 will be returned.
+ *
+ * Since: 1.4
+ **/
+unsigned int
+cairo_font_face_get_reference_count (cairo_font_face_t *font_face)
+{
+    if (font_face == NULL || font_face->ref_count == CAIRO_REF_COUNT_INVALID)
+	return 0;
+
+    return font_face->ref_count;
+}
+
+/**
+ * cairo_font_face_status:
+ * @font_face: a #cairo_font_face_t
+ *
+ * Checks whether an error has previously occurred for this
+ * font face
+ *
+ * Return value: %CAIRO_STATUS_SUCCESS or another error such as
+ *   %CAIRO_STATUS_NO_MEMORY.
+ **/
+cairo_status_t
+cairo_font_face_status (cairo_font_face_t *font_face)
+{
+    return font_face->status;
+}
+
+/**
+ * cairo_font_face_get_user_data:
+ * @font_face: a #cairo_font_face_t
+ * @key: the address of the #cairo_user_data_key_t the user data was
+ * attached to
+ *
+ * Return user data previously attached to @font_face using the specified
+ * key.  If no user data has been attached with the given key this
+ * function returns %NULL.
+ *
+ * Return value: the user data previously attached or %NULL.
+ **/
+void *
+cairo_font_face_get_user_data (cairo_font_face_t	   *font_face,
+			       const cairo_user_data_key_t *key)
+{
+    return _cairo_user_data_array_get_data (&font_face->user_data,
+					    key);
+}
+
+/**
+ * cairo_font_face_set_user_data:
+ * @font_face: a #cairo_font_face_t
+ * @key: the address of a #cairo_user_data_key_t to attach the user data to
+ * @user_data: the user data to attach to the font face
+ * @destroy: a #cairo_destroy_func_t which will be called when the
+ * font face is destroyed or when new user data is attached using the
+ * same key.
+ *
+ * Attach user data to @font_face.  To remove user data from a font face,
+ * call this function with the key that was used to set it and %NULL
+ * for @data.
+ *
+ * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
+ * slot could not be allocated for the user data.
+ **/
+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,
+			       cairo_destroy_func_t	    destroy)
+{
+    if (font_face->ref_count == CAIRO_REF_COUNT_INVALID)
+	return CAIRO_STATUS_NO_MEMORY;
+
+    return _cairo_user_data_array_set_data (&font_face->user_data,
+					    key, user_data, destroy);
+}
+
+static const cairo_font_face_backend_t _cairo_toy_font_face_backend;
+
+static int
+_cairo_toy_font_face_keys_equal (const void *key_a,
+				 const void *key_b);
+
+/* We maintain a hash table from family/weight/slant =>
+ * cairo_font_face_t for cairo_toy_font_t. The primary purpose of
+ * this mapping is to provide unique cairo_font_face_t values so that
+ * our cache and mapping from cairo_font_face_t => cairo_scaled_font_t
+ * works. Once the corresponding cairo_font_face_t objects fall out of
+ * downstream caches, we don't need them in this hash table anymore.
+ *
+ * Modifications to this hash table are protected by
+ * _cairo_font_face_mutex.
+ */
+static cairo_hash_table_t *cairo_toy_font_face_hash_table = NULL;
+
+static cairo_hash_table_t *
+_cairo_toy_font_face_hash_table_lock (void)
+{
+    CAIRO_MUTEX_LOCK (_cairo_font_face_mutex);
+
+    if (cairo_toy_font_face_hash_table == NULL)
+    {
+	cairo_toy_font_face_hash_table =
+	    _cairo_hash_table_create (_cairo_toy_font_face_keys_equal);
+
+	if (cairo_toy_font_face_hash_table == NULL) {
+	    CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
+	    return NULL;
+	}
+    }
+
+    return cairo_toy_font_face_hash_table;
+}
+
+static void
+_cairo_toy_font_face_hash_table_unlock (void)
+{
+    CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
+}
+
+/**
+ * _cairo_toy_font_face_init_key:
+ *
+ * Initialize those portions of cairo_toy_font_face_t needed to use
+ * it as a hash table key, including the hash code buried away in
+ * font_face->base.hash_entry. No memory allocation is performed here
+ * so that no fini call is needed. We do this to make it easier to use
+ * an automatic cairo_toy_font_face_t variable as a key.
+ **/
+static void
+_cairo_toy_font_face_init_key (cairo_toy_font_face_t *key,
+			       const char	     *family,
+			       cairo_font_slant_t     slant,
+			       cairo_font_weight_t    weight)
+{
+    unsigned long hash;
+
+    key->family = family;
+    key->owns_family = FALSE;
+
+    key->slant = slant;
+    key->weight = weight;
+
+    /* 1607 and 1451 are just a couple of arbitrary primes. */
+    hash = _cairo_hash_string (family);
+    hash += ((unsigned long) slant) * 1607;
+    hash += ((unsigned long) weight) * 1451;
+
+    key->base.hash_entry.hash = hash;
+}
+
+static cairo_status_t
+_cairo_toy_font_face_init (cairo_toy_font_face_t *font_face,
+			   const char	         *family,
+			   cairo_font_slant_t	  slant,
+			   cairo_font_weight_t	  weight)
+{
+    char *family_copy;
+
+    family_copy = strdup (family);
+    if (family_copy == NULL)
+	return CAIRO_STATUS_NO_MEMORY;
+
+    _cairo_toy_font_face_init_key (font_face, family_copy,
+				      slant, weight);
+    font_face->owns_family = TRUE;
+
+    _cairo_font_face_init (&font_face->base, &_cairo_toy_font_face_backend);
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static void
+_cairo_toy_font_face_fini (cairo_toy_font_face_t *font_face)
+{
+    /* We assert here that we own font_face->family before casting
+     * away the const qualifer. */
+    assert (font_face->owns_family);
+    free ((char*) font_face->family);
+}
+
+static int
+_cairo_toy_font_face_keys_equal (const void *key_a,
+				 const void *key_b)
+{
+    const cairo_toy_font_face_t *face_a = key_a;
+    const cairo_toy_font_face_t *face_b = key_b;
+
+    return (strcmp (face_a->family, face_b->family) == 0 &&
+	    face_a->slant == face_b->slant &&
+	    face_a->weight == face_b->weight);
+}
+
+/**
+ * _cairo_toy_font_face_create:
+ * @family: a font family name, encoded in UTF-8
+ * @slant: the slant for the font
+ * @weight: the weight for the font
+ *
+ * Creates a font face from a triplet of family, slant, and weight.
+ * These font faces are used in implementation of the the #cairo_t "toy"
+ * font API.
+ *
+ * Return value: a newly created #cairo_font_face_t, destroy with
+ *  cairo_font_face_destroy()
+ **/
+cairo_font_face_t *
+_cairo_toy_font_face_create (const char          *family,
+			     cairo_font_slant_t   slant,
+			     cairo_font_weight_t  weight)
+{
+    cairo_status_t status;
+    cairo_toy_font_face_t key, *font_face;
+    cairo_hash_table_t *hash_table;
+
+    hash_table = _cairo_toy_font_face_hash_table_lock ();
+    if (hash_table == NULL)
+	goto UNWIND;
+
+    _cairo_toy_font_face_init_key (&key, family, slant, weight);
+
+    /* Return existing font_face if it exists in the hash table. */
+    if (_cairo_hash_table_lookup (hash_table,
+				  &key.base.hash_entry,
+				  (cairo_hash_entry_t **) &font_face))
+    {
+	/* We increment the reference count here manually to avoid
+	   double-locking. */
+	font_face->base.ref_count++;
+	_cairo_toy_font_face_hash_table_unlock ();
+	return &font_face->base;
+    }
+
+    /* Otherwise create it and insert into hash table. */
+    font_face = malloc (sizeof (cairo_toy_font_face_t));
+    if (font_face == NULL)
+	goto UNWIND_HASH_TABLE_LOCK;
+
+    status = _cairo_toy_font_face_init (font_face, family, slant, weight);
+    if (status)
+	goto UNWIND_FONT_FACE_MALLOC;
+
+    status = _cairo_hash_table_insert (hash_table, &font_face->base.hash_entry);
+    if (status)
+	goto UNWIND_FONT_FACE_INIT;
+
+    _cairo_toy_font_face_hash_table_unlock ();
+
+    return &font_face->base;
+
+ UNWIND_FONT_FACE_INIT:
+ UNWIND_FONT_FACE_MALLOC:
+    free (font_face);
+ UNWIND_HASH_TABLE_LOCK:
+    _cairo_toy_font_face_hash_table_unlock ();
+ UNWIND:
+    return (cairo_font_face_t*) &_cairo_font_face_nil;
+}
+
+static void
+_cairo_toy_font_face_destroy (void *abstract_face)
+{
+    cairo_toy_font_face_t *font_face = abstract_face;
+    cairo_hash_table_t *hash_table;
+
+    if (font_face == NULL)
+	return;
+
+    hash_table = _cairo_toy_font_face_hash_table_lock ();
+    /* All created objects must have been mapped in the hash table. */
+    assert (hash_table != NULL);
+
+    _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
+
+    _cairo_toy_font_face_hash_table_unlock ();
+
+    _cairo_toy_font_face_fini (font_face);
+}
+
+static cairo_status_t
+_cairo_toy_font_face_scaled_font_create (void                *abstract_font_face,
+					 const cairo_matrix_t       *font_matrix,
+					 const cairo_matrix_t       *ctm,
+					 const cairo_font_options_t *options,
+					 cairo_scaled_font_t	   **scaled_font)
+{
+    cairo_toy_font_face_t *font_face = abstract_font_face;
+    const cairo_scaled_font_backend_t * backend = CAIRO_SCALED_FONT_BACKEND_DEFAULT;
+    cairo_status_t status;
+
+    status = cairo_font_options_status ((cairo_font_options_t *) options);
+    if (status)
+	return status;
+
+    return backend->create_toy (font_face,
+				font_matrix, ctm, options, scaled_font);
+}
+
+static const cairo_font_face_backend_t _cairo_toy_font_face_backend = {
+    CAIRO_FONT_TYPE_TOY,
+    _cairo_toy_font_face_destroy,
+    _cairo_toy_font_face_scaled_font_create
+};
+
+void
+_cairo_unscaled_font_init (cairo_unscaled_font_t               *unscaled_font,
+			   const cairo_unscaled_font_backend_t *backend)
+{
+    unscaled_font->ref_count = 1;
+    unscaled_font->backend = backend;
+}
+
+cairo_unscaled_font_t *
+_cairo_unscaled_font_reference (cairo_unscaled_font_t *unscaled_font)
+{
+    if (unscaled_font == NULL)
+	return NULL;
+
+    unscaled_font->ref_count++;
+
+    return unscaled_font;
+}
+
+void
+_cairo_unscaled_font_destroy (cairo_unscaled_font_t *unscaled_font)
+{
+    if (unscaled_font == NULL)
+	return;
+
+    if (--(unscaled_font->ref_count) > 0)
+	return;
+
+    unscaled_font->backend->destroy (unscaled_font);
+
+    free (unscaled_font);
+}
+
+void
+_cairo_font_reset_static_data (void)
+{
+    _cairo_scaled_font_map_destroy ();
+
+    /* We manually acquire the lock rather than calling
+     * cairo_toy_font_face_hash_table_lock simply to avoid
+     * creating the table only to destroy it again. */
+    CAIRO_MUTEX_LOCK (_cairo_font_face_mutex);
+    _cairo_hash_table_destroy (cairo_toy_font_face_hash_table);
+    cairo_toy_font_face_hash_table = NULL;
+    CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
+}
--- a/gfx/cairo/cairo/src/cairo-font-options.c
+++ b/gfx/cairo/cairo/src/cairo-font-options.c
@@ -31,33 +31,33 @@
  * California.
  *
  * Contributor(s):
  *      Owen Taylor <otaylor@redhat.com>
  */
 
 #include "cairoint.h"
 
-static const cairo_font_options_t cairo_font_options_nil = {
+static const cairo_font_options_t _cairo_font_options_nil = {
     CAIRO_ANTIALIAS_DEFAULT,
     CAIRO_SUBPIXEL_ORDER_DEFAULT,
     CAIRO_HINT_STYLE_DEFAULT,
     CAIRO_HINT_METRICS_DEFAULT
 };
 
 /**
  * _cairo_font_options_init_default:
  * @options: a #cairo_font_options_t
  *
  * Initializes all fields of the font options object to default values.
  **/
 void
 _cairo_font_options_init_default (cairo_font_options_t *options)
 {
-    if (options == (cairo_font_options_t *)&cairo_font_options_nil)
+    if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
 	return;
 
     options->antialias = CAIRO_ANTIALIAS_DEFAULT;
     options->subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
     options->hint_style = CAIRO_HINT_STYLE_DEFAULT;
     options->hint_metrics = CAIRO_HINT_METRICS_DEFAULT;
 }
 
@@ -84,17 +84,17 @@ void
  *   You can check for this with cairo_font_options_status().
  **/
 cairo_font_options_t *
 cairo_font_options_create (void)
 {
     cairo_font_options_t *options = malloc (sizeof (cairo_font_options_t));
 
     if (!options)
-	return (cairo_font_options_t *)&cairo_font_options_nil;
+	return (cairo_font_options_t *)&_cairo_font_options_nil;
 
     _cairo_font_options_init_default (options);
 
     return options;
 }
 slim_hidden_def (cairo_font_options_create);
 
 /**
@@ -108,37 +108,41 @@ slim_hidden_def (cairo_font_options_crea
  *   cairo_font_options_destroy(). This function always returns a
  *   valid pointer; if memory cannot be allocated, then a special
  *   error object is returned where all operations on the object do nothing.
  *   You can check for this with cairo_font_options_status().
  **/
 cairo_font_options_t *
 cairo_font_options_copy (const cairo_font_options_t *original)
 {
-    cairo_font_options_t *options = malloc (sizeof (cairo_font_options_t));
+    cairo_font_options_t *options;
 
+    if (original == &_cairo_font_options_nil)
+	return (cairo_font_options_t *)&_cairo_font_options_nil;
+
+    options = malloc (sizeof (cairo_font_options_t));
     if (!options)
-	return (cairo_font_options_t *)&cairo_font_options_nil;
+	return (cairo_font_options_t *)&_cairo_font_options_nil;
 
     _cairo_font_options_init_copy (options, original);
 
     return options;
 }
 
 /**
  * cairo_font_options_destroy:
  * @options: a #cairo_font_options_t
  *
  * Destroys a #cairo_font_options_t object created with with
  * cairo_font_options_create() or cairo_font_options_copy().
  **/
 void
 cairo_font_options_destroy (cairo_font_options_t *options)
 {
-    if (options == (cairo_font_options_t *)&cairo_font_options_nil)
+    if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
 	return;
 
     free (options);
 }
 slim_hidden_def (cairo_font_options_destroy);
 
 /**
  * cairo_font_options_status:
@@ -147,37 +151,38 @@ slim_hidden_def (cairo_font_options_dest
  * Checks whether an error has previously occurred for this
  * font options object
  *
  * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
  **/
 cairo_status_t
 cairo_font_options_status (cairo_font_options_t *options)
 {
-    if (options == (cairo_font_options_t *)&cairo_font_options_nil)
+    if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
 	return CAIRO_STATUS_NO_MEMORY;
     else
 	return CAIRO_STATUS_SUCCESS;
 }
+slim_hidden_def (cairo_font_options_status);
 
 /**
  * cairo_font_options_merge:
  * @options: a #cairo_font_options_t
  * @other: another #cairo_font_options_t
  *
  * Merges non-default options from @other into @options, replacing
  * existing values. This operation can be thought of as somewhat
  * similar to compositing @other onto @options with the operation
  * of %CAIRO_OPERATION_OVER.
  **/
 void
 cairo_font_options_merge (cairo_font_options_t       *options,
 			  const cairo_font_options_t *other)
 {
-    if (options == (cairo_font_options_t *)&cairo_font_options_nil)
+    if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
 	return;
 
     if (other->antialias != CAIRO_ANTIALIAS_DEFAULT)
 	options->antialias = other->antialias;
     if (other->subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT)
 	options->subpixel_order = other->subpixel_order;
     if (other->hint_style != CAIRO_HINT_STYLE_DEFAULT)
 	options->hint_style = other->hint_style;
@@ -235,17 +240,17 @@ slim_hidden_def (cairo_font_options_hash
  *
  * Sets the antialiasing mode for the font options object. This
  * specifies the type of antialiasing to do when rendering text.
  **/
 void
 cairo_font_options_set_antialias (cairo_font_options_t *options,
 				  cairo_antialias_t     antialias)
 {
-    if (options == (cairo_font_options_t *)&cairo_font_options_nil)
+    if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
 	return;
 
     options->antialias = antialias;
 }
 slim_hidden_def (cairo_font_options_set_antialias);
 
 /**
  * cairo_font_options_get_antialias:
@@ -271,17 +276,17 @@ cairo_font_options_get_antialias (const 
  * the display device when rendering with an antialiasing mode of
  * %CAIRO_ANTIALIAS_SUBPIXEL. See the documentation for
  * #cairo_subpixel_order_t for full details.
  **/
 void
 cairo_font_options_set_subpixel_order (cairo_font_options_t   *options,
 				       cairo_subpixel_order_t  subpixel_order)
 {
-    if (options == (cairo_font_options_t *)&cairo_font_options_nil)
+    if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
 	return;
 
     options->subpixel_order = subpixel_order;
 }
 slim_hidden_def (cairo_font_options_set_subpixel_order);
 
 /**
  * cairo_font_options_get_subpixel_order:
@@ -307,17 +312,17 @@ cairo_font_options_get_subpixel_order (c
  * This controls whether to fit font outlines to the pixel grid,
  * and if so, whether to optimize for fidelity or contrast.
  * See the documentation for #cairo_hint_style_t for full details.
  **/
 void
 cairo_font_options_set_hint_style (cairo_font_options_t *options,
 				   cairo_hint_style_t    hint_style)
 {
-    if (options == (cairo_font_options_t *)&cairo_font_options_nil)
+    if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
 	return;
 
     options->hint_style = hint_style;
 }
 slim_hidden_def (cairo_font_options_set_hint_style);
 
 /**
  * cairo_font_options_get_hint_style:
@@ -343,17 +348,17 @@ cairo_font_options_get_hint_style (const
  * controls whether metrics are quantized to integer values in
  * device units.
  * See the documentation for #cairo_hint_metrics_t for full details.
  **/
 void
 cairo_font_options_set_hint_metrics (cairo_font_options_t *options,
 				     cairo_hint_metrics_t  hint_metrics)
 {
-    if (options == (cairo_font_options_t *)&cairo_font_options_nil)
+    if (options == (cairo_font_options_t *)&_cairo_font_options_nil)
 	return;
 
     options->hint_metrics = hint_metrics;
 }
 slim_hidden_def (cairo_font_options_set_hint_metrics);
 
 /**
  * cairo_font_options_get_hint_metrics:
deleted file mode 100644
--- a/gfx/cairo/cairo/src/cairo-font.c
+++ /dev/null
@@ -1,516 +0,0 @@
-/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2002 University of Southern California
- * Copyright © 2005 Red Hat Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is University of Southern
- * California.
- *
- * Contributor(s):
- *	Carl D. Worth <cworth@cworth.org>
- *      Graydon Hoare <graydon@redhat.com>
- *      Owen Taylor <otaylor@redhat.com>
- */
-
-#include "cairoint.h"
-
-/* Forward declare so we can use it as an arbitrary backend for
- * _cairo_font_face_nil.
- */
-static const cairo_font_face_backend_t _cairo_toy_font_face_backend;
-
-/* cairo_font_face_t */
-
-const cairo_font_face_t _cairo_font_face_nil = {
-    { 0 },			/* hash_entry */
-    CAIRO_STATUS_NO_MEMORY,	/* status */
-    CAIRO_REF_COUNT_INVALID,	/* ref_count */
-    { 0, 0, 0, NULL },		/* user_data */
-    &_cairo_toy_font_face_backend
-};
-
-void
-_cairo_font_face_init (cairo_font_face_t               *font_face,
-		       const cairo_font_face_backend_t *backend)
-{
-    font_face->status = CAIRO_STATUS_SUCCESS;
-    font_face->ref_count = 1;
-    font_face->backend = backend;
-
-    _cairo_user_data_array_init (&font_face->user_data);
-}
-
-/* This mutex protects both cairo_toy_font_hash_table as well as
-   reference count manipulations for all cairo_font_face_t. */
-CAIRO_MUTEX_DECLARE (_cairo_font_face_mutex);
-
-/**
- * cairo_font_face_reference:
- * @font_face: a #cairo_font_face_t, (may be %NULL in which case this
- * function does nothing).
- *
- * Increases the reference count on @font_face by one. This prevents
- * @font_face from being destroyed until a matching call to
- * cairo_font_face_destroy() is made.
- *
- * The number of references to a #cairo_font_face_t can be get using
- * cairo_font_face_get_reference_count().
- *
- * Return value: the referenced #cairo_font_face_t.
- **/
-cairo_font_face_t *
-cairo_font_face_reference (cairo_font_face_t *font_face)
-{
-    if (font_face == NULL || font_face->ref_count == CAIRO_REF_COUNT_INVALID)
-	return font_face;
-
-    CAIRO_MUTEX_LOCK (_cairo_font_face_mutex);
-
-    /* We would normally assert (font_face->ref_count >0) here but we
-     * can't get away with that due to the zombie case as documented
-     * in _cairo_ft_font_face_destroy. */
-
-    font_face->ref_count++;
-
-    CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
-
-    return font_face;
-}
-slim_hidden_def (cairo_font_face_reference);
-
-/**
- * cairo_font_face_destroy:
- * @font_face: a #cairo_font_face_t
- *
- * Decreases the reference count on @font_face by one. If the result
- * is zero, then @font_face and all associated resources are freed.
- * See cairo_font_face_reference().
- **/
-void
-cairo_font_face_destroy (cairo_font_face_t *font_face)
-{
-    if (font_face == NULL || font_face->ref_count == CAIRO_REF_COUNT_INVALID)
-	return;
-
-    CAIRO_MUTEX_LOCK (_cairo_font_face_mutex);
-
-    assert (font_face->ref_count > 0);
-
-    if (--(font_face->ref_count) > 0) {
-        CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
-	return;
-    }
-
-    CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
-
-    font_face->backend->destroy (font_face);
-
-    /* We allow resurrection to deal with some memory management for the
-     * FreeType backend where cairo_ft_font_face_t and cairo_ft_unscaled_font_t
-     * need to effectively mutually reference each other
-     */
-    if (font_face->ref_count > 0)
-	return;
-
-    _cairo_user_data_array_fini (&font_face->user_data);
-
-    free (font_face);
-}
-slim_hidden_def (cairo_font_face_destroy);
-
-/**
- * cairo_font_face_get_type:
- * @font_face: a font face
- *
- * This function returns the type of the backend used to create
- * a font face. See #cairo_font_type_t for available types.
- *
- * Return value: The type of @font_face.
- *
- * Since: 1.2
- **/
-cairo_font_type_t
-cairo_font_face_get_type (cairo_font_face_t *font_face)
-{
-    return font_face->backend->type;
-}
-
-/**
- * cairo_font_face_get_reference_count:
- * @font_face: a #cairo_font_face_t
- *
- * Returns the current reference count of @font_face.
- *
- * Return value: the current reference count of @font_face.  If the
- * object is a nil object, 0 will be returned.
- *
- * Since: 1.4
- **/
-unsigned int
-cairo_font_face_get_reference_count (cairo_font_face_t *font_face)
-{
-    if (font_face == NULL || font_face->ref_count == CAIRO_REF_COUNT_INVALID)
-	return 0;
-
-    return font_face->ref_count;
-}
-
-/**
- * cairo_font_face_status:
- * @font_face: a #cairo_font_face_t
- *
- * Checks whether an error has previously occurred for this
- * font face
- *
- * Return value: %CAIRO_STATUS_SUCCESS or another error such as
- *   %CAIRO_STATUS_NO_MEMORY.
- **/
-cairo_status_t
-cairo_font_face_status (cairo_font_face_t *font_face)
-{
-    return font_face->status;
-}
-
-/**
- * cairo_font_face_get_user_data:
- * @font_face: a #cairo_font_face_t
- * @key: the address of the #cairo_user_data_key_t the user data was
- * attached to
- *
- * Return user data previously attached to @font_face using the specified
- * key.  If no user data has been attached with the given key this
- * function returns %NULL.
- *
- * Return value: the user data previously attached or %NULL.
- **/
-void *
-cairo_font_face_get_user_data (cairo_font_face_t	   *font_face,
-			       const cairo_user_data_key_t *key)
-{
-    return _cairo_user_data_array_get_data (&font_face->user_data,
-					    key);
-}
-
-/**
- * cairo_font_face_set_user_data:
- * @font_face: a #cairo_font_face_t
- * @key: the address of a #cairo_user_data_key_t to attach the user data to
- * @user_data: the user data to attach to the font face
- * @destroy: a #cairo_destroy_func_t which will be called when the
- * font face is destroyed or when new user data is attached using the
- * same key.
- *
- * Attach user data to @font_face.  To remove user data from a font face,
- * call this function with the key that was used to set it and %NULL
- * for @data.
- *
- * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
- * slot could not be allocated for the user data.
- **/
-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,
-			       cairo_destroy_func_t	    destroy)
-{
-    if (font_face->ref_count == CAIRO_REF_COUNT_INVALID)
-	return CAIRO_STATUS_NO_MEMORY;
-
-    return _cairo_user_data_array_set_data (&font_face->user_data,
-					    key, user_data, destroy);
-}
-
-static const cairo_font_face_backend_t _cairo_toy_font_face_backend;
-
-static int
-_cairo_toy_font_face_keys_equal (const void *key_a,
-				 const void *key_b);
-
-/* We maintain a hash table from family/weight/slant =>
- * cairo_font_face_t for cairo_toy_font_t. The primary purpose of
- * this mapping is to provide unique cairo_font_face_t values so that
- * our cache and mapping from cairo_font_face_t => cairo_scaled_font_t
- * works. Once the corresponding cairo_font_face_t objects fall out of
- * downstream caches, we don't need them in this hash table anymore.
- *
- * Modifications to this hash table are protected by
- * _cairo_font_face_mutex.
- */
-static cairo_hash_table_t *cairo_toy_font_face_hash_table = NULL;
-
-static cairo_hash_table_t *
-_cairo_toy_font_face_hash_table_lock (void)
-{
-    CAIRO_MUTEX_LOCK (_cairo_font_face_mutex);
-
-    if (cairo_toy_font_face_hash_table == NULL)
-    {
-	cairo_toy_font_face_hash_table =
-	    _cairo_hash_table_create (_cairo_toy_font_face_keys_equal);
-
-	if (cairo_toy_font_face_hash_table == NULL) {
-	    CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
-	    return NULL;
-	}
-    }
-
-    return cairo_toy_font_face_hash_table;
-}
-
-static void
-_cairo_toy_font_face_hash_table_unlock (void)
-{
-    CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
-}
-
-/**
- * _cairo_toy_font_face_init_key:
- *
- * Initialize those portions of cairo_toy_font_face_t needed to use
- * it as a hash table key, including the hash code buried away in
- * font_face->base.hash_entry. No memory allocation is performed here
- * so that no fini call is needed. We do this to make it easier to use
- * an automatic cairo_toy_font_face_t variable as a key.
- **/
-static void
-_cairo_toy_font_face_init_key (cairo_toy_font_face_t *key,
-			       const char	     *family,
-			       cairo_font_slant_t     slant,
-			       cairo_font_weight_t    weight)
-{
-    unsigned long hash;
-
-    key->family = family;
-    key->owns_family = FALSE;
-
-    key->slant = slant;
-    key->weight = weight;
-
-    /* 1607 and 1451 are just a couple of arbitrary primes. */
-    hash = _cairo_hash_string (family);
-    hash += ((unsigned long) slant) * 1607;
-    hash += ((unsigned long) weight) * 1451;
-
-    key->base.hash_entry.hash = hash;
-}
-
-static cairo_status_t
-_cairo_toy_font_face_init (cairo_toy_font_face_t *font_face,
-			   const char	         *family,
-			   cairo_font_slant_t	  slant,
-			   cairo_font_weight_t	  weight)
-{
-    char *family_copy;
-
-    family_copy = strdup (family);
-    if (family_copy == NULL)
-	return CAIRO_STATUS_NO_MEMORY;
-
-    _cairo_toy_font_face_init_key (font_face, family_copy,
-				      slant, weight);
-    font_face->owns_family = TRUE;
-
-    _cairo_font_face_init (&font_face->base, &_cairo_toy_font_face_backend);
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static void
-_cairo_toy_font_face_fini (cairo_toy_font_face_t *font_face)
-{
-    /* We assert here that we own font_face->family before casting
-     * away the const qualifer. */
-    assert (font_face->owns_family);
-    free ((char*) font_face->family);
-}
-
-static int
-_cairo_toy_font_face_keys_equal (const void *key_a,
-				 const void *key_b)
-{
-    const cairo_toy_font_face_t *face_a = key_a;
-    const cairo_toy_font_face_t *face_b = key_b;
-
-    return (strcmp (face_a->family, face_b->family) == 0 &&
-	    face_a->slant == face_b->slant &&
-	    face_a->weight == face_b->weight);
-}
-
-/**
- * _cairo_toy_font_face_create:
- * @family: a font family name, encoded in UTF-8
- * @slant: the slant for the font
- * @weight: the weight for the font
- *
- * Creates a font face from a triplet of family, slant, and weight.
- * These font faces are used in implementation of the the #cairo_t "toy"
- * font API.
- *
- * Return value: a newly created #cairo_font_face_t, destroy with
- *  cairo_font_face_destroy()
- **/
-cairo_font_face_t *
-_cairo_toy_font_face_create (const char          *family,
-			     cairo_font_slant_t   slant,
-			     cairo_font_weight_t  weight)
-{
-    cairo_status_t status;
-    cairo_toy_font_face_t key, *font_face;
-    cairo_hash_table_t *hash_table;
-
-    hash_table = _cairo_toy_font_face_hash_table_lock ();
-    if (hash_table == NULL)
-	goto UNWIND;
-
-    _cairo_toy_font_face_init_key (&key, family, slant, weight);
-
-    /* Return existing font_face if it exists in the hash table. */
-    if (_cairo_hash_table_lookup (hash_table,
-				  &key.base.hash_entry,
-				  (cairo_hash_entry_t **) &font_face))
-    {
-	/* We increment the reference count here manually to avoid
-	   double-locking. */
-	font_face->base.ref_count++;
-	_cairo_toy_font_face_hash_table_unlock ();
-	return &font_face->base;
-    }
-
-    /* Otherwise create it and insert into hash table. */
-    font_face = malloc (sizeof (cairo_toy_font_face_t));
-    if (font_face == NULL)
-	goto UNWIND_HASH_TABLE_LOCK;
-
-    status = _cairo_toy_font_face_init (font_face, family, slant, weight);
-    if (status)
-	goto UNWIND_FONT_FACE_MALLOC;
-
-    status = _cairo_hash_table_insert (hash_table, &font_face->base.hash_entry);
-    if (status)
-	goto UNWIND_FONT_FACE_INIT;
-
-    _cairo_toy_font_face_hash_table_unlock ();
-
-    return &font_face->base;
-
- UNWIND_FONT_FACE_INIT:
- UNWIND_FONT_FACE_MALLOC:
-    free (font_face);
- UNWIND_HASH_TABLE_LOCK:
-    _cairo_toy_font_face_hash_table_unlock ();
- UNWIND:
-    return (cairo_font_face_t*) &_cairo_font_face_nil;
-}
-
-static void
-_cairo_toy_font_face_destroy (void *abstract_face)
-{
-    cairo_toy_font_face_t *font_face = abstract_face;
-    cairo_hash_table_t *hash_table;
-
-    if (font_face == NULL)
-	return;
-
-    hash_table = _cairo_toy_font_face_hash_table_lock ();
-    /* All created objects must have been mapped in the hash table. */
-    assert (hash_table != NULL);
-
-    _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
-
-    _cairo_toy_font_face_hash_table_unlock ();
-
-    _cairo_toy_font_face_fini (font_face);
-}
-
-static cairo_status_t
-_cairo_toy_font_face_scaled_font_create (void                *abstract_font_face,
-					 const cairo_matrix_t       *font_matrix,
-					 const cairo_matrix_t       *ctm,
-					 const cairo_font_options_t *options,
-					 cairo_scaled_font_t	   **scaled_font)
-{
-    cairo_toy_font_face_t *font_face = abstract_font_face;
-    const cairo_scaled_font_backend_t * backend = CAIRO_SCALED_FONT_BACKEND_DEFAULT;
-
-    return backend->create_toy (font_face,
-				font_matrix, ctm, options, scaled_font);
-}
-
-static const cairo_font_face_backend_t _cairo_toy_font_face_backend = {
-    CAIRO_FONT_TYPE_TOY,
-    _cairo_toy_font_face_destroy,
-    _cairo_toy_font_face_scaled_font_create
-};
-
-void
-_cairo_unscaled_font_init (cairo_unscaled_font_t               *unscaled_font,
-			   const cairo_unscaled_font_backend_t *backend)
-{
-    unscaled_font->ref_count = 1;
-    unscaled_font->backend = backend;
-}
-
-cairo_unscaled_font_t *
-_cairo_unscaled_font_reference (cairo_unscaled_font_t *unscaled_font)
-{
-    if (unscaled_font == NULL)
-	return NULL;
-
-    unscaled_font->ref_count++;
-
-    return unscaled_font;
-}
-
-void
-_cairo_unscaled_font_destroy (cairo_unscaled_font_t *unscaled_font)
-{
-    if (unscaled_font == NULL)
-	return;
-
-    if (--(unscaled_font->ref_count) > 0)
-	return;
-
-    unscaled_font->backend->destroy (unscaled_font);
-
-    free (unscaled_font);
-}
-
-void
-_cairo_font_reset_static_data (void)
-{
-    _cairo_scaled_font_map_destroy ();
-
-    /* We manually acquire the lock rather than calling
-     * cairo_toy_font_face_hash_table_lock simply to avoid
-     * creating the table only to destroy it again. */
-    CAIRO_MUTEX_LOCK (_cairo_font_face_mutex);
-    _cairo_hash_table_destroy (cairo_toy_font_face_hash_table);
-    cairo_toy_font_face_hash_table = NULL;
-    CAIRO_MUTEX_UNLOCK (_cairo_font_face_mutex);
-}
--- a/gfx/cairo/cairo/src/cairo-freelist-private.h
+++ b/gfx/cairo/cairo/src/cairo-freelist-private.h
@@ -21,18 +21,16 @@
  */
 #ifndef CAIRO_FREELIST_H
 #define CAIRO_FREELIST_H
 
 #include "cairoint.h"
 #include <stddef.h>
 
 /* Opaque implementation types. */
-struct _cairo_freelist;
-struct _cairo_freelist_node;
 typedef struct _cairo_freelist cairo_freelist_t;
 typedef struct _cairo_freelist_node cairo_freelist_node_t;
 
 struct _cairo_freelist_node {
     cairo_freelist_node_t *next;
 };
 
 struct _cairo_freelist {
--- a/gfx/cairo/cairo/src/cairo-freelist.c
+++ b/gfx/cairo/cairo/src/cairo-freelist.c
@@ -14,18 +14,19 @@
  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  * OF THIS SOFTWARE.
  */
-#include <stdlib.h>
-#include <string.h>
+
+#include "cairoint.h"
+
 #include "cairo-freelist-private.h"
 
 void
 _cairo_freelist_init (cairo_freelist_t *freelist, unsigned nodesize)
 {
     memset (freelist, 0, sizeof(cairo_freelist_t));
     freelist->nodesize = nodesize;
 }
--- a/gfx/cairo/cairo/src/cairo-ft-font.c
+++ b/gfx/cairo/cairo/src/cairo-ft-font.c
@@ -32,20 +32,22 @@
  *
  * Contributor(s):
  *      Graydon Hoare <graydon@redhat.com>
  *	Owen Taylor <otaylor@redhat.com>
  *      Keith Packard <keithp@keithp.com>
  *      Carl Worth <cworth@cworth.org>
  */
 
-#include <float.h>
+#include "cairoint.h"
 
 #include "cairo-ft-private.h"
 
+#include <float.h>
+
 #include <fontconfig/fontconfig.h>
 #include <fontconfig/fcfreetype.h>
 
 #include <ft2build.h>
 #include FT_FREETYPE_H
 #include FT_OUTLINE_H
 #include FT_IMAGE_H
 #include FT_TRUETYPE_TABLES_H
@@ -57,22 +59,16 @@
 #define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0)
 #define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
 #define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0)
 
 /* This is the max number of FT_face objects we keep open at once
  */
 #define MAX_OPEN_FACES 10
 
-#ifndef MOZILLA_CAIRO_NOT_DEFINED
-/* This is the maximum font size we allow to be passed to FT_Set_Char_Size
- */
-#define MAX_FONT_SIZE 1000
-#endif /* !MOZILLA_CAIRO_NOT_DEFINED */
-
 /*
  * The simple 2x2 matrix is converted into separate scale and shape
  * factors so that hinting works right
  */
 
 typedef struct _cairo_ft_font_transform {
     double  x_scale, y_scale;
     double  shape[2][2];
@@ -151,18 +147,16 @@ static const cairo_unscaled_font_backend
 typedef struct _cairo_ft_unscaled_font_map {
     cairo_hash_table_t *hash_table;
     FT_Library ft_library;
     int num_open_faces;
 } cairo_ft_unscaled_font_map_t;
 
 static cairo_ft_unscaled_font_map_t *cairo_ft_unscaled_font_map = NULL;
 
-CAIRO_MUTEX_DECLARE(_cairo_ft_unscaled_font_map_mutex);
-
 static void
 _font_map_release_face_lock_held (cairo_ft_unscaled_font_map_t *font_map,
 				  cairo_ft_unscaled_font_t *unscaled)
 {
     if (unscaled->face) {
 	FT_Done_Face (unscaled->face);
 	unscaled->face = NULL;
 	unscaled->have_scale = FALSE;
@@ -256,16 +250,17 @@ static cairo_ft_unscaled_font_map_t *
     CAIRO_MUTEX_LOCK (_cairo_ft_unscaled_font_map_mutex);
 
     if (cairo_ft_unscaled_font_map == NULL)
     {
 	_cairo_ft_unscaled_font_map_create ();
 
 	if (cairo_ft_unscaled_font_map == NULL) {
 	    CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex);
+	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    return NULL;
 	}
     }
 
     return cairo_ft_unscaled_font_map;
 }
 
 static void
@@ -328,24 +323,26 @@ static cairo_status_t
 	unscaled->id = 0;
     } else {
 	char *filename_copy;
 
 	unscaled->from_face = FALSE;
 	unscaled->face = NULL;
 
 	filename_copy = strdup (filename);
-	if (filename_copy == NULL)
+	if (filename_copy == NULL) {
+	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    return CAIRO_STATUS_NO_MEMORY;
+	}
 
 	_cairo_ft_unscaled_font_init_key (unscaled, filename_copy, id);
     }
 
     unscaled->have_scale = FALSE;
-    CAIRO_MUTEX_INIT (&unscaled->mutex);
+    CAIRO_MUTEX_INIT (unscaled->mutex);
     unscaled->lock_count = 0;
 
     unscaled->faces = NULL;
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 cairo_bool_t
@@ -370,17 +367,17 @@ static void
 {
     assert (unscaled->face == NULL);
 
     if (unscaled->filename) {
 	free (unscaled->filename);
 	unscaled->filename = NULL;
     }
 
-    CAIRO_MUTEX_FINI (&unscaled->mutex);
+    CAIRO_MUTEX_FINI (unscaled->mutex);
 }
 
 static int
 _cairo_ft_unscaled_font_keys_equal (const void *key_a,
 				    const void *key_b)
 {
     const cairo_ft_unscaled_font_t *unscaled_a = key_a;
     const cairo_ft_unscaled_font_t *unscaled_b = key_b;
@@ -414,18 +411,18 @@ static cairo_ft_unscaled_font_t *
 	goto UNWIND;
 
     _cairo_ft_unscaled_font_init_key (&key, filename, id);
 
     /* Return existing unscaled font if it exists in the hash table. */
     if (_cairo_hash_table_lookup (font_map->hash_table, &key.base.hash_entry,
 				  (cairo_hash_entry_t **) &unscaled))
     {
+	_cairo_unscaled_font_reference (&unscaled->base);
 	_cairo_ft_unscaled_font_map_unlock ();
-	_cairo_unscaled_font_reference (&unscaled->base);
 	return unscaled;
     }
 
     /* Otherwise create it and insert into hash table. */
     unscaled = malloc (sizeof (cairo_ft_unscaled_font_t));
     if (unscaled == NULL)
 	goto UNWIND_FONT_MAP_LOCK;
 
@@ -551,16 +548,17 @@ FT_Face
     _cairo_ft_unscaled_font_map_unlock ();
 
     if (FT_New_Face (font_map->ft_library,
 		     unscaled->filename,
 		     unscaled->id,
 		     &face) != FT_Err_Ok)
     {
 	CAIRO_MUTEX_UNLOCK (unscaled->mutex);
+	_cairo_error (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
     }
 
     unscaled->face = face;
 
     font_map->num_open_faces++;
 
     return face;
@@ -609,32 +607,32 @@ static void
 	sf->shape[0][0] = sf->shape[1][1] = 1.0;
 	sf->shape[0][1] = sf->shape[1][0] = 0.0;
     }
 }
 
 /* Temporarily scales an unscaled font to the give scale. We catch
  * scaling to the same size, since changing a FT_Face is expensive.
  */
-static void
+static cairo_status_t
 _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
 				   cairo_matrix_t	      *scale)
 {
     cairo_ft_font_transform_t sf;
     FT_Matrix mat;
     FT_Error error;
 
     assert (unscaled->face != NULL);
 
     if (unscaled->have_scale &&
 	scale->xx == unscaled->current_scale.xx &&
 	scale->yx == unscaled->current_scale.yx &&
 	scale->xy == unscaled->current_scale.xy &&
 	scale->yy == unscaled->current_scale.yy)
-	return;
+	return CAIRO_STATUS_SUCCESS;
 
     unscaled->have_scale = TRUE;
     unscaled->current_scale = *scale;
 
     _compute_transform (&sf, scale);
 
     unscaled->x_scale = sf.x_scale;
     unscaled->y_scale = sf.y_scale;
@@ -653,37 +651,24 @@ static void
     cairo_matrix_init (&unscaled->current_shape,
 		       sf.shape[0][0], sf.shape[0][1],
 		       sf.shape[1][0], sf.shape[1][1],
 		       0.0, 0.0);
 
     FT_Set_Transform(unscaled->face, &mat, NULL);
 
     if ((unscaled->face->face_flags & FT_FACE_FLAG_SCALABLE) != 0) {
-#ifndef MOZILLA_CAIRO_NOT_DEFINED
-        double x_scale = sf.x_scale;
-        double y_scale = sf.y_scale;
-        if (x_scale > MAX_FONT_SIZE) {
-            x_scale = MAX_FONT_SIZE;
-        }
-        if (y_scale > MAX_FONT_SIZE) {
-            y_scale = MAX_FONT_SIZE;
-        }
-
 	error = FT_Set_Char_Size (unscaled->face,
 				  sf.x_scale * 64.0,
 				  sf.y_scale * 64.0,
 				  0, 0);
-#else
-	error = FT_Set_Char_Size (unscaled->face,
-				  x_scale * 64.0,
-				  y_scale * 64.0,
-				  0, 0);
-#endif /* MOZCAIRO */
-	assert (error == 0);
+	if (error) {
+	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    return CAIRO_STATUS_NO_MEMORY;
+	}
     } else {
 	double min_distance = DBL_MAX;
 	int i;
 	int best_i = 0;
 
 	for (i = 0; i < unscaled->face->num_fixed_sizes; i++) {
 #if HAVE_FT_BITMAP_SIZE_Y_PPEM
 	    double size = unscaled->face->available_sizes[i].y_ppem / 64.;
@@ -702,18 +687,23 @@ static void
 				  unscaled->face->available_sizes[best_i].x_ppem,
 				  unscaled->face->available_sizes[best_i].y_ppem,
 				  0, 0);
 	if (error)
 #endif
 	    error = FT_Set_Pixel_Sizes (unscaled->face,
 					unscaled->face->available_sizes[best_i].width,
 					unscaled->face->available_sizes[best_i].height);
-	assert (error == 0);
+	if (error) {
+	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    return CAIRO_STATUS_NO_MEMORY;
+	}
     }
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 /* Empirically-derived subpixel filtering values thanks to Keith
  * Packard and libXft. */
 static const int    filters[3][3] = {
     /* red */
 #if 0
     {    65538*4/7,65538*2/7,65538*1/7 },
@@ -748,18 +738,20 @@ static cairo_status_t
     switch (bitmap->pixel_mode) {
     case FT_PIXEL_MODE_MONO:
 	stride = (((width + 31) & ~31) >> 3);
 	if (own_buffer) {
 	    data = bitmap->buffer;
 	    assert (stride == bitmap->pitch);
 	} else {
 	    data = malloc (stride * height);
-	    if (!data)
+	    if (!data) {
+		_cairo_error (CAIRO_STATUS_NO_MEMORY);
 		return CAIRO_STATUS_NO_MEMORY;
+	    }
 
 	    if (stride == bitmap->pitch) {
 		memcpy (data, bitmap->buffer, stride * height);
 	    } else {
 		int i;
 		unsigned char *source, *dest;
 
 		source = bitmap->buffer;
@@ -796,18 +788,20 @@ static cairo_status_t
 	case CAIRO_ANTIALIAS_GRAY:
 	case CAIRO_ANTIALIAS_NONE:
 	default:
 	    stride = bitmap->pitch;
 	    if (own_buffer) {
 		data = bitmap->buffer;
 	    } else {
 		data = malloc (stride * height);
-		if (!data)
+		if (!data) {
+		    _cairo_error (CAIRO_STATUS_NO_MEMORY);
 		    return CAIRO_STATUS_NO_MEMORY;
+		}
 		memcpy (data, bitmap->buffer, stride * height);
 	    }
 	    format = CAIRO_FORMAT_A8;
 	    break;
 	case CAIRO_ANTIALIAS_SUBPIXEL: {
 	    int		    x, y;
 	    unsigned char   *in_line, *out_line, *in;
 	    unsigned int    *out;
@@ -836,16 +830,22 @@ static cairo_status_t
 	    }
 	    /*
 	     * Filter the glyph to soften the color fringes
 	     */
 	    width_rgba = width;
 	    stride = bitmap->pitch;
 	    stride_rgba = (width_rgba * 4 + 3) & ~3;
 	    data_rgba = calloc (1, stride_rgba * height);
+	    if (data_rgba == NULL) {
+		if (own_buffer)
+		    free (bitmap->buffer);
+		_cairo_error (CAIRO_STATUS_NO_MEMORY);
+		return CAIRO_STATUS_NO_MEMORY;
+	    }
 
 	    os = 1;
 	    switch (font_options->subpixel_order) {
 	    case CAIRO_SUBPIXEL_ORDER_VRGB:
 		os = stride;
 	    case CAIRO_SUBPIXEL_ORDER_DEFAULT:
 	    case CAIRO_SUBPIXEL_ORDER_RGB:
 	    default:
@@ -900,16 +900,19 @@ static cairo_status_t
 	    break;
 	}
 	}
 	break;
     case FT_PIXEL_MODE_GRAY2:
     case FT_PIXEL_MODE_GRAY4:
 	/* These could be triggered by very rare types of TrueType fonts */
     default:
+	if (own_buffer)
+	    free (bitmap->buffer);
+	_cairo_error (CAIRO_STATUS_NO_MEMORY);
 	return CAIRO_STATUS_NO_MEMORY;
     }
 
     *surface = (cairo_image_surface_t *)
 	cairo_image_surface_create_for_data (data,
 					     format,
 					     width, height, stride);
     if ((*surface)->base.status) {
@@ -1030,23 +1033,25 @@ static cairo_status_t
 	}
 
 	bitmap.pitch = stride;
 	bitmap.width = width * hmul;
 	bitmap.rows = height * vmul;
 	bitmap.buffer = calloc (1, stride * bitmap.rows);
 
 	if (bitmap.buffer == NULL) {
+	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    return CAIRO_STATUS_NO_MEMORY;
 	}
 
 	FT_Outline_Translate (outline, -cbox.xMin*hmul, -cbox.yMin*vmul);
 
 	if (FT_Outline_Get_Bitmap (glyphslot->library, outline, &bitmap) != 0) {
 	    free (bitmap.buffer);
+	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    return CAIRO_STATUS_NO_MEMORY;
 	}
 
 	status = _get_bitmap_surface (&bitmap, TRUE, font_options, surface);
 	if (status)
 	    return status;
     }
 
@@ -1074,18 +1079,20 @@ static cairo_status_t
     /* According to the FreeType docs, glyphslot->format could be
      * something other than FT_GLYPH_FORMAT_OUTLINE or
      * FT_GLYPH_FORMAT_BITMAP. Calling FT_Render_Glyph gives FreeType
      * the opportunity to convert such to
      * bitmap. FT_GLYPH_FORMAT_COMPOSITE will not be encountered since
      * we avoid the FT_LOAD_NO_RECURSE flag.
      */
     error = FT_Render_Glyph (glyphslot, FT_RENDER_MODE_NORMAL);
-    if (error)
+    if (error) {
+	_cairo_error (CAIRO_STATUS_NO_MEMORY);
 	return CAIRO_STATUS_NO_MEMORY;
+    }
 
     status = _get_bitmap_surface (&glyphslot->bitmap, FALSE, font_options, surface);
     if (status)
 	return status;
 
     /*
      * Note: the font's coordinate system is upside down from ours, so the
      * Y coordinate of the control box needs to be negated.
@@ -1173,34 +1180,43 @@ static cairo_status_t
     /* We need to pad out the width to 32-bit intervals for cairo-xlib-surface.c */
     width = (width + 3) & ~3;
     image = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
     if (image->status)
 	return CAIRO_STATUS_NO_MEMORY;
 
     /* 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.
      */
     origin_x = - origin_x;
     origin_y = - origin_y;
     cairo_matrix_transform_point (&original_to_transformed,
 				  &origin_x, &origin_y);
 
@@ -1440,43 +1456,58 @@ static cairo_scaled_font_t *
 			      const cairo_matrix_t	 *ctm,
 			      const cairo_font_options_t *options,
 			      cairo_ft_options_t	  ft_options)
 {
     cairo_ft_scaled_font_t *scaled_font = NULL;
     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)
 	return NULL;
 
     scaled_font = malloc (sizeof(cairo_ft_scaled_font_t));
     if (scaled_font == NULL) {
 	_cairo_ft_unscaled_font_unlock_face (unscaled);
+	_cairo_error (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
     }
 
     _cairo_unscaled_font_reference (&unscaled->base);
     scaled_font->unscaled = unscaled;
 
     if (options->hint_metrics != CAIRO_HINT_METRICS_OFF)
 	ft_options.extra_flags |= CAIRO_FT_OPTIONS_HINT_METRICS;
 
     _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);
-
-    _cairo_ft_unscaled_font_set_scale (unscaled,
-				       &scaled_font->base.scale);
+    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_unscaled_font_destroy (&unscaled->base);
+	_cairo_ft_unscaled_font_unlock_face (unscaled);
+	return NULL;
+    }
+
+    status = _cairo_ft_unscaled_font_set_scale (unscaled,
+				                &scaled_font->base.scale);
+    if (status) {
+	free (scaled_font);
+	_cairo_unscaled_font_destroy (&unscaled->base);
+	_cairo_ft_unscaled_font_unlock_face (unscaled);
+	return NULL;
+    }
+
 
     metrics = &face->size->metrics;
 
     /*
      * Get to unscaled metrics so that the upper level can get back to
      * user space
      */
     if (scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF) {
@@ -1544,18 +1575,20 @@ static cairo_status_t
     int fcslant;
     int fcweight;
     cairo_matrix_t scale;
     cairo_ft_font_transform_t sf;
     cairo_ft_options_t ft_options;
     unsigned char *family = (unsigned char*) toy_face->family;
 
     pattern = FcPatternCreate ();
-    if (!pattern)
+    if (!pattern) {
+	_cairo_error (CAIRO_STATUS_NO_MEMORY);
 	return CAIRO_STATUS_NO_MEMORY;
+    }
 
     switch (toy_face->weight)
     {
     case CAIRO_FONT_WEIGHT_BOLD:
         fcweight = FC_WEIGHT_BOLD;
         break;
     case CAIRO_FONT_WEIGHT_NORMAL:
     default:
@@ -1615,16 +1648,17 @@ static cairo_status_t
 
  FREE_PATTERN:
     FcPatternDestroy (pattern);
 
     if (new_font) {
 	*font = new_font;
 	return CAIRO_STATUS_SUCCESS;
     } else {
+	_cairo_error (CAIRO_STATUS_NO_MEMORY);
 	return CAIRO_STATUS_NO_MEMORY;
     }
 }
 
 static void
 _cairo_ft_scaled_font_fini (void *abstract_font)
 {
     cairo_ft_scaled_font_t *scaled_font = abstract_font;
@@ -1639,65 +1673,71 @@ static int
 _move_to (FT_Vector *to, void *closure)
 {
     cairo_path_fixed_t *path = closure;
     cairo_fixed_t x, y;
 
     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;
 }
 
 static int
 _line_to (FT_Vector *to, void *closure)
 {
     cairo_path_fixed_t *path = closure;
     cairo_fixed_t x, y;
 
     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;
 }
 
 static int
 _conic_to (FT_Vector *control, FT_Vector *to, void *closure)
 {
     cairo_path_fixed_t *path = closure;
 
     cairo_fixed_t x0, y0;
     cairo_fixed_t x1, y1;
     cairo_fixed_t x2, y2;
     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);
 
     x3 = _cairo_fixed_from_26_6 (to->x);
     y3 = _cairo_fixed_from_26_6 (to->y);
 
     x1 = x0 + 2.0/3.0 * (conic.x - x0);
     y1 = y0 + 2.0/3.0 * (conic.y - y0);
 
     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;
 }
 
 static int
 _cubic_to (FT_Vector *control1, FT_Vector *control2,
 	   FT_Vector *to, void *closure)
 {
@@ -1710,20 +1750,21 @@ static int
     y0 = _cairo_fixed_from_26_6 (control1->y);
 
     x1 = _cairo_fixed_from_26_6 (control2->x);
     y1 = _cairo_fixed_from_26_6 (control2->y);
 
     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;
 }
 
 static cairo_status_t
 _decompose_glyph_outline (FT_Face		  face,
 			  cairo_font_options_t	 *options,
 			  cairo_path_fixed_t	**pathp)
@@ -1738,28 +1779,37 @@ static cairo_status_t
     };
     static const FT_Matrix invert_y = {
 	DOUBLE_TO_16_16 (1.0), 0,
 	0, DOUBLE_TO_16_16 (-1.0),
     };
 
     FT_GlyphSlot glyph;
     cairo_path_fixed_t *path;
+    cairo_status_t status;
 
     path = _cairo_path_fixed_create ();
     if (!path)
 	return CAIRO_STATUS_NO_MEMORY;
 
     glyph = face->glyph;
 
     /* 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);
-
-    _cairo_path_fixed_close_path (path);
+    if (FT_Outline_Decompose (&glyph->outline, &outline_funcs, path)) {
+	_cairo_path_fixed_destroy (path);
+	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	return CAIRO_STATUS_NO_MEMORY;
+    }
+
+    status = _cairo_path_fixed_close_path (path);
+    if (status) {
+	_cairo_path_fixed_destroy (path);
+	return status;
+    }
 
     *pathp = path;
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 /*
  * Translate glyph to match its metrics.
@@ -1793,24 +1843,26 @@ static cairo_int_status_t
     cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;
     FT_GlyphSlot glyph;
     FT_Face face;
     FT_Error error;
     int load_flags = scaled_font->ft_options.load_flags;
     FT_Glyph_Metrics *metrics;
     double x_factor, y_factor;
     cairo_bool_t vertical_layout = FALSE;
-    cairo_status_t status = CAIRO_STATUS_SUCCESS;
+    cairo_status_t status;
 
     face = _cairo_ft_unscaled_font_lock_face (unscaled);
     if (!face)
 	return CAIRO_STATUS_NO_MEMORY;
 
-    _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
-				       &scaled_font->base.scale);
+    status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
+				                &scaled_font->base.scale);
+    if (status)
+	goto FAIL;
 
     /* Ignore global advance unconditionally */
     load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
 
     if ((info & CAIRO_SCALED_GLYPH_INFO_PATH) != 0 &&
 	(info & CAIRO_SCALED_GLYPH_INFO_SURFACE) == 0)
 	load_flags |= FT_LOAD_NO_BITMAP;
 
@@ -1946,19 +1998,22 @@ static cairo_int_status_t
 	cairo_image_surface_t	*surface;
 
 	if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
 	    status = _render_glyph_outline (face, &scaled_font->ft_options.base,
 					    &surface);
 	} else {
 	    status = _render_glyph_bitmap (face, &scaled_font->ft_options.base,
 					   &surface);
-	    if (status == CAIRO_STATUS_SUCCESS && unscaled->have_shape)
+	    if (status == CAIRO_STATUS_SUCCESS && unscaled->have_shape) {
 		status = _transform_glyph_bitmap (&unscaled->current_shape,
 						  &surface);
+		if (status)
+		    cairo_surface_destroy (&surface->base);
+	    }
 	}
 	if (status)
 	    goto FAIL;
 
 	_cairo_scaled_glyph_set_surface (scaled_glyph,
 					 &scaled_font->base,
 					 surface);
     }
@@ -1972,16 +2027,17 @@ static cairo_int_status_t
 	 */
 	if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
 	    error = FT_Load_Glyph (face,
 				   _cairo_scaled_glyph_index(scaled_glyph),
 				   load_flags | FT_LOAD_NO_BITMAP);
 
 	    if (error) {
 		_cairo_ft_unscaled_font_unlock_face (unscaled);
+		_cairo_error (CAIRO_STATUS_NO_MEMORY);
 		return CAIRO_STATUS_NO_MEMORY;
 	    }
 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
 	    /*
 	     * embolden glyphs if requested
 	     */
 	    if (scaled_font->ft_options.extra_flags & CAIRO_FT_OPTIONS_EMBOLDEN)
 		FT_GlyphSlot_Embolden (glyph);
@@ -2181,49 +2237,60 @@ static cairo_status_t
      */
 
     ft_options = font_face->ft_options;
 
     *scaled_font = _cairo_ft_scaled_font_create (font_face->unscaled,
 						 &font_face->base,
 						 font_matrix, ctm,
 						 options, ft_options);
-    if (*scaled_font)
+    if (*scaled_font) {
 	return CAIRO_STATUS_SUCCESS;
-    else
+    } else {
+	_cairo_error (CAIRO_STATUS_NO_MEMORY);
 	return CAIRO_STATUS_NO_MEMORY;
+    }
 }
 
 static const cairo_font_face_backend_t _cairo_ft_font_face_backend = {
     CAIRO_FONT_TYPE_FT,
     _cairo_ft_font_face_destroy,
     _cairo_ft_font_face_scaled_font_create
 };
 
 static cairo_font_face_t *
 _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled,
 			    cairo_ft_options_t	     *ft_options)
 {
-    cairo_ft_font_face_t *font_face;
+    cairo_ft_font_face_t *font_face, **prev_font_face;
 
     /* Looked for an existing matching font face */
-    for (font_face = unscaled->faces;
+    for (font_face = unscaled->faces, prev_font_face = &unscaled->faces;
 	 font_face;
-	 font_face = font_face->next)
+	 prev_font_face = &font_face->next, font_face = font_face->next)
     {
 	if (font_face->ft_options.load_flags == ft_options->load_flags &&
 	    font_face->ft_options.extra_flags == ft_options->extra_flags &&
 	    cairo_font_options_equal (&font_face->ft_options.base, &ft_options->base))
-	    return cairo_font_face_reference (&font_face->base);
+	{
+	    if (! font_face->base.status)
+		return cairo_font_face_reference (&font_face->base);
+
+	    /* The font_face has been left in an error state, abandon it. */
+	    *prev_font_face = font_face->next;
+	    break;
+	}
     }
 
     /* No match found, create a new one */
     font_face = malloc (sizeof (cairo_ft_font_face_t));
-    if (!font_face)
+    if (!font_face) {
+	_cairo_error (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
+    }
 
     font_face->unscaled = unscaled;
     _cairo_unscaled_font_reference (&unscaled->base);
 
     font_face->ft_options = *ft_options;
 
     font_face->next = unscaled->faces;
     unscaled->faces = font_face;
@@ -2371,20 +2438,18 @@ cairo_ft_font_face_create_for_pattern (F
     }
 
     _get_pattern_ft_options (pattern, &ft_options);
     font_face = _cairo_ft_font_face_create (unscaled, &ft_options);
     _cairo_unscaled_font_destroy (&unscaled->base);
 
     if (font_face)
 	return font_face;
-    else {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+    else
 	return (cairo_font_face_t *)&_cairo_font_face_nil;
-    }
 }
 
 /**
  * cairo_ft_font_face_create_for_ft_face:
  * @face: A FreeType face object, already opened. This must
  *   be kept around until the face's ref_count drops to
  *   zero and it is freed. Since the face may be referenced
  *   internally to Cairo, the best way to determine when it
@@ -2424,22 +2489,20 @@ cairo_ft_font_face_create_for_ft_face (F
 
     ft_options.load_flags = load_flags;
     ft_options.extra_flags = 0;
     _cairo_font_options_init_default (&ft_options.base);
 
     font_face = _cairo_ft_font_face_create (unscaled, &ft_options);
     _cairo_unscaled_font_destroy (&unscaled->base);
 
-    if (font_face) {
+    if (font_face)
 	return font_face;
-    } else {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+    else
 	return (cairo_font_face_t *)&_cairo_font_face_nil;
-    }
 }
 
 /**
  * cairo_ft_scaled_font_lock_face:
  * @scaled_font: A #cairo_scaled_font_t from the FreeType font backend. Such an
  *   object can be created by calling cairo_scaled_font_create() on a
  *   FreeType backend font face (see cairo_ft_font_face_create_for_pattern(),
  *   cairo_ft_font_face_create_for_face()).
@@ -2467,28 +2530,34 @@ cairo_ft_font_face_create_for_ft_face (F
  * or %NULL if @scaled_font is in an error state (see
  * cairo_scaled_font_status()) or there is insufficient memory.
  **/
 FT_Face
 cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *abstract_font)
 {
     cairo_ft_scaled_font_t *scaled_font = (cairo_ft_scaled_font_t *) abstract_font;
     FT_Face face;
+    cairo_status_t status;
 
     if (scaled_font->base.status)
 	return NULL;
 
     face = _cairo_ft_unscaled_font_lock_face (scaled_font->unscaled);
     if (face == NULL) {
 	_cairo_scaled_font_set_error (&scaled_font->base, CAIRO_STATUS_NO_MEMORY);
 	return NULL;
     }
 
-    _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
-				       &scaled_font->base.scale);
+    status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
+				                &scaled_font->base.scale);
+    if (status) {
+	_cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled);
+	_cairo_scaled_font_set_error (&scaled_font->base, status);
+	return NULL;
+    }
 
     /* NOTE: We deliberately release the unscaled font's mutex here,
      * so that we are not holding a lock across two separate calls to
      * cairo function, (which would give the application some
      * opportunity for creating deadlock. This is obviously unsafe,
      * but as documented, the user must add manual locking when using
      * this function. */
      CAIRO_MUTEX_UNLOCK (scaled_font->unscaled->mutex);
--- a/gfx/cairo/cairo/src/cairo-glitz-surface.c
+++ b/gfx/cairo/cairo/src/cairo-glitz-surface.c
@@ -28,31 +28,31 @@
 #include "cairo-glitz.h"
 #include "cairo-glitz-private.h"
 
 typedef struct _cairo_glitz_surface {
     cairo_surface_t   base;
 
     glitz_surface_t   *surface;
     glitz_format_t    *format;
-    pixman_region16_t *clip;
+    cairo_bool_t      has_clip;
+    pixman_region16_t clip;
 } cairo_glitz_surface_t;
 
 static const cairo_surface_backend_t *
 _cairo_glitz_surface_get_backend (void);
 
 static cairo_status_t
 _cairo_glitz_surface_finish (void *abstract_surface)
 {
     cairo_glitz_surface_t *surface = abstract_surface;
 
-    if (surface->clip)
-    {
-	glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0);
-	pixman_region_destroy (surface->clip);
+    if (surface->has_clip) {
+        glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0);
+        pixman_region_fini (&surface->clip);
     }
 
     glitz_surface_destroy (surface->surface);
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static glitz_format_name_t
@@ -203,35 +203,35 @@ static cairo_status_t
 
     buffer = glitz_buffer_create_for_data (pixels);
     if (!buffer) {
 	free (pixels);
 	return CAIRO_STATUS_NO_MEMORY;
     }
 
     /* clear out the glitz clip; the clip affects glitz_get_pixels */
-    if (surface->clip)
+    if (surface->has_clip)
 	glitz_surface_set_clip_region (surface->surface,
 				       0, 0, NULL, 0);
 
     glitz_get_pixels (surface->surface,
 		      x1, y1,
 		      width, height,
 		      &pf,
 		      buffer);
 
     glitz_buffer_destroy (buffer);
 
     /* restore the clip, if any */
-    if (surface->clip) {
+    if (surface->has_clip) {
 	glitz_box_t *box;
 	int	    n;
 
-	box = (glitz_box_t *) pixman_region_rects (surface->clip);
-	n = pixman_region_num_rects (surface->clip);
+	box = (glitz_box_t *) pixman_region_rects (&surface->clip);
+	n = pixman_region_num_rects (&surface->clip);
 	glitz_surface_set_clip_region (surface->surface, 0, 0, box, n);
     }
 
     image = (cairo_image_surface_t *)
 	_cairo_image_surface_create_with_masks (pixels,
 						&format,
 						width, height,
 						pf.bytes_per_line);
@@ -663,17 +663,17 @@ static cairo_int_status_t
 		(((int) (gradient->stops[i].color.blue  >> 8)));
 
 	    params[n_base_params + 3 * i + 0] = gradient->stops[i].x;
 	    params[n_base_params + 3 * i + 1] = i << 16;
 	    params[n_base_params + 3 * i + 2] = 0;
 	}
 
 	glitz_set_pixels (src->surface, 0, 0, gradient->n_stops, 1,
-			  &format, buffer);
+			  (glitz_pixel_format_t *)&format, buffer);
 
 	glitz_buffer_destroy (buffer);
 
 	if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR)
 	{
 	    cairo_linear_pattern_t *grad = (cairo_linear_pattern_t *) pattern;
 
 	    params[0] = grad->gradient.p1.x;
@@ -817,36 +817,43 @@ static cairo_int_status_t
     {
 	cairo_color_t combined;
 	cairo_solid_pattern_t *src_solid = (cairo_solid_pattern_t *) src;
 	cairo_solid_pattern_t *mask_solid = (cairo_solid_pattern_t *) mask;
 
 	combined = src_solid->color;
 	_cairo_color_multiply_alpha (&combined, mask_solid->color.alpha);
 
-	_cairo_pattern_init_solid (&tmp.solid, &combined);
+	_cairo_pattern_init_solid (&tmp.solid, &combined,
+				   CAIRO_COLOR_IS_OPAQUE (&combined) ?
+				   CAIRO_CONTENT_COLOR :
+				   CAIRO_CONTENT_COLOR_ALPHA);
 
 	mask = NULL;
     } else {
-	_cairo_pattern_init_copy (&tmp.base, src);
+	status = _cairo_pattern_init_copy (&tmp.base, src);
+	if (status)
+	    return status;
     }
 
     status = _cairo_glitz_pattern_acquire_surface (&tmp.base, dst,
 						   src_x, src_y,
 						   width, height,
 						   src_out, sattr);
 
     _cairo_pattern_fini (&tmp.base);
 
     if (status)
 	return status;
 
     if (mask)
     {
-	_cairo_pattern_init_copy (&tmp.base, mask);
+	status = _cairo_pattern_init_copy (&tmp.base, mask);
+	if (status)
+	    return status;
 
 	status = _cairo_glitz_pattern_acquire_surface (&tmp.base, dst,
 						       mask_x, mask_y,
 						       width, height,
 						       mask_out, mattr);
 
 	if (status)
 	    _cairo_glitz_pattern_release_surface (&tmp.base, *src_out, sattr);
@@ -997,17 +1004,18 @@ static cairo_int_status_t
     default:
 	if (_glitz_ensure_target (dst->surface))
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
 
 	src = (cairo_glitz_surface_t *)
 	    _cairo_surface_create_similar_solid (&dst->base,
 						 CAIRO_CONTENT_COLOR_ALPHA,
 						 1, 1,
-						 (cairo_color_t *) color);
+						 (cairo_color_t *) color,
+						 NULL);
 	if (src->base.status)
 	    return CAIRO_STATUS_NO_MEMORY;
 
 	glitz_surface_set_fill (src->surface, GLITZ_FILL_REPEAT);
 
 	while (n_rects--)
 	{
 	    glitz_composite (_glitz_operator (op),
@@ -1066,17 +1074,19 @@ static cairo_int_status_t
     if (op == CAIRO_OPERATOR_SATURATE)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     if (_glitz_ensure_target (dst->surface))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE)
     {
-	_cairo_pattern_init_copy (&tmp_src_pattern.base, pattern);
+	status = _cairo_pattern_init_copy (&tmp_src_pattern.base, pattern);
+	if (status)
+	    return status;
 
 	status = _cairo_glitz_pattern_acquire_surface (&tmp_src_pattern.base,
 						       dst,
 						       src_x, src_y,
 						       width, height,
 						       &src, &attributes);
 	src_pattern = &tmp_src_pattern.base;
     }
@@ -1278,36 +1288,42 @@ static cairo_int_status_t
 {
     cairo_glitz_surface_t *surface = abstract_surface;
 
     if (region)
     {
 	glitz_box_t *box;
 	int	    n;
 
-	if (!surface->clip)
-	{
-	    surface->clip = pixman_region_create ();
-	    if (!surface->clip)
-		return CAIRO_STATUS_NO_MEMORY;
-	}
-	pixman_region_copy (surface->clip, region);
+	if (!surface->has_clip) {
+            pixman_region_init (&surface->clip);
+            surface->has_clip = TRUE;
+        }
 
-	box = (glitz_box_t *) pixman_region_rects (surface->clip);
-	n = pixman_region_num_rects (surface->clip);
+	if (pixman_region_copy (&surface->clip, region) !=
+            PIXMAN_REGION_STATUS_SUCCESS)
+        {
+	    pixman_region_fini (&surface->clip);
+	    surface->has_clip = FALSE;
+            return CAIRO_STATUS_NO_MEMORY;
+        }
+
+	box = (glitz_box_t *) pixman_region_rects (&surface->clip);
+	n = pixman_region_num_rects (&surface->clip);
+
 	glitz_surface_set_clip_region (surface->surface, 0, 0, box, n);
     }
     else
     {
 	glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0);
 
-	if (surface->clip)
-	    pixman_region_destroy (surface->clip);
-
-	surface->clip = NULL;
+	if (surface->has_clip) {
+	    pixman_region_fini (&surface->clip);
+	    surface->has_clip = FALSE;
+        }
     }
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_int_status_t
 _cairo_glitz_surface_get_extents (void		          *abstract_surface,
 				  cairo_rectangle_int16_t *rectangle)
@@ -2167,16 +2183,43 @@ static cairo_status_t
 {
     cairo_glitz_surface_t *surface = abstract_surface;
 
     glitz_surface_flush (surface->surface);
 
     return CAIRO_STATUS_SUCCESS;
 }
 
+static cairo_bool_t
+_cairo_glitz_surface_is_similar (void *surface_a,
+	                         void *surface_b,
+				 cairo_content_t content)
+{
+    cairo_glitz_surface_t *a = (cairo_glitz_surface_t *) surface_a;
+    cairo_glitz_surface_t *b = (cairo_glitz_surface_t *) surface_b;
+
+    glitz_drawable_t *drawable_a = glitz_surface_get_drawable (a->surface);
+    glitz_drawable_t *drawable_b = glitz_surface_get_drawable (b->surface);
+
+    return drawable_a == drawable_b;
+}
+
+static cairo_status_t
+_cairo_glitz_surface_reset (void *abstract_surface)
+{
+    cairo_glitz_surface_t *surface = abstract_surface;
+    cairo_status_t status;
+
+    status = _cairo_glitz_surface_set_clip_region (surface, NULL);
+    if (status)
+	return status;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
 static const cairo_surface_backend_t cairo_glitz_surface_backend = {
     CAIRO_SURFACE_TYPE_GLITZ,
     _cairo_glitz_surface_create_similar,
     _cairo_glitz_surface_finish,
     _cairo_glitz_surface_acquire_source_image,
     _cairo_glitz_surface_release_source_image,
     _cairo_glitz_surface_acquire_dest_image,
     _cairo_glitz_surface_release_dest_image,
@@ -2189,17 +2232,28 @@ static const cairo_surface_backend_t cai
     _cairo_glitz_surface_set_clip_region,
     NULL, /* intersect_clip_path */
     _cairo_glitz_surface_get_extents,
     _cairo_glitz_surface_old_show_glyphs,
     NULL, /* get_font_options */
     _cairo_glitz_surface_flush,
     NULL, /* mark_dirty_rectangle */
     _cairo_glitz_surface_scaled_font_fini,
-    _cairo_glitz_surface_scaled_glyph_fini
+    _cairo_glitz_surface_scaled_glyph_fini,
+
+    NULL, /* paint */
+    NULL, /* mask */
+    NULL, /* stroke */
+    NULL, /* fill */
+    NULL, /* show_glyphs */
+
+    NULL, /* snapshot */
+    _cairo_glitz_surface_is_similar,
+
+    _cairo_glitz_surface_reset
 };
 
 static const cairo_surface_backend_t *
 _cairo_glitz_surface_get_backend (void)
 {
     return &cairo_glitz_surface_backend;
 }
 
@@ -2235,15 +2289,15 @@ cairo_glitz_surface_create (glitz_surfac
     }
 
     format = glitz_surface_get_format (surface);
     _cairo_surface_init (&crsurface->base, &cairo_glitz_surface_backend,
 			 _glitz_format_to_content(format));
 
     glitz_surface_reference (surface);
 
-    crsurface->surface = surface;
-    crsurface->format  = format;
-    crsurface->clip    = NULL;
+    crsurface->surface  = surface;
+    crsurface->format   = format;
+    crsurface->has_clip = FALSE;
 
     return (cairo_surface_t *) crsurface;
 }
 slim_hidden_def (cairo_glitz_surface_create);
--- a/gfx/cairo/cairo/src/cairo-gstate.c
+++ b/gfx/cairo/cairo/src/cairo-gstate.c
@@ -30,18 +30,16 @@
  *
  * The Initial Developer of the Original Code is University of Southern
  * California.
  *
  * Contributor(s):
  *	Carl D. Worth <cworth@cworth.org>
  */
 
-#include <stdlib.h>
-
 #include "cairoint.h"
 
 #include "cairo-clip-private.h"
 #include "cairo-gstate-private.h"
 
 static cairo_status_t
 _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other);
 
@@ -59,16 +57,18 @@ static void
                                            const cairo_glyph_t *glyphs,
                                            int                  num_glyphs,
                                            cairo_glyph_t       *transformed_glyphs);
 
 cairo_status_t
 _cairo_gstate_init (cairo_gstate_t  *gstate,
 		    cairo_surface_t *target)
 {
+    gstate->next = NULL;
+
     gstate->op = CAIRO_GSTATE_OPERATOR_DEFAULT;
 
     gstate->tolerance = CAIRO_GSTATE_TOLERANCE_DEFAULT;
     gstate->antialias = CAIRO_ANTIALIAS_DEFAULT;
 
     _cairo_stroke_style_init (&gstate->stroke_style);
 
     gstate->fill_rule = CAIRO_GSTATE_FILL_RULE_DEFAULT;
@@ -86,23 +86,22 @@ cairo_status_t
 
     gstate->target = cairo_surface_reference (target);
     gstate->parent_target = NULL;
     gstate->original_target = cairo_surface_reference (target);
 
     _cairo_gstate_identity_matrix (gstate);
     gstate->source_ctm_inverse = gstate->ctm_inverse;
 
-    gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK);
+    gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK,
+						  CAIRO_CONTENT_COLOR);
     if (gstate->source->status)
 	return CAIRO_STATUS_NO_MEMORY;
 
-    gstate->next = NULL;
-
-    return CAIRO_STATUS_SUCCESS;
+    return target ? target->status : CAIRO_STATUS_NULL_POINTER;
 }
 
 /**
  * _cairo_gstate_init_copy:
  *
  * Initialize @gstate by performing a deep copy of state fields from
  * @other. Note that gstate->next is not copied but is set to NULL by
  * this function.
@@ -126,17 +125,19 @@ static cairo_status_t
 
     gstate->font_face = cairo_font_face_reference (other->font_face);
     gstate->scaled_font = cairo_scaled_font_reference (other->scaled_font);
 
     gstate->font_matrix = other->font_matrix;
 
     _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 */
     gstate->parent_target = NULL;
     gstate->original_target = cairo_surface_reference (other->original_target);
 
     gstate->ctm = other->ctm;
     gstate->ctm_inverse = other->ctm_inverse;
@@ -155,32 +156,32 @@ void
     _cairo_stroke_style_fini (&gstate->stroke_style);
 
     cairo_font_face_destroy (gstate->font_face);
     gstate->font_face = NULL;
 
     cairo_scaled_font_destroy (gstate->scaled_font);
     gstate->scaled_font = NULL;
 
-    _cairo_clip_fini (&gstate->clip);
+    _cairo_clip_reset (&gstate->clip);
 
     cairo_surface_destroy (gstate->target);
     gstate->target = NULL;
 
     cairo_surface_destroy (gstate->parent_target);
     gstate->parent_target = NULL;
 
     cairo_surface_destroy (gstate->original_target);
     gstate->target = NULL;
 
     cairo_pattern_destroy (gstate->source);
     gstate->source = NULL;
 }
 
-void
+static void
 _cairo_gstate_destroy (cairo_gstate_t *gstate)
 {
     if (gstate == NULL)
 	return;
 
     _cairo_gstate_fini (gstate);
     free (gstate);
 }
@@ -192,17 +193,17 @@ void
  * Create a new #cairo_gstate_t setting all graphics state parameters
  * to the same values as contained in @other. gstate->next will be set
  * to NULL and may be used by the caller to chain cairo_gstate_t
  * objects together.
  *
  * Return value: a new cairo_gstate_t or NULL if there is insufficient
  * memory.
  **/
-cairo_gstate_t*
+static cairo_gstate_t*
 _cairo_gstate_clone (cairo_gstate_t *other)
 {
     cairo_status_t status;
     cairo_gstate_t *gstate;
 
     assert (other != NULL);
 
     gstate = malloc (sizeof (cairo_gstate_t));
@@ -213,16 +214,65 @@ cairo_gstate_t*
     if (status) {
 	free (gstate);
 	return NULL;
     }
 
     return gstate;
 }
 
+/**
+ * _cairo_gstate_save:
+ * @gstate: input/output gstate pointer
+ *
+ * Makes a copy of the current state of @gstate and saves it
+ * to @gstate->next, then put the address of the newly allcated
+ * copy into @gstate.  _cairo_gstate_restore() reverses this.
+ **/
+cairo_status_t
+_cairo_gstate_save (cairo_gstate_t **gstate)
+{
+    cairo_gstate_t *top;
+
+    top = _cairo_gstate_clone (*gstate);
+
+    if (top == NULL) {
+	return CAIRO_STATUS_NO_MEMORY;
+    }
+
+    top->next = *gstate;
+    *gstate = top;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+/**
+ * _cairo_gstate_restore:
+ * @gstate: input/output gstate pointer
+ *
+ * Reverses the effects of one _cairo_gstate_save() call.
+ **/
+cairo_status_t
+_cairo_gstate_restore (cairo_gstate_t **gstate)
+{
+    cairo_gstate_t *top;
+
+    top = *gstate;
+
+    if (top->next == NULL) {
+	return CAIRO_STATUS_INVALID_RESTORE;
+    }
+
+    *gstate = top->next;
+
+    _cairo_gstate_destroy (top);
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
 static cairo_status_t
 _cairo_gstate_recursive_apply_clip_path (cairo_gstate_t *gstate,
 					 cairo_clip_path_t *cpath)
 {
     cairo_status_t status;
 
     if (cpath == NULL)
 	return CAIRO_STATUS_SUCCESS;
@@ -247,41 +297,47 @@ static cairo_status_t
  * Redirect @gstate rendering to a "child" target. The original
  * "parent" target with which the gstate was created will not be
  * affected. See _cairo_gstate_get_target().
  *
  * Unless the redirected target has the same device offsets as the
  * 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);
 
     /* Set up our new parent_target based on our current target;
      * gstate->parent_target will take the ref that is held by gstate->target
      */
     cairo_surface_destroy (gstate->parent_target);
     gstate->parent_target = gstate->target;
 
     /* Now set up our new target; we overwrite gstate->target directly,
      * since its ref is now owned by gstate->parent_target */
     gstate->target = cairo_surface_reference (child);
 
-    _cairo_clip_fini (&gstate->clip);
-    _cairo_clip_init_deep_copy (&gstate->clip, &gstate->next->clip, child);
+    _cairo_clip_reset (&gstate->clip);
+    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;
 }
 
 /**
  * _cairo_gstate_is_redirected
  * @gstate: a #cairo_gstate_t
  *
  * Return value: TRUE if the gstate is redirected to a target
  * different than the original, FALSE otherwise.
@@ -351,17 +407,17 @@ cairo_clip_t *
 
 cairo_status_t
 _cairo_gstate_set_source (cairo_gstate_t  *gstate,
 			  cairo_pattern_t *source)
 {
     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;
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 cairo_pattern_t *
@@ -502,16 +558,34 @@ cairo_status_t
     if (offset < 0)
 	offset += ceil (-offset / dash_total + 0.5) * dash_total;
 
     gstate->stroke_style.dash_offset = offset;
 
     return CAIRO_STATUS_SUCCESS;
 }
 
+void
+_cairo_gstate_get_dash (cairo_gstate_t *gstate,
+			double         *dashes,
+			int            *num_dashes,
+			double         *offset)
+{
+    if (dashes)
+	memcpy (dashes,
+		gstate->stroke_style.dash,
+		sizeof (double) * gstate->stroke_style.num_dashes);
+
+    if (num_dashes)
+	*num_dashes = gstate->stroke_style.num_dashes;
+
+    if (offset)
+	*offset = gstate->stroke_style.dash_offset;
+}
+
 cairo_status_t
 _cairo_gstate_set_miter_limit (cairo_gstate_t *gstate, double limit)
 {
     gstate->stroke_style.miter_limit = limit;
 
     return CAIRO_STATUS_SUCCESS;
 }
 
@@ -578,23 +652,26 @@ cairo_status_t
     return CAIRO_STATUS_SUCCESS;
 }
 
 cairo_status_t
 _cairo_gstate_transform (cairo_gstate_t	      *gstate,
 			 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;
 }
 
 cairo_status_t
 _cairo_gstate_set_matrix (cairo_gstate_t       *gstate,
 			  const cairo_matrix_t *matrix)
@@ -608,59 +685,49 @@ cairo_status_t
     gstate->ctm_inverse = *matrix;
     status = cairo_matrix_invert (&gstate->ctm_inverse);
     if (status)
 	return status;
 
     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
+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
 _cairo_gstate_user_to_backend (cairo_gstate_t *gstate, double *x, double *y)
 {
     cairo_matrix_transform_point (&gstate->ctm, x, y);
     cairo_matrix_transform_point (&gstate->target->device_transform, x, y);
 }
@@ -692,70 +759,77 @@ cairo_status_t
 {
     cairo_status_t status;
 
     _cairo_pen_init (&gstate);
     return CAIRO_STATUS_SUCCESS;
 }
 */
 
-static void
+static cairo_status_t
 _cairo_gstate_copy_transformed_pattern (cairo_gstate_t  *gstate,
 					cairo_pattern_t *pattern,
 					cairo_pattern_t *original,
 					cairo_matrix_t  *ctm_inverse)
 {
     cairo_surface_pattern_t *surface_pattern;
     cairo_surface_t *surface;
+    cairo_status_t status;
 
-    _cairo_pattern_init_copy (pattern, original);
+    status = _cairo_pattern_init_copy (pattern, original);
+    if (status)
+	return status;
+
     _cairo_pattern_transform (pattern, ctm_inverse);
 
     if (cairo_pattern_get_type (original) == CAIRO_PATTERN_TYPE_SURFACE) {
         surface_pattern = (cairo_surface_pattern_t *) original;
         surface = surface_pattern->surface;
         if (_cairo_surface_has_device_transform (surface))
             _cairo_pattern_transform (pattern, &surface->device_transform);
     }
 
+    return CAIRO_STATUS_SUCCESS;
 }
 
-static void
+static cairo_status_t
 _cairo_gstate_copy_transformed_source (cairo_gstate_t  *gstate,
 				       cairo_pattern_t *pattern)
 {
-    _cairo_gstate_copy_transformed_pattern (gstate, pattern,
-					    gstate->source,
-					    &gstate->source_ctm_inverse);
+    return _cairo_gstate_copy_transformed_pattern (gstate, pattern,
+					           gstate->source,
+					           &gstate->source_ctm_inverse);
 }
 
-static void
+static cairo_status_t
 _cairo_gstate_copy_transformed_mask (cairo_gstate_t  *gstate,
 				     cairo_pattern_t *pattern,
 				     cairo_pattern_t *mask)
 {
-    _cairo_gstate_copy_transformed_pattern (gstate, pattern,
-					    mask,
-					    &gstate->ctm_inverse);
+    return _cairo_gstate_copy_transformed_pattern (gstate, pattern,
+					           mask,
+					           &gstate->ctm_inverse);
 }
 
 cairo_status_t
 _cairo_gstate_paint (cairo_gstate_t *gstate)
 {
     cairo_status_t status;
     cairo_pattern_union_t pattern;
 
     if (gstate->source->status)
 	return gstate->source->status;
 
     status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
     if (status)
 	return status;
 
-    _cairo_gstate_copy_transformed_source (gstate, &pattern.base);
+    status = _cairo_gstate_copy_transformed_source (gstate, &pattern.base);
+    if (status)
+	return status;
 
     status = _cairo_surface_paint (gstate->target,
 				   gstate->op,
 				   &pattern.base);
 
     _cairo_pattern_fini (&pattern.base);
 
     return status;
@@ -852,26 +926,32 @@ cairo_status_t
 
     if (gstate->source->status)
 	return gstate->source->status;
 
     status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
     if (status)
 	return status;
 
-    _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
-    _cairo_gstate_copy_transformed_mask (gstate, &mask_pattern.base, mask);
+    status = _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
+    if (status)
+	return status;
+
+    status = _cairo_gstate_copy_transformed_mask (gstate, &mask_pattern.base, mask);
+    if (status)
+	goto CLEANUP_SOURCE;
 
     status = _cairo_surface_mask (gstate->target,
 				  gstate->op,
 				  &source_pattern.base,
 				  &mask_pattern.base);
 
+    _cairo_pattern_fini (&mask_pattern.base);
+CLEANUP_SOURCE:
     _cairo_pattern_fini (&source_pattern.base);
-    _cairo_pattern_fini (&mask_pattern.base);
 
     return status;
 }
 
 cairo_status_t
 _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
 {
     cairo_status_t status;
@@ -882,17 +962,20 @@ cairo_status_t
 
     if (gstate->stroke_style.line_width <= 0.0)
 	return CAIRO_STATUS_SUCCESS;
 
     status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
     if (status)
 	return status;
 
-    _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
+    status = _cairo_gstate_copy_transformed_source (gstate,
+	                                            &source_pattern.base);
+    if (status)
+	return status;
 
     status = _cairo_surface_stroke (gstate->target,
 				    gstate->op,
 				    &source_pattern.base,
 				    path,
 				    &gstate->stroke_style,
 				    &gstate->ctm,
 				    &gstate->ctm_inverse,
@@ -949,17 +1032,19 @@ cairo_status_t
 
     if (gstate->source->status)
 	return gstate->source->status;
 
     status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
     if (status)
 	return status;
 
-    _cairo_gstate_copy_transformed_source (gstate, &pattern.base);
+    status = _cairo_gstate_copy_transformed_source (gstate, &pattern.base);
+    if (status)
+	return status;
 
     status = _cairo_surface_fill (gstate->target,
 				  gstate->op,
 				  &pattern.base,
 				  path,
 				  gstate->fill_rule,
 				  gstate->tolerance,
 				  gstate->antialias);
@@ -996,39 +1081,23 @@ BAIL:
     _cairo_traps_fini (&traps);
 
     return status;
 }
 
 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
 _cairo_gstate_traps_extents_to_user_rectangle (cairo_gstate_t	  *gstate,
                                                cairo_traps_t      *traps,
                                                double *x1, double *y1,
                                                double *x2, double *y2)
 {
@@ -1120,17 +1189,19 @@ cairo_status_t
     _cairo_traps_fini (&traps);
 
     return status;
 }
 
 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
 _cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
 {
     return _cairo_clip_clip (&gstate->clip,
 			     path, gstate->fill_rule, gstate->tolerance,
 			     gstate->antialias, gstate->target);
@@ -1185,22 +1256,25 @@ static void
 
 cairo_status_t
 _cairo_gstate_select_font_face (cairo_gstate_t       *gstate,
 				const char           *family,
 				cairo_font_slant_t    slant,
 				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;
 }
 
 cairo_status_t
 _cairo_gstate_set_font_size (cairo_gstate_t *gstate,
 			     double          size)
@@ -1225,25 +1299,23 @@ cairo_status_t
 
 void
 _cairo_gstate_get_font_matrix (cairo_gstate_t *gstate,
 			       cairo_matrix_t *matrix)
 {
     *matrix = gstate->font_matrix;
 }
 
-cairo_status_t
+void
 _cairo_gstate_set_font_options (cairo_gstate_t             *gstate,
 				const cairo_font_options_t *options)
 {
     _cairo_gstate_unset_scaled_font (gstate);
 
     gstate->font_options = *options;
-
-    return CAIRO_STATUS_SUCCESS;
 }
 
 void
 _cairo_gstate_get_font_options (cairo_gstate_t       *gstate,
 				cairo_font_options_t *options)
 {
     *options = gstate->font_options;
 }
@@ -1352,92 +1424,93 @@ cairo_status_t
  * CTM (for user-input glyph vectors), and return values by the CTM inverse
  * (for font responses such as metrics or glyph vectors).
  *
  */
 
 static cairo_status_t
 _cairo_gstate_ensure_font_face (cairo_gstate_t *gstate)
 {
-    if (!gstate->font_face) {
-	cairo_font_face_t *font_face;
+    cairo_font_face_t *font_face;
+
+    if (gstate->font_face != NULL)
+	return gstate->font_face->status;
+
 
-	font_face = _cairo_toy_font_face_create (CAIRO_FONT_FAMILY_DEFAULT,
-						 CAIRO_FONT_SLANT_DEFAULT,
-						 CAIRO_FONT_WEIGHT_DEFAULT);
-	if (font_face->status)
-	    return font_face->status;
-	else
-	    gstate->font_face = font_face;
-    }
+    font_face = _cairo_toy_font_face_create (CAIRO_FONT_FAMILY_DEFAULT,
+					     CAIRO_FONT_SLANT_DEFAULT,
+					     CAIRO_FONT_WEIGHT_DEFAULT);
+    if (font_face->status)
+	return font_face->status;
+
+    gstate->font_face = font_face;
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
 _cairo_gstate_ensure_scaled_font (cairo_gstate_t *gstate)
 {
     cairo_status_t status;
     cairo_font_options_t options;
+    cairo_scaled_font_t *scaled_font;
 
-    if (gstate->scaled_font)
-	return CAIRO_STATUS_SUCCESS;
+    if (gstate->scaled_font != NULL)
+	return gstate->scaled_font->status;
 
     status = _cairo_gstate_ensure_font_face (gstate);
     if (status)
 	return status;
 
     cairo_surface_get_font_options (gstate->target, &options);
     cairo_font_options_merge (&options, &gstate->font_options);
 
-    gstate->scaled_font = cairo_scaled_font_create (gstate->font_face,
-						    &gstate->font_matrix,
-						    &gstate->ctm,
-						    &options);
+    scaled_font = cairo_scaled_font_create (gstate->font_face,
+				            &gstate->font_matrix,
+					    &gstate->ctm,
+					    &options);
 
-    if (!gstate->scaled_font)
-	return CAIRO_STATUS_NO_MEMORY;
+    status = cairo_scaled_font_status (scaled_font);
+    if (status)
+	return status;
+
+    gstate->scaled_font = scaled_font;
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 cairo_status_t
 _cairo_gstate_get_font_extents (cairo_gstate_t *gstate,
 				cairo_font_extents_t *extents)
 {
     cairo_status_t status = _cairo_gstate_ensure_scaled_font (gstate);
     if (status)
 	return status;
 
     cairo_scaled_font_extents (gstate->scaled_font, extents);
 
-    return CAIRO_STATUS_SUCCESS;
+    return cairo_scaled_font_status (gstate->scaled_font);
 }
 
 cairo_status_t
 _cairo_gstate_text_to_glyphs (cairo_gstate_t *gstate,
 			      const char     *utf8,
 			      double	      x,
 			      double	      y,
 			      cairo_glyph_t **glyphs,
 			      int	     *num_glyphs)
 {
     cairo_status_t status;
 
     status = _cairo_gstate_ensure_scaled_font (gstate);
     if (status)
 	return status;
 
-    status = _cairo_scaled_font_text_to_glyphs (gstate->scaled_font, x, y,
-						utf8, glyphs, num_glyphs);
-
-    if (status || !glyphs || !num_glyphs || !(*glyphs) || !(num_glyphs))
-	return status;
-
-    return CAIRO_STATUS_SUCCESS;
+    return _cairo_scaled_font_text_to_glyphs (gstate->scaled_font, x, y,
+					      utf8, glyphs, num_glyphs);
 }
 
 cairo_status_t
 _cairo_gstate_set_font_face (cairo_gstate_t    *gstate,
 			     cairo_font_face_t *font_face)
 {
     if (font_face && font_face->status)
 	return font_face->status;
@@ -1463,17 +1536,17 @@ cairo_status_t
     status = _cairo_gstate_ensure_scaled_font (gstate);
     if (status)
 	return status;
 
     cairo_scaled_font_glyph_extents (gstate->scaled_font,
 				     glyphs, num_glyphs,
 				     extents);
 
-    return CAIRO_STATUS_SUCCESS;
+    return cairo_scaled_font_status (gstate->scaled_font);
 }
 
 #define STACK_GLYPHS_LEN ((int) (CAIRO_STACK_BUFFER_SIZE / sizeof (cairo_glyph_t)))
 cairo_status_t
 _cairo_gstate_show_glyphs (cairo_gstate_t *gstate,
 			   const cairo_glyph_t *glyphs,
 			   int num_glyphs)
 {
@@ -1500,27 +1573,30 @@ cairo_status_t
 	transformed_glyphs = malloc (num_glyphs * sizeof(cairo_glyph_t));
 	if (transformed_glyphs == NULL)
 	    return CAIRO_STATUS_NO_MEMORY;
     }
 
     _cairo_gstate_transform_glyphs_to_backend (gstate, glyphs, num_glyphs,
                                                transformed_glyphs);
 
-    _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
+    status = _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
+    if (status)
+	goto CLEANUP_GLYPHS;
 
     status = _cairo_surface_show_glyphs (gstate->target,
 					 gstate->op,
 					 &source_pattern.base,
 					 transformed_glyphs,
 					 num_glyphs,
 					 gstate->scaled_font);
 
     _cairo_pattern_fini (&source_pattern.base);
 
+CLEANUP_GLYPHS:
     if (transformed_glyphs != stack_transformed_glyphs)
       free (transformed_glyphs);
 
     return status;
 }
 
 cairo_status_t
 _cairo_gstate_glyph_path (cairo_gstate_t      *gstate,
--- a/gfx/cairo/cairo/src/cairo-hash-private.h
+++ b/gfx/cairo/cairo/src/cairo-hash-private.h
@@ -34,61 +34,23 @@
  *      Keith Packard <keithp@keithp.com>
  *	Graydon Hoare <graydon@redhat.com>
  *	Carl Worth <cworth@cworth.org>
  */
 
 #ifndef CAIRO_HASH_PRIVATE_H
 #define CAIRO_HASH_PRIVATE_H
 
+#include "cairo-types-private.h"
+
 /* XXX: I'd like this file to be self-contained in terms of
  * includeability, but that's not really possible with the current
  * monolithic cairoint.h. So, for now, just include cairoint.h instead
  * if you want to include this file. */
 
-typedef struct _cairo_hash_table cairo_hash_table_t;
-
-/**
- * cairo_hash_entry_t:
- *
- * A #cairo_hash_entry_t contains both a key and a value for
- * cairo_hash_table_t. User-derived types for cairo_hash_entry_t must
- * be type-compatible with this structure (eg. they must have an
- * unsigned long as the first parameter. The easiest way to get this
- * is to use:
- *
- * 	typedef _my_entry {
- *	    cairo_hash_entry_t base;
- *	    ... Remainder of key and value fields here ..
- *	} my_entry_t;
- *
- * which then allows a pointer to my_entry_t to be passed to any of
- * the cairo_hash_table functions as follows without requiring a cast:
- *
- *	_cairo_hash_table_insert (hash_table, &my_entry->base);
- *
- * IMPORTANT: The caller is reponsible for initializing
- * my_entry->base.hash with a hash code derived from the key. The
- * essential property of the hash code is that keys_equal must never
- * return TRUE for two keys that have different hashes. The best hash
- * code will reduce the frequency of two keys with the same code for
- * which keys_equal returns FALSE.
- *
- * Which parts of the entry make up the "key" and which part make up
- * the value are entirely up to the caller, (as determined by the
- * computation going into base.hash as well as the keys_equal
- * function). A few of the cairo_hash_table functions accept an entry
- * which will be used exclusively as a "key", (indicated by a
- * parameter name of key). In these cases, the value-related fields of
- * the entry need not be initialized if so desired.
- **/
-typedef struct _cairo_hash_entry {
-    unsigned long hash;
-} cairo_hash_entry_t;
-
 typedef cairo_bool_t
 (*cairo_hash_keys_equal_func_t) (const void *key_a, const void *key_b);
 
 typedef cairo_bool_t
 (*cairo_hash_predicate_func_t) (void *entry);
 
 typedef void
 (*cairo_hash_callback_func_t) (void *entry,
--- a/gfx/cairo/cairo/src/cairo-hash.c
+++ b/gfx/cairo/cairo/src/cairo-hash.c
@@ -110,17 +110,17 @@ static const cairo_hash_table_arrangemen
     { 8388608,		18455029,	18455027	},
     { 16777216,		36911011,	36911009	},
     { 33554432,		73819861,	73819859 	},
     { 67108864,		147639589,	147639587	},
     { 134217728,	295279081,	295279079	},
     { 268435456,	590559793,	590559791	}
 };
 
-#define NUM_HASH_TABLE_ARRANGEMENTS ((int)(sizeof(hash_table_arrangements)/sizeof(hash_table_arrangements[0])))
+#define NUM_HASH_TABLE_ARRANGEMENTS ARRAY_LENGTH (hash_table_arrangements)
 
 struct _cairo_hash_table {
     cairo_hash_keys_equal_func_t keys_equal;
 
     const cairo_hash_table_arrangement_t *arrangement;
     cairo_hash_entry_t **entries;
 
     unsigned long live_entries;
@@ -476,18 +476,22 @@ cairo_status_t
 	/* User is being bad, let's crash. */
 	ASSERT_NOT_REACHED;
     }
 
     *entry = key_and_value;
     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;
 }
 
 /**
  * _cairo_hash_table_remove:
  * @hash_table: a hash table
  * @key: key of entry to be removed
@@ -556,11 +560,14 @@ void
 	entry = hash_table->entries[i];
 	if (ENTRY_IS_LIVE(entry))
 	    hash_callback (entry, closure);
     }
     /* If some elements were deleted during the iteration,
      * 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);
+    }
 }
--- a/gfx/cairo/cairo/src/cairo-image-surface.c
+++ b/gfx/cairo/cairo/src/cairo-image-surface.c
@@ -31,17 +31,17 @@
  * California.
  *
  * Contributor(s):
  *	Carl D. Worth <cworth@cworth.org>
  */
 
 #include "cairoint.h"
 
-const cairo_image_surface_t _cairo_image_surface_nil_invalid_format = {
+static const cairo_image_surface_t _cairo_image_surface_nil_invalid_format = {
     {
 	&cairo_image_surface_backend,	/* backend */
 	CAIRO_SURFACE_TYPE_IMAGE,
 	CAIRO_CONTENT_COLOR,
 	CAIRO_REF_COUNT_INVALID,	/* ref_count */
 	CAIRO_STATUS_INVALID_FORMAT,	/* status */
 	FALSE,				/* finished */
 	{ 0,	/* size */
@@ -126,17 +126,17 @@ cairo_surface_t *
     surface->stride = pixman_image_get_stride (pixman_image);
     surface->depth = pixman_image_get_depth (pixman_image);
 
     return &surface->base;
 }
 
 /* Try to recover a cairo_format_t from a pixman_format
  * by looking at the bpp and masks values. */
-static cairo_format_t
+static cairo_internal_format_t
 _cairo_format_from_pixman_format (pixman_format_t *pixman_format)
 {
     unsigned int bpp, am, rm, gm, bm;
 
     pixman_format_get_masks (pixman_format, &bpp, &am, &rm, &gm, &bm);
 
     /* See definition of cairo_internal_format_t for an explanation of
      * the CAIRO_INTERNAL_FORMAT values used here. */
@@ -162,17 +162,17 @@ static cairo_format_t
 		return CAIRO_INTERNAL_FORMAT_BGR24;
 	}
 	break;
     case 16:
 	if (am == 0x0 &&
 	    rm == 0xf800 &&
 	    gm == 0x07e0 &&
 	    bm == 0x001f)
-	    return CAIRO_FORMAT_RGB16_565;
+	    return CAIRO_INTERNAL_FORMAT_RGB16_565;
 	break;
     case 8:
 	if (am == 0xff &&
 	    rm == 0x0 &&
 	    gm == 0x0 &&
 	    bm == 0x0)
 	    return CAIRO_FORMAT_A8;
 	break;
@@ -207,67 +207,67 @@ static cairo_format_t
 cairo_surface_t *
 _cairo_image_surface_create_with_masks (unsigned char	       *data,
 					cairo_format_masks_t   *format,
 					int			width,
 					int			height,
 					int			stride)
 {
     cairo_surface_t *surface;
-    pixman_format_t *pixman_format;
-    pixman_image_t *pixman_image;
-    cairo_format_t cairo_format;
-
-    pixman_format = pixman_format_create_masks (format->bpp,
-						format->alpha_mask,
-						format->red_mask,
-						format->green_mask,
-						format->blue_mask);
+    pixman_format_t  pixman_format;
+    pixman_image_t  *pixman_image;
+    cairo_format_t   cairo_format;
 
-    if (pixman_format == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return (cairo_surface_t*) &_cairo_surface_nil;
-    }
+    pixman_format_init_masks (&pixman_format,
+	                      format->bpp,
+			      format->alpha_mask,
+			      format->red_mask,
+			      format->green_mask,
+			      format->blue_mask);
 
-    cairo_format = _cairo_format_from_pixman_format (pixman_format);
+    cairo_format = _cairo_format_from_pixman_format (&pixman_format);
 
-    pixman_image = pixman_image_create_for_data ((pixman_bits_t *) data, pixman_format,
+    pixman_image = pixman_image_create_for_data ((pixman_bits_t *) data,
+	                                         &pixman_format,
 						 width, height, format->bpp, stride);
 
-    pixman_format_destroy (pixman_format);
-
     if (pixman_image == NULL) {
 	_cairo_error (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
     surface = _cairo_image_surface_create_for_pixman_image (pixman_image,
 							    cairo_format);
+    if (cairo_surface_status (surface)) {
+	pixman_image_destroy (pixman_image);
+    }
 
     return surface;
 }
 
-static pixman_format_t *
-_create_pixman_format (cairo_format_t format)
+static void
+_init_pixman_format (pixman_format_t *pixman_format, cairo_format_t format)
 {
+    int ret;
     switch (format) {
     case CAIRO_FORMAT_A1:
-	return pixman_format_create (PIXMAN_FORMAT_NAME_A1);
+	ret = pixman_format_init (pixman_format, PIXMAN_FORMAT_NAME_A1);
 	break;
     case CAIRO_FORMAT_A8:
-	return pixman_format_create (PIXMAN_FORMAT_NAME_A8);
+	ret = pixman_format_init (pixman_format, PIXMAN_FORMAT_NAME_A8);
 	break;
     case CAIRO_FORMAT_RGB24:
-	return pixman_format_create (PIXMAN_FORMAT_NAME_RGB24);
+	ret = pixman_format_init (pixman_format, PIXMAN_FORMAT_NAME_RGB24);
 	break;
     case CAIRO_FORMAT_ARGB32:
     default:
-	return pixman_format_create (PIXMAN_FORMAT_NAME_ARGB32);
+	ret = pixman_format_init (pixman_format, PIXMAN_FORMAT_NAME_ARGB32);
 	break;
     }
+    assert (ret);
 }
 
 /**
  * cairo_image_surface_create:
  * @format: format of pixels in the surface to create
  * @width: width of the surface, in pixels
  * @height: height of the surface, in pixels
  *
@@ -285,41 +285,37 @@ static pixman_format_t *
  * pointer to a "nil" surface if an error such as out of memory
  * occurs. You can use cairo_surface_status() to check for this.
  **/
 cairo_surface_t *
 cairo_image_surface_create (cairo_format_t	format,
 			    int			width,
 			    int			height)
 {
-    cairo_surface_t *surface;
-    pixman_format_t *pixman_format;
-    pixman_image_t *pixman_image;
+    cairo_surface_t	*surface;
+    pixman_format_t	 pixman_format;
+    pixman_image_t	*pixman_image;
 
     if (! CAIRO_FORMAT_VALID (format)) {
 	_cairo_error (CAIRO_STATUS_INVALID_FORMAT);
 	return (cairo_surface_t*) &_cairo_image_surface_nil_invalid_format;
     }
 
-    pixman_format = _create_pixman_format (format);
-    if (pixman_format == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return (cairo_surface_t*) &_cairo_surface_nil;
-    }
+    _init_pixman_format (&pixman_format, format);
 
-    pixman_image = pixman_image_create (pixman_format, width, height);
-
-    pixman_format_destroy (pixman_format);
-
+    pixman_image = pixman_image_create (&pixman_format, width, height);
     if (pixman_image == NULL) {
 	_cairo_error (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
     surface = _cairo_image_surface_create_for_pixman_image (pixman_image, format);
+    if (cairo_surface_status (surface)) {
+	pixman_image_destroy (pixman_image);
+    }
 
     return surface;
 }
 slim_hidden_def (cairo_image_surface_create);
 
 cairo_surface_t *
 _cairo_image_surface_create_with_content (cairo_content_t	content,
 					  int			width,
@@ -364,42 +360,39 @@ cairo_surface_t *
  **/
 cairo_surface_t *
 cairo_image_surface_create_for_data (unsigned char     *data,
 				     cairo_format_t	format,
 				     int		width,
 				     int		height,
 				     int		stride)
 {
-    cairo_surface_t *surface;
-    pixman_format_t *pixman_format;
-    pixman_image_t *pixman_image;
+    cairo_surface_t	*surface;
+    pixman_format_t	 pixman_format;
+    pixman_image_t	*pixman_image;
 
     if (! CAIRO_FORMAT_VALID (format))
 	return (cairo_surface_t*) &_cairo_surface_nil;
 
-    pixman_format = _create_pixman_format (format);
-    if (pixman_format == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return (cairo_surface_t*) &_cairo_surface_nil;
-    }
+    _init_pixman_format (&pixman_format, format);
 
-    pixman_image = pixman_image_create_for_data ((pixman_bits_t *) data, pixman_format,
+    pixman_image = pixman_image_create_for_data ((pixman_bits_t *) data,
+	                                         &pixman_format,
 						 width, height,
 						 _cairo_format_bpp (format),
 						 stride);
-
-    pixman_format_destroy (pixman_format);
-
     if (pixman_image == NULL) {
 	_cairo_error (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t*) &_cairo_surface_nil;
     }
 
     surface = _cairo_image_surface_create_for_pixman_image (pixman_image, format);
+    if (cairo_surface_status (surface)) {
+	pixman_image_destroy (pixman_image);
+    }
 
     return surface;
 }
 slim_hidden_def (cairo_image_surface_create_for_data);
 
 cairo_surface_t *
 _cairo_image_surface_create_for_data_with_content (unsigned char	*data,
 						   cairo_content_t	 content,
@@ -562,17 +555,17 @@ cairo_content_t
      * bug #7294 fixed so we can release cairo 1.2.2 . */
     int f = format;
 
     switch (f) {
     case CAIRO_FORMAT_ARGB32:
     case CAIRO_INTERNAL_FORMAT_ABGR32:
 	return CAIRO_CONTENT_COLOR_ALPHA;
     case CAIRO_FORMAT_RGB24:
-    case CAIRO_FORMAT_RGB16_565:
+    case CAIRO_INTERNAL_FORMAT_RGB16_565:
     case CAIRO_INTERNAL_FORMAT_BGR24:
 	return CAIRO_CONTENT_COLOR;
     case CAIRO_FORMAT_A8:
     case CAIRO_FORMAT_A1:
 	return CAIRO_CONTENT_ALPHA;
     }
 
     ASSERT_NOT_REACHED;
@@ -685,17 +678,18 @@ static cairo_status_t
 static cairo_status_t
 _cairo_image_surface_set_matrix (cairo_image_surface_t	*surface,
 				 const cairo_matrix_t	*matrix)
 {
     pixman_transform_t pixman_transform;
 
     _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;
 }
 
 static cairo_status_t
 _cairo_image_surface_set_filter (cairo_image_surface_t *surface, cairo_filter_t filter)
 {
     pixman_filter_t pixman_filter;
@@ -902,18 +896,20 @@ static cairo_int_status_t
     pixman_color_t pixman_color;
 
     pixman_color.red   = color->red_short;
     pixman_color.green = color->green_short;
     pixman_color.blue  = color->blue_short;
     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;
 }
 
 static cairo_int_status_t
 _cairo_image_surface_composite_trapezoids (cairo_operator_t	op,
 					   cairo_pattern_t	*pattern,
 					   void			*abstract_dst,
@@ -927,20 +923,21 @@ static cairo_int_status_t
 					   cairo_trapezoid_t	*traps,
 					   int			num_traps)
 {
     cairo_surface_attributes_t	attributes;
     cairo_image_surface_t	*dst = abstract_dst;
     cairo_image_surface_t	*src;
     cairo_int_status_t		status;
     pixman_image_t		*mask;
-    pixman_format_t		*format;
+    pixman_format_t		 format;
     pixman_bits_t		*mask_data;
-    int				mask_stride;
-    int				mask_bpp;
+    int				 mask_stride;
+    int				 mask_bpp;
+    int				 ret;
 
     /* Special case adding trapezoids onto a mask surface; we want to avoid
      * creating an intermediate temporary mask unecessarily.
      *
      * We make the assumption here that the portion of the trapezoids
      * contained within the surface is bounded by [dst_x,dst_y,width,height];
      * the Cairo core code passes bounds based on the trapezoid extents.
      *
@@ -969,46 +966,42 @@ static cairo_int_status_t
 	return status;
 
     status = _cairo_image_surface_set_attributes (src, &attributes);
     if (status)
 	goto CLEANUP_SOURCE;
 
     switch (antialias) {
     case CAIRO_ANTIALIAS_NONE:
-	format = pixman_format_create (PIXMAN_FORMAT_NAME_A1);
+	ret = pixman_format_init (&format, PIXMAN_FORMAT_NAME_A1);
+	assert (ret);
 	mask_stride = (width + 31)/8;
 	mask_bpp = 1;
  	break;
     case CAIRO_ANTIALIAS_GRAY:
     case CAIRO_ANTIALIAS_SUBPIXEL:
     case CAIRO_ANTIALIAS_DEFAULT:
     default:
-	format = pixman_format_create (PIXMAN_FORMAT_NAME_A8);
+	ret = pixman_format_init (&format, PIXMAN_FORMAT_NAME_A8);
+	assert (ret);
 	mask_stride = (width + 3) & ~3;
 	mask_bpp = 8;
  	break;
     }
-    if (!format) {
+
+    /* The image must be initially transparent */
+    mask_data = calloc (1, mask_stride * height);
+    if (mask_data == NULL) {
 	status = CAIRO_STATUS_NO_MEMORY;
 	goto CLEANUP_SOURCE;
     }
 
-    /* The image must be initially transparent */
-    mask_data = calloc (1, mask_stride * height);
-    if (!mask_data) {
-	status = CAIRO_STATUS_NO_MEMORY;
-	pixman_format_destroy (format);
-	goto CLEANUP_SOURCE;
-    }
-
-    mask = pixman_image_create_for_data (mask_data, format, width, height,
+    mask = pixman_image_create_for_data (mask_data, &format, width, height,
 					 mask_bpp, mask_stride);
-    pixman_format_destroy (format);
-    if (!mask) {
+    if (mask == NULL) {
 	status = CAIRO_STATUS_NO_MEMORY;
 	goto CLEANUP_IMAGE_DATA;
     }
 
     /* XXX: The pixman_trapezoid_t cast is evil and needs to go away
      * somehow. */
     pixman_add_trapezoids (mask, - dst_x, - dst_y,
 			   (pixman_trapezoid_t *) traps, num_traps);
@@ -1042,17 +1035,18 @@ static cairo_int_status_t
 }
 
 cairo_int_status_t
 _cairo_image_surface_set_clip_region (void *abstract_surface,
 				      pixman_region16_t *region)
 {
     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;
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_int_status_t
 _cairo_image_surface_get_extents (void			  *abstract_surface,
@@ -1063,16 +1057,38 @@ static cairo_int_status_t
     rectangle->x = 0;
     rectangle->y = 0;
     rectangle->width  = surface->width;
     rectangle->height = surface->height;
 
     return CAIRO_STATUS_SUCCESS;
 }
 
+static void
+_cairo_image_surface_get_font_options (void                  *abstract_surface,
+				       cairo_font_options_t  *options)
+{
+    _cairo_font_options_init_default (options);
+
+    cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON);
+}
+
+static cairo_status_t
+_cairo_image_surface_reset (void *abstract_surface)
+{
+    cairo_image_surface_t *surface = abstract_surface;
+    cairo_status_t status;
+
+    status = _cairo_image_surface_set_clip_region (surface, NULL);
+    if (status)
+	return status;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
 /**
  * _cairo_surface_is_image:
  * @surface: a #cairo_surface_t
  *
  * Checks if a surface is an #cairo_image_surface_t
  *
  * Return value: TRUE if the surface is an image surface
  **/
@@ -1094,17 +1110,32 @@ const cairo_surface_backend_t cairo_imag
     _cairo_image_surface_composite,
     _cairo_image_surface_fill_rectangles,
     _cairo_image_surface_composite_trapezoids,
     NULL, /* copy_page */
     NULL, /* show_page */
     _cairo_image_surface_set_clip_region,
     NULL, /* intersect_clip_path */
     _cairo_image_surface_get_extents,
-    NULL /* old_show_glyphs */
+    NULL, /* old_show_glyphs */
+    _cairo_image_surface_get_font_options,
+    NULL, /* flush */
+    NULL, /* mark_dirty_rectangle */
+    NULL, //* font_fini */
+    NULL, //* glyph_fini */
+
+    NULL, /* paint */
+    NULL, /* mask */
+    NULL, /* stroke */
+    NULL, /* fill */
+    NULL, /* show_glyphs */
+    NULL,  /* snapshot */
+    NULL, /* is_similar */
+
+    _cairo_image_surface_reset
 };
 
 /* A convenience function for when one needs to coerce an image
  * surface to an alternate format. */
 cairo_image_surface_t *
 _cairo_image_surface_clone (cairo_image_surface_t	*surface,
 			    cairo_format_t		 format)
 {
--- a/gfx/cairo/cairo/src/cairo-matrix.c
+++ b/gfx/cairo/cairo/src/cairo-matrix.c
@@ -30,17 +30,16 @@
  * The Initial Developer of the Original Code is University of Southern
  * California.
  *
  * Contributor(s):
  *	Carl D. Worth <cworth@cworth.org>
  */
 
 #define _GNU_SOURCE
-#include <stdlib.h>
 
 #include "cairoint.h"
 
 static void
 _cairo_matrix_scalar_multiply (cairo_matrix_t *matrix, double scalar);
 
 static void
 _cairo_matrix_compute_adjoint (cairo_matrix_t *matrix);
@@ -193,17 +192,17 @@ cairo_matrix_init_scale (cairo_matrix_t 
 slim_hidden_def(cairo_matrix_init_scale);
 
 /**
  * cairo_matrix_scale:
  * @matrix: a #cairo_matrix_t
  * @sx: scale factor in the X direction
  * @sy: scale factor in the Y direction
  *
- * Applies scaling by @tx, @ty to the transformation in @matrix. The
+ * Applies scaling by @sx, @sy to the transformation in @matrix. The
  * effect of the new transformation is to first scale the coordinates
  * by @sx and @sy, then apply the original transformation to the coordinates.
  **/
 void
 cairo_matrix_scale (cairo_matrix_t *matrix, double sx, double sy)
 {
     cairo_matrix_t tmp;
 
@@ -491,17 +490,17 @@ void
 
     a = matrix->xx; b = matrix->yx;
     c = matrix->xy; d = matrix->yy;
 
     *det = a*d - b*c;
 }
 
 /* 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)
 {
     double det;
 
     _cairo_matrix_compute_determinant (matrix, &det);
 
     if (det == 0)
@@ -531,18 +530,16 @@ cairo_status_t
 	    *sy = minor;
 	}
 	else
 	{
 	    *sx = minor;
 	    *sy = major;
 	}
     }
-
-    return CAIRO_STATUS_SUCCESS;
 }
 
 cairo_bool_t
 _cairo_matrix_is_identity (const cairo_matrix_t *matrix)
 {
     return (matrix->xx == 1.0 && matrix->yx == 0.0 &&
 	    matrix->xy == 0.0 && matrix->yy == 1.0 &&
 	    matrix->x0 == 0.0 && matrix->y0 == 0.0);
--- a/gfx/cairo/cairo/src/cairo-meta-surface.c
+++ b/gfx/cairo/cairo/src/cairo-meta-surface.c
@@ -207,17 +207,21 @@ static void
 {
     cairo_surface_destroy (&image->base);
 }
 
 static cairo_status_t
 _init_pattern_with_snapshot (cairo_pattern_t       *pattern,
 			     const cairo_pattern_t *other)
 {
-    _cairo_pattern_init_copy (pattern, other);
+    cairo_status_t status;
+
+    status = _cairo_pattern_init_copy (pattern, other);
+    if (status)
+	return status;
 
     if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
 	cairo_surface_pattern_t *surface_pattern =
 	    (cairo_surface_pattern_t *) pattern;
 	cairo_surface_t *surface = surface_pattern->surface;
 
 	surface_pattern->surface = _cairo_surface_snapshot (surface);
 
@@ -643,16 +647,19 @@ cairo_status_t
     cairo_command_t *command, **elements;
     int i, num_elements;
     cairo_int_status_t status;
     cairo_clip_t clip;
     cairo_bool_t has_device_transform = _cairo_surface_has_device_transform (target);
     cairo_matrix_t *device_transform = &target->device_transform;
     cairo_path_fixed_t path_copy, *dev_path;
 
+    if (surface->status)
+	return surface->status;
+
     meta = (cairo_meta_surface_t *) surface;
     status = CAIRO_STATUS_SUCCESS;
 
     _cairo_clip_init (&clip, target);
 
     num_elements = meta->commands.num_elements;
     elements = _cairo_array_index (&meta->commands, 0);
     for (i = meta->replay_start_idx; i < num_elements; i++) {
@@ -663,17 +670,19 @@ cairo_status_t
 	if (command->type != CAIRO_COMMAND_INTERSECT_CLIP_PATH) {
 	    status = _cairo_surface_set_clip (target, &clip);
 	    if (status)
 		break;
 	}
 
 	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;
 	}
 
 	switch (command->type) {
 	case CAIRO_COMMAND_PAINT:
 	    status = _cairo_surface_paint (target,
 					   command->paint.op,
@@ -749,17 +758,17 @@ cairo_status_t
 		free (dev_glyphs);
 
 	    break;
 	}
 	case CAIRO_COMMAND_INTERSECT_CLIP_PATH:
 	    /* 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,
 					   command->intersect_clip_path.tolerance,
 					   command->intersect_clip_path.antialias,
 					   target);
 	    break;
 	default:
@@ -768,12 +777,12 @@ cairo_status_t
 
 	if (dev_path == &path_copy)
 	    _cairo_path_fixed_fini (&path_copy);
 
 	if (status)
 	    break;
     }
 
-    _cairo_clip_fini (&clip);
+    _cairo_clip_reset (&clip);
 
     return status;
 }
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/cairo/src/cairo-mutex-list-private.h
@@ -0,0 +1,51 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2007 Mathias Hasselmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * Contributor(s):
+ *	Mathias Hasselmann <mathias.hasselmann@gmx.de>
+ */
+
+
+CAIRO_MUTEX_DECLARE (_cairo_pattern_solid_pattern_cache_lock);
+CAIRO_MUTEX_DECLARE (_cairo_pattern_solid_surface_cache_lock);
+
+CAIRO_MUTEX_DECLARE (_cairo_font_face_mutex);
+CAIRO_MUTEX_DECLARE (_cairo_scaled_font_map_mutex);
+
+#if CAIRO_HAS_FT_FONT
+CAIRO_MUTEX_DECLARE (_cairo_ft_unscaled_font_map_mutex);
+#endif
+
+#if CAIRO_HAS_XLIB_SURFACE
+CAIRO_MUTEX_DECLARE (_cairo_xlib_display_mutex);
+#endif
+
+
+/* Undefine, to err on unintended inclusion */
+#undef   CAIRO_MUTEX_DECLARE
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/cairo/src/cairo-mutex-private.h
@@ -0,0 +1,175 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2002 University of Southern California
+ * Copyright © 2005,2007 Red Hat, Inc.
+ * Copyright © 2007 Mathias Hasselmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is University of Southern
+ * California.
+ *
+ * Contributor(s):
+ *	Carl D. Worth <cworth@cworth.org>
+ *	Mathias Hasselmann <mathias.hasselmann@gmx.de>
+ *	Behdad Esfahbod <behdad@behdad.org>
+ */
+
+#ifndef CAIRO_MUTEX_PRIVATE_H
+#define CAIRO_MUTEX_PRIVATE_H
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cairo-features.h>
+
+#include "cairo-mutex-type-private.h"
+
+/* Only the following three are mandatory at this point */
+#ifndef CAIRO_MUTEX_LOCK
+# error "CAIRO_MUTEX_LOCK not defined.  Check cairo-mutex-type-private.h."
+#endif
+#ifndef CAIRO_MUTEX_UNLOCK
+# error "CAIRO_MUTEX_UNLOCK not defined.  Check cairo-mutex-type-private.h."
+#endif
+#ifndef CAIRO_MUTEX_NIL_INITIALIZER
+# error "CAIRO_MUTEX_NIL_INITIALIZER not defined.  Check cairo-mutex-type-private.h."
+#endif
+
+CAIRO_BEGIN_DECLS
+
+
+#define CAIRO_MUTEX_DECLARE(mutex) extern cairo_mutex_t mutex
+#include "cairo-mutex-list-private.h"
+#undef CAIRO_MUTEX_DECLARE
+
+
+/* make sure implementations don't fool us: we decide these ourself */
+#undef _CAIRO_MUTEX_USE_STATIC_INITIALIZER
+#undef _CAIRO_MUTEX_USE_STATIC_FINALIZER
+
+
+#ifdef CAIRO_MUTEX_INIT
+
+/* If CAIRO_MUTEX_INIT is defined, we may need to initialize all
+ * static mutex'es. */
+# ifndef CAIRO_MUTEX_INITIALIZE
+#  define CAIRO_MUTEX_INITIALIZE() do {	\
+       if (!_cairo_mutex_initialized)	\
+           _cairo_mutex_initialize ();	\
+   } while(0)
+
+   cairo_private void _cairo_mutex_initialize (void);
+
+   /* and make sure we implement the above */
+#  define _CAIRO_MUTEX_USE_STATIC_INITIALIZER 1
+# endif /* CAIRO_MUTEX_INITIALIZE */
+
+#else /* no CAIRO_MUTEX_INIT */
+
+/* Otherwise we probably don't need to initialize static mutex'es, */
+# ifndef CAIRO_MUTEX_INITIALIZE
+#  define CAIRO_MUTEX_INITIALIZE() CAIRO_MUTEX_NOOP
+# endif /* CAIRO_MUTEX_INITIALIZE */
+
+/* and dynamic ones can be initialized using the static initializer. */
+# define CAIRO_MUTEX_INIT(mutex) do {				\
+      cairo_mutex_t _tmp_mutex = CAIRO_MUTEX_NIL_INITIALIZER;	\
+      memcpy (&(mutex), &_tmp_mutex, sizeof (_tmp_mutex));	\
+  } while (0)
+
+#endif /* CAIRO_MUTEX_INIT */
+
+
+#ifdef CAIRO_MUTEX_FINI
+
+/* If CAIRO_MUTEX_FINI is defined, we may need to finalize all
+ * static mutex'es. */
+# ifndef CAIRO_MUTEX_FINALIZE
+#  define CAIRO_MUTEX_FINALIZE() do {	\
+       if (_cairo_mutex_initialized)	\
+           _cairo_mutex_finalize ();	\
+   } while(0)
+
+   cairo_private void _cairo_mutex_finalize (void);
+
+   /* and make sure we implement the above */
+#  define _CAIRO_MUTEX_USE_STATIC_FINALIZER 1
+# endif /* CAIRO_MUTEX_FINALIZE */
+
+#else /* no CAIRO_MUTEX_FINI */
+
+/* Otherwise we probably don't need to finalize static mutex'es, */
+# ifndef CAIRO_MUTEX_FINALIZE
+#  define CAIRO_MUTEX_FINALIZE() CAIRO_MUTEX_NOOP
+# endif /* CAIRO_MUTEX_FINALIZE */
+
+/* neither do the dynamic ones. */
+# define CAIRO_MUTEX_FINI(mutex)	CAIRO_MUTEX_NOOP1(mutex)
+
+#endif /* CAIRO_MUTEX_FINI */
+
+
+#ifndef _CAIRO_MUTEX_USE_STATIC_INITIALIZER
+#define _CAIRO_MUTEX_USE_STATIC_INITIALIZER 0
+#endif
+#ifndef _CAIRO_MUTEX_USE_STATIC_FINALIZER
+#define _CAIRO_MUTEX_USE_STATIC_FINALIZER 0
+#endif
+
+/* only if using static initializer and/or finalizer define the boolean */
+#if _CAIRO_MUTEX_USE_STATIC_INITIALIZER || _CAIRO_MUTEX_USE_STATIC_FINALIZER
+  cairo_private extern cairo_bool_t _cairo_mutex_initialized;
+#endif
+
+
+CAIRO_END_DECLS
+
+/* Make sure everything we want is defined */
+#ifndef CAIRO_MUTEX_INITIALIZE
+# error "CAIRO_MUTEX_INITIALIZE not defined"
+#endif
+#ifndef CAIRO_MUTEX_FINALIZE
+# error "CAIRO_MUTEX_FINALIZE not defined"
+#endif
+#ifndef CAIRO_MUTEX_LOCK
+# error "CAIRO_MUTEX_LOCK not defined"
+#endif
+#ifndef CAIRO_MUTEX_UNLOCK
+# error "CAIRO_MUTEX_UNLOCK not defined"
+#endif
+#ifndef CAIRO_MUTEX_INIT
+# error "CAIRO_MUTEX_INIT not defined"
+#endif
+#ifndef CAIRO_MUTEX_FINI
+# error "CAIRO_MUTEX_FINI not defined"
+#endif
+#ifndef CAIRO_MUTEX_NIL_INITIALIZER
+# error "CAIRO_MUTEX_NIL_INITIALIZER not defined"
+#endif
+
+#endif
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/cairo/src/cairo-mutex-type-private.h
@@ -0,0 +1,210 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2002 University of Southern California
+ * Copyright © 2005,2007 Red Hat, Inc.
+ * Copyright © 2007 Mathias Hasselmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is University of Southern
+ * California.
+ *
+ * Contributor(s):
+ *	Carl D. Worth <cworth@cworth.org>
+ *	Mathias Hasselmann <mathias.hasselmann@gmx.de>
+ *	Behdad Esfahbod <behdad@behdad.org>
+ */
+
+#ifndef CAIRO_MUTEX_TYPE_PRIVATE_H
+#define CAIRO_MUTEX_TYPE_PRIVATE_H
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cairo-features.h>
+
+CAIRO_BEGIN_DECLS
+
+
+/* A fully qualified no-operation statement */
+#define CAIRO_MUTEX_NOOP	do {/*no-op*/} while (0)
+/* And one that evaluates it's argument once */
+#define CAIRO_MUTEX_NOOP1(expr)        do { if (expr) ; } while (0)
+
+
+/* Cairo mutex implementation:
+ *
+ * Any new mutex implementation needs to do the following:
+ *
+ * - Condition on the right header or feature.  Headers are
+ *   preferred as eg. you still can use win32 mutex implementation
+ *   on a win32 system even if you do not compile the win32
+ *   surface/backend.
+ *
+ * - typedef cairo_mutex_t to the proper mutex type on your target
+ *   system.  Note that you may or may not need to use a pointer,
+ *   depending on what kinds of initialization your mutex
+ *   implementation supports.  No trailing semicolon needed.
+ *   You should be able to compile the following snippet (don't try
+ *   running it):
+ *
+ *	cairo_mutex_t _cairo_some_mutex;
+ *
+ * - #define CAIRO_MUTEX_LOCK(mutex) and CAIRO_MUTEX_UNLOCK(mutex) to
+ *   proper statement to lock/unlock the mutex object passed in.
+ *   You can (and should) assume that the mutex is already
+ *   initialized, and is-not-already-locked/is-locked,
+ *   respectively.  Use the "do { ... } while (0)" idiom if necessary.
+ *   No trailing semicolons are needed (in any macro you define here).
+ *   You should be able to compile the following snippet:
+ *
+ *	cairo_mutex_t _cairo_some_mutex;
+ *
+ *      if (1)
+ *          CAIRO_MUTEX_LOCK (_cairo_some_mutex);
+ *      else
+ *          CAIRO_MUTEX_UNLOCK (_cairo_some_mutex);
+ *
+ * - #define CAIRO_MUTEX_NIL_INITIALIZER to something that can
+ *   initialize the cairo_mutex_t type you defined.  Most of the
+ *   time one of 0, NULL, or {} works.  At this point
+ *   you should be able to compile the following snippet:
+ *
+ *	cairo_mutex_t _cairo_some_mutex = CAIRO_MUTEX_NIL_INITIALIZER;
+ *
+ *      if (1)
+ *          CAIRO_MUTEX_LOCK (_cairo_some_mutex);
+ *      else
+ *          CAIRO_MUTEX_UNLOCK (_cairo_some_mutex);
+ *
+ * - If the above code is not enough to initialize a mutex on
+ *   your platform, #define CAIRO_MUTEX_INIT(mutex) to statement
+ *   to initialize the mutex (allocate resources, etc).  Such that
+ *   you should be able to compile AND RUN the following snippet:
+ *
+ *	cairo_mutex_t _cairo_some_mutex = CAIRO_MUTEX_NIL_INITIALIZER;
+ *
+ *      CAIRO_MUTEX_INIT (_cairo_some_mutex);
+ *
+ *      if (1)
+ *          CAIRO_MUTEX_LOCK (_cairo_some_mutex);
+ *      else
+ *          CAIRO_MUTEX_UNLOCK (_cairo_some_mutex);
+ *
+ * - If you define CAIRO_MUTEX_INIT(mutex), cairo will use it to
+ *   initialize all static mutex'es.  If for any reason that should
+ *   not happen (eg. CAIRO_MUTEX_INIT is just a faster way than
+ *   what cairo does using CAIRO_MUTEX_NIL_INITIALIZER), then
+ *   #define CAIRO_MUTEX_INITIALIZE() CAIRO_MUTEX_NOOP
+ *
+ * - If your system supports freeing a mutex object (deallocating
+ *   resources, etc), then #define CAIRO_MUTEX_FINI(mutex) to do
+ *   that.
+ *
+ * - If you define CAIRO_MUTEX_FINI(mutex), cairo will use it to
+ *   define a finalizer function to finalize all static mutex'es.
+ *   However, it's up to you to call CAIRO_MUTEX_FINALIZE() at
+ *   proper places, eg. when the system is unloading the cairo library.
+ *   So, if for any reason finalizing static mutex'es is not needed
+ *   (eg. you never call CAIRO_MUTEX_FINALIZE), then
+ *   #define CAIRO_MUTEX_FINALIZE() CAIRO_MUTEX_NOOP
+ *
+ * - That is all.  If for any reason you think the above API is
+ *   not enough to implement cairo_mutex_t on your system, please
+ *   stop and write to the cairo mailing list about it.  DO NOT
+ *   poke around cairo-mutex-private.h for possible solutions.
+ */
+
+#if CAIRO_NO_MUTEX
+
+/* A poor man's mutex */
+
+  typedef int cairo_mutex_t;
+
+# define CAIRO_MUTEX_INITIALIZE() CAIRO_MUTEX_NOOP
+# define CAIRO_MUTEX_LOCK(mutex) do { while (mutex) ; (mutex) = 1; } while (0)
+# define CAIRO_MUTEX_UNLOCK(mutex) (mutex) = 0
+# define CAIRO_MUTEX_NIL_INITIALIZER 0
+
+#elif HAVE_PTHREAD_H /*******************************************************/
+
+# include <pthread.h>
+
+  typedef pthread_mutex_t cairo_mutex_t;
+
+# define CAIRO_MUTEX_LOCK(mutex) pthread_mutex_lock (&(mutex))
+# define CAIRO_MUTEX_UNLOCK(mutex) pthread_mutex_unlock (&(mutex))
+# define CAIRO_MUTEX_FINI(mutex) pthread_mutex_destroy (&(mutex))
+# define CAIRO_MUTEX_FINALIZE() CAIRO_MUTEX_NOOP
+# define CAIRO_MUTEX_NIL_INITIALIZER PTHREAD_MUTEX_INITIALIZER
+
+#elif HAVE_WINDOWS_H /*******************************************************/
+
+# include <windows.h>
+
+  typedef CRITICAL_SECTION cairo_mutex_t;
+
+# define CAIRO_MUTEX_LOCK(mutex) EnterCriticalSection (&(mutex))
+# define CAIRO_MUTEX_UNLOCK(mutex) LeaveCriticalSection (&(mutex))
+# define CAIRO_MUTEX_INIT(mutex) InitializeCriticalSection (&(mutex))
+# define CAIRO_MUTEX_FINI(mutex) DeleteCriticalSection (&(mutex))
+# define CAIRO_MUTEX_NIL_INITIALIZER { NULL, 0, 0, NULL, NULL, 0 }
+
+#elif defined __OS2__ /******************************************************/
+
+# define INCL_BASE
+# define INCL_PM
+# include <os2.h>
+
+  typedef HMTX cairo_mutex_t;
+
+# define CAIRO_MUTEX_LOCK(mutex) DosRequestMutexSem(mutex, SEM_INDEFINITE_WAIT)
+# define CAIRO_MUTEX_UNLOCK(mutex) DosReleaseMutexSem(mutex)
+# define CAIRO_MUTEX_INIT(mutex) DosCreateMutexSem (NULL, &(mutex), 0L, FALSE)
+# define CAIRO_MUTEX_FINI(mutex) DosCloseMutexSem (mutex)
+# define CAIRO_MUTEX_NIL_INITIALIZER 0
+
+#elif CAIRO_HAS_BEOS_SURFACE /***********************************************/
+
+  typedef BLocker* cairo_mutex_t;
+
+# define CAIRO_MUTEX_LOCK(mutex) (mutex)->Lock()
+# define CAIRO_MUTEX_UNLOCK(mutex) (mutex)->Unlock()
+# define CAIRO_MUTEX_INIT(mutex) (mutex) = new BLocker()
+# define CAIRO_MUTEX_FINI(mutex) delete (mutex)
+# define CAIRO_MUTEX_NIL_INITIALIZER NULL
+
+#else /**********************************************************************/
+
+# error "XXX: No mutex implementation found.  Cairo will not work with multiple threads.  Define CAIRO_NO_MUTEX to 1 to acknowledge and accept this limitation and compile cairo without thread-safety support."
+
+
+#endif
+
+CAIRO_END_DECLS
+
+#endif
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/cairo/src/cairo-mutex.c
@@ -0,0 +1,80 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2007 Mathias Hasselmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * Contributor(s):
+ *	Mathias Hasselmann <mathias.hasselmann@gmx.de>
+ */
+
+#include "cairoint.h"
+
+#define CAIRO_MUTEX_DECLARE(mutex) cairo_mutex_t mutex = CAIRO_MUTEX_NIL_INITIALIZER
+#include "cairo-mutex-list-private.h"
+#undef   CAIRO_MUTEX_DECLARE
+
+#if _CAIRO_MUTEX_USE_STATIC_INITIALIZER || _CAIRO_MUTEX_USE_STATIC_FINALIZER
+
+# if _CAIRO_MUTEX_USE_STATIC_INITIALIZER
+#  define _CAIRO_MUTEX_INITIALIZED_DEFAULT_VALUE FALSE
+# else
+#  define _CAIRO_MUTEX_INITIALIZED_DEFAULT_VALUE TRUE
+# endif
+
+cairo_bool_t _cairo_mutex_initialized = _CAIRO_MUTEX_INITIALIZED_DEFAULT_VALUE;
+
+# undef _CAIRO_MUTEX_INITIALIZED_DEFAULT_VALUE
+
+#endif
+
+#if _CAIRO_MUTEX_USE_STATIC_INITIALIZER
+void _cairo_mutex_initialize (void)
+{
+    if (_cairo_mutex_initialized)
+        return;
+
+    _cairo_mutex_initialized = TRUE;
+
+#define  CAIRO_MUTEX_DECLARE(mutex) CAIRO_MUTEX_INIT (mutex)
+#include "cairo-mutex-list-private.h"
+#undef   CAIRO_MUTEX_DECLARE
+}
+#endif
+
+#if _CAIRO_MUTEX_USE_STATIC_FINALIZER
+void _cairo_mutex_finalize (void)
+{
+    if (!_cairo_mutex_initialized)
+        return;
+
+    _cairo_mutex_initialized = FALSE;
+
+#define  CAIRO_MUTEX_DECLARE(mutex) CAIRO_MUTEX_FINI (mutex)
+#include "cairo-mutex-list-private.h"
+#undef   CAIRO_MUTEX_DECLARE
+}
+#endif
--- a/gfx/cairo/cairo/src/cairo-os2-surface.c
+++ b/gfx/cairo/cairo/src/cairo-os2-surface.c
@@ -30,57 +30,50 @@
  *
  * The Initial Developer of the Original Code is
  *     Doodle <doodle@scenergy.dfmk.hu>
  *
  * Contributor(s):
  *     Peter Weilbacher <mozilla@Weilbacher.org>
  */
 
-#include <stdlib.h>
-#include <stdio.h>
+#include "cairoint.h"
+
+#include "cairo-os2-private.h"
+
+#include <fontconfig/fontconfig.h>
+
 #include <float.h>
 #ifdef BUILD_CAIRO_DLL
 # define INCL_WIN
 # define INCL_GPI
 # define INCL_DOS
 # define INCL_DOSERRORS
 # include <os2emx.h>
 # include "cairo-os2.h"
 # ifndef __WATCOMC__
 #  include <emx/startup.h>
 # endif
 #endif
-#include "cairoint.h"
-#include "cairo-os2-private.h"
-#include "fontconfig/fontconfig.h"
 
 /*
  * Here comes the extra API for the OS/2 platform. Currently it consists
  * of two extra functions, the cairo_os2_init () and the
  * cairo_os2_fini (). Both of them are called automatically if
  * Cairo is compiled to be a DLL file, but you have to call them before
  * using the Cairo API if you link to Cairo statically!
  *
  * You'll also find the code in here which deals with DLL initialization
  * and termination, if the code is built to be a DLL.
  * (if BUILD_CAIRO_DLL is defined)
  */
 
 /* Initialization counter: */
 static int cairo_os2_initialization_count = 0;
 
-/* The mutex semaphores Cairo uses all around: */
-HMTX _cairo_scaled_font_map_mutex = 0;
-HMTX _global_image_glyph_cache_mutex = 0;
-HMTX _cairo_font_face_mutex = 0;
-#ifdef CAIRO_HAS_FT_FONT
-HMTX _cairo_ft_unscaled_font_map_mutex = 0;
-#endif
-
 static void inline
 DisableFPUException (void)
 {
     unsigned short usCW;
 
     /* Some OS/2 PM API calls modify the FPU Control Word,
      * but forget to restore it.
      *
@@ -98,30 +91,20 @@ cairo_os2_init (void)
 {
     /* This may initialize some stuffs, like create mutex semaphores etc.. */
 
     cairo_os2_initialization_count++;
     if (cairo_os2_initialization_count > 1) return;
 
     DisableFPUException ();
 
-    /* Create the mutex semaphores we'll use! */
-
-    /* cairo-font.c: */
-    DosCreateMutexSem (NULL, &_cairo_scaled_font_map_mutex, 0, FALSE);
-    DosCreateMutexSem (NULL, &_global_image_glyph_cache_mutex, 0, FALSE);
-    DosCreateMutexSem (NULL, &_cairo_font_face_mutex, 0, FALSE);
-
-#ifdef CAIRO_HAS_FT_FONT
-    /* cairo-ft-font.c: */
-    DosCreateMutexSem (NULL, &_cairo_ft_unscaled_font_map_mutex, 0, FALSE);
-#endif
-
     /* Initialize FontConfig */
     FcInit ();
+
+    CAIRO_MUTEX_INITIALIZE ();
 }
 
 cairo_public void
 cairo_os2_fini (void)
 {
     /* This has to uninitialize some stuffs, like destroy mutex semaphores etc.. */
 
     if (cairo_os2_initialization_count <= 0) return;
@@ -132,38 +115,17 @@ cairo_os2_fini (void)
 
     /* Free allocated memories! */
     /* (Check cairo_debug_reset_static_date () for an example of this!) */
     _cairo_font_reset_static_data ();
 #ifdef CAIRO_HAS_FT_FONT
     _cairo_ft_font_reset_static_data ();
 #endif
 
-    /* Destroy the mutex semaphores we've created! */
-    /* cairo-font.c: */
-    if (_cairo_scaled_font_map_mutex) {
-        DosCloseMutexSem (_cairo_scaled_font_map_mutex);
-        _cairo_scaled_font_map_mutex = 0;
-    }
-    if (_global_image_glyph_cache_mutex) {
-        DosCloseMutexSem (_global_image_glyph_cache_mutex);
-        _global_image_glyph_cache_mutex = 0;
-    }
-    if (_cairo_font_face_mutex) {
-        DosCloseMutexSem (_cairo_font_face_mutex);
-        _cairo_font_face_mutex = 0;
-    }
-
-#ifdef CAIRO_HAS_FT_FONT
-    /* cairo-ft-font.c: */
-    if (_cairo_ft_unscaled_font_map_mutex) {
-        DosCloseMutexSem (_cairo_ft_unscaled_font_map_mutex);
-        _cairo_ft_unscaled_font_map_mutex = 0;
-    }
-#endif
+    CAIRO_MUTEX_FINALIZE ();
 
     /* Uninitialize FontConfig */
     FcFini ();
 
 #ifdef __WATCOMC__
     /* It can happen that the libraries we use have memory leaks,
      * so there are still memory chunks allocated at this point.
      * In these cases, Watcom might still have a bigger memory chunk,
--- a/gfx/cairo/cairo/src/cairo-output-stream-private.h
+++ b/gfx/cairo/cairo/src/cairo-output-stream-private.h
@@ -32,33 +32,33 @@
  *
  * Author(s):
  *	Kristian Høgsberg <krh@redhat.com>
  */
 
 #ifndef CAIRO_OUTPUT_STREAM_PRIVATE_H
 #define CAIRO_OUTPUT_STREAM_PRIVATE_H
 
-typedef struct _cairo_output_stream cairo_output_stream_t;
+#include "cairo-types-private.h"
 
 typedef cairo_status_t (*cairo_output_stream_write_func_t) (cairo_output_stream_t *output_stream,
 							    const unsigned char   *data,
 							    unsigned int           length);
 
 typedef cairo_status_t (*cairo_output_stream_close_func_t) (cairo_output_stream_t *output_stream);
 
 struct _cairo_output_stream {
     cairo_output_stream_write_func_t write_func;
     cairo_output_stream_close_func_t close_func;
     unsigned long		     position;
     cairo_status_t		     status;
     cairo_bool_t		     closed;
 };
 
-extern const cairo_private cairo_output_stream_t cairo_output_stream_nil;
+extern const cairo_private cairo_output_stream_t _cairo_output_stream_nil;
 
 cairo_private void
 _cairo_output_stream_init (cairo_output_stream_t            *stream,
 			   cairo_output_stream_write_func_t  write_func,
 			   cairo_output_stream_close_func_t  close_func);
 
 cairo_private cairo_status_t
 _cairo_output_stream_fini (cairo_output_stream_t *stream);
@@ -102,17 +102,17 @@ cairo_private void
 _cairo_output_stream_write (cairo_output_stream_t *stream,
 			    const void *data, size_t length);
 
 cairo_private void
 _cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
 				       const char *data,
 				       size_t length);
 
-cairo_private int
+cairo_private void
 _cairo_dtostr (char *buffer, size_t size, double d);
 
 cairo_private void
 _cairo_output_stream_vprintf (cairo_output_stream_t *stream,
 			      const char *fmt, va_list ap);
 
 cairo_private void
 _cairo_output_stream_printf (cairo_output_stream_t *stream,
--- a/gfx/cairo/cairo/src/cairo-output-stream.c
+++ b/gfx/cairo/cairo/src/cairo-output-stream.c
@@ -29,21 +29,22 @@
  *   cairo graphics library.
  *
  * The Initial Developer of the Original Code is Red Hat, Inc.
  *
  * Author(s):
  *	Kristian Høgsberg <krh@redhat.com>
  */
 
-#include <stdio.h>
+#include "cairoint.h"
+
+#include "cairo-output-stream-private.h"
+
 #include <locale.h>
 #include <ctype.h>
-#include "cairoint.h"
-#include "cairo-output-stream-private.h"
 
 #ifdef _MSC_VER
 #define snprintf _snprintf
 #endif /* _MSC_VER */
 
 
 cairo_private void
 _cairo_output_stream_init (cairo_output_stream_t            *stream,
@@ -58,25 +59,25 @@ cairo_private void
 }
 
 cairo_private cairo_status_t
 _cairo_output_stream_fini (cairo_output_stream_t *stream)
 {
     return _cairo_output_stream_close (stream);
 }
 
-const cairo_output_stream_t cairo_output_stream_nil = {
+const cairo_output_stream_t _cairo_output_stream_nil = {
     NULL, /* write_func */
     NULL, /* close_func */
     0,    /* position */
     CAIRO_STATUS_NO_MEMORY,
     FALSE /* closed */
 };
 
-static const cairo_output_stream_t cairo_output_stream_nil_write_error = {
+static const cairo_output_stream_t _cairo_output_stream_nil_write_error = {
     NULL, /* write_func */
     NULL, /* close_func */
     0,    /* position */
     CAIRO_STATUS_WRITE_ERROR,
     FALSE /* closed */
 };
 
 typedef struct _cairo_output_stream_with_closure {
@@ -114,17 +115,17 @@ cairo_output_stream_t *
 _cairo_output_stream_create (cairo_write_func_t		write_func,
 			     cairo_close_func_t		close_func,
 			     void			*closure)
 {
     cairo_output_stream_with_closure_t *stream;
 
     stream = malloc (sizeof (cairo_output_stream_with_closure_t));
     if (stream == NULL)
-	return (cairo_output_stream_t *) &cairo_output_stream_nil;
+	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
 
     _cairo_output_stream_init (&stream->base, closure_write, closure_close);
     stream->write_func = write_func;
     stream->close_func = close_func;
     stream->closure = closure;
 
     return &stream->base;
 }
@@ -132,18 +133,18 @@ cairo_output_stream_t *
 cairo_status_t
 _cairo_output_stream_close (cairo_output_stream_t *stream)
 {
     cairo_status_t status;
 
     if (stream->closed)
 	return stream->status;
 
-    if (stream == &cairo_output_stream_nil ||
-	stream == &cairo_output_stream_nil_write_error)
+    if (stream == &_cairo_output_stream_nil ||
+	stream == &_cairo_output_stream_nil_write_error)
     {
 	return stream->status;
     }
 
     if (stream->close_func) {
 	status = stream->close_func (stream);
 	/* Don't overwrite a pre-existing status failure. */
 	if (stream->status == CAIRO_STATUS_SUCCESS)
@@ -209,62 +210,59 @@ void
 /* Format a double in a locale independent way and trim trailing
  * zeros.  Based on code from Alex Larson <alexl@redhat.com>.
  * http://mail.gnome.org/archives/gtk-devel-list/2001-October/msg00087.html
  *
  * The code in the patch is copyright Red Hat, Inc under the LGPL, but
  * has been relicensed under the LGPL/MPL dual license for inclusion
  * into cairo (see COPYING). -- Kristian Høgsberg <krh@redhat.com>
  */
-
-int
+void
 _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;
+    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;
+    /* Omit the minus sign from negative zero. */
+    if (d == 0.0)
+	d = 0.0;
 
-  snprintf (buffer, size, "%f", d);
+    snprintf (buffer, size, "%f", d);
 
-  locale_data = localeconv ();
-  decimal_point = locale_data->decimal_point;
-  decimal_point_len = strlen (decimal_point);
+    locale_data = localeconv ();
+    decimal_point = locale_data->decimal_point;
+    decimal_point_len = strlen (decimal_point);
 
-  assert (decimal_point_len != 0);
-  p = buffer;
+    assert (decimal_point_len != 0);
+    p = buffer;
 
-  if (*p == '+' || *p == '-')
-      p++;
-
-  while (isdigit (*p))
-      p++;
+    if (*p == '+' || *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;
+    while (isdigit (*p))
+	p++;
 
-      /* Remove trailing zeros and decimal point if possible. */
-      for (p = p + decimal_len; *p == '0'; p--)
-	  *p = 0;
+    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;
 
-      if (*p == '.') {
-	  *p = 0;
-	  p--;
-      }
-  }
+	/* Remove trailing zeros and decimal point if possible. */
+	for (p = p + decimal_len; *p == '0'; p--)
+	    *p = 0;
 
-  return p + 1 - buffer;
+	if (*p == '.') {
+	    *p = 0;
+	    p--;
+	}
+    }
 }
 
 enum {
     LENGTH_MODIFIER_LONG = 0x100
 };
 
 /* Here's a limited reimplementation of printf.  The reason for doing
  * this is primarily to special case handling of doubles.  We want
@@ -273,20 +271,23 @@ enum {
  * below handles everything else by calling snprintf() to do the
  * formatting.  This functionality is only for internal use and we
  * only implement the formats we actually use.
  */
 void
 _cairo_output_stream_vprintf (cairo_output_stream_t *stream,
 			      const char *fmt, va_list ap)
 {
-    char buffer[512], single_fmt[32];
-    char *p, *end;
+#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;
+    int length_modifier, width;
+    cairo_bool_t var_width;
 
     if (stream->status)
 	return;
 
     f = fmt;
     p = buffer;
     while (*f != '\0') {
 	if (p == buffer + sizeof (buffer)) {
@@ -300,30 +301,40 @@ void
 	}
 
 	start = f;
 	f++;
 
 	if (*f == '0')
 	    f++;
 
-	if (isdigit (*f)) {
-	    strtol (f, &end, 10);
-	    f = end;
-	}
+        var_width = FALSE;
+        if (*f == '*') {
+            var_width = TRUE;
+	    f++;
+        }
+
+	while (isdigit (*f))
+	    f++;
 
 	length_modifier = 0;
 	if (*f == 'l') {
 	    length_modifier = LENGTH_MODIFIER_LONG;
 	    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);
 	p = buffer;
 
 	/* We group signed and unsigned together in this switch, the
 	 * only thing that matters here is the size of the arguments,
 	 * since we're just passing the data through to sprintf(). */
@@ -332,25 +343,37 @@ void
 	    buffer[0] = *f;
 	    buffer[1] = 0;
 	    break;
 	case 'd':
 	case 'u':
 	case 'o':
 	case 'x':
 	case 'X':
-	    snprintf (buffer, sizeof buffer, single_fmt, va_arg (ap, int));
+            if (var_width) {
+                width = va_arg (ap, int);
+                snprintf (buffer, sizeof buffer,
+                          single_fmt, width, va_arg (ap, int));
+            } else {
+                snprintf (buffer, sizeof buffer, single_fmt, va_arg (ap, int));
+            }
 	    break;
 	case 'd' | LENGTH_MODIFIER_LONG:
 	case 'u' | LENGTH_MODIFIER_LONG:
 	case 'o' | LENGTH_MODIFIER_LONG:
 	case 'x' | LENGTH_MODIFIER_LONG:
 	case 'X' | LENGTH_MODIFIER_LONG:
-	    snprintf (buffer, sizeof buffer,
-		      single_fmt, va_arg (ap, long int));
+            if (var_width) {
+                width = va_arg (ap, int);
+                snprintf (buffer, sizeof buffer,
+                          single_fmt, width, va_arg (ap, long int));
+            } else {
+                snprintf (buffer, sizeof buffer,
+                          single_fmt, va_arg (ap, long int));
+            }
 	    break;
 	case 's':
 	    snprintf (buffer, sizeof buffer,
 		      single_fmt, va_arg (ap, const char *));
 	    break;
 	case 'f':
 	    _cairo_dtostr (buffer, sizeof buffer, va_arg (ap, double));
 	    break;
@@ -441,42 +464,42 @@ stdio_close (cairo_output_stream_t *base
 }
 
 cairo_output_stream_t *
 _cairo_output_stream_create_for_file (FILE *file)
 {
     stdio_stream_t *stream;
 
     if (file == NULL)
-	return (cairo_output_stream_t *) &cairo_output_stream_nil_write_error;
+	return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error;
 
     stream = malloc (sizeof *stream);
     if (stream == NULL)
-	return (cairo_output_stream_t *) &cairo_output_stream_nil;
+	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
 
     _cairo_output_stream_init (&stream->base, stdio_write, stdio_flush);
     stream->file = file;
 
     return &stream->base;
 }
 
 cairo_output_stream_t *
 _cairo_output_stream_create_for_filename (const char *filename)
 {
     stdio_stream_t *stream;
     FILE *file;
 
     file = fopen (filename, "wb");
     if (file == NULL)
-	return (cairo_output_stream_t *) &cairo_output_stream_nil_write_error;
+	return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error;
 
     stream = malloc (sizeof *stream);
     if (stream == NULL) {
 	fclose (file);
-	return (cairo_output_stream_t *) &cairo_output_stream_nil;
+	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
     }
 
     _cairo_output_stream_init (&stream->base, stdio_write, stdio_close);
     stream->file = file;
 
     return &stream->base;
 }
 
@@ -507,17 +530,17 @@ memory_close (cairo_output_stream_t *bas
 
 cairo_output_stream_t *
 _cairo_memory_stream_create (void)
 {
     memory_stream_t *stream;
 
     stream = malloc (sizeof *stream);
     if (stream == NULL)
-	return (cairo_output_stream_t *) &cairo_output_stream_nil;
+	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
 
     _cairo_output_stream_init (&stream->base, memory_write, memory_close);
     _cairo_array_init (&stream->array, 1);
 
     return &stream->base;
 }
 
 void
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/cairo/src/cairo-paginated-private.h
@@ -0,0 +1,136 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2005 Red Hat, Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Red Hat, Inc.
+ *
+ * Contributor(s):
+ *	Carl Worth <cworth@cworth.org>
+ */
+
+#ifndef CAIRO_PAGINATED_H
+#define CAIRO_PAGINATED_H
+
+#include "cairoint.h"
+
+struct _cairo_paginated_surface_backend {
+    /* Optional. Will be called once for each page.
+     *
+     * NOTE: With respect to the order of drawing operations as seen
+     * by the target, this call will occur before any drawing
+     * operations for the relevant page. However, with respect to the
+     * function calls as made by the user, this call will be *after*
+     * any drawing operations for the page, (that is, it will occur
+     * during the user's call to cairo_show_page or cairo_copy_page).
+     */
+    cairo_warn cairo_int_status_t
+    (*start_page)		(void			*surface);
+
+    /* Required. Will be called twice for each page, once with an
+     * argument of CAIRO_PAGINATED_MODE_ANALYZE and once with
+     * CAIRO_PAGINATED_MODE_RENDER. See more details in the
+     * documentation for _cairo_paginated_surface_create below.
+     */
+    void
+    (*set_paginated_mode)	(void			*surface,
+				 cairo_paginated_mode_t	 mode);
+};
+
+/* A cairo_paginated_surface provides a very convenient wrapper that
+ * is well-suited for doing the analysis common to most surfaces that
+ * have paginated output, (that is, things directed at printers, or
+ * for saving content in files such as PostScript or PDF files).
+ *
+ * To use the paginated surface, you'll first need to create your
+ * 'real' surface using _cairo_surface_init and the standard
+ * cairo_surface_backend_t. Then you also call
+ * _cairo_paginated_surface_create which takes its own, much simpler,
+ * cairo_paginated_surface_backend. You are free to return the result
+ * of _cairo_paginated_surface_create from your public
+ * cairo_<foo>_surface_create. The paginated backend will be careful
+ * to not let the user see that they really got a "wrapped"
+ * surface. See test-paginated-surface.c for a fairly minimal example
+ * of a paginated-using surface. That should be a reasonable example
+ * to follow.
+ *
+ * What the paginated surface does is first save all drawing
+ * operations for a page into a meta-surface. Then when the user calls
+ * cairo_show_page, the paginated surface performs the following
+ * sequence of operations (using the backend functions passed to
+ * cairo_paginated_surface_create):
+ *
+ * 1. Calls start_page (if non NULL). At this point, it is appropriate
+ *    for the target to emit any page-specific header information into
+ *    its output.
+ *
+ * 2. Calls set_paginated_mode with an argument of CAIRO_PAGINATED_MODE_ANALYZE
+ *
+ * 3. Replays the meta-surface to the target surface, (with an
+ *    analysis surface inserted between which watches the return value
+ *    from each operation). This analysis stage is used to decide which
+ *    operations will require fallbacks.
+ *
+ * 4. Calls set_paginated_mode with an argument of CAIRO_PAGINATED_MODE_RENDER
+ *
+ * 5. Replays a subset of the meta-surface operations to the target surface
+ *
+ * 6. Replays the remaining operations to an image surface, sets an
+ *    appropriate clip on the target, then paints the resulting image
+ *    surface to the target.
+ *
+ * So, the target will see drawing operations during two separate
+ * stages, (ANALYZE and RENDER). During the ANALYZE phase the target
+ * should not actually perform any rendering, (for example, if
+ * performing output to a file, no output should be generated during
+ * this stage). Instead the drawing functions simply need to return
+ * CAIRO_STATUS_SUCCESS or CAIRO_INT_STATUS_UNSUPPORTED to indicate
+ * whether rendering would be supported. And it should do this as
+ * quickly as possible.
+ *
+ * NOTE: The paginated surface layer assumes that the target surface
+ * is "blank" by default at the beginning of each page, without any
+ * need for an explicit erasea operation, (as opposed to an image
+ * surface, for example, which might have uninitialized content
+ * originally). As such, it optimizes away CLEAR operations that
+ * happen at the beginning of each page---the target surface will not
+ * even see these operations.
+ */
+cairo_private cairo_surface_t *
+_cairo_paginated_surface_create (cairo_surface_t				*target,
+				 cairo_content_t				 content,
+				 int						 width,
+				 int						 height,
+				 const cairo_paginated_surface_backend_t	*backend);
+
+cairo_private cairo_surface_t *
+_cairo_paginated_surface_get_target (cairo_surface_t *surface);
+
+cairo_private cairo_bool_t
+_cairo_surface_is_paginated (cairo_surface_t *surface);
+
+#endif /* CAIRO_PAGINATED_H */
--- a/gfx/cairo/cairo/src/cairo-paginated-surface-private.h
+++ b/gfx/cairo/cairo/src/cairo-paginated-surface-private.h
@@ -31,111 +31,42 @@
  *
  * Contributor(s):
  *	Carl Worth <cworth@cworth.org>
  */
 
 #ifndef CAIRO_PAGINATED_SURFACE_H
 #define CAIRO_PAGINATED_SURFACE_H
 
-#include "cairoint.h"
+#include "cairo.h"
 
-typedef enum {
-    CAIRO_PAGINATED_MODE_ANALYZE,	/* analyze page regions */
-    CAIRO_PAGINATED_MODE_RENDER		/* render page contents */
-} cairo_paginated_mode_t;
+#include "cairo-surface-private.h"
 
-typedef struct _cairo_paginated_surface_backend {
-    /* Optional. Will be called once for each page.
-     *
-     * NOTE: With respect to the order of drawing operations as seen
-     * by the target, this call will occur before any drawing
-     * operations for the relevant page. However, with respect to the
-     * function calls as made by the user, this call will be *after*
-     * any drawing operations for the page, (that is, it will occur
-     * during the user's call to cairo_show_page or cairo_copy_page).
-     */
-    cairo_int_status_t
-    (*start_page)		(void			*surface);
+typedef struct _cairo_paginated_surface {
+    cairo_surface_t base;
 
-    /* Required. Will be called twice for each page, once with an
-     * argument of CAIRO_PAGINATED_MODE_ANALYZE and once with
-     * CAIRO_PAGINATED_MODE_RENDER. See more details in the
-     * documentation for _cairo_paginated_surface_create below.
-     */
-    void
-    (*set_paginated_mode)	(void			*surface,
-				 cairo_paginated_mode_t	 mode);
-} cairo_paginated_surface_backend_t;
+    /* The target surface to hold the final result. */
+    cairo_surface_t *target;
+
+    cairo_content_t content;
 
-/* A cairo_paginated_surface provides a very convenient wrapper that
- * is well-suited for doing the analysis common to most surfaces that
- * have paginated output, (that is, things directed at printers, or
- * for saving content in files such as PostScript or PDF files).
- *
- * To use the paginated surface, you'll first need to create your
- * 'real' surface using _cairo_surface_init and the standard
- * cairo_surface_backend_t. Then you also call
- * _cairo_paginated_surface_create which takes its own, much simpler,
- * cairo_paginated_surface_backend. You are free to return the result
- * of _cairo_paginated_surface_create from your public
- * cairo_<foo>_surface_create. The paginated backend will be careful
- * to not let the user see that they really got a "wrapped"
- * surface. See test-paginated-surface.c for a fairly minimal example
- * of a paginated-using surface. That should be a reasonable example
- * to follow.
- *
- * What the paginated surface does is first save all drawing
- * operations for a page into a meta-surface. Then when the user calls
- * cairo_show_page, the paginated surface performs the following
- * sequence of operations (using the backend functions passed to
- * cairo_paginated_surface_create):
- *
- * 1. Calls start_page (if non NULL). At this point, it is appropriate
- *    for the target to emit any page-specific header information into
- *    its output.
- *
- * 2. Calls set_paginated_mode with an argument of CAIRO_PAGINATED_MODE_ANALYZE
- *
- * 3. Replays the meta-surface to the target surface, (with an
- *    analysis surface inserted between which watches the return value
- *    from each operation). This analysis stage is used to decide which
- *    operations will require fallbacks.
- *
- * 4. Calls set_paginated_mode with an argument of CAIRO_PAGINATED_MODE_RENDER
- *
- * 5. Replays a subset of the meta-surface operations to the target surface
- *
- * 6. Replays the remaining operations to an image surface, sets an
- *    appropriate clip on the target, then paints the resulting image
- *    surface to the target.
- *
- * So, the target will see drawing operations during two separate
- * stages, (ANALYZE and RENDER). During the ANALYZE phase the target
- * should not actually perform any rendering, (for example, if
- * performing output to a file, no output should be generated during
- * this stage). Instead the drawing functions simply need to return
- * CAIRO_STATUS_SUCCESS or CAIRO_INT_STATUS_UNSUPPORTED to indicate
- * whether rendering would be supported. And it should do this as
- * quickly as possible.
- *
- * NOTE: The paginated surface layer assumes that the target surface
- * is "blank" by default at the beginning of each page, without any
- * need for an explicit erasea operation, (as opposed to an image
- * surface, for example, which might have uninitialized content
- * originally). As such, it optimizes away CLEAR operations that
- * happen at the beginning of each page---the target surface will not
- * even see these operations.
- */
-cairo_private cairo_surface_t *
-_cairo_paginated_surface_create (cairo_surface_t				*target,
-				 cairo_content_t				 content,
-				 int						 width,
-				 int						 height,
-				 const cairo_paginated_surface_backend_t	*backend);
+    /* XXX: These shouldn't actually exist. We inherit this ugliness
+     * from _cairo_meta_surface_create. The width/height parameters
+     * from that function also should not exist. The fix that will
+     * allow us to remove all of these is to fix acquire_source_image
+     * to pass an interest rectangle. */
+    int width;
+    int height;
 
-cairo_private cairo_surface_t *
-_cairo_paginated_surface_get_target (cairo_surface_t *surface);
+    /* Paginated-surface specific functions for the target */
+    const cairo_paginated_surface_backend_t *backend;
 
-cairo_private cairo_bool_t
-_cairo_surface_is_paginated (cairo_surface_t *surface);
+    /* A cairo_meta_surface to record all operations. To be replayed
+     * against target, and also against image surface as necessary for
+     * fallbacks. */
+    cairo_surface_t *meta;
+
+    int page_num;
+    cairo_bool_t page_is_blank;
+
+} cairo_paginated_surface_t;
 
 #endif /* CAIRO_PAGINATED_SURFACE_H */
--- a/gfx/cairo/cairo/src/cairo-paginated-surface.c
+++ b/gfx/cairo/cairo/src/cairo-paginated-surface.c
@@ -31,55 +31,27 @@
  *
  * Contributor(s):
  *	Carl Worth <cworth@cworth.org>
  *	Keith Packard <keithp@keithp.com>
  */
 
 /* The paginated surface layer exists to provide as much code sharing
  * as possible for the various paginated surface backends in cairo
- * (PostScript, PDF, etc.). See cairo-paginated-surface-private.h for
+ * (PostScript, PDF, etc.). See cairo-paginated-private.h for
  * more details on how it works and how to use it.
  */
 
 #include "cairoint.h"
 
+#include "cairo-paginated-private.h"
 #include "cairo-paginated-surface-private.h"
 #include "cairo-meta-surface-private.h"
 #include "cairo-analysis-surface-private.h"
 
-typedef struct _cairo_paginated_surface {
-    cairo_surface_t base;
-
-    /* The target surface to hold the final result. */
-    cairo_surface_t *target;
-
-    cairo_content_t content;
-
-    /* XXX: These shouldn't actually exist. We inherit this ugliness
-     * from _cairo_meta_surface_create. The width/height parameters
-     * from that function also should not exist. The fix that will
-     * allow us to remove all of these is to fix acquire_source_image
-     * to pass an interest rectangle. */
-    int width;
-    int height;
-
-    /* Paginated-surface specific functions for the target */
-    const cairo_paginated_surface_backend_t *backend;
-
-    /* A cairo_meta_surface to record all operations. To be replayed
-     * against target, and also against image surface as necessary for
-     * fallbacks. */
-    cairo_surface_t *meta;
-
-    int page_num;
-    cairo_bool_t page_is_blank;
-
-} cairo_paginated_surface_t;
-
 const cairo_private cairo_surface_backend_t cairo_paginated_surface_backend;
 
 static cairo_int_status_t
 _cairo_paginated_surface_show_page (void *abstract_surface);
 
 static cairo_surface_t *
 _cairo_paginated_surface_create_similar (void			*abstract_surface,
 					 cairo_content_t	 content,
@@ -157,21 +129,25 @@ static cairo_status_t
 _cairo_paginated_surface_finish (void *abstract_surface)
 {
     cairo_paginated_surface_t *surface = abstract_surface;
     cairo_status_t status = CAIRO_STATUS_SUCCESS;
 
     if (surface->page_is_blank == FALSE || surface->page_num == 1)
 	status = _cairo_paginated_surface_show_page (abstract_surface);
 
-    if (status == CAIRO_STATUS_SUCCESS)
+    if (status == CAIRO_STATUS_SUCCESS) {
 	cairo_surface_finish (surface->target);
+	status = cairo_surface_status (surface->target);
+    }
 
-    if (status == CAIRO_STATUS_SUCCESS)
+    if (status == CAIRO_STATUS_SUCCESS) {
 	cairo_surface_finish (surface->meta);
+	status = cairo_surface_status (surface->meta);
+    }
 
     cairo_surface_destroy (surface->target);
 
     cairo_surface_destroy (surface->meta);
 
     return status;
 }
 
@@ -196,25 +172,32 @@ static cairo_surface_t *
 
 static cairo_status_t
 _cairo_paginated_surface_acquire_source_image (void	       *abstract_surface,
 					       cairo_image_surface_t **image_out,
 					       void		   **image_extra)
 {
     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;
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static void
@@ -230,58 +213,64 @@ static cairo_int_status_t
 {
     cairo_surface_t *analysis;
     cairo_surface_t *image;
     cairo_pattern_t *pattern;
     cairo_status_t status;
 
     analysis = _cairo_analysis_surface_create (surface->target,
 					       surface->width, surface->height);
+    if (analysis == NULL)
+	return CAIRO_STATUS_NO_MEMORY;
 
     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;
     }
 
     if (_cairo_analysis_surface_has_unsupported (analysis))
     {
 	double x_scale = surface->base.x_fallback_resolution / 72.0;
 	double y_scale = surface->base.y_fallback_resolution / 72.0;
 	cairo_matrix_t matrix;
 
 	image = _cairo_paginated_surface_create_image_surface (surface,
 							       surface->width  * x_scale,
 							       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
 _start_page (cairo_paginated_surface_t *surface)
 {
     if (! surface->backend->start_page)
 	return CAIRO_STATUS_SUCCESS;
 
@@ -293,17 +282,19 @@ static cairo_int_status_t
 {
     cairo_status_t status;
     cairo_paginated_surface_t *surface = abstract_surface;
 
     status = _start_page (surface);
     if (status)
 	return status;
 
-    _paint_page (surface);
+    status = _paint_page (surface);
+    if (status)
+	return status;
 
     surface->page_num++;
 
     /* XXX: It might make sense to add some suport here for calling
      * _cairo_surface_copy_page on the target surface. It would be an
      * optimization for the output, (so that PostScript could include
      * copypage, for example), but the interaction with image
      * fallbacks gets tricky. For now, we just let the target see a
@@ -318,19 +309,26 @@ static cairo_int_status_t
 {
     cairo_status_t status;
     cairo_paginated_surface_t *surface = abstract_surface;
 
     status = _start_page (surface);
     if (status)
 	return status;
 
-    _paint_page (surface);
+    status = _paint_page (surface);
+    if (status)
+	return status;
 
-    _cairo_surface_show_page (surface->target);
+    status = _cairo_surface_show_page (surface->target);
+    if (status)
+	return status;
+
+    if (cairo_surface_status (surface->meta))
+	return cairo_surface_status (surface->meta);
 
     cairo_surface_destroy (surface->meta);
 
     surface->meta = _cairo_meta_surface_create (surface->content,
 						surface->width, surface->height);
     if (cairo_surface_status (surface->meta))
 	return cairo_surface_status (surface->meta);
 
@@ -480,16 +478,17 @@ static cairo_int_status_t
     CAIRO_MUTEX_LOCK (scaled_font->mutex);
 
     return status;
 }
 
 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
      * want. But this currently triggers a bug somewhere (the "mask"
      * test from the test suite segfaults).
      *
      * For now, we'll create a new image surface and replay onto
      * that. It would be tempting to replay into other->image and then
@@ -500,23 +499,29 @@ static cairo_surface_t *
      */
 
 #if 0
     return _cairo_surface_snapshot (other->meta);
 #else
     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,
 							     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
 }
 
 const cairo_surface_backend_t cairo_paginated_surface_backend = {
     CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED,
     _cairo_paginated_surface_create_similar,
--- a/gfx/cairo/cairo/src/cairo-path-bounds.c
+++ b/gfx/cairo/cairo/src/cairo-path-bounds.c
@@ -46,17 +46,17 @@ typedef struct cairo_path_bounder {
 } cairo_path_bounder_t;
 
 static void
 _cairo_path_bounder_init (cairo_path_bounder_t *bounder);
 
 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
 _cairo_path_bounder_move_to (void *closure, cairo_point_t *point);
 
 static cairo_status_t
 _cairo_path_bounder_line_to (void *closure, cairo_point_t *point);
 
@@ -76,17 +76,17 @@ static void
 }
 
 static void
 _cairo_path_bounder_fini (cairo_path_bounder_t *bounder)
 {
     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) {
 	if (point->x < bounder->min_x)
 	    bounder->min_x = point->x;
 
 	if (point->y < bounder->min_y)
 	    bounder->min_y = point->y;
@@ -99,18 +99,16 @@ static cairo_status_t
     } else {
 	bounder->min_x = point->x;
 	bounder->min_y = point->y;
 	bounder->max_x = point->x;
 	bounder->max_y = point->y;
 
 	bounder->has_point = 1;
     }
-
-    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
 _cairo_path_bounder_move_to (void *closure, cairo_point_t *point)
 {
     cairo_path_bounder_t *bounder = closure;
 
     _cairo_path_bounder_add_point (bounder, point);
--- a/gfx/cairo/cairo/src/cairo-path-fill.c
+++ b/gfx/cairo/cairo/src/cairo-path-fill.c
@@ -83,47 +83,38 @@ static void
 _cairo_filler_fini (cairo_filler_t *filler)
 {
     _cairo_polygon_fini (&filler->polygon);
 }
 
 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
 _cairo_filler_curve_to (void *closure,
 			cairo_point_t *b,
 			cairo_point_t *c,
 			cairo_point_t *d)
 {
@@ -133,46 +124,40 @@ static cairo_status_t
     cairo_polygon_t *polygon = &filler->polygon;
     cairo_spline_t spline;
 
     status = _cairo_spline_init (&spline, &filler->current_point, b, c, d);
 
     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;
 
-    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);
 
     filler->current_point = *d;
 
     return status;
 }
 
 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
 _cairo_path_fixed_fill_rectangle (cairo_path_fixed_t	*path,
 				  cairo_traps_t		*traps);
 
 cairo_status_t
 _cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path,
@@ -196,17 +181,18 @@ cairo_status_t
 					  _cairo_filler_move_to,
 					  _cairo_filler_line_to,
 					  _cairo_filler_curve_to,
 					  _cairo_filler_close_path,
 					  &filler);
     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;
 
     status = _cairo_bentley_ottmann_tessellate_polygon (filler.traps,
 							&filler.polygon,
 							fill_rule);
     if (status)
 	goto BAIL;
--- a/gfx/cairo/cairo/src/cairo-path-fixed.c
+++ b/gfx/cairo/cairo/src/cairo-path-fixed.c
@@ -30,17 +30,16 @@
  *
  * The Initial Developer of the Original Code is University of Southern
  * California.
  *
  * Contributor(s):
  *	Carl D. Worth <cworth@cworth.org>
  */
 
-#include <stdlib.h>
 #include "cairoint.h"
 
 #include "cairo-path-fixed-private.h"
 
 /* private functions */
 static cairo_status_t
 _cairo_path_fixed_add (cairo_path_fixed_t *path,
 		       cairo_path_op_t 	   op,
@@ -351,18 +350,18 @@ cairo_status_t
 }
 
 static cairo_status_t
 _cairo_path_fixed_add (cairo_path_fixed_t *path,
 		       cairo_path_op_t	   op,
 		       cairo_point_t	  *points,
 		       int		   num_points)
 {
-    if (path->buf_tail->num_ops + 1 > CAIRO_PATH_BUF_SIZE ||
-	path->buf_tail->num_points + num_points > CAIRO_PATH_BUF_SIZE)
+    if ((unsigned int) path->buf_tail->num_ops + 1 > CAIRO_PATH_BUF_SIZE ||
+	(unsigned int) path->buf_tail->num_points + num_points > CAIRO_PATH_BUF_SIZE)
     {
 	cairo_path_buf_t *buf;
 
 	buf = _cairo_path_buf_create ();
 	if (buf == NULL)
 	    return CAIRO_STATUS_NO_MEMORY;
 
 	_cairo_path_fixed_add_buf (path, buf);
--- a/gfx/cairo/cairo/src/cairo-path-stroke.c
+++ b/gfx/cairo/cairo/src/cairo-path-stroke.c
@@ -62,17 +62,17 @@ typedef struct cairo_stroker {
     cairo_bool_t dashed;
     unsigned int dash_index;
     cairo_bool_t dash_on;
     cairo_bool_t dash_starts_on;
     double dash_remain;
 } 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,
 		     cairo_matrix_t		*ctm_inverse,
 		     double			 tolerance,
 		     cairo_traps_t		*traps);
 
 static void
@@ -143,42 +143,47 @@ static void
 	stroker->dash_index++;
 	if (stroker->dash_index == stroker->style->num_dashes)
 	    stroker->dash_index = 0;
 	stroker->dash_on = !stroker->dash_on;
 	stroker->dash_remain = stroker->style->dash[stroker->dash_index];
     }
 }
 
-static void
+static cairo_status_t
 _cairo_stroker_init (cairo_stroker_t		*stroker,
 		     cairo_stroke_style_t	*stroke_style,
 		     cairo_matrix_t		*ctm,
 		     cairo_matrix_t		*ctm_inverse,
 		     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;
     stroker->has_initial_sub_path = FALSE;
 
     if (stroker->style->dash)
 	_cairo_stroker_start_dash (stroker);
     else
 	stroker->dashed = FALSE;
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static void
 _cairo_stroker_fini (cairo_stroker_t *stroker)
 {
     _cairo_pen_fini (&stroker->pen);
 }
 
@@ -200,16 +205,17 @@ static int
     return _cairo_slope_clockwise (&in_slope, &out_slope);
 }
 
 static cairo_status_t
 _cairo_stroker_join (cairo_stroker_t *stroker, cairo_stroke_face_t *in, cairo_stroke_face_t *out)
 {
     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
 	&& in->ccw.x == out->ccw.x
 	&& in->ccw.y == out->ccw.y)
     {
 	return CAIRO_STATUS_SUCCESS;
     }
@@ -226,31 +232,41 @@ static cairo_status_t
     case CAIRO_LINE_JOIN_ROUND: {
 	int i;
 	int start, step, stop;
 	cairo_point_t tri[3];
 	cairo_pen_t *pen = &stroker->pen;
 
 	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;
 	tri[1] = *inpt;
 	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)
 		i = pen->num_vertices - 1;
 	    if (i >= pen->num_vertices)
 		i = 0;
 	}
 
@@ -373,27 +389,33 @@ static cairo_status_t
     case CAIRO_LINE_CAP_ROUND: {
 	int i;
 	int start, stop;
 	cairo_slope_t slope;
 	cairo_point_t tri[3];
 	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;
 
 	return _cairo_traps_tessellate_triangle (stroker->traps, tri);
     }
     case CAIRO_LINE_CAP_SQUARE: {
 	double dx, dy;
@@ -414,18 +436,24 @@ static cairo_status_t
 	ocw.y = f->cw.y + fvector.dy;
 
 	_cairo_polygon_init (&polygon);
 	_cairo_polygon_move_to (&polygon, &f->cw);
 	_cairo_polygon_line_to (&polygon, &ocw);
 	_cairo_polygon_line_to (&polygon, &occw);
 	_cairo_polygon_line_to (&polygon, &f->ccw);
 	_cairo_polygon_close (&polygon);
+	status = _cairo_polygon_status (&polygon);
 
-	status = _cairo_bentley_ottmann_tessellate_polygon (stroker->traps, &polygon, CAIRO_FILL_RULE_WINDING);
+	if (status == CAIRO_STATUS_SUCCESS) {
+	    status = _cairo_bentley_ottmann_tessellate_polygon (stroker->traps,
+								&polygon,
+								CAIRO_FILL_RULE_WINDING);
+	}
+
 	_cairo_polygon_fini (&polygon);
 
 	return status;
     }
     case CAIRO_LINE_CAP_BUTT:
     default:
 	return CAIRO_STATUS_SUCCESS;
     }
@@ -962,19 +990,21 @@ cairo_status_t
      * regions, etc.) */
     status = _cairo_path_fixed_stroke_rectilinear (path,
 						   stroke_style,
 						   ctm,
 						   traps);
     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,
 					      CAIRO_DIRECTION_FORWARD,
 					      _cairo_stroker_move_to_dashed,
 					      _cairo_stroker_line_to_dashed,
 					      _cairo_stroker_curve_to_dashed,
 					      _cairo_stroker_close_path,
--- a/gfx/cairo/cairo/src/cairo-path.c
+++ b/gfx/cairo/cairo/src/cairo-path.c
@@ -29,19 +29,20 @@
  * The Original Code is the cairo graphics library.
  *
  * The Initial Developer of the Original Code is Red Hat, Inc.
  *
  * Contributor(s):
  *	Carl D. Worth <cworth@redhat.com>
  */
 
+#include "cairoint.h"
+
 #include "cairo-path-private.h"
 #include "cairo-path-fixed-private.h"
-#include "cairo-gstate-private.h"
 
 const cairo_path_t _cairo_path_nil = { CAIRO_STATUS_NO_MEMORY, NULL, 0 };
 
 /* Closure for path interpretation. */
 typedef struct cairo_path_count {
     int count;
     double tolerance;
     cairo_point_t current_point;
@@ -130,32 +131,35 @@ static cairo_status_t
 }
 
 static int
 _cairo_path_count (cairo_path_t		*path,
 		   cairo_path_fixed_t	*path_fixed,
 		   double		 tolerance,
 		   cairo_bool_t		 flatten)
 {
+    cairo_status_t status;
     cpc_t cpc;
 
     cpc.count = 0;
     cpc.tolerance = tolerance;
     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);
+    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 -1;
 
     return cpc.count;
 }
 
 /* Closure for path interpretation. */
 typedef struct cairo_path_populate {
     cairo_path_data_t *data;
     cairo_gstate_t    *gstate;
@@ -270,17 +274,18 @@ static cairo_status_t
     int i;
 
     cairo_point_t *p0 = &cpp->current_point;
 
     status = _cairo_spline_init (&spline, p0, p1, p2, p3);
     if (status == CAIRO_INT_STATUS_DEGENERATE)
 	return CAIRO_STATUS_SUCCESS;
 
-    status = _cairo_spline_decompose (&spline, cpp->gstate->tolerance);
+    status = _cairo_spline_decompose (&spline,
+				      _cairo_gstate_get_tolerance (cpp->gstate));
     if (status)
       goto out;
 
     for (i=1; i < spline.num_points; i++)
 	_cpp_line_to (cpp, &spline.points[i]);
 
     cpp->current_point = *p3;
 
@@ -300,48 +305,57 @@ static cairo_status_t
     data->header.type = CAIRO_PATH_CLOSE_PATH;
     data->header.length = 1;
 
     cpp->data += data->header.length;
 
     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;
     cpp.gstate = gstate;
     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 *
 _cairo_path_create_in_error (cairo_status_t status)
 {
     cairo_path_t *path;
 
+    /* special case NO_MEMORY so as to avoid allocations */
+    if (status == CAIRO_STATUS_NO_MEMORY)
+	return (cairo_path_t*) &_cairo_path_nil;
+
     path = malloc (sizeof (cairo_path_t));
     if (path == NULL)
 	return (cairo_path_t*) &_cairo_path_nil;
 
     path->num_data = 0;
     path->data = NULL;
     path->status = status;
 
@@ -355,28 +369,31 @@ static cairo_path_t *
 {
     cairo_path_t *path;
 
     path = malloc (sizeof (cairo_path_t));
     if (path == NULL)
 	return (cairo_path_t*) &_cairo_path_nil;
 
     path->num_data = _cairo_path_count (path, path_fixed,
-					gstate->tolerance, flatten);
+					_cairo_gstate_get_tolerance (gstate),
+					flatten);
+    if (path->num_data <= 0) {
+	free (path);
+	return (cairo_path_t*) &_cairo_path_nil;
+    }
 
     path->data = malloc (path->num_data * sizeof (cairo_path_data_t));
     if (path->data == NULL) {
 	free (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;
 }
 
 /**
  * cairo_path_destroy:
  * @path: a path previously returned by either cairo_copy_path() or
  * cairo_copy_path_flat().
@@ -455,16 +472,17 @@ cairo_path_t *
  * is invalid, and CAIRO_STATUS_SUCCESS otherwise.
  **/
 cairo_status_t
 _cairo_path_append_to_context (const cairo_path_t	*path,
 			       cairo_t			*cr)
 {
     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];
 	switch (p->header.type) {
 	case CAIRO_PATH_MOVE_TO:
 	    if (p->header.length < 2)
 		return CAIRO_STATUS_INVALID_PATH_DATA;
 	    cairo_move_to (cr,
@@ -487,12 +505,16 @@ cairo_status_t
 	case CAIRO_PATH_CLOSE_PATH:
 	    if (p->header.length < 1)
 		return CAIRO_STATUS_INVALID_PATH_DATA;
 	    cairo_close_path (cr);
 	    break;
 	default:
 	    return CAIRO_STATUS_INVALID_PATH_DATA;
 	}
+
+	status = cairo_status (cr);
+	if (status)
+	    return status;
     }
 
     return CAIRO_STATUS_SUCCESS;
 }
--- a/gfx/cairo/cairo/src/cairo-pattern.c
+++ b/gfx/cairo/cairo/src/cairo-pattern.c
@@ -25,36 +25,46 @@
  *
  * Authors: David Reveman <davidr@novell.com>
  *	    Keith Packard <keithp@keithp.com>
  *	    Carl Worth <cworth@cworth.org>
  */
 
 #include "cairoint.h"
 
-const cairo_solid_pattern_t cairo_pattern_nil = {
+const cairo_solid_pattern_t _cairo_pattern_nil = {
     { CAIRO_PATTERN_TYPE_SOLID, 	/* type */
       CAIRO_REF_COUNT_INVALID,		/* ref_count */
       CAIRO_STATUS_NO_MEMORY,	/* status */
       { 0, 0, 0, NULL },		/* user_data */
       { 1., 0., 0., 1., 0., 0., }, /* matrix */
       CAIRO_FILTER_DEFAULT,	/* filter */
       CAIRO_EXTEND_GRADIENT_DEFAULT },	/* extend */
 };
 
-static const cairo_solid_pattern_t cairo_pattern_nil_null_pointer = {
+static const cairo_solid_pattern_t _cairo_pattern_nil_null_pointer = {
     { CAIRO_PATTERN_TYPE_SOLID, 	/* type */
       CAIRO_REF_COUNT_INVALID,		/* ref_count */
       CAIRO_STATUS_NULL_POINTER,/* status */
       { 0, 0, 0, NULL },		/* user_data */
       { 1., 0., 0., 1., 0., 0., }, /* matrix */
       CAIRO_FILTER_DEFAULT,	/* filter */
       CAIRO_EXTEND_GRADIENT_DEFAULT },	/* extend */
 };
 
+const cairo_solid_pattern_t cairo_pattern_none = {
+    { CAIRO_PATTERN_TYPE_SOLID, 	/* type */
+      CAIRO_REF_COUNT_INVALID,		/* ref_count */
+      CAIRO_STATUS_SUCCESS,		/* status */
+      { 0, 0, 0, NULL },		/* user_data */
+      { 1., 0., 0., 1., 0., 0., }, /* matrix */
+      CAIRO_FILTER_DEFAULT,	/* filter */
+      CAIRO_EXTEND_GRADIENT_DEFAULT },	/* extend */
+};
+
 /**
  * _cairo_pattern_set_error:
  * @pattern: a pattern
  * @status: a status value indicating an error, (eg. not
  * CAIRO_STATUS_SUCCESS)
  *
  * Sets pattern->status to @status and calls _cairo_error;
  *
@@ -77,33 +87,35 @@ static void
 	pattern->status = status;
 
     _cairo_error (status);
 }
 
 static void
 _cairo_pattern_init (cairo_pattern_t *pattern, cairo_pattern_type_t type)
 {
+    CAIRO_MUTEX_INITIALIZE ();
+
     pattern->type      = type;
     pattern->ref_count = 1;
     pattern->status    = CAIRO_STATUS_SUCCESS;
 
     _cairo_user_data_array_init (&pattern->user_data);
 
     if (type == CAIRO_PATTERN_TYPE_SURFACE)
 	pattern->extend = CAIRO_EXTEND_SURFACE_DEFAULT;
     else
 	pattern->extend = CAIRO_EXTEND_GRADIENT_DEFAULT;
 
     pattern->filter    = CAIRO_FILTER_DEFAULT;
 
     cairo_matrix_init_identity (&pattern->matrix);
 }
 
-static void
+stati