backing out cairo 1.4.8 due to qm-rhel02 stupidity
authorvladimir@pobox.com
Sun, 10 Jun 2007 20:53:49 -0700
changeset 2258 517bdd2a7f34183e21983d3602206cfe61cfb9b3
parent 2257 8087986aaacc89e6f42ce152a31b43f9ebff8847
child 2259 2da15aed4b42e2c3f17496820094f4a7ca69a5b8
push idunknown
push userunknown
push dateunknown
milestone1.9a6pre
backing out cairo 1.4.8 due to qm-rhel02 stupidity
gfx/cairo/README
gfx/cairo/avoid-region-extract.patch
gfx/cairo/cairo/src/Makefile.in
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-ft-font.c.orig
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-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.h
gfx/cairo/cairo/src/cairoint.h
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/fbcompose-bandaid.patch
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/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/icint.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
gfx/cairo/quartz-glyph-rounding.patch
gfx/cairo/win32-no-printer-bitblt.patch
gfx/cairo/win32-scaled-font-size.patch
--- a/gfx/cairo/README
+++ b/gfx/cairo/README
@@ -19,21 +19,13 @@ VC6 is not supported.  Please upgrade to
 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
+
 win32-scaled-font-size.patch: Add cairo_win32_font_face_create_for_logfontw_hfont,
 allow win32 scaled_fonts to rescale themselves properly to the required CTM
 and only use the font_face's hfont if we're sure it's appropriate
-
-win32-no-printer-bitblt.patch: If we need to BitBlt from a DC (to do
-fallback), only bother trying if the IS_DISPLAY flag is set -- many
-printers lie about their support for BitBlt, and we end up getting
-black instead of what we want.
-
-avoid-region-extract.patch: Bail from _cairo_traps_extract_region early
-if we have over 200 traps (arbitrary); this avoids an O(N*N) perf hit
-when the region is built up, because we call union_rect with each rect
-individually instead of building the region up in one go.
\ No newline at end of file
deleted file mode 100644
--- a/gfx/cairo/avoid-region-extract.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-diff -r 0e7cd985a7f0 gfx/cairo/cairo/src/cairo-traps.c
---- a/gfx/cairo/cairo/src/cairo-traps.c	Fri Jun 08 18:09:53 2007 -0700
-+++ b/gfx/cairo/cairo/src/cairo-traps.c	Fri Jun 08 18:10:48 2007 -0700
-@@ -599,6 +599,12 @@ _cairo_traps_extract_region (cairo_traps
- {
-     int i;
- 
-+    /* Bail early if we have lots of traps, until we fix the code
-+     * below to not use Union()
-+     */
-+    if (traps->num_traps > 200)
-+        return CAIRO_INT_STATUS_UNSUPPORTED;
-+
-     for (i = 0; i < traps->num_traps; i++)
- 	if (!(traps->traps[i].left.p1.x == traps->traps[i].left.p2.x
- 	      && traps->traps[i].right.p1.x == traps->traps[i].right.p2.x
--- a/gfx/cairo/cairo/src/Makefile.in
+++ b/gfx/cairo/cairo/src/Makefile.in
@@ -65,27 +65,26 @@ 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-face.c \
+        cairo-font.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 \
@@ -150,18 +149,17 @@ 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-display.c
+	   cairo-xlib-screen.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.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-private.h"
+#include "cairo-paginated-surface-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,18 +29,16 @@
  *
  * 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:
 
@@ -82,17 +80,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 = ARRAY_LENGTH (table);
+    int table_size = (sizeof (table) / sizeof (table[0]));
 
     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,20 +29,21 @@
  * 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 "cairo-atsui.h"
 #include "cairoint.h"
-
 #include "cairo.h"
-#include "cairo-atsui.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)
@@ -111,17 +112,18 @@ 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, ARRAY_LENGTH (styleTags),
+    err = ATSUSetAttributes(style,
+                            sizeof(styleTags) / sizeof(styleTags[0]),
                             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,
@@ -142,16 +144,24 @@ 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, 
@@ -217,23 +227,18 @@ 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;
 
-    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_scaled_font_init(&font->base, font_face, font_matrix, ctm, options,
+			    &cairo_atsui_scaled_font_backend);
 
     _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);
 
@@ -364,17 +369,18 @@ 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, ARRAY_LENGTH (styleTags),
+	err = ATSUSetAttributes(style,
+				sizeof(styleTags) / sizeof(styleTags[0]),
 				styleTags, styleSizes, styleValues);
     }
 
     return _cairo_atsui_font_create_scaled (&toy_face->base, fontID, style,
 					    font_matrix, ctm, options, font_out);
 }
 
 static void
@@ -386,33 +392,83 @@ 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;
+    OSStatus err, callback_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;
     }
 
@@ -428,25 +484,51 @@ 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;
-    
-    extents.x_bearing = metricsH.topLeft.x * xscale;
-    extents.y_bearing = -metricsH.topLeft.y * yscale;
-    extents.width = metricsH.width * xscale;
-    extents.height = metricsH.height * yscale;
+
+    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;
 
     _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;
@@ -580,63 +662,54 @@ 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);
-	status = cairo_surface_status ((cairo_surface_t *)surface);
-	if (status)
-	    return status;
-
+	if (!surface)
+	    return CAIRO_STATUS_NO_MEMORY;
 	_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:
@@ -665,19 +738,18 @@ 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);
-    status = cairo_surface_status ((cairo_surface_t *)surface);
-    if (status)
-	return status;
+    if (!surface)
+	return CAIRO_STATUS_NO_MEMORY;
 
     /* 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,17 +132,16 @@ 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;
 }
@@ -688,26 +687,23 @@ static void
 		      cairo_bo_point32_t	 point)
 {
     event->type = type;
     event->e1 = e1;
     event->e2 = e2;
     event->point = point;
 }
 
-static cairo_status_t
+static void
 _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. */
-    if (_cairo_skip_list_insert (&queue->intersection_queue, event,
-		      event->type == CAIRO_BO_EVENT_TYPE_INTERSECTION) == NULL)
-	status = CAIRO_STATUS_NO_MEMORY;
-    return status;
+    _cairo_skip_list_insert (&queue->intersection_queue, event,
+		      event->type == CAIRO_BO_EVENT_TYPE_INTERSECTION);
 }
 
 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 );
@@ -749,24 +745,26 @@ 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) + sizeof(cairo_bo_event_t*)));
-    if (events == NULL)
+    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);
 	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 = num_events;
+    event_queue->num_startstop_events = (unsigned)(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;
@@ -789,51 +787,53 @@ 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 cairo_status_t
+static void
 _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 CAIRO_STATUS_SUCCESS;
+	return;
 
     /* 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 CAIRO_STATUS_SUCCESS;
+	return;
 
     status = _cairo_bo_edge_intersect (left, right, &intersection);
     if (status == CAIRO_BO_STATUS_PARALLEL ||
 	status == CAIRO_BO_STATUS_NO_INTERSECTION)
     {
-	return CAIRO_STATUS_SUCCESS;
+	return;
     }
 
     _cairo_bo_event_init (&event,
 			  CAIRO_BO_EVENT_TYPE_INTERSECTION,
 			  left, right,
 			  intersection);
 
-    return _cairo_bo_event_queue_insert (event_queue, &event);
+    _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,28 +843,26 @@ 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 cairo_status_t
+static void
 _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)
@@ -873,18 +871,16 @@ static cairo_status_t
 	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;
 
@@ -1056,16 +1052,17 @@ 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. */
@@ -1097,36 +1094,35 @@ 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)
 	{
-	    _cairo_traps_add_trap_from_points (bo_traps->traps,
-					       fixed_top,
-					       fixed_bot,
-					       left_top, left_bot,
-					       right_top, right_bot);
+	    status = _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 _cairo_traps_status (bo_traps->traps);
+    return status;
 }
 
 /* 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
@@ -1253,30 +1249,27 @@ 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_t status = CAIRO_STATUS_SUCCESS;
     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;
 
-    status = _cairo_bo_event_queue_init (&event_queue, edges, num_edges);
-    if (status)
-	return status;
-
+    _cairo_bo_event_queue_init (&event_queue, edges, num_edges);
     _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)
@@ -1298,33 +1291,27 @@ 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;
 
-	    status = _cairo_bo_sweep_line_insert (&sweep_line, edge);
-	    if (status)
-		goto unwind;
+	    _cairo_bo_sweep_line_insert (&sweep_line, edge);
 	    /* Cache the insert position for use in pass 2.
 	    event->e2 = Sortlist::prev (sweep_line, edge);
 	    */
 
 	    left = edge->prev;
 	    right = edge->next;
 
-	    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, left, edge);
 
-	    status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, edge, right);
-	    if (status)
-		goto unwind;
+	    _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, edge, right);
 
 #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:
@@ -1334,19 +1321,17 @@ 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;
 
-	    status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, right);
-	    if (status)
-		goto unwind;
+	    _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, right);
 
 #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:
@@ -1364,25 +1349,21 @@ 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 */
 
-	    status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue,
+	    _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue,
 								       left, edge2);
-	    if (status)
-		goto unwind;
 
-	    status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue,
+	    _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;
 	}
@@ -1416,35 +1397,30 @@ 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;
 
-    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;
-    }
+    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);
@@ -1514,18 +1490,17 @@ 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);
 
-    if (edges != stack_edges)
-	free (edges);
+    free (edges);
 
     return status;
 }
 
 #if 0
 static cairo_bool_t
 edges_have_an_intersection_quadratic (cairo_bo_edge_t	*edges,
 				      int		 num_edges)
@@ -1791,17 +1766,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 < ARRAY_LENGTH (tests); i++) {
+    for (i = 0; i < sizeof (tests) / sizeof (tests[0]); 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
 
-#include "cairo-types-private.h"
+typedef struct _cairo_cache cairo_cache_t;
 
 /**
  * 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,16 +33,27 @@
  * 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,44 +32,39 @@
  * 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 {
@@ -82,16 +77,23 @@ 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;
@@ -101,33 +103,24 @@ 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;
-    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;
+    cff_charset_t        charset;
+    int                  charset_offset;
 
     /* Subsetted Font Data */
     char                *subset_font_name;
     cairo_array_t        charstrings_subset_index;
     cairo_array_t        strings_subset_index;
-    int                 *fdselect_subset;
-    unsigned int         num_subset_fontdicts;
-    int                 *fd_subset_map;
-    int                 *private_dict_offset;
+    cairo_array_t        charset_subset;
     cairo_array_t        output;
 
     /* Subset Metrics */
     int                 *widths;
     int                  x_min, y_min, x_max, y_max;
     int                  ascent, descent;
 
 } cairo_cff_font_t;
@@ -349,16 +342,17 @@ 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)
@@ -375,19 +369,17 @@ 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,
-                       const unsigned char *object,
-                       unsigned int length)
+cff_index_append_copy (cairo_array_t *index, unsigned char *object , 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;
@@ -491,31 +483,16 @@ 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);
@@ -581,65 +558,49 @@ 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_write_operator (cff_dict_operator_t *op, dict_write_info_t *write_info)
+_cairo_dict_collect (void *entry, void *closure)
 {
+    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)
 {
@@ -680,163 +641,42 @@ 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 (private_dict, ptr, size);
-    operand = cff_dict_get_operands (private_dict, LOCAL_SUB_OP, &i);
+    cff_dict_read (font->private_dict, ptr, size);
+    operand = cff_dict_get_operands (font->private_dict, LOCAL_SUB_OP, &i);
     if (operand) {
         decode_integer (operand, &offset);
         p = ptr + offset;
-        cff_index_read (local_sub_index, &p, font->data_end);
+        cff_index_read (&font->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 (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;
+        cff_dict_set_operands (font->private_dict, LOCAL_SUB_OP, buf, end_buf - buf);
     }
 
     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;
@@ -845,66 +685,53 @@ 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);
-    status = cff_dict_read (font->top_dict, element->data, element->length);
-    if (status)
-        goto fail;
+    cff_dict_read (font->top_dict, element->data, element->length);
 
-    if (cff_dict_get_operands (font->top_dict, ROS_OP, &size) != NULL)
-        font->is_cid = TRUE;
-    else
-        font->is_cid = FALSE;
+    /* CID fonts are NYI */
+    if (cff_dict_get_operands (font->top_dict, ROS_OP, &size) != NULL) {
+        status = CAIRO_INT_STATUS_UNSUPPORTED;
+        goto fail;
+    }
 
     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);
 
-    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, PRIVATE_OP, &size);
+    operand = decode_integer (operand, &size);
+    decode_integer (operand, &offset);
+    cairo_cff_font_read_private_dict (font, font->data + offset, size);
 
-        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);
+    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;
     }
 
     /* 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, 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, ENCODING_OP, buf, end_buf - buf);
     cff_dict_set_operands (font->top_dict, CHARSET_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);
+    /* 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);
 
 fail:
     cff_index_fini (&index);
 
     return status;
 }
 
 static cairo_int_status_t
@@ -914,25 +741,159 @@ 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;
 
@@ -940,44 +901,16 @@ 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;
@@ -1029,156 +962,148 @@ 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 cairo_status_t
-cairo_cff_font_subset_fontdict (cairo_cff_font_t  *font)
+static uint16_t
+cff_sid_from_gid (const cff_charset_t *charset, int gid)
 {
-    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;
-
-    font->private_dict_offset = calloc (font->num_fontdicts, sizeof (int));
-    if (font->private_dict_offset == NULL)
-        return CAIRO_STATUS_NO_MEMORY;
+    const uint16_t *sids;
+    const unsigned char *p;
+    int prev_glyph;
 
-    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];
+    if (charset->is_builtin) {
+        if (gid - 1 < charset->length / 2)
+	    return charset->sids[gid - 1];
     }
-
-    free (reverse_map);
-
-    return CAIRO_STATUS_SUCCESS;
+    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;
 }
 
 static cairo_status_t
-cairo_cff_font_create_cid_fontdict (cairo_cff_font_t *font)
+cairo_cff_font_subset_charset (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;
 
-    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;
+    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->fd_private_dict[font->fd_subset_map[i]]);
-            if (status)
-                return status;
-        }
-    } else {
-        status = cairo_cff_font_subset_dict_strings (font, font->private_dict);
+	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_array_append(&font->charset_subset, &new_sid);
+	if (status)
+	    return status;
     }
-
-    return status;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
 cairo_cff_font_subset_font (cairo_cff_font_t  *font)
 {
     cairo_status_t status;
 
-    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);
+    /* TODO: subset subroutines */
 
     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
@@ -1282,255 +1207,114 @@ 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_fdselect (cairo_cff_font_t  *font)
+cairo_cff_font_write_encoding (cairo_cff_font_t  *font)
 {
-    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;
+    unsigned char buf[10];
 
-        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);
+    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;
 
-        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;
+    return _cairo_array_append_multiple (&font->output, buf, 4);
 }
 
 static cairo_status_t
 cairo_cff_font_write_charset (cairo_cff_font_t  *font)
 {
-    unsigned char byte;
-    uint16_t word;
+    unsigned char format = 0;
+    unsigned int i;
     cairo_status_t status;
 
     cairo_cff_font_set_topdict_operator_to_cur_pos (font, CHARSET_OP);
-    status = _cairo_array_grow_by (&font->output, 5);
+    status = _cairo_array_append (&font->output, &format);
     if (status)
-        return status;
-
-    byte = 2;
-    status = _cairo_array_append (&font->output, &byte);
-    assert (status == CAIRO_STATUS_SUCCESS);
+	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);
-
+    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;
+    }
     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_cid_fontdict (cairo_cff_font_t *font)
+cairo_cff_font_write_private_dict_and_local_sub (cairo_cff_font_t *font)
 {
-    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 offset, private_dict_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 */
-    font->private_dict_offset[dict_num] = _cairo_array_num_elements (&font->output);
-    status = cff_dict_write (private_dict, &font->output);
+    private_dict_offset = _cairo_array_num_elements (&font->output);
+    status = cff_dict_write (font->private_dict, &font->output);
     if (status)
         return status;
-    size = _cairo_array_num_elements (&font->output) - font->private_dict_offset[dict_num];
+    size = _cairo_array_num_elements (&font->output) - private_dict_offset;
     /* private entry has two operands - size and offset */
     buf_end = encode_integer_max (buf, size);
-    buf_end = encode_integer_max (buf_end, font->private_dict_offset[dict_num]);
-    offset = cff_dict_get_location (parent_dict, PRIVATE_OP, &size);
+    buf_end = encode_integer_max (buf_end, private_dict_offset);
+    offset = cff_dict_get_location (font->top_dict, PRIVATE_OP, &size);
     assert (offset > 0);
     p = _cairo_array_index (&font->output, offset);
     memcpy (p, buf, buf_end - buf);
 
-    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) {
+    if (_cairo_array_num_elements (&font->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) - font->private_dict_offset[dict_num];
+        offset = _cairo_array_num_elements (&font->output) - private_dict_offset;
         buf_end = encode_integer_max (buf, offset);
-        offset = cff_dict_get_location (private_dict, LOCAL_SUB_OP, &size);
+        offset = cff_dict_get_location (font->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 (local_sub_index, &font->output);
+        status = cff_index_write (&font->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_fdselect,
+    cairo_cff_font_write_encoding,
     cairo_cff_font_write_charset,
     cairo_cff_font_write_charstrings,
-    cairo_cff_font_write_cid_fontdict,
-    cairo_cff_font_write_cid_private_dict_and_local_sub,
+    cairo_cff_font_write_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;
 
@@ -1584,17 +1368,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 = 1; i < font->scaled_font_subset->num_glyphs; i++) {
+    for (i = 0; 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);
@@ -1766,23 +1550,17 @@ 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);
-    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;
+    _cairo_array_init (&font->charset_subset, sizeof(uint16_t));
 
     free (name);
     *font_return = font;
 
     return CAIRO_STATUS_SUCCESS;
 
 fail7:
     free (font->data);
@@ -1799,67 +1577,29 @@ 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);
-
-    /* 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);
-
+    _cairo_array_fini (&font->charset_subset);
     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)
 {
@@ -1917,220 +1657,8 @@ 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 const cairo_private cairo_rectangle_list_t _cairo_rectangles_nil;
+extern cairo_private const 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,37 +67,39 @@ 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;
-    cairo_bool_t has_region;
+    pixman_region16_t *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 cairo_status_t
+cairo_private void
+_cairo_clip_fini (cairo_clip_t *clip);
+
+cairo_private void
 _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other);
 
-cairo_private cairo_status_t
+cairo_private void
 _cairo_clip_init_deep_copy (cairo_clip_t    *clip,
                             cairo_clip_t    *other,
                             cairo_surface_t *target);
 
-cairo_private void
+cairo_private cairo_status_t
 _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,72 +56,74 @@ 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;
 
-    pixman_region_init (&clip->region);
-    clip->has_region = FALSE;
+    clip->region = NULL;
 
     clip->path = NULL;
 }
 
-cairo_status_t
+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_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;
 
-    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;
+    if (other->region == NULL) {
+	clip->region = other->region;
     } else {
-        clip->has_region = FALSE;
+	clip->region = pixman_region_create ();
+	pixman_region_copy (clip->region, other->region);
     }
 
     clip->path = _cairo_clip_path_reference (other->path);
-    
-    return CAIRO_STATUS_SUCCESS;
 }
 
-void
+cairo_status_t
 _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->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;
-    }
+    if (clip->region)
+	pixman_region_destroy (clip->region);
+    clip->region = NULL;
 
     _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;
@@ -163,79 +165,78 @@ cairo_status_t
         cairo_status_t status;
         
         status = _cairo_clip_path_intersect_to_rectangle (clip->path,
                                                           rectangle);
         if (status)
             return status;
     }
 
-    if (clip->has_region) {
+    if (clip->region) {
+	pixman_region16_t *intersection;
 	cairo_status_t status = CAIRO_STATUS_SUCCESS;
-	pixman_region16_t intersection;
+	pixman_region_status_t pixman_status;
 
-	pixman_region_init_rect (&intersection,
-                                  rectangle->x, rectangle->y,
-                                  rectangle->width, rectangle->height);
+	intersection = _cairo_region_create_from_rectangle (rectangle);
+	if (intersection == NULL)
+	    return CAIRO_STATUS_NO_MEMORY;
 
-	if (PIXMAN_REGION_STATUS_SUCCESS !=
-            pixman_region_intersect (&intersection, &clip->region,
-                                     &intersection)) {
+	pixman_status = pixman_region_intersect (intersection,
+					  clip->region,
+					  intersection);
+	if (pixman_status == PIXMAN_REGION_STATUS_SUCCESS)
+	    _cairo_region_extents_rectangle (intersection, rectangle);
+	else
 	    status = CAIRO_STATUS_NO_MEMORY;
-	} else {
-            _cairo_region_extents_rectangle (&intersection, rectangle);
-        }
+
+	pixman_region_destroy (intersection);
 
-        pixman_region_fini (&intersection);
-
-        if (status)
-            return status;
+	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->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->region)
+	pixman_region_intersect (region, clip->region, region);
 
     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;
 
-        pixman_region_init_rect (&clip_rect,
-                                  clip->surface_rect.x, clip->surface_rect.y,
-                                  clip->surface_rect.width, clip->surface_rect.height);
+	clip_rect = _cairo_region_create_from_rectangle (&clip->surface_rect);
+	if (clip_rect == NULL)
+	    return CAIRO_STATUS_NO_MEMORY;
 
-        if (PIXMAN_REGION_STATUS_SUCCESS !=
-            pixman_region_intersect (region, &clip_rect, region))
+	pixman_status = pixman_region_intersect (region,
+						 clip_rect,
+						 region);
+	if (pixman_status != PIXMAN_REGION_STATUS_SUCCESS)
 	    status = CAIRO_STATUS_NO_MEMORY;
 
-        pixman_region_fini (&clip_rect);
+	pixman_region_destroy (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
@@ -323,57 +324,52 @@ 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_int_status_t
+static cairo_status_t
 _cairo_clip_intersect_region (cairo_clip_t    *clip,
 			      cairo_traps_t   *traps,
 			      cairo_surface_t *target)
 {
-    pixman_region16_t region;
-    cairo_int_status_t status;
+    pixman_region16_t *region;
+    cairo_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;
 
-    status = CAIRO_STATUS_SUCCESS;
+    if (region == NULL)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    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;
+    status = CAIRO_STATUS_SUCCESS;
+    if (clip->region == NULL) {
+	clip->region = region;
     } else {
-	pixman_region16_t intersection;
-        pixman_region_init (&intersection);
+	pixman_region16_t *intersection = pixman_region_create();
 
-	if (PIXMAN_REGION_STATUS_SUCCESS !=
-		pixman_region_intersect (&intersection,
-		                         &clip->region,
-		                         &region) ||
-	    PIXMAN_REGION_STATUS_SUCCESS !=
-		pixman_region_copy (&clip->region, &intersection))
+	if (pixman_region_intersect (intersection,
+				     clip->region, region)
+	    == PIXMAN_REGION_STATUS_SUCCESS) {
+	    pixman_region_destroy (clip->region);
+	    clip->region = intersection;
+	} else {
 	    status = CAIRO_STATUS_NO_MEMORY;
-
-        pixman_region_fini (&intersection);
+	}
+	pixman_region_destroy (region);
     }
 
     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,
@@ -401,26 +397,24 @@ 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,
-						   NULL);
+						   CAIRO_COLOR_WHITE);
     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_CONTENT_COLOR);
+    _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE);
 
     status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_IN,
 						  &pattern.base,
 						  surface,
 						  antialias,
 						  0, 0,
 						  0, 0,
 						  surface_rect.width,
@@ -510,18 +504,18 @@ cairo_status_t
     return status;
 }
 
 void
 _cairo_clip_translate (cairo_clip_t  *clip,
                        cairo_fixed_t  tx,
                        cairo_fixed_t  ty)
 {
-    if (clip->has_region) {
-        pixman_region_translate (&clip->region,
+    if (clip->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);
     }
@@ -550,60 +544,46 @@ static void
 
     _cairo_clip_intersect_path (clip,
                                 &clip_path->path,
                                 clip_path->fill_rule,
                                 clip_path->tolerance,
                                 clip_path->antialias);
 }
 
-cairo_status_t
+void
 _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->has_region) {
-            if (pixman_region_copy (&clip->region, &other->region) !=
-		    PIXMAN_REGION_STATUS_SUCCESS)
-		goto BAIL;
-	    clip->has_region = TRUE;
+        if (other->region) {
+            clip->region = pixman_region_create ();
+            pixman_region_copy (clip->region, other->region);
         }
 
         if (other->surface) {
-            if (_cairo_surface_clone_similar (target, other->surface,
+            _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) !=
-		    CAIRO_STATUS_SUCCESS)
-		goto BAIL;
+					  &clip->surface);
             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
@@ -628,46 +608,42 @@ 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->has_region ? pixman_region_num_rects (&clip->region) : 1;
+    n_boxes = clip->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->has_region) {
+    if (clip->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;
-        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)) {
+        _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)) {
             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,18 +155,8 @@ 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,16 +54,18 @@
  * 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,31 +114,29 @@ 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) {
-	free (stream);
-	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
-    }
+    if (deflateInit (&stream->zlib_stream, Z_DEFAULT_COMPRESSION) != Z_OK)
+	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,27 +30,31 @@
  * 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 "cairoint.h"
-
-#include "cairo-directfb.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <assert.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.
@@ -328,17 +332,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 == (cairo_format_t) -1) {
+    if (surface->format == -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;
@@ -1506,27 +1510,16 @@ 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*/ 
@@ -1566,19 +1559,17 @@ 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 */
-	_cairo_directfb_is_similar,
-	NULL /* reset */
+        NULL /* snapshot */
 };
 
 
 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,18 +36,16 @@
 
 #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,30 +48,28 @@
 #endif
 
 #ifndef cairo_public
 # define cairo_public
 #endif
 
 #define CAIRO_VERSION_MAJOR 1
 #define CAIRO_VERSION_MINOR 4
-#define CAIRO_VERSION_MICRO 8
+#define CAIRO_VERSION_MICRO 2
 
-#define CAIRO_VERSION_STRING "1.4.8"
+#define CAIRO_VERSION_STRING "1.4.2"
 
 @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@
 
deleted file mode 100644
--- a/gfx/cairo/cairo/src/cairo-font-face.c
+++ /dev/null
@@ -1,519 +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)
-{
-    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,41 +108,37 @@ 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;
+    cairo_font_options_t *options = malloc (sizeof (cairo_font_options_t));
 
-    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:
@@ -151,38 +147,37 @@ 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;
@@ -240,17 +235,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:
@@ -276,17 +271,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:
@@ -312,17 +307,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:
@@ -348,17 +343,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:
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/cairo/src/cairo-font.c
@@ -0,0 +1,516 @@
+/* -*- 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,16 +21,18 @@
  */
 #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,19 +14,18 @@
  * 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 "cairoint.h"
-
+#include <stdlib.h>
+#include <string.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,22 +32,20 @@
  *
  * Contributor(s):
  *      Graydon Hoare <graydon@redhat.com>
  *	Owen Taylor <otaylor@redhat.com>
  *      Keith Packard <keithp@keithp.com>
  *      Carl Worth <cworth@cworth.org>
  */
 
-#include "cairoint.h"
+#include <float.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
@@ -59,19 +57,21 @@
 #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;
@@ -151,16 +151,18 @@ 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;
@@ -254,17 +256,16 @@ 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
@@ -327,26 +328,24 @@ 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) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	if (filename_copy == NULL)
 	    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
@@ -371,17 +370,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;
@@ -415,18 +414,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_ft_unscaled_font_map_unlock ();
 	_cairo_unscaled_font_reference (&unscaled->base);
-	_cairo_ft_unscaled_font_map_unlock ();
 	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;
 
@@ -552,17 +551,16 @@ 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;
@@ -611,32 +609,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 cairo_status_t
+static void
 _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 CAIRO_STATUS_SUCCESS;
+	return;
 
     unscaled->have_scale = TRUE;
     unscaled->current_scale = *scale;
 
     _compute_transform (&sf, scale);
 
     unscaled->x_scale = sf.x_scale;
     unscaled->y_scale = sf.y_scale;
@@ -655,33 +653,37 @@ static cairo_status_t
     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);
-	if (error) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+#endif /* MOZCAIRO */
+	assert (error == 0);
     } 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.;
@@ -700,23 +702,18 @@ static cairo_status_t
 				  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);
-	if (error) {
-	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+	assert (error == 0);
     }
-
-    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 },
@@ -751,20 +748,18 @@ 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) {
-		_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    if (!data)
 		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;
@@ -801,20 +796,18 @@ 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) {
-		    _cairo_error (CAIRO_STATUS_NO_MEMORY);
+		if (!data)
 		    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;
@@ -843,22 +836,16 @@ 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:
@@ -913,19 +900,16 @@ 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) {
@@ -1046,25 +1030,23 @@ 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;
     }
 
@@ -1092,20 +1074,18 @@ 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) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+    if (error)
 	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.
@@ -1193,43 +1173,34 @@ 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
      */
-    status = _cairo_surface_fill_rectangle (image, CAIRO_OPERATOR_CLEAR,
-				            CAIRO_COLOR_TRANSPARENT,
-					    0, 0,
-					    width, height);
-    if (status) {
-	cairo_surface_destroy (image);
-	return status;
-    }
+    _cairo_surface_fill_rectangle (image, CAIRO_OPERATOR_CLEAR,
+				   CAIRO_COLOR_TRANSPARENT,
+				   0, 0,
+				   width, height);
 
     /* 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);
 
-    status = _cairo_surface_composite (CAIRO_OPERATOR_OVER,
-			               &pattern.base, NULL, image,
-				       0, 0, 0, 0, 0, 0,
-				       width,
-				       height);
+    _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);
 
@@ -1469,58 +1440,43 @@ 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);
 
-    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;
-    }
+    _cairo_scaled_font_init (&scaled_font->base,
+			     font_face,
+			     font_matrix, ctm, options,
+			     &cairo_ft_scaled_font_backend);
 
-    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;
-    }
-
+    _cairo_ft_unscaled_font_set_scale (unscaled,
+				       &scaled_font->base.scale);
 
     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) {
@@ -1588,20 +1544,18 @@ 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) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+    if (!pattern)
 	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:
@@ -1661,17 +1615,16 @@ 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;
@@ -1686,71 +1639,65 @@ 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);
 
-    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;
+    _cairo_path_fixed_close_path (path);
+    _cairo_path_fixed_move_to (path, x, y);
 
     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);
 
-    if (_cairo_path_fixed_line_to (path, x, y) != CAIRO_STATUS_SUCCESS)
-	return 1;
+    _cairo_path_fixed_line_to (path, x, y);
 
     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;
 
-    if (_cairo_path_fixed_get_current_point (path, &x0, &y0) !=
-	    CAIRO_STATUS_SUCCESS)
-	return 1;
+    _cairo_path_fixed_get_current_point (path, &x0, &y0);
 
     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);
 
-    if (_cairo_path_fixed_curve_to (path,
-				    x1, y1,
-				    x2, y2,
-				    x3, y3) != CAIRO_STATUS_SUCCESS)
-	return 1;
+    _cairo_path_fixed_curve_to (path,
+				x1, y1,
+				x2, y2,
+				x3, y3);
 
     return 0;
 }
 
 static int
 _cubic_to (FT_Vector *control1, FT_Vector *control2,
 	   FT_Vector *to, void *closure)
 {
@@ -1763,21 +1710,20 @@ 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);
 
-    if (_cairo_path_fixed_curve_to (path,
-				    x0, y0,
-				    x1, y1,
-				    x2, y2) != CAIRO_STATUS_SUCCESS)
-	return 1;
+    _cairo_path_fixed_curve_to (path,
+				x0, y0,
+				x1, y1,
+				x2, y2);
 
     return 0;
 }
 
 static cairo_status_t
 _decompose_glyph_outline (FT_Face		  face,
 			  cairo_font_options_t	 *options,
 			  cairo_path_fixed_t	**pathp)
@@ -1792,37 +1738,28 @@ 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);
-    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;
-    }
+    FT_Outline_Decompose (&glyph->outline, &outline_funcs, path);
 
-    status = _cairo_path_fixed_close_path (path);
-    if (status) {
-	_cairo_path_fixed_destroy (path);
-	return status;
-    }
+    _cairo_path_fixed_close_path (path);
 
     *pathp = path;
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 /*
  * Translate glyph to match its metrics.
@@ -1856,26 +1793,24 @@ 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_t status = CAIRO_STATUS_SUCCESS;
 
     face = _cairo_ft_unscaled_font_lock_face (unscaled);
     if (!face)
 	return CAIRO_STATUS_NO_MEMORY;
 
-    status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
-				                &scaled_font->base.scale);
-    if (status)
-	goto FAIL;
+    _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
+				       &scaled_font->base.scale);
 
     /* 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;
 
@@ -2011,22 +1946,19 @@ 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);
     }
@@ -2040,17 +1972,16 @@ 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);
@@ -2250,60 +2181,49 @@ 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 {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+    else
 	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, **prev_font_face;
+    cairo_ft_font_face_t *font_face;
 
     /* Looked for an existing matching font face */
-    for (font_face = unscaled->faces, prev_font_face = &unscaled->faces;
+    for (font_face = unscaled->faces;
 	 font_face;
-	 prev_font_face = &font_face->next, 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))
-	{
-	    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;
-	}
+	    return cairo_font_face_reference (&font_face->base);
     }
 
     /* No match found, create a new one */
     font_face = malloc (sizeof (cairo_ft_font_face_t));
-    if (!font_face) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+    if (!font_face)
 	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;
@@ -2451,18 +2371,20 @@ 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
+    else {
+	_cairo_error (CAIRO_STATUS_NO_MEMORY);
 	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
@@ -2502,20 +2424,22 @@ 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
+    } else {
+	_cairo_error (CAIRO_STATUS_NO_MEMORY);
 	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()).
@@ -2543,34 +2467,28 @@ 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;
     }
 
-    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;
-    }
+    _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
+				       &scaled_font->base.scale);
 
     /* 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);
deleted file mode 100644
--- a/gfx/cairo/cairo/src/cairo-ft-font.c.orig
+++ /dev/null
@@ -1,2624 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2000 Keith Packard
- * 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):
- *      Graydon Hoare <graydon@redhat.com>
- *	Owen Taylor <otaylor@redhat.com>
- *      Keith Packard <keithp@keithp.com>
- *      Carl Worth <cworth@cworth.org>
- */
-
-#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
-#if HAVE_FT_GLYPHSLOT_EMBOLDEN
-#include FT_SYNTHESIS_H
-#endif
-
-#define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0))
-#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
-
-/*
- * 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];
-} cairo_ft_font_transform_t;
-
-/*
- * We create an object that corresponds to a single font on the disk;
- * (identified by a filename/id pair) these are shared between all
- * fonts using that file.  For cairo_ft_font_face_create_for_ft_face(), we
- * just create a one-off version with a permanent face value.
- */
-
-typedef struct _cairo_ft_font_face cairo_ft_font_face_t;
-
-struct _cairo_ft_unscaled_font {
-    cairo_unscaled_font_t base;
-
-    cairo_bool_t from_face; /* from cairo_ft_font_face_create_for_ft_face()? */
-    FT_Face face;	    /* provided or cached face */
-
-    /* only set if from_face is false */
-    char *filename;
-    int id;
-
-    /* We temporarily scale the unscaled font as needed */
-    cairo_bool_t have_scale;
-    cairo_matrix_t current_scale;
-    double x_scale;		/* Extracted X scale factor */
-    double y_scale;             /* Extracted Y scale factor */
-    cairo_bool_t have_shape;	/* true if the current scale has a non-scale component*/
-    cairo_matrix_t current_shape;
-    FT_Matrix Current_Shape;
-
-    cairo_mutex_t mutex;
-    int lock_count;
-
-    cairo_ft_font_face_t *faces;	/* Linked list of faces for this font */
-};
-
-static int
-_cairo_ft_unscaled_font_keys_equal (const void *key_a,
-				    const void *key_b);
-
-static void
-_cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled);
-
-typedef enum _cairo_ft_extra_flags {
-    CAIRO_FT_OPTIONS_HINT_METRICS = (1 << 0),
-    CAIRO_FT_OPTIONS_EMBOLDEN = (1 << 1)
-} cairo_ft_extra_flags_t;
-
-typedef struct _cairo_ft_options {
-    cairo_font_options_t    base;
-    int			    load_flags;	 /* flags for FT_Load_Glyph */
-    cairo_ft_extra_flags_t  extra_flags; /* other flags that affect results */
-} cairo_ft_options_t;
-
-struct _cairo_ft_font_face {
-    cairo_font_face_t base;
-    cairo_ft_unscaled_font_t *unscaled;
-    cairo_ft_options_t ft_options;
-    cairo_ft_font_face_t *next;
-};
-
-static const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend;
-
-/*
- * We maintain a hash table to map file/id => cairo_ft_unscaled_font_t.
- * The hash table itself isn't limited in size. However, we limit the
- * number of FT_Face objects we keep around; when we've exceeded that
- * limit and need to create a new FT_Face, we dump the FT_Face from a
- * random cairo_ft_unscaled_font_t which has an unlocked FT_Face, (if
- * there are any).
- */
-
-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;
-
-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;
-
-	font_map->num_open_faces--;
-    }
-}
-
-static void
-_cairo_ft_unscaled_font_map_create (void)
-{
-    cairo_ft_unscaled_font_map_t *font_map;
-
-    /* This function is only intended to be called from
-     * _cairo_ft_unscaled_font_map_lock. So we'll crash if we can
-     * detect some other call path. */
-    assert (cairo_ft_unscaled_font_map == NULL);
-
-    font_map = malloc (sizeof (cairo_ft_unscaled_font_map_t));
-    if (font_map == NULL)
-	goto FAIL;
-
-    font_map->hash_table =
-	_cairo_hash_table_create (_cairo_ft_unscaled_font_keys_equal);
-
-    if (font_map->hash_table == NULL)
-	goto FAIL;
-
-    if (FT_Init_FreeType (&font_map->ft_library))
-	goto FAIL;
-
-    font_map->num_open_faces = 0;
-
-    cairo_ft_unscaled_font_map = font_map;
-    return;
-
-FAIL:
-    if (font_map) {
-	if (font_map->hash_table)
-	    _cairo_hash_table_destroy (font_map->hash_table);
-	free (font_map);
-    }
-    cairo_ft_unscaled_font_map = NULL;
-}
-
-static void
-_cairo_ft_unscaled_font_map_destroy (void)
-{
-    cairo_ft_unscaled_font_t *unscaled;
-    cairo_ft_unscaled_font_map_t *font_map;
-
-    CAIRO_MUTEX_LOCK (_cairo_ft_unscaled_font_map_mutex);
-
-    if (cairo_ft_unscaled_font_map) {
-	font_map = cairo_ft_unscaled_font_map;
-
-	/* This is rather inefficient, but destroying the hash table
-	 * is something we only do during debugging, (during
-	 * cairo_debug_reset_static_data), when efficiency is not
-	 * relevant. */
-        while (1) {
-	    unscaled = _cairo_hash_table_random_entry (font_map->hash_table,
-						       NULL);
-	    if (unscaled == NULL)
-		break;
-	    _cairo_hash_table_remove (font_map->hash_table,
-				      &unscaled->base.hash_entry);
-
-	    _font_map_release_face_lock_held (font_map, unscaled);
-	    _cairo_ft_unscaled_font_fini (unscaled);
-	    free (unscaled);
-	}
-
-	assert (font_map->num_open_faces == 0);
-
-	FT_Done_FreeType (font_map->ft_library);
-
-	_cairo_hash_table_destroy (font_map->hash_table);
-
-	free (font_map);
-
-	cairo_ft_unscaled_font_map = NULL;
-    }
-
-    CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex);
-}
-
-static cairo_ft_unscaled_font_map_t *
-_cairo_ft_unscaled_font_map_lock (void)
-{
-    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
-_cairo_ft_unscaled_font_map_unlock (void)
-{
-    CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex);
-}
-
-static void
-_cairo_ft_unscaled_font_init_key (cairo_ft_unscaled_font_t *key,
-				  char			   *filename,
-				  int			    id)
-{
-    unsigned long hash;
-
-    key->filename = filename;
-    key->id = id;
-
-    /* 1607 is just an arbitrary prime. */
-    hash = _cairo_hash_string (filename);
-    hash += ((unsigned long) id) * 1607;
-
-    key->base.hash_entry.hash = hash;
-}
-
-/**
- * _cairo_ft_unscaled_font_init:
- *
- * Initialize a cairo_ft_unscaled_font_t.
- *
- * There are two basic flavors of cairo_ft_unscaled_font_t, one
- * created from an FT_Face and the other created from a filename/id
- * pair. These two flavors are identified as from_face and !from_face.
- *
- * To initialize a from_face font, pass filename==NULL, id=0 and the
- * desired face.
- *
- * To initialize a !from_face font, pass the filename/id as desired
- * and face==NULL.
- *
- * Note that the code handles these two flavors in very distinct
- * ways. For example there is a hash_table mapping
- * filename/id->cairo_unscaled_font_t in the !from_face case, but no
- * parallel in the from_face case, (where the calling code would have
- * to do its own mapping to ensure similar sharing).
- **/
-static cairo_status_t
-_cairo_ft_unscaled_font_init (cairo_ft_unscaled_font_t *unscaled,
-			      const char	       *filename,
-			      int			id,
-			      FT_Face			face)
-{
-    _cairo_unscaled_font_init (&unscaled->base,
-			       &cairo_ft_unscaled_font_backend);
-
-    if (face) {
-	unscaled->from_face = TRUE;
-	unscaled->face = face;
-	unscaled->filename = NULL;
-	unscaled->id = 0;
-    } else {
-	char *filename_copy;
-
-	unscaled->from_face = FALSE;
-	unscaled->face = NULL;
-
-	filename_copy = strdup (filename);
-	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);
-    unscaled->lock_count = 0;
-
-    unscaled->faces = NULL;
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-cairo_bool_t
-_cairo_unscaled_font_is_ft (cairo_unscaled_font_t *unscaled_font)
-{
-    return unscaled_font->backend == &cairo_ft_unscaled_font_backend;
-}
-
-/**
- * _cairo_ft_unscaled_font_fini:
- *
- * Free all data associated with a cairo_ft_unscaled_font_t.
- *
- * CAUTION: The unscaled->face field must be NULL before calling this
- * function. This is because the cairo_ft_unscaled_font_map keeps a
- * count of these faces (font_map->num_open_faces) so it maintains the
- * unscaled->face field while it has its lock held. See
- * _font_map_release_face_lock_held().
- **/
-static void
-_cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled)
-{
-    assert (unscaled->face == NULL);
-
-    if (unscaled->filename) {
-	free (unscaled->filename);
-	unscaled->filename = NULL;
-    }
-
-    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;
-
-    return (strcmp (unscaled_a->filename, unscaled_b->filename) == 0 &&
-	    unscaled_a->id == unscaled_b->id);
-}
-
-/* Finds or creates a cairo_ft_unscaled_font for the filename/id from
- * pattern.  Returns a new reference to the unscaled font.
- */
-static cairo_ft_unscaled_font_t *
-_cairo_ft_unscaled_font_create_for_pattern (FcPattern *pattern)
-{
-    cairo_ft_unscaled_font_t key, *unscaled;
-    cairo_ft_unscaled_font_map_t *font_map;
-    cairo_status_t status;
-    FcChar8 *fc_filename;
-    char *filename;
-    int id;
-
-    if (FcPatternGetString (pattern, FC_FILE, 0, &fc_filename) != FcResultMatch)
-	goto UNWIND;
-    filename = (char *) fc_filename;
-
-    if (FcPatternGetInteger (pattern, FC_INDEX, 0, &id) != FcResultMatch)
-	goto UNWIND;
-
-    font_map = _cairo_ft_unscaled_font_map_lock ();
-    if (font_map == NULL)
-	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 ();
-	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;
-
-    status = _cairo_ft_unscaled_font_init (unscaled, filename, id, NULL);
-    if (status)
-	goto UNWIND_UNSCALED_MALLOC;
-
-    status = _cairo_hash_table_insert (font_map->hash_table,
-				       &unscaled->base.hash_entry);
-    if (status)
-	goto UNWIND_UNSCALED_FONT_INIT;
-
-    _cairo_ft_unscaled_font_map_unlock ();
-
-    return unscaled;
-
-UNWIND_UNSCALED_FONT_INIT:
-    _cairo_ft_unscaled_font_fini (unscaled);
-UNWIND_UNSCALED_MALLOC:
-    free (unscaled);
-UNWIND_FONT_MAP_LOCK:
-    _cairo_ft_unscaled_font_map_unlock ();
-UNWIND:
-    return NULL;
-}
-
-static cairo_ft_unscaled_font_t *
-_cairo_ft_unscaled_font_create_from_face (FT_Face face)
-{
-    cairo_status_t status;
-    cairo_ft_unscaled_font_t *unscaled;
-
-    unscaled = malloc (sizeof (cairo_ft_unscaled_font_t));
-    if (unscaled == NULL)
-	return NULL;
-
-    status = _cairo_ft_unscaled_font_init (unscaled, NULL, 0, face);
-    if (status) {
-	free (unscaled);
-	return NULL;
-    }
-
-    return unscaled;
-}
-
-static void
-_cairo_ft_unscaled_font_destroy (void *abstract_font)
-{
-    cairo_ft_unscaled_font_t *unscaled  = abstract_font;
-
-    if (unscaled == NULL)
-	return;
-
-    if (unscaled->from_face) {
-	/* See comments in _ft_font_face_destroy about the "zombie" state
-	 * for a _ft_font_face.
-	 */
-	if (unscaled->faces && !unscaled->faces->unscaled)
-	    cairo_font_face_destroy (&unscaled->faces->base);
-    } else {
-	cairo_ft_unscaled_font_map_t *font_map;
-
-	font_map = _cairo_ft_unscaled_font_map_lock ();
-	/* All created objects must have been mapped in the font map. */
-	assert (font_map != NULL);
-
-	_cairo_hash_table_remove (font_map->hash_table,
-				  &unscaled->base.hash_entry);
-
-	_font_map_release_face_lock_held (font_map, unscaled);
-	_cairo_ft_unscaled_font_fini (unscaled);
-
-	_cairo_ft_unscaled_font_map_unlock ();
-    }
-}
-
-static cairo_bool_t
-_has_unlocked_face (void *entry)
-{
-    cairo_ft_unscaled_font_t *unscaled = entry;
-
-    return (unscaled->lock_count == 0 && unscaled->face);
-}
-
-/* Ensures that an unscaled font has a face object. If we exceed
- * MAX_OPEN_FACES, try to close some.
- *
- * This differs from _cairo_ft_scaled_font_lock_face in that it doesn't
- * set the scale on the face, but just returns it at the last scale.
- */
-FT_Face
-_cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled)
-{
-    cairo_ft_unscaled_font_map_t *font_map;
-    FT_Face face = NULL;
-
-    CAIRO_MUTEX_LOCK (unscaled->mutex);
-    unscaled->lock_count++;
-
-    if (unscaled->face)
-	return unscaled->face;
-
-    /* If this unscaled font was created from an FT_Face then we just
-     * returned it above. */
-    assert (!unscaled->from_face);
-
-    font_map = _cairo_ft_unscaled_font_map_lock ();
-    {
-	assert (font_map != NULL);
-
-	while (font_map->num_open_faces >= MAX_OPEN_FACES)
-	{
-	    cairo_ft_unscaled_font_t *entry;
-
-	    entry = _cairo_hash_table_random_entry (font_map->hash_table,
-						    _has_unlocked_face);
-	    if (entry == NULL)
-		break;
-
-	    _font_map_release_face_lock_held (font_map, entry);
-	}
-    }
-    _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;
-}
-slim_hidden_def (cairo_ft_scaled_font_lock_face);
-
-/* Unlock unscaled font locked with _cairo_ft_unscaled_font_lock_face
- */
-void
-_cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled)
-{
-    assert (unscaled->lock_count > 0);
-
-    unscaled->lock_count--;
-
-    CAIRO_MUTEX_UNLOCK (unscaled->mutex);
-}
-slim_hidden_def (cairo_ft_scaled_font_unlock_face);
-
-static void
-_compute_transform (cairo_ft_font_transform_t *sf,
-		    cairo_matrix_t      *scale)
-{
-    cairo_matrix_t normalized = *scale;
-    double tx, ty;
-
-    /* The font matrix has x and y "scale" components which we extract and
-     * use as character scale values. These influence the way freetype
-     * chooses hints, as well as selecting different bitmaps in
-     * hand-rendered fonts. We also copy the normalized matrix to
-     * freetype's transformation.
-     */
-
-    _cairo_matrix_compute_scale_factors (&normalized,
-					 &sf->x_scale, &sf->y_scale,
-					 /* XXX */ 1);
-
-    if (sf->x_scale != 0 && sf->y_scale != 0) {
-	cairo_matrix_scale (&normalized, 1.0 / sf->x_scale, 1.0 / sf->y_scale);
-
-	_cairo_matrix_get_affine (&normalized,
-				  &sf->shape[0][0], &sf->shape[0][1],
-				  &sf->shape[1][0], &sf->shape[1][1],
-				  &tx, &ty);
-    } else {
-	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 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 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;
-
-    mat.xx = DOUBLE_TO_16_16(sf.shape[0][0]);
-    mat.yx = - DOUBLE_TO_16_16(sf.shape[0][1]);
-    mat.xy = - DOUBLE_TO_16_16(sf.shape[1][0]);
-    mat.yy = DOUBLE_TO_16_16(sf.shape[1][1]);
-
-    unscaled->have_shape = (mat.xx != 0x10000 ||
-			    mat.yx != 0x00000 ||
-			    mat.xy != 0x00000 ||
-			    mat.yy != 0x10000);
-
-    unscaled->Current_Shape = mat;
-    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) {
-	error = FT_Set_Char_Size (unscaled->face,
-				  sf.x_scale * 64.0,
-				  sf.y_scale * 64.0,
-				  0, 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.;
-#else
-	    double size = unscaled->face->available_sizes[i].height;
-#endif
-	    double distance = fabs (size - sf.y_scale);
-
-	    if (distance <= min_distance) {
-		min_distance = distance;
-		best_i = i;
-	    }
-	}
-#if HAVE_FT_BITMAP_SIZE_Y_PPEM
-	error = FT_Set_Char_Size (unscaled->face,
-				  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);
-	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 },
-    /* green */
-    {    65536*1/4, 65536*2/4, 65537*1/4 },
-    /* blue */
-    {    65538*1/7,65538*2/7,65538*4/7 },
-#endif
-    {    65538*9/13,65538*3/13,65538*1/13 },
-    /* green */
-    {    65538*1/6, 65538*4/6, 65538*1/6 },
-    /* blue */
-    {    65538*1/13,65538*3/13,65538*9/13 },
-};
-
-/* Fills in val->image with an image surface created from @bitmap
- */
-static cairo_status_t
-_get_bitmap_surface (FT_Bitmap		     *bitmap,
-		     cairo_bool_t	      own_buffer,
-		     cairo_font_options_t    *font_options,
-		     cairo_image_surface_t  **surface)
-{
-    int width, height, stride;
-    unsigned char *data;
-    int format = CAIRO_FORMAT_A8;
-    cairo_bool_t subpixel = FALSE;
-
-    width = bitmap->width;
-    height = bitmap->rows;
-
-    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) {
-		_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;
-		dest = data;
-		for (i = height; i; i--) {
-		    memcpy (dest, source, bitmap->pitch);
-		    memset (dest + bitmap->pitch, '\0', stride - bitmap->pitch);
-
-		    source += bitmap->pitch;
-		    dest += stride;
-		}
-	    }
-	}
-
-#ifndef WORDS_BIGENDIAN
-	{
-	    unsigned char   *d = data;
-	    int		count = stride * height;
-
-	    while (count--) {
-		*d = CAIRO_BITSWAP8 (*d);
-		d++;
-	    }
-	}
-#endif
-	format = CAIRO_FORMAT_A1;
-	break;
-
-    case FT_PIXEL_MODE_LCD:
-    case FT_PIXEL_MODE_LCD_V:
-    case FT_PIXEL_MODE_GRAY:
-	switch (font_options->antialias) {
-	case CAIRO_ANTIALIAS_DEFAULT:
-	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) {
-		    _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;
-	    unsigned int    red, green, blue;
-	    int		    rf, gf, bf;
-	    int		    s;
-	    int		    o, os;
-	    unsigned char   *data_rgba;
-	    unsigned int    width_rgba, stride_rgba;
-	    int		    vmul = 1;
-	    int		    hmul = 1;
-
-	    switch (font_options->subpixel_order) {
-	    case CAIRO_SUBPIXEL_ORDER_DEFAULT:
-	    case CAIRO_SUBPIXEL_ORDER_RGB:
-	    case CAIRO_SUBPIXEL_ORDER_BGR:
-	    default:
-		width /= 3;
-		hmul = 3;
-		break;
-	    case CAIRO_SUBPIXEL_ORDER_VRGB:
-	    case CAIRO_SUBPIXEL_ORDER_VBGR:
-		vmul = 3;
-		height /= 3;
-		break;
-	    }
-	    /*
-	     * 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:
-		rf = 0;
-		gf = 1;
-		bf = 2;
-		break;
-	    case CAIRO_SUBPIXEL_ORDER_VBGR:
-		os = stride;
-	    case CAIRO_SUBPIXEL_ORDER_BGR:
-		bf = 0;
-		gf = 1;
-		rf = 2;
-		break;
-	    }
-	    in_line = bitmap->buffer;
-	    out_line = data_rgba;
-	    for (y = 0; y < height; y++)
-	    {
-		in = in_line;
-		out = (unsigned int *) out_line;
-		in_line += stride * vmul;
-		out_line += stride_rgba;
-		for (x = 0; x < width * hmul; x += hmul)
-		{
-		    red = green = blue = 0;
-		    o = 0;
-		    for (s = 0; s < 3; s++)
-		    {
-			red += filters[rf][s]*in[x+o];
-			green += filters[gf][s]*in[x+o];
-			blue += filters[bf][s]*in[x+o];
-			o += os;
-		    }
-		    red = red / 65536;
-		    green = green / 65536;
-		    blue = blue / 65536;
-		    *out++ = (green << 24) | (red << 16) | (green << 8) | blue;
-		}
-	    }
-
-	    /* Images here are stored in native format. The
-	     * backend must convert to its own format as needed
-	     */
-
-	    if (own_buffer)
-		free (bitmap->buffer);
-	    data = data_rgba;
-	    stride = stride_rgba;
-	    format = CAIRO_FORMAT_ARGB32;
-	    subpixel = TRUE;
-	    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) {
-	free (data);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
-
-    if (subpixel)
-	pixman_image_set_component_alpha ((*surface)->pixman_image, TRUE);
-
-    _cairo_image_surface_assume_ownership_of_data ((*surface));
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-/* Converts an outline FT_GlyphSlot into an image
- *
- * This could go through _render_glyph_bitmap as well, letting
- * FreeType convert the outline to a bitmap, but doing it ourselves
- * has two minor advantages: first, we save a copy of the bitmap
- * buffer: we can directly use the buffer that FreeType renders
- * into.
- *
- * Second, it may help when we add support for subpixel
- * rendering: the Xft code does it this way. (Keith thinks that
- * it may also be possible to get the subpixel rendering with
- * FT_Render_Glyph: something worth looking into in more detail
- * when we add subpixel support. If so, we may want to eliminate
- * this version of the code path entirely.
- */
-static cairo_status_t
-_render_glyph_outline (FT_Face                    face,
-		       cairo_font_options_t	 *font_options,
-		       cairo_image_surface_t	**surface)
-{
-    FT_GlyphSlot glyphslot = face->glyph;
-    FT_Outline *outline = &glyphslot->outline;
-    FT_Bitmap bitmap;
-    FT_BBox cbox;
-    FT_Matrix matrix;
-    int hmul = 1;
-    int vmul = 1;
-    unsigned int width, height, stride;
-    cairo_bool_t subpixel = FALSE;
-    cairo_status_t status;
-
-    FT_Outline_Get_CBox (outline, &cbox);
-
-    cbox.xMin &= -64;
-    cbox.yMin &= -64;
-    cbox.xMax = (cbox.xMax + 63) & -64;
-    cbox.yMax = (cbox.yMax + 63) & -64;
-
-    width = (unsigned int) ((cbox.xMax - cbox.xMin) >> 6);
-    height = (unsigned int) ((cbox.yMax - cbox.yMin) >> 6);
-    stride = (width * hmul + 3) & ~3;
-
-    if (width * height == 0) {
-	cairo_format_t format;
-	/* Looks like fb handles zero-sized images just fine */
-	switch (font_options->antialias) {
-	case CAIRO_ANTIALIAS_NONE:
-	    format = CAIRO_FORMAT_A1;
-	    break;
-	case CAIRO_ANTIALIAS_SUBPIXEL:
-	    format= CAIRO_FORMAT_ARGB32;
-	    break;
-	case CAIRO_ANTIALIAS_DEFAULT:
-	case CAIRO_ANTIALIAS_GRAY:
-	default:
-	    format = CAIRO_FORMAT_A8;
-	    break;
-	}
-
-	(*surface) = (cairo_image_surface_t *)
-	    cairo_image_surface_create_for_data (NULL, format, 0, 0, 0);
-	if ((*surface)->base.status)
-	    return CAIRO_STATUS_NO_MEMORY;
-    } else  {
-
-	matrix.xx = matrix.yy = 0x10000L;
-	matrix.xy = matrix.yx = 0;
-
-	switch (font_options->antialias) {
-	case CAIRO_ANTIALIAS_NONE:
-	    bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
-	    bitmap.num_grays  = 1;
-	    stride = ((width + 31) & -32) >> 3;
-	    break;
-	case CAIRO_ANTIALIAS_DEFAULT:
-	case CAIRO_ANTIALIAS_GRAY:
-	    bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
-	    bitmap.num_grays  = 256;
-	    stride = (width + 3) & -4;
-	    break;
-	case CAIRO_ANTIALIAS_SUBPIXEL:
-	    switch (font_options->subpixel_order) {
-	    case CAIRO_SUBPIXEL_ORDER_RGB:
-	    case CAIRO_SUBPIXEL_ORDER_BGR:
-	    case CAIRO_SUBPIXEL_ORDER_DEFAULT:
-	    default:
-		matrix.xx *= 3;
-		hmul = 3;
-		subpixel = TRUE;
-		break;
-	    case CAIRO_SUBPIXEL_ORDER_VRGB:
-	    case CAIRO_SUBPIXEL_ORDER_VBGR:
-		matrix.yy *= 3;
-		vmul = 3;
-		subpixel = TRUE;
-		break;
-	    }
-	    FT_Outline_Transform (outline, &matrix);
-
-	    bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
-	    bitmap.num_grays  = 256;
-	    stride = (width * hmul + 3) & -4;
-	}
-
-	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;
-    }
-
-    /*
-     * Note: the font's coordinate system is upside down from ours, so the
-     * Y coordinate of the control box needs to be negated.
-     */
-    cairo_surface_set_device_offset (&(*surface)->base,
-				     floor ((double) cbox.xMin / 64.0),
-				     floor (-(double) cbox.yMax / 64.0));
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-/* Converts a bitmap (or other) FT_GlyphSlot into an image */
-static cairo_status_t
-_render_glyph_bitmap (FT_Face		      face,
-		      cairo_font_options_t   *font_options,
-		      cairo_image_surface_t **surface)
-{
-    FT_GlyphSlot glyphslot = face->glyph;
-    cairo_status_t status = CAIRO_STATUS_SUCCESS;
-    FT_Error error;
-
-    /* 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) {
-	_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.
-     */
-    cairo_surface_set_device_offset (&(*surface)->base,
-				     glyphslot->bitmap_left,
-				     -glyphslot->bitmap_top);
-
-    return status;
-}
-
-static cairo_status_t
-_transform_glyph_bitmap (cairo_matrix_t         * shape,
-			 cairo_image_surface_t ** surface)
-{
-    cairo_matrix_t original_to_transformed;
-    cairo_matrix_t transformed_to_original;
-    cairo_image_surface_t *old_image;
-    cairo_surface_t *image;
-    double x[4], y[4];
-    double origin_x, origin_y;
-    int origin_width, origin_height;
-    int i;
-    int x_min, y_min, x_max, y_max;
-    int width, height;
-    cairo_status_t status;
-    cairo_surface_pattern_t pattern;
-
-    /* We want to compute a transform that takes the origin
-     * (device_x_offset, device_y_offset) to 0,0, then applies
-     * the "shape" portion of the font transform
-     */
-    original_to_transformed = *shape;
-    
-    cairo_surface_get_device_offset (&(*surface)->base, &origin_x, &origin_y);
-    origin_width = cairo_image_surface_get_width (&(*surface)->base);
-    origin_height = cairo_image_surface_get_height (&(*surface)->base);
-
-    cairo_matrix_translate (&original_to_transformed,
-			    origin_x, origin_y);
-
-    /* Find the bounding box of the original bitmap under that
-     * transform
-     */
-    x[0] = 0;            y[0] = 0;
-    x[1] = origin_width; y[1] = 0;
-    x[2] = origin_width; y[2] = origin_height;
-    x[3] = 0;            y[3] = origin_height;
-
-    for (i = 0; i < 4; i++)
-      cairo_matrix_transform_point (&original_to_transformed,
-				    &x[i], &y[i]);
-
-    x_min = floor (x[0]);   y_min = floor (y[0]);
-    x_max =  ceil (x[0]);   y_max =  ceil (y[0]);
-
-    for (i = 1; i < 4; i++) {
-	if (x[i] < x_min)
-	    x_min = floor (x[i]);
-	if (x[i] > x_max)
-	    x_max = ceil (x[i]);
-	if (y[i] < y_min)
-	    y_min = floor (y[i]);
-	if (y[i] > y_max)
-	    y_max = ceil (y[i]);
-    }
-
-    /* Adjust the transform so that the bounding box starts at 0,0 ...
-     * this gives our final transform from original bitmap to transformed
-     * bitmap.
-     */
-    original_to_transformed.x0 -= x_min;
-    original_to_transformed.y0 -= y_min;
-
-    /* Create the transformed bitmap
-     */
-    width = x_max - x_min;
-    height = y_max - y_min;
-
-    transformed_to_original = original_to_transformed;
-    status = cairo_matrix_invert (&transformed_to_original);
-    if (status)
-	return status;
-
-    /* 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
-     */
-    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);
-
-    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);
-
-    old_image = (*surface);
-    (*surface) = (cairo_image_surface_t *)image;
-    cairo_surface_destroy (&old_image->base);
-
-    cairo_surface_set_device_offset (&(*surface)->base,
-				     - _cairo_lround (origin_x),
-				     - _cairo_lround (origin_y));
-    return status;
-}
-
-static const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend = {
-    _cairo_ft_unscaled_font_destroy,
-#if 0
-    _cairo_ft_unscaled_font_create_glyph
-#endif
-};
-
-/* cairo_ft_scaled_font_t */
-
-typedef struct _cairo_ft_scaled_font {
-    cairo_scaled_font_t base;
-    cairo_ft_unscaled_font_t *unscaled;
-    cairo_ft_options_t ft_options;
-} cairo_ft_scaled_font_t;
-
-const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend;
-
-/* The load flags passed to FT_Load_Glyph control aspects like hinting and
- * antialiasing. Here we compute them from the fields of a FcPattern.
- */
-static void
-_get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret)
-{
-    FcBool antialias, vertical_layout, hinting, autohint, bitmap, embolden;
-    cairo_ft_options_t ft_options;
-    int rgba;
-#ifdef FC_HINT_STYLE
-    int hintstyle;
-#endif
-
-    _cairo_font_options_init_default (&ft_options.base);
-    ft_options.load_flags = FT_LOAD_DEFAULT;
-    ft_options.extra_flags = 0;
-
-#ifndef FC_EMBEDDED_BITMAP
-#define FC_EMBEDDED_BITMAP "embeddedbitmap"
-#endif
-
-    /* Check whether to force use of embedded bitmaps */
-    if (FcPatternGetBool (pattern,
-			  FC_EMBEDDED_BITMAP, 0, &bitmap) != FcResultMatch)
-	bitmap = FcFalse;
-
-    /* disable antialiasing if requested */
-    if (FcPatternGetBool (pattern,
-			  FC_ANTIALIAS, 0, &antialias) != FcResultMatch)
-	antialias = FcTrue;
-    
-    if (antialias) {
-	cairo_subpixel_order_t subpixel_order;
-
-	if (!bitmap)
-	    ft_options.load_flags |= FT_LOAD_NO_BITMAP;
-	
-	/* disable hinting if requested */
-	if (FcPatternGetBool (pattern,
-			      FC_HINTING, 0, &hinting) != FcResultMatch)
-	    hinting = FcTrue;
-
-	if (FcPatternGetInteger (pattern,
-				 FC_RGBA, 0, &rgba) != FcResultMatch)
-	    rgba = FC_RGBA_UNKNOWN;
-
-	switch (rgba) {
-	case FC_RGBA_RGB:
-	    subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB;
-	    break;
-	case FC_RGBA_BGR:
-	    subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR;
-	    break;
-	case FC_RGBA_VRGB:
-	    subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB;
-	    break;
-	case FC_RGBA_VBGR:
-	    subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR;
-	    break;
-	case FC_RGBA_UNKNOWN:
-	case FC_RGBA_NONE:
-	default:
-	    subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
-	    break;
-	}
-
-	if (subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT) {
-	    ft_options.base.subpixel_order = subpixel_order;
-	    ft_options.base.antialias = CAIRO_ANTIALIAS_SUBPIXEL;
-	}
-
-#ifdef FC_HINT_STYLE    
-	if (FcPatternGetInteger (pattern, 
-				 FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch)
-	    hintstyle = FC_HINT_FULL;
-
-	if (!hinting)
-	    hintstyle = FC_HINT_NONE;
-
-	switch (hintstyle) {
-	case FC_HINT_NONE:
-	    ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE;	
-	    break;
-	case FC_HINT_SLIGHT:
-	    ft_options.base.hint_style = CAIRO_HINT_STYLE_SLIGHT;
-	    break;
-	case FC_HINT_MEDIUM:
-	default:
-	    ft_options.base.hint_style = CAIRO_HINT_STYLE_MEDIUM;
-	    break;
-	case FC_HINT_FULL:
-	    ft_options.base.hint_style = CAIRO_HINT_STYLE_FULL;
-	    break;
-	}
-#else /* !FC_HINT_STYLE */
-	if (!hinting) {
-	    ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE;
-	}
-#endif /* FC_FHINT_STYLE */
-    } else {
-	ft_options.base.antialias = CAIRO_ANTIALIAS_NONE;
-    }
-
-    /* force autohinting if requested */
-    if (FcPatternGetBool (pattern,
-			  FC_AUTOHINT, 0, &autohint) != FcResultMatch)
-	autohint = FcFalse;
-
-    if (autohint)
-	ft_options.load_flags |= FT_LOAD_FORCE_AUTOHINT;
-
-    if (FcPatternGetBool (pattern,
-			  FC_VERTICAL_LAYOUT, 0, &vertical_layout) != FcResultMatch)
-	vertical_layout = FcFalse;
-
-    if (vertical_layout)
-	ft_options.load_flags |= FT_LOAD_VERTICAL_LAYOUT;
-    
-#ifndef FC_EMBOLDEN
-#define FC_EMBOLDEN "embolden"
-#endif
-    if (FcPatternGetBool (pattern,
-			  FC_EMBOLDEN, 0, &embolden) != FcResultMatch)
-	embolden = FcFalse;
-    
-    if (embolden)
-	ft_options.extra_flags |= CAIRO_FT_OPTIONS_EMBOLDEN;
-
-    *ret = ft_options;
-}
-
-static void
-_cairo_ft_options_merge (cairo_ft_options_t *options,
-			 cairo_ft_options_t *other)
-{
-    int load_flags = other->load_flags;
-    int load_target = FT_LOAD_TARGET_NORMAL;
-
-    /* clear load target mode */
-    load_flags &= ~(FT_LOAD_TARGET_(FT_LOAD_TARGET_MODE(other->load_flags)));
-    
-    if (load_flags & FT_LOAD_NO_HINTING)
-	other->base.hint_style = CAIRO_HINT_STYLE_NONE;
-
-    if (other->base.antialias == CAIRO_ANTIALIAS_NONE ||
-	options->base.antialias == CAIRO_ANTIALIAS_NONE) {
-	options->base.antialias = CAIRO_ANTIALIAS_NONE;
-	options->base.subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
-    }
-
-    if (other->base.antialias == CAIRO_ANTIALIAS_SUBPIXEL &&
-	(options->base.antialias == CAIRO_ANTIALIAS_DEFAULT || 
-	 options->base.antialias == CAIRO_ANTIALIAS_GRAY)) {
-	options->base.antialias = CAIRO_ANTIALIAS_SUBPIXEL;
-	options->base.subpixel_order = other->base.subpixel_order;
-    }
-
-    if (options->base.hint_style == CAIRO_HINT_STYLE_DEFAULT)
-	options->base.hint_style = other->base.hint_style;
-
-    if (other->base.hint_style == CAIRO_HINT_STYLE_NONE)
-	options->base.hint_style = CAIRO_HINT_STYLE_NONE;
-
-    if (options->base.antialias == CAIRO_ANTIALIAS_NONE) {
-	if (options->base.hint_style == CAIRO_HINT_STYLE_NONE)
-	    load_flags |= FT_LOAD_NO_HINTING;
-	else
-	    load_target = FT_LOAD_TARGET_MONO;
-	load_flags |= FT_LOAD_MONOCHROME;
-    } else {
-	switch (options->base.hint_style) {
-	case CAIRO_HINT_STYLE_NONE:
-	    load_flags |= FT_LOAD_NO_HINTING;
-	    break;
-	case CAIRO_HINT_STYLE_SLIGHT:
-	    load_target = FT_LOAD_TARGET_LIGHT;
-	    break;
-	case CAIRO_HINT_STYLE_MEDIUM:
-	    break;
-	case CAIRO_HINT_STYLE_FULL:
-	case CAIRO_HINT_STYLE_DEFAULT:
-	    if (options->base.antialias == CAIRO_ANTIALIAS_SUBPIXEL) {
-		switch (options->base.subpixel_order) {
-		case CAIRO_SUBPIXEL_ORDER_DEFAULT:
-		case CAIRO_SUBPIXEL_ORDER_RGB:
-		case CAIRO_SUBPIXEL_ORDER_BGR:
-		    load_target |= FT_LOAD_TARGET_LCD;
-		    break;
-		case CAIRO_SUBPIXEL_ORDER_VRGB:
-		case CAIRO_SUBPIXEL_ORDER_VBGR:
-		    load_target |= FT_LOAD_TARGET_LCD_V;
-		break;
-		}
-	    }
-	    break;
-	}
-    }
-
-    options->load_flags = load_flags | load_target;
-    options->extra_flags = other->extra_flags;
-}
-
-static cairo_scaled_font_t *
-_cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t	 *unscaled,
-			      cairo_font_face_t		 *font_face,
-			      const cairo_matrix_t	 *font_matrix,
-			      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);
-
-    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) {
-	double x_factor, y_factor;
-
-	if (unscaled->x_scale == 0)
-	    x_factor = 0;
-	else
-	    x_factor = 1 / unscaled->x_scale;
-
-	if (unscaled->y_scale == 0)
-	    y_factor = 0;
-	else
-	    y_factor = 1 / unscaled->y_scale;
-
-	fs_metrics.ascent =        DOUBLE_FROM_26_6(metrics->ascender) * y_factor;
-	fs_metrics.descent =       DOUBLE_FROM_26_6(- metrics->descender) * y_factor;
-	fs_metrics.height =        DOUBLE_FROM_26_6(metrics->height) * y_factor;
-	if (!_cairo_ft_scaled_font_is_vertical (&scaled_font->base)) {
-	    fs_metrics.max_x_advance = DOUBLE_FROM_26_6(metrics->max_advance) * x_factor;
-	    fs_metrics.max_y_advance = 0;
-	} else {
-	    fs_metrics.max_x_advance = 0;
-	    fs_metrics.max_y_advance = DOUBLE_FROM_26_6(metrics->max_advance) * y_factor;
-	}
-    } else {
-	double scale = face->units_per_EM;
-
-	fs_metrics.ascent =        face->ascender / scale;
-	fs_metrics.descent =       - face->descender / scale;
-	fs_metrics.height =        face->height / scale;
-	if (!_cairo_ft_scaled_font_is_vertical (&scaled_font->base)) {
-	    fs_metrics.max_x_advance = face->max_advance_width / scale;
-	    fs_metrics.max_y_advance = 0;
-	} else {
-	    fs_metrics.max_x_advance = 0;
-	    fs_metrics.max_y_advance = face->max_advance_height / scale;
-	}
-    }
-
-    _cairo_scaled_font_set_metrics (&scaled_font->base, &fs_metrics);
-
-    _cairo_ft_unscaled_font_unlock_face (unscaled);
-
-    return &scaled_font->base;
-}
-
-cairo_bool_t
-_cairo_scaled_font_is_ft (cairo_scaled_font_t *scaled_font)
-{
-    return scaled_font->backend == &cairo_ft_scaled_font_backend;
-}
-
-static cairo_status_t
-_cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t	      *toy_face,
-				  const cairo_matrix_t	      *font_matrix,
-				  const cairo_matrix_t	      *ctm,
-				  const cairo_font_options_t  *font_options,
-				  cairo_scaled_font_t	     **font)
-{
-    FcPattern *pattern, *resolved;
-    cairo_ft_unscaled_font_t *unscaled;
-    cairo_scaled_font_t *new_font = NULL;
-    FcResult result;
-    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) {
-	_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:
-        fcweight = FC_WEIGHT_MEDIUM;
-        break;
-    }
-
-    switch (toy_face->slant)
-    {
-    case CAIRO_FONT_SLANT_ITALIC:
-        fcslant = FC_SLANT_ITALIC;
-        break;
-    case CAIRO_FONT_SLANT_OBLIQUE:
-	fcslant = FC_SLANT_OBLIQUE;
-        break;
-    case CAIRO_FONT_SLANT_NORMAL:
-    default:
-        fcslant = FC_SLANT_ROMAN;
-        break;
-    }
-
-    if (!FcPatternAddString (pattern, FC_FAMILY, family))
-	goto FREE_PATTERN;
-    if (!FcPatternAddInteger (pattern, FC_SLANT, fcslant))
-	goto FREE_PATTERN;
-    if (!FcPatternAddInteger (pattern, FC_WEIGHT, fcweight))
-	goto FREE_PATTERN;
-
-    cairo_matrix_multiply (&scale, font_matrix, ctm);
-    _compute_transform (&sf, &scale);
-
-    FcPatternAddInteger (pattern, FC_PIXEL_SIZE, sf.y_scale);
-
-    FcConfigSubstitute (NULL, pattern, FcMatchPattern);
-    cairo_ft_font_options_substitute (font_options, pattern);
-    FcDefaultSubstitute (pattern);
-
-    resolved = FcFontMatch (NULL, pattern, &result);
-    if (!resolved)
-	goto FREE_PATTERN;
-
-    unscaled = _cairo_ft_unscaled_font_create_for_pattern (resolved);
-    if (!unscaled)
-	goto FREE_RESOLVED;
-
-    _get_pattern_ft_options (resolved, &ft_options);
-
-    new_font = _cairo_ft_scaled_font_create (unscaled,
-					     &toy_face->base,
-					     font_matrix, ctm,
-					     font_options, ft_options);
-
-    _cairo_unscaled_font_destroy (&unscaled->base);
-
- FREE_RESOLVED:
-    FcPatternDestroy (resolved);
-
- 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;
-
-    if (scaled_font == NULL)
-        return;
-
-    _cairo_unscaled_font_destroy (&scaled_font->unscaled->base);
-}
-
-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);
-
-    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);
-
-    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;
-
-    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);
-
-    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)
-{
-    cairo_path_fixed_t *path = closure;
-    cairo_fixed_t x0, y0;
-    cairo_fixed_t x1, y1;
-    cairo_fixed_t x2, y2;
-
-    x0 = _cairo_fixed_from_26_6 (control1->x);
-    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);
-
-    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)
-{
-    static const FT_Outline_Funcs outline_funcs = {
-	(FT_Outline_MoveToFunc)_move_to,
-	(FT_Outline_LineToFunc)_line_to,
-	(FT_Outline_ConicToFunc)_conic_to,
-	(FT_Outline_CubicToFunc)_cubic_to,
-	0, /* shift */
-	0, /* delta */
-    };
-    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);
-    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.
- */
-static void
-_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (void        *abstract_font,
-						    FT_GlyphSlot glyph)
-{
-    cairo_ft_scaled_font_t *scaled_font = abstract_font;
-    FT_Vector vector;
-
-    vector.x = glyph->metrics.vertBearingX - glyph->metrics.horiBearingX;
-    vector.y = -glyph->metrics.vertBearingY - glyph->metrics.horiBearingY;
-
-    if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
-	FT_Vector_Transform (&vector, &scaled_font->unscaled->Current_Shape);
-	FT_Outline_Translate(&glyph->outline, vector.x, vector.y);
-    } else if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {
-	glyph->bitmap_left += vector.x / 64;
-	glyph->bitmap_top  += vector.y / 64;
-    }
-}
-
-static cairo_int_status_t
-_cairo_ft_scaled_glyph_init (void			*abstract_font,
-			     cairo_scaled_glyph_t	*scaled_glyph,
-			     cairo_scaled_glyph_info_t	 info)
-{
-    cairo_text_extents_t    fs_metrics;
-    cairo_ft_scaled_font_t *scaled_font = abstract_font;
-    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;
-
-    face = _cairo_ft_unscaled_font_lock_face (unscaled);
-    if (!face)
-	return CAIRO_STATUS_NO_MEMORY;
-
-    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;
-
-    /*
-     * Don't pass FT_LOAD_VERTICAL_LAYOUT to FT_Load_Glyph here as
-     * suggested by freetype people.
-     */
-    if (load_flags & FT_LOAD_VERTICAL_LAYOUT) {
-	load_flags &= ~FT_LOAD_VERTICAL_LAYOUT;
-	vertical_layout = TRUE;
-    }
-
-    error = FT_Load_Glyph (scaled_font->unscaled->face,
-			   _cairo_scaled_glyph_index(scaled_glyph),
-			   load_flags);
-
-    if (error) {
-	status = CAIRO_STATUS_NO_MEMORY;
-	goto FAIL;
-    }
-
-    glyph = face->glyph;
-
-#if HAVE_FT_GLYPHSLOT_EMBOLDEN
-    /*
-     * embolden glyphs if requested
-     */
-    if (scaled_font->ft_options.extra_flags & CAIRO_FT_OPTIONS_EMBOLDEN)
-	FT_GlyphSlot_Embolden (glyph);
-#endif
-
-    if (vertical_layout)
-	_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font, glyph);
-
-    if (info & CAIRO_SCALED_GLYPH_INFO_METRICS) {
-
-	cairo_bool_t hint_metrics = scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF;
-	/*
-	 * Compute font-space metrics
-	 */
-	metrics = &glyph->metrics;
-
-	if (unscaled->x_scale == 0)
-	    x_factor = 0;
-	else
-	    x_factor = 1 / unscaled->x_scale;
-
-	if (unscaled->y_scale == 0)
-	    y_factor = 0;
-	else
-	    y_factor = 1 / unscaled->y_scale;
-
-	/*
-	 * Note: Y coordinates of the horizontal bearing need to be negated.
-	 *
-	 * Scale metrics back to glyph space from the scaled glyph space returned
-	 * by FreeType
-	 *
-	 * If we want hinted metrics but aren't asking for hinted glyphs from
-	 * FreeType, then we need to do the metric hinting ourselves.
-	 */
-
-	if (hint_metrics && (load_flags & FT_LOAD_NO_HINTING))
-	{
-	    FT_Pos x1, x2;
-	    FT_Pos y1, y2;
-	    FT_Pos advance;
-	    
-	    if (!vertical_layout) {
-		x1 = (metrics->horiBearingX) & -64;
-		x2 = (metrics->horiBearingX + metrics->width + 63) & -64;
-		y1 = (-metrics->horiBearingY) & -64;
-		y2 = (-metrics->horiBearingY + metrics->height + 63) & -64;
-		
-		advance = ((metrics->horiAdvance + 32) & -64);
-		
-		fs_metrics.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor;
-		fs_metrics.y_bearing = DOUBLE_FROM_26_6 (y1) * y_factor;
-		
-		fs_metrics.width  = DOUBLE_FROM_26_6 (x2 - x1) * x_factor;
-		fs_metrics.height  = DOUBLE_FROM_26_6 (y2 - y1) * y_factor;
-
-		fs_metrics.x_advance = DOUBLE_FROM_26_6 (advance) * x_factor;
-		fs_metrics.y_advance = 0;
-	    } else {
-		x1 = (metrics->vertBearingX) & -64;
-		x2 = (metrics->vertBearingX + metrics->width + 63) & -64;
-		y1 = (metrics->vertBearingY) & -64;
-		y2 = (metrics->vertBearingY + metrics->height + 63) & -64;
-		
-		advance = ((metrics->vertAdvance + 32) & -64);
-		
-		fs_metrics.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor;
-		fs_metrics.y_bearing = DOUBLE_FROM_26_6 (y1) * y_factor;
-		
-		fs_metrics.width  = DOUBLE_FROM_26_6 (x2 - x1) * x_factor;
-		fs_metrics.height  = DOUBLE_FROM_26_6 (y2 - y1) * y_factor;
-
-		fs_metrics.x_advance = 0;
-		fs_metrics.y_advance = DOUBLE_FROM_26_6 (advance) * y_factor;
-	    }
-	 } else {
-	    fs_metrics.width  = DOUBLE_FROM_26_6 (metrics->width) * x_factor;
-	    fs_metrics.height = DOUBLE_FROM_26_6 (metrics->height) * y_factor;
-
-	    if (!vertical_layout) {
-		fs_metrics.x_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingX) * x_factor;
-		fs_metrics.y_bearing = DOUBLE_FROM_26_6 (-metrics->horiBearingY) * y_factor;
-		
-		if (hint_metrics || glyph->format != FT_GLYPH_FORMAT_OUTLINE)
-		    fs_metrics.x_advance = DOUBLE_FROM_26_6 (metrics->horiAdvance) * x_factor;
-		else
-		    fs_metrics.x_advance = DOUBLE_FROM_16_16 (glyph->linearHoriAdvance) * x_factor;
-		fs_metrics.y_advance = 0 * y_factor;
-	    } else {
-		fs_metrics.x_bearing = DOUBLE_FROM_26_6 (metrics->vertBearingX) * x_factor;
-		fs_metrics.y_bearing = DOUBLE_FROM_26_6 (metrics->vertBearingY) * y_factor;
-		
-		fs_metrics.x_advance = 0 * x_factor;
-		if (hint_metrics || glyph->format != FT_GLYPH_FORMAT_OUTLINE)
-		    fs_metrics.y_advance = DOUBLE_FROM_26_6 (metrics->vertAdvance) * y_factor;
-		else
-		    fs_metrics.y_advance = DOUBLE_FROM_26_6 (glyph->linearVertAdvance) * y_factor;
-	    }
-	 }
-
-	_cairo_scaled_glyph_set_metrics (scaled_glyph,
-					 &scaled_font->base,
-					 &fs_metrics);
-    }
-
-    if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
-	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) {
-		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);
-    }
-
-    if (info & CAIRO_SCALED_GLYPH_INFO_PATH) {
-	cairo_path_fixed_t *path;
-
-	/*
-	 * A kludge -- the above code will trash the outline,
-	 * so reload it. This will probably never occur though
-	 */
-	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);
-#endif
-	    if (vertical_layout)
-		_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font, glyph);
-
-	}
-	if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)
-	    status = _decompose_glyph_outline (face, &scaled_font->ft_options.base,
-					       &path);
-	else
-	    status = CAIRO_INT_STATUS_UNSUPPORTED;
-
-	if (status)
-	    goto FAIL;
-
-	_cairo_scaled_glyph_set_path (scaled_glyph,
-				      &scaled_font->base,
-				      path);
-    }
- FAIL:
-    _cairo_ft_unscaled_font_unlock_face (unscaled);
-
-    return status;
-}
-
-static unsigned long
-_cairo_ft_ucs4_to_index (void	    *abstract_font,
-			 uint32_t    ucs4)
-{
-    cairo_ft_scaled_font_t *scaled_font = abstract_font;
-    cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;
-    FT_Face face;
-    FT_UInt index;
-
-    face = _cairo_ft_unscaled_font_lock_face (unscaled);
-    if (!face)
-	return 0;
-    index = FT_Get_Char_Index (face, ucs4);
-    _cairo_ft_unscaled_font_unlock_face (unscaled);
-    return index;
-}
-
-static cairo_int_status_t
-_cairo_ft_load_truetype_table (void	       *abstract_font,
-                              unsigned long     tag,
-                              long              offset,
-                              unsigned char    *buffer,
-                              unsigned long    *length)
-{
-    cairo_ft_scaled_font_t *scaled_font = abstract_font;
-    cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;
-    FT_Face face;
-    cairo_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
-
-    if (_cairo_ft_scaled_font_is_vertical (&scaled_font->base))
-        return CAIRO_INT_STATUS_UNSUPPORTED;
-
-#if HAVE_FT_LOAD_SFNT_TABLE
-    face = _cairo_ft_unscaled_font_lock_face (unscaled);
-    if (!face)
-	return CAIRO_STATUS_NO_MEMORY;
-
-    if (FT_IS_SFNT (face) &&
-	FT_Load_Sfnt_Table (face, tag, offset, buffer, length) == 0)
-        status = CAIRO_STATUS_SUCCESS;
-
-    _cairo_ft_unscaled_font_unlock_face (unscaled);
-#endif
-
-    return status;
-}
-
-static void
-_cairo_ft_map_glyphs_to_unicode (void	                    *abstract_font,
-                                 cairo_scaled_font_subset_t *font_subset)
-{
-    cairo_ft_scaled_font_t *scaled_font = abstract_font;
-    cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;
-    FT_Face face;
-    FT_UInt glyph;
-    unsigned long charcode;
-    unsigned int i;
-    int count;
-
-    face = _cairo_ft_unscaled_font_lock_face (unscaled);
-    if (!face)
-	return;
-
-    count = font_subset->num_glyphs;
-    charcode = FT_Get_First_Char( face, &glyph);
-    while (glyph != 0 && count > 0)
-    {
-        for (i = 0; i < font_subset->num_glyphs; i++) {
-            if (font_subset->glyphs[i] == glyph) {
-                font_subset->to_unicode[i] = charcode;
-                count--;
-                break;
-            }
-        }
-        charcode = FT_Get_Next_Char(face, charcode, &glyph);
-    }
-    _cairo_ft_unscaled_font_unlock_face (unscaled);
-}
-
-const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend = {
-    CAIRO_FONT_TYPE_FT,
-    _cairo_ft_scaled_font_create_toy,
-    _cairo_ft_scaled_font_fini,
-    _cairo_ft_scaled_glyph_init,
-    NULL,			/* text_to_glyphs */
-    _cairo_ft_ucs4_to_index,
-    NULL, 			/* show_glyphs */
-    _cairo_ft_load_truetype_table,
-    _cairo_ft_map_glyphs_to_unicode,
-};
-
-/* cairo_ft_font_face_t */
-
-static void
-_cairo_ft_font_face_destroy (void *abstract_face)
-{
-    cairo_ft_font_face_t *font_face = abstract_face;
-
-    cairo_ft_font_face_t *tmp_face = NULL;
-    cairo_ft_font_face_t *last_face = NULL;
-
-    if (font_face == NULL)
-	return;
-
-    /* When destroying the face created by cairo_ft_font_face_create_for_ft_face,
-     * we have a special "zombie" state for the face when the unscaled font
-     * is still alive but there are no public references to the font face.
-     *
-     * We go from:
-     *
-     *   font_face ------> unscaled
-     *        <-....weak....../
-     *
-     * To:
-     *
-     *    font_face <------- unscaled
-     */
-
-    if (font_face->unscaled &&
-	font_face->unscaled->from_face &&
-	font_face->unscaled->base.ref_count > 1)
-    {
-	cairo_font_face_reference (&font_face->base);
-
-	_cairo_unscaled_font_destroy (&font_face->unscaled->base);
-	font_face->unscaled = NULL;
-
-	return;
-    }
-
-    if (font_face->unscaled) {
-	/* Remove face from linked list */
-	for (tmp_face = font_face->unscaled->faces;
-	     tmp_face;
-	     tmp_face = tmp_face->next)
-	{
-	    if (tmp_face == font_face) {
-		if (last_face)
-		    last_face->next = tmp_face->next;
-		else
-		    font_face->unscaled->faces = tmp_face->next;
-	    }
-
-	    last_face = tmp_face;
-	}
-
-	_cairo_unscaled_font_destroy (&font_face->unscaled->base);
-	font_face->unscaled = NULL;
-    }
-}
-
-static cairo_status_t
-_cairo_ft_font_face_scaled_font_create (void                     *abstract_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_ft_font_face_t *font_face = abstract_face;
-    cairo_ft_options_t ft_options;
-
-    /* The handling of font options is different depending on how the
-     * font face was created. When the user creates a font face with
-     * cairo_ft_font_face_create_for_ft_face(), then the load flags
-     * passed in augment the load flags for the options.  But for
-     * cairo_ft_font_face_create_for_pattern(), the load flags are
-     * derived from a pattern where the user has called
-     * cairo_ft_font_options_substitute(), so *just* use those load
-     * flags and ignore the options.
-     */
-
-    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) {
-	return CAIRO_STATUS_SUCCESS;
-    } 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, **prev_font_face;
-
-    /* Looked for an existing matching font face */
-    for (font_face = unscaled->faces, prev_font_face = &unscaled->faces;
-	 font_face;
-	 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))
-	{
-	    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) {
-	_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;
-
-    _cairo_font_face_init (&font_face->base, &_cairo_ft_font_face_backend);
-
-    return &font_face->base;
-}
-
-/* implement the platform-specific interface */
-
-/**
- * cairo_ft_font_options_substitute:
- * @options: a #cairo_font_options_t object
- * @pattern: an existing #FcPattern
- *
- * Add options to a #FcPattern based on a #cairo_font_options_t font
- * options object. Options that are already in the pattern, are not overridden,
- * so you should call this function after calling FcConfigSubstitute() (the
- * user's settings should override options based on the surface type), but
- * before calling FcDefaultSubstitute().
- **/
-void
-cairo_ft_font_options_substitute (const cairo_font_options_t *options,
-				  FcPattern                  *pattern)
-{
-    FcValue v;
-
-    if (options->antialias != CAIRO_ANTIALIAS_DEFAULT)
-    {
-	if (FcPatternGet (pattern, FC_ANTIALIAS, 0, &v) == FcResultNoMatch)
-	{
-	    FcPatternAddBool (pattern, FC_ANTIALIAS, options->antialias != CAIRO_ANTIALIAS_NONE);
-	    if (options->antialias != CAIRO_ANTIALIAS_SUBPIXEL) {
-		FcPatternDel (pattern, FC_RGBA);
-		FcPatternAddInteger (pattern, FC_RGBA, FC_RGBA_NONE);
-	    }
-	}
-    }
-
-    if (options->antialias != CAIRO_ANTIALIAS_DEFAULT)
-    {
-	if (FcPatternGet (pattern, FC_RGBA, 0, &v) == FcResultNoMatch)
-	{
-	    int rgba;
-
-	    if (options->antialias == CAIRO_ANTIALIAS_SUBPIXEL) {
-		switch (options->subpixel_order) {
-		case CAIRO_SUBPIXEL_ORDER_DEFAULT:
-		case CAIRO_SUBPIXEL_ORDER_RGB:
-		default:
-		    rgba = FC_RGBA_RGB;
-		    break;
-		case CAIRO_SUBPIXEL_ORDER_BGR:
-		    rgba = FC_RGBA_BGR;
-		    break;
-		case CAIRO_SUBPIXEL_ORDER_VRGB:
-		    rgba = FC_RGBA_VRGB;
-		    break;
-		case CAIRO_SUBPIXEL_ORDER_VBGR:
-		    rgba = FC_RGBA_VBGR;
-		    break;
-		}
-	    } else {
-		rgba = FC_RGBA_NONE;
-	    }
-
-	    FcPatternAddInteger (pattern, FC_RGBA, rgba);
-	}
-    }
-
-    if (options->hint_style != CAIRO_HINT_STYLE_DEFAULT)
-    {
-	if (FcPatternGet (pattern, FC_HINTING, 0, &v) == FcResultNoMatch)
-	{
-	    FcPatternAddBool (pattern, FC_HINTING, options->hint_style != CAIRO_HINT_STYLE_NONE);
-	}
-
-#ifdef FC_HINT_STYLE
-	if (FcPatternGet (pattern, FC_HINT_STYLE, 0, &v) == FcResultNoMatch)
-	{
-	    int hint_style;
-
-	    switch (options->hint_style) {
-	    case CAIRO_HINT_STYLE_NONE:
-		hint_style = FC_HINT_NONE;
-		break;
-	    case CAIRO_HINT_STYLE_SLIGHT:
-		hint_style = FC_HINT_SLIGHT;
-		break;
-	    case CAIRO_HINT_STYLE_MEDIUM:
-		hint_style = FC_HINT_MEDIUM;
-		break;
-	    case CAIRO_HINT_STYLE_FULL:
-	    case CAIRO_HINT_STYLE_DEFAULT:
-	    default:
-		hint_style = FC_HINT_FULL;
-		break;
-	    }
-
-	    FcPatternAddInteger (pattern, FC_HINT_STYLE, hint_style);
-	}
-#endif
-    }
-}
-slim_hidden_def (cairo_ft_font_options_substitute);
-
-/**
- * cairo_ft_font_face_create_for_pattern:
- * @pattern: A fully resolved fontconfig
- *   pattern. A pattern can be resolved, by, among other things, calling
- *   FcConfigSubstitute(), FcDefaultSubstitute(), then
- *   FcFontMatch(). Cairo will call FcPatternReference() on this
- *   pattern, so you should not further modify the pattern, but you can
- *   release your reference to the pattern with FcPatternDestroy() if
- *   you no longer need to access it.
- *
- * Creates a new font face for the FreeType font backend based on a
- * fontconfig pattern. This font can then be used with
- * cairo_set_font_face() or cairo_scaled_font_create(). The
- * #cairo_scaled_font_t returned from cairo_scaled_font_create() is
- * also for the FreeType backend and can be used with functions such
- * as cairo_ft_font_lock_face().
- *
- * Font rendering options are represented both here and when you
- * call cairo_scaled_font_create(). Font options that have a representation
- * in a #FcPattern must be passed in here; to modify #FcPattern
- * appropriately to reflect the options in a #cairo_font_options_t, call
- * cairo_ft_font_options_substitute().
- *
- * Return value: a newly created #cairo_font_face_t. Free with
- *  cairo_font_face_destroy() when you are done using it.
- **/
-cairo_font_face_t *
-cairo_ft_font_face_create_for_pattern (FcPattern *pattern)
-{
-    cairo_ft_unscaled_font_t *unscaled;
-    cairo_font_face_t *font_face;
-    cairo_ft_options_t ft_options;
-
-    unscaled = _cairo_ft_unscaled_font_create_for_pattern (pattern);
-    if (unscaled == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return (cairo_font_face_t *)&_cairo_font_face_nil;
-    }
-
-    _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
-	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
- *   is safe to free the face is to pass a
- *   #cairo_destroy_func_t to cairo_font_face_set_user_data()
- * @load_flags: flags to pass to FT_Load_Glyph when loading
- *   glyphs from the font. These flags are OR'ed together with
- *   the flags derived from the #cairo_font_options_t passed
- *   to cairo_scaled_font_create(), so only a few values such
- *   as %FT_LOAD_VERTICAL_LAYOUT, and %FT_LOAD_FORCE_AUTOHINT
- *   are useful. You should not pass any of the flags affecting
- *   the load target, such as %FT_LOAD_TARGET_LIGHT.
- *
- * Creates a new font face for the FreeType font backend from a
- * pre-opened FreeType face. This font can then be used with
- * cairo_set_font_face() or cairo_scaled_font_create(). The
- * #cairo_scaled_font_t returned from cairo_scaled_font_create() is
- * also for the FreeType backend and can be used with functions such
- * as cairo_ft_font_lock_face().
- *
- * Return value: a newly created #cairo_font_face_t. Free with
- *  cairo_font_face_destroy() when you are done using it.
- **/
-cairo_font_face_t *
-cairo_ft_font_face_create_for_ft_face (FT_Face         face,
-				       int             load_flags)
-{
-    cairo_ft_unscaled_font_t *unscaled;
-    cairo_font_face_t *font_face;
-    cairo_ft_options_t ft_options;
-
-    unscaled = _cairo_ft_unscaled_font_create_from_face (face);
-    if (unscaled == NULL) {
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return (cairo_font_face_t *)&_cairo_font_face_nil;
-    }
-
-    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)
-	return font_face;
-    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()).
- *
- * cairo_ft_font_lock_face() gets the #FT_Face object from a FreeType
- * backend font and scales it appropriately for the font. You must
- * release the face with cairo_ft_font_unlock_face()
- * when you are done using it.  Since the #FT_Face object can be
- * shared between multiple #cairo_scaled_font_t objects, you must not
- * lock any other font objects until you unlock this one. A count is
- * kept of the number of times cairo_ft_font_lock_face() is
- * called. cairo_ft_font_unlock_face() must be called the same number
- * of times.
- *
- * You must be careful when using this function in a library or in a
- * threaded application, because freetype's design makes it unsafe to
- * call freetype functions simultaneously from multiple threads, (even
- * if using distinct FT_Face objects). Because of this, application
- * code that acquires an FT_Face object with this call must add it's
- * own locking to protect any use of that object, (and which also must
- * protect any other calls into cairo as almost any cairo function
- * might result in a call into the freetype library).
- *
- * Return value: The #FT_Face object for @font, scaled appropriately,
- * 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;
-    }
-
-    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);
-
-    return face;
-}
-
-/**
- * cairo_ft_scaled_font_unlock_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_ft_face()).
- *
- * Releases a face obtained with cairo_ft_scaled_font_lock_face().
- **/
-void
-cairo_ft_scaled_font_unlock_face (cairo_scaled_font_t *abstract_font)
-{
-    cairo_ft_scaled_font_t *scaled_font = (cairo_ft_scaled_font_t *) abstract_font;
-
-    if (scaled_font->base.status)
-	return;
-
-    /* NOTE: We released the unscaled font's mutex at the end of
-     * cairo_ft_scaled_font_lock_face, so we have to acquire it again
-     * as _cairo_ft_unscaled_font_unlock_face expects it to be held
-     * when we call into it. */
-    CAIRO_MUTEX_LOCK (scaled_font->unscaled->mutex);
-
-    _cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled);
-}
-
-/* We expose our unscaled font implementation internally for the the
- * PDF backend, which needs to keep track of the the different
- * fonts-on-disk used by a document, so it can embed them.
- */
-cairo_unscaled_font_t *
-_cairo_ft_scaled_font_get_unscaled_font (cairo_scaled_font_t *abstract_font)
-{
-    cairo_ft_scaled_font_t *scaled_font = (cairo_ft_scaled_font_t *) abstract_font;
-
-    return &scaled_font->unscaled->base;
-}
-
-cairo_bool_t
-_cairo_ft_scaled_font_is_vertical (cairo_scaled_font_t *scaled_font)
-{
-    cairo_ft_scaled_font_t *ft_scaled_font;
-    
-    if (!_cairo_scaled_font_is_ft (scaled_font))
-	return FALSE;
-    
-    ft_scaled_font = (cairo_ft_scaled_font_t *) scaled_font;
-    if (ft_scaled_font->ft_options.load_flags & FT_LOAD_VERTICAL_LAYOUT)
-	return TRUE;
-    return FALSE;
-}
-
-void
-_cairo_ft_font_reset_static_data (void)
-{
-    _cairo_ft_unscaled_font_map_destroy ();
-}
--- 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;
-    cairo_bool_t      has_clip;
-    pixman_region16_t 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->has_clip) {
-        glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0);
-        pixman_region_fini (&surface->clip);
+    if (surface->clip)
+    {
+	glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0);
+	pixman_region_destroy (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->has_clip)
+    if (surface->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->has_clip) {
+    if (surface->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,
-			  (glitz_pixel_format_t *)&format, buffer);
+			  &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,43 +817,36 @@ 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_COLOR_IS_OPAQUE (&combined) ?
-				   CAIRO_CONTENT_COLOR :
-				   CAIRO_CONTENT_COLOR_ALPHA);
+	_cairo_pattern_init_solid (&tmp.solid, &combined);
 
 	mask = NULL;
     } else {
-	status = _cairo_pattern_init_copy (&tmp.base, src);
-	if (status)
-	    return status;
+	_cairo_pattern_init_copy (&tmp.base, src);
     }
 
     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)
     {
-	status = _cairo_pattern_init_copy (&tmp.base, mask);
-	if (status)
-	    return status;
+	_cairo_pattern_init_copy (&tmp.base, mask);
 
 	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);
@@ -1004,18 +997,17 @@ 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,
-						 NULL);
+						 (cairo_color_t *) color);
 	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),
@@ -1074,19 +1066,17 @@ 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)
     {
-	status = _cairo_pattern_init_copy (&tmp_src_pattern.base, pattern);
-	if (status)
-	    return status;
+	_cairo_pattern_init_copy (&tmp_src_pattern.base, pattern);
 
 	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;
     }
@@ -1288,42 +1278,36 @@ static cairo_int_status_t
 {
     cairo_glitz_surface_t *surface = abstract_surface;
 
     if (region)
     {
 	glitz_box_t *box;
 	int	    n;
 
-	if (!surface->has_clip) {
-            pixman_region_init (&surface->clip);
-            surface->has_clip = TRUE;
-        }
+	if (!surface->clip)
+	{
+	    surface->clip = pixman_region_create ();
+	    if (!surface->clip)
+		return CAIRO_STATUS_NO_MEMORY;
+	}
+	pixman_region_copy (surface->clip, region);
 
-	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);
-
+	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->has_clip) {
-	    pixman_region_fini (&surface->clip);
-	    surface->has_clip = FALSE;
-        }
+	if (surface->clip)
+	    pixman_region_destroy (surface->clip);
+
+	surface->clip = NULL;
     }
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_int_status_t
 _cairo_glitz_surface_get_extents (void		          *abstract_surface,
 				  cairo_rectangle_int16_t *rectangle)
@@ -2183,43 +2167,16 @@ 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,
@@ -2232,28 +2189,17 @@ 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,
-
-    NULL, /* paint */
-    NULL, /* mask */
-    NULL, /* stroke */
-    NULL, /* fill */
-    NULL, /* show_glyphs */
-
-    NULL, /* snapshot */
-    _cairo_glitz_surface_is_similar,
-
-    _cairo_glitz_surface_reset
+    _cairo_glitz_surface_scaled_glyph_fini
 };
 
 static const cairo_surface_backend_t *
 _cairo_glitz_surface_get_backend (void)
 {
     return &cairo_glitz_surface_backend;
 }
 
@@ -2289,15 +2235,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->has_clip = FALSE;
+    crsurface->surface = surface;
+    crsurface->format  = format;
+    crsurface->clip    = NULL;
 
     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,16 +30,18 @@
  *
  * 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);
 
@@ -57,18 +59,16 @@ 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,22 +86,23 @@ 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,
-						  CAIRO_CONTENT_COLOR);
+    gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK);
     if (gstate->source->status)
 	return CAIRO_STATUS_NO_MEMORY;
 
-    return target ? target->status : CAIRO_STATUS_NULL_POINTER;
+    gstate->next = NULL;
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 /**
  * _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.
@@ -125,19 +126,17 @@ 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);
 
-    status = _cairo_clip_init_copy (&gstate->clip, &other->clip);
-    if (status)
-	return status;
+    _cairo_clip_init_copy (&gstate->clip, &other->clip);
 
     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;
@@ -156,32 +155,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_reset (&gstate->clip);
+    _cairo_clip_fini (&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;
 }
 
-static void
+void
 _cairo_gstate_destroy (cairo_gstate_t *gstate)
 {
     if (gstate == NULL)
 	return;
 
     _cairo_gstate_fini (gstate);
     free (gstate);
 }
@@ -193,17 +192,17 @@ static 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.
  **/
-static cairo_gstate_t*
+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));
@@ -214,65 +213,16 @@ static 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;
@@ -297,47 +247,41 @@ 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.
  **/
-cairo_status_t
+void
 _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_reset (&gstate->clip);
-    status = _cairo_clip_init_deep_copy (&gstate->clip, &gstate->next->clip, child);
-    if (status)
-	return status;
+    _cairo_clip_fini (&gstate->clip);
+    _cairo_clip_init_deep_copy (&gstate->clip, &gstate->next->clip, child);
 
     /* 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.
@@ -407,17 +351,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;
 
-    source = cairo_pattern_reference (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 *
@@ -558,34 +502,16 @@ 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;
 }
 
@@ -652,26 +578,23 @@ 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);
 
-    status = cairo_matrix_invert (&tmp);
-    if (status)
-	return status;
+    cairo_matrix_invert (&tmp);
     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)
@@ -685,49 +608,59 @@ cairo_status_t
     gstate->ctm_inverse = *matrix;
     status = cairo_matrix_invert (&gstate->ctm_inverse);
     if (status)
 	return status;
 
     return CAIRO_STATUS_SUCCESS;
 }
 
-void
+cairo_status_t
 _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;
 }
 
-void
+cairo_status_t
 _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;
 }
 
-void
+cairo_status_t
 _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;
 }
 
-void
+cairo_status_t
 _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;
 }
 
-void
+cairo_status_t
 _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);
 }
@@ -759,77 +692,70 @@ cairo_status_t
 {
     cairo_status_t status;
 
     _cairo_pen_init (&gstate);
     return CAIRO_STATUS_SUCCESS;
 }
 */
 
-static cairo_status_t
+static void
 _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;
 
-    status = _cairo_pattern_init_copy (pattern, original);
-    if (status)
-	return status;
-
+    _cairo_pattern_init_copy (pattern, original);
     _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 cairo_status_t
+static void
 _cairo_gstate_copy_transformed_source (cairo_gstate_t  *gstate,
 				       cairo_pattern_t *pattern)
 {
-    return _cairo_gstate_copy_transformed_pattern (gstate, pattern,
-					           gstate->source,
-					           &gstate->source_ctm_inverse);
+    _cairo_gstate_copy_transformed_pattern (gstate, pattern,
+					    gstate->source,
+					    &gstate->source_ctm_inverse);
 }
 
-static cairo_status_t
+static void
 _cairo_gstate_copy_transformed_mask (cairo_gstate_t  *gstate,
 				     cairo_pattern_t *pattern,
 				     cairo_pattern_t *mask)
 {
-    return _cairo_gstate_copy_transformed_pattern (gstate, pattern,
-					           mask,
-					           &gstate->ctm_inverse);
+    _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;
 
-    status = _cairo_gstate_copy_transformed_source (gstate, &pattern.base);
-    if (status)
-	return status;
+    _cairo_gstate_copy_transformed_source (gstate, &pattern.base);
 
     status = _cairo_surface_paint (gstate->target,
 				   gstate->op,
 				   &pattern.base);
 
     _cairo_pattern_fini (&pattern.base);
 
     return status;
@@ -926,32 +852,26 @@ cairo_status_t
 
     if (gstate->source->status)
 	return gstate->source->status;
 
     status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
     if (status)
 	return status;
 
-    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;
+    _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
+    _cairo_gstate_copy_transformed_mask (gstate, &mask_pattern.base, mask);
 
     status = _cairo_surface_mask (gstate->target,
 				  gstate->op,
 				  &source_pattern.base,
 				  &mask_pattern.base);
 
+    _cairo_pattern_fini (&source_pattern.base);
     _cairo_pattern_fini (&mask_pattern.base);
-CLEANUP_SOURCE:
-    _cairo_pattern_fini (&source_pattern.base);
 
     return status;
 }
 
 cairo_status_t
 _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
 {
     cairo_status_t status;
@@ -962,20 +882,17 @@ 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;
 
-    status = _cairo_gstate_copy_transformed_source (gstate,
-	                                            &source_pattern.base);
-    if (status)
-	return status;
+    _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
 
     status = _cairo_surface_stroke (gstate->target,
 				    gstate->op,
 				    &source_pattern.base,
 				    path,
 				    &gstate->stroke_style,
 				    &gstate->ctm,
 				    &gstate->ctm_inverse,
@@ -1032,19 +949,17 @@ cairo_status_t
 
     if (gstate->source->status)
 	return gstate->source->status;
 
     status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
     if (status)
 	return status;
 
-    status = _cairo_gstate_copy_transformed_source (gstate, &pattern.base);
-    if (status)
-	return status;
+    _cairo_gstate_copy_transformed_source (gstate, &pattern.base);
 
     status = _cairo_surface_fill (gstate->target,
 				  gstate->op,
 				  &pattern.base,
 				  path,
 				  gstate->fill_rule,
 				  gstate->tolerance,
 				  gstate->antialias);
@@ -1081,23 +996,39 @@ BAIL:
     _cairo_traps_fini (&traps);
 
     return status;
 }
 
 cairo_status_t
 _cairo_gstate_copy_page (cairo_gstate_t *gstate)
 {
-    return _cairo_surface_copy_page (gstate->target);
+    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;
 }
 
 cairo_status_t
 _cairo_gstate_show_page (cairo_gstate_t *gstate)
 {
-    return _cairo_surface_show_page (gstate->target);
+    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;
 }
 
 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)
 {
@@ -1189,19 +1120,17 @@ cairo_status_t
     _cairo_traps_fini (&traps);
 
     return status;
 }
 
 cairo_status_t
 _cairo_gstate_reset_clip (cairo_gstate_t *gstate)
 {
-    _cairo_clip_reset (&gstate->clip);
-
-    return CAIRO_STATUS_SUCCESS;
+    return _cairo_clip_reset (&gstate->clip);
 }
 
 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);
@@ -1256,25 +1185,22 @@ 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;
 
-    status = _cairo_gstate_set_font_face (gstate, font_face);
-    if (status)
-	return status;
+    _cairo_gstate_set_font_face (gstate, font_face);
     cairo_font_face_destroy (font_face);
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 cairo_status_t
 _cairo_gstate_set_font_size (cairo_gstate_t *gstate,
 			     double          size)
@@ -1299,23 +1225,25 @@ cairo_status_t
 
 void
 _cairo_gstate_get_font_matrix (cairo_gstate_t *gstate,
 			       cairo_matrix_t *matrix)
 {
     *matrix = gstate->font_matrix;
 }
 
-void
+cairo_status_t
 _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;
 }
@@ -1424,93 +1352,92 @@ 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)
 {
-    cairo_font_face_t *font_face;
-
-    if (gstate->font_face != NULL)
-	return gstate->font_face->status;
-
+    if (!gstate->font_face) {
+	cairo_font_face_t *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;
+	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;
+    }
 
     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 != NULL)
-	return gstate->scaled_font->status;
+    if (gstate->scaled_font)
+	return CAIRO_STATUS_SUCCESS;
 
     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);
 
-    scaled_font = cairo_scaled_font_create (gstate->font_face,
-				            &gstate->font_matrix,
-					    &gstate->ctm,
-					    &options);
+    gstate->scaled_font = cairo_scaled_font_create (gstate->font_face,
+						    &gstate->font_matrix,
+						    &gstate->ctm,
+						    &options);
 
-    status = cairo_scaled_font_status (scaled_font);
-    if (status)
-	return status;
-
-    gstate->scaled_font = scaled_font;
+    if (!gstate->scaled_font)
+	return CAIRO_STATUS_NO_MEMORY;
 
     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_scaled_font_status (gstate->scaled_font);
+    return CAIRO_STATUS_SUCCESS;
 }
 
 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;
 
-    return _cairo_scaled_font_text_to_glyphs (gstate->scaled_font, x, y,
-					      utf8, glyphs, num_glyphs);
+    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;
 }
 
 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;
@@ -1536,17 +1463,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_scaled_font_status (gstate->scaled_font);
+    return CAIRO_STATUS_SUCCESS;
 }
 
 #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)
 {
@@ -1573,30 +1500,27 @@ 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);
 
-    status = _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
-    if (status)
-	goto CLEANUP_GLYPHS;
+    _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
 
     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,23 +34,61 @@
  *      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 ARRAY_LENGTH (hash_table_arrangements)
+#define NUM_HASH_TABLE_ARRANGEMENTS ((int)(sizeof(hash_table_arrangements)/sizeof(hash_table_arrangements[0])))
 
 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,22 +476,18 @@ 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) {
-	/* abort the insert... */
-	*entry = DEAD_ENTRY;
-	hash_table->live_entries--;
+    if (status)
 	return status;
-    }
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 /**
  * _cairo_hash_table_remove:
  * @hash_table: a hash table
  * @key: key of entry to be removed
@@ -560,14 +556,11 @@ 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) {
-	/* Should we fail to shrink the hash table, it is left unaltered,
-	 * and we don't need to propagate the error status. */
+    if (--hash_table->iterating == 0)
 	_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"
 
-static const cairo_image_surface_t _cairo_image_surface_nil_invalid_format = {
+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_internal_format_t
+static cairo_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_internal_format_t
 		return CAIRO_INTERNAL_FORMAT_BGR24;
 	}
 	break;
     case 16:
 	if (am == 0x0 &&
 	    rm == 0xf800 &&
 	    gm == 0x07e0 &&
 	    bm == 0x001f)
-	    return CAIRO_INTERNAL_FORMAT_RGB16_565;
+	    return CAIRO_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_internal_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_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_init_masks (&pixman_format,
-	                      format->bpp,
-			      format->alpha_mask,
-			      format->red_mask,
-			      format->green_mask,
-			      format->blue_mask);
+    if (pixman_format == NULL) {
+	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	return (cairo_surface_t*) &_cairo_surface_nil;
+    }
 
-    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 void
-_init_pixman_format (pixman_format_t *pixman_format, cairo_format_t format)
+static pixman_format_t *
+_create_pixman_format (cairo_format_t format)
 {
-    int ret;
     switch (format) {
     case CAIRO_FORMAT_A1:
-	ret = pixman_format_init (pixman_format, PIXMAN_FORMAT_NAME_A1);
+	return pixman_format_create (PIXMAN_FORMAT_NAME_A1);
 	break;
     case CAIRO_FORMAT_A8:
-	ret = pixman_format_init (pixman_format, PIXMAN_FORMAT_NAME_A8);
+	return pixman_format_create (PIXMAN_FORMAT_NAME_A8);
 	break;
     case CAIRO_FORMAT_RGB24:
-	ret = pixman_format_init (pixman_format, PIXMAN_FORMAT_NAME_RGB24);
+	return pixman_format_create (PIXMAN_FORMAT_NAME_RGB24);
 	break;
     case CAIRO_FORMAT_ARGB32:
     default:
-	ret = pixman_format_init (pixman_format, PIXMAN_FORMAT_NAME_ARGB32);
+	return pixman_format_create (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,37 +285,41 @@ static void
  * 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;
     }
 
-    _init_pixman_format (&pixman_format, format);
+    pixman_format = _create_pixman_format (format);
+    if (pixman_format == NULL) {
+	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	return (cairo_surface_t*) &_cairo_surface_nil;
+    }
 
-    pixman_image = pixman_image_create (&pixman_format, width, height);
+    pixman_image = pixman_image_create (pixman_format, width, height);
+
+    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);
 
 cairo_surface_t *
 _cairo_image_surface_create_with_content (cairo_content_t	content,
 					  int			width,
@@ -360,39 +364,42 @@ 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;
 
-    _init_pixman_format (&pixman_format, format);
+    pixman_format = _create_pixman_format (format);
+    if (pixman_format == NULL) {
+	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	return (cairo_surface_t*) &_cairo_surface_nil;
+    }
 
-    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 *
</