b=419715, upgrade cairo to 1.6 or as-close-as-possible -- imported patch cairo-upgrade.patch ; r=me
authorvladimir@pobox.com
Sun, 06 Apr 2008 15:14:09 -0700
changeset 13973 e4d65d55a17db08212ae995037888addf4d63fc4
parent 13972 dcbc55d15ed9114be2b81ed750db0b5e32732ea8
child 13974 dca881da922ddbbc1e50f1d765f85c391401df81
push idunknown
push userunknown
push dateunknown
reviewersme
bugs419715
milestone1.9pre
b=419715, upgrade cairo to 1.6 or as-close-as-possible -- imported patch cairo-upgrade.patch ; r=me
configure.in
gfx/cairo/README
gfx/cairo/cairo/src/Makefile.in
gfx/cairo/cairo/src/cairo-analysis-surface.c
gfx/cairo/cairo/src/cairo-array.c
gfx/cairo/cairo/src/cairo-atsui-font.c
gfx/cairo/cairo/src/cairo-atsui.h
gfx/cairo/cairo/src/cairo-deprecated.h
gfx/cairo/cairo/src/cairo-features.h.in
gfx/cairo/cairo/src/cairo-font-face.c
gfx/cairo/cairo/src/cairo-glitz-surface.c
gfx/cairo/cairo/src/cairo-gstate.c
gfx/cairo/cairo/src/cairo-hull.c
gfx/cairo/cairo/src/cairo-image-surface.c
gfx/cairo/cairo/src/cairo-meta-surface.c
gfx/cairo/cairo/src/cairo-output-stream-private.h
gfx/cairo/cairo/src/cairo-output-stream.c
gfx/cairo/cairo/src/cairo-path-fixed.c
gfx/cairo/cairo/src/cairo-pattern.c
gfx/cairo/cairo/src/cairo-pdf-operators.c
gfx/cairo/cairo/src/cairo-pdf-surface.c
gfx/cairo/cairo/src/cairo-png.c
gfx/cairo/cairo/src/cairo-ps-surface.c
gfx/cairo/cairo/src/cairo-quartz-font.c
gfx/cairo/cairo/src/cairo-quartz-private.h
gfx/cairo/cairo/src/cairo-quartz-surface.c
gfx/cairo/cairo/src/cairo-quartz.h
gfx/cairo/cairo/src/cairo-rectangle.c
gfx/cairo/cairo/src/cairo-surface-fallback.c
gfx/cairo/cairo/src/cairo-surface.c
gfx/cairo/cairo/src/cairo-svg-surface.c
gfx/cairo/cairo/src/cairo-truetype-subset.c
gfx/cairo/cairo/src/cairo-win32-font.c
gfx/cairo/cairo/src/cairo-win32-printing-surface.c
gfx/cairo/cairo/src/cairo-win32-surface.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-visual.c
gfx/cairo/cairo/src/cairo.c
gfx/cairo/cairo/src/cairo.h
gfx/cairo/cairo/src/cairoint.h
gfx/thebes/src/gfxAtsuiFonts.cpp
--- a/configure.in
+++ b/configure.in
@@ -7176,17 +7176,17 @@ if test "$MOZ_TREE_CAIRO"; then
         PDF_SURFACE_FEATURE="#define CAIRO_HAS_PDF_SURFACE 1"
         FT_FONT_FEATURE="#define CAIRO_HAS_FT_FONT 1"
         MOZ_ENABLE_CAIRO_FT=1
         CAIRO_FT_CFLAGS="$FT2_CFLAGS"
     fi
     if test "$MOZ_WIDGET_TOOLKIT" = "mac" -o "$MOZ_WIDGET_TOOLKIT" = "cocoa"; then
         QUARTZ_SURFACE_FEATURE="#define CAIRO_HAS_QUARTZ_SURFACE 1"
         QUARTZ_IMAGE_SURFACE_FEATURE="#define CAIRO_HAS_QUARTZ_IMAGE_SURFACE 1"
-        ATSUI_FONT_FEATURE="#define CAIRO_HAS_ATSUI_FONT 1"
+        QUARTZ_FONT_FEATURE="#define CAIRO_HAS_QUARTZ_FONT 1"
     fi
     if test "$MOZ_WIDGET_TOOLKIT" = "windows"; then
         WIN32_SURFACE_FEATURE="#define CAIRO_HAS_WIN32_SURFACE 1"
         WIN32_FONT_FEATURE="#define CAIRO_HAS_WIN32_FONT 1"
         PDF_SURFACE_FEATURE="#define CAIRO_HAS_PDF_SURFACE 1"
     fi
     if test "$MOZ_WIDGET_TOOLKIT" = "os2"; then
         OS2_SURFACE_FEATURE="#define CAIRO_HAS_OS2_SURFACE 1"
@@ -7226,17 +7226,17 @@ if test "$MOZ_TREE_CAIRO"; then
     AC_SUBST(XCB_SURFACE_FEATURE)
     AC_SUBST(WIN32_SURFACE_FEATURE)
     AC_SUBST(OS2_SURFACE_FEATURE)
     AC_SUBST(BEOS_SURFACE_FEATURE)
     AC_SUBST(GLITZ_SURFACE_FEATURE)
     AC_SUBST(DIRECTFB_SURFACE_FEATURE)
     AC_SUBST(FT_FONT_FEATURE)
     AC_SUBST(WIN32_FONT_FEATURE)
-    AC_SUBST(ATSUI_FONT_FEATURE)
+    AC_SUBST(QUARTZ_FONT_FEATURE)
     AC_SUBST(PNG_FUNCTIONS_FEATURE)
 
     if test "$_WIN32_MSVC"; then
         MOZ_CAIRO_LIBS='$(DEPTH)/gfx/cairo/cairo/src/mozcairo.lib $(DEPTH)/gfx/cairo/libpixman/src/mozlibpixman.lib'
         if test "$MOZ_ENABLE_GLITZ"; then
             MOZ_CAIRO_LIBS="$MOZ_CAIRO_LIBS "'$(DEPTH)/gfx/cairo/glitz/src/mozglitz.lib $(DEPTH)/gfx/cairo/glitz/src/wgl/mozglitzwgl.lib'
         fi
     else
--- a/gfx/cairo/README
+++ b/gfx/cairo/README
@@ -2,17 +2,17 @@ Snapshots of cairo and glitz for mozilla
 
 We only include the relevant parts of each release (generally, src/*.[ch]),
 as we have Makefile.in's that integrate into the Mozilla build system.  For
 documentation and similar, please see the official tarballs at
 http://www.cairographics.org/.
 
 VERSIONS:
 
-  cairo (1.6.x - 1.5.12-56-ga33351f)
+  cairo (1.6.x - 1.5.16-23-gbb76eb5)
   pixman (0.10.x - pixman-0.10.0-5-g4cde088)
   glitz 0.5.2 (cvs - 2006-01-10)
 
 ***** NOTE FOR VISUAL C++ 6.0 *****
 
 VC6 is not supported.  Please upgrade to VC8.
 
 ==== Patches ====
--- a/gfx/cairo/cairo/src/Makefile.in
+++ b/gfx/cairo/cairo/src/Makefile.in
@@ -159,18 +159,18 @@ DEFINES += -DOS2_HIGH_MEMORY
 endif
 CSRCS   += cairo-os2-surface.c
 EXPORTS += cairo-os2.h cairo-os2-private.h
 CSRCS   += $(PSPDF_BASE_CSRCS) $(PDF_CSRCS)
 EXPORTS += $(PDF_EXPORTS)
 endif
 
 ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
-CSRCS   += cairo-quartz-surface.c cairo-quartz-image-surface.c cairo-atsui-font.c
-EXPORTS += cairo-quartz.h cairo-atsui.h cairo-quartz-image.h
+CSRCS   += cairo-quartz-surface.c cairo-quartz-image-surface.c cairo-quartz-font.c
+EXPORTS += cairo-quartz.h cairo-quartz-image.h
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),beos)
 CPPSRCS += cairo-beos-surface.cpp
 EXPORTS += cairo-beos.h
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
@@ -181,16 +181,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-visual.c \
 	   cairo-xlib-display.c
 EXPORTS += cairo-xlib.h cairo-xlib-xrender.h
 endif
 
 ifdef MOZ_ENABLE_CAIRO_FT
 CSRCS   += cairo-ft-font.c cairo-type1-subset.c
 EXPORTS += cairo-ft.h
 OS_INCLUDES += $(CAIRO_FT_CFLAGS)
--- a/gfx/cairo/cairo/src/cairo-analysis-surface.c
+++ b/gfx/cairo/cairo/src/cairo-analysis-surface.c
@@ -120,36 +120,61 @@ static cairo_int_status_t
 static cairo_int_status_t
 _cairo_analysis_surface_add_operation  (cairo_analysis_surface_t *surface,
 					cairo_rectangle_int_t    *rect,
 					cairo_int_status_t        backend_status)
 {
     cairo_int_status_t status;
     cairo_box_t bbox;
 
-    if (rect->width == 0 || rect->height == 0)
-	return CAIRO_STATUS_SUCCESS;
+    if (rect->width == 0 || rect->height == 0) {
+	/* Even though the operation is not visible we must be careful
+	 * to not allow unsupported operations to be replayed to the
+	 * backend during CAIRO_PAGINATED_MODE_RENDER */
+	if (backend_status == CAIRO_STATUS_SUCCESS ||
+	    backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
+	{
+	    return CAIRO_STATUS_SUCCESS;
+	}
+	else
+	{
+	    return CAIRO_INT_STATUS_IMAGE_FALLBACK;
+	}
+    }
 
     if (surface->has_ctm) {
 	double x1, y1, x2, y2;
 
 	x1 = rect->x;
 	y1 = rect->y;
 	x2 = rect->x + rect->width;
 	y2 = rect->y + rect->height;
 	_cairo_matrix_transform_bounding_box (&surface->ctm,
 					      &x1, &y1, &x2, &y2,
 					      NULL);
 	rect->x = floor (x1);
 	rect->y = floor (y1);
 
 	x2 = ceil (x2) - rect->x;
 	y2 = ceil (y2) - rect->y;
-	if (x2 <= 0 || y2 <= 0)
-	    return CAIRO_STATUS_SUCCESS;
+	if (x2 <= 0 || y2 <= 0) {
+	    /* Even though the operation is not visible we must be
+	     * careful to not allow unsupported operations to be
+	     * replayed to the backend during
+	     * CAIRO_PAGINATED_MODE_RENDER */
+	    if (backend_status == CAIRO_STATUS_SUCCESS ||
+		backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
+	    {
+		return CAIRO_STATUS_SUCCESS;
+	    }
+	    else
+	    {
+		return CAIRO_INT_STATUS_IMAGE_FALLBACK;
+	    }
+	}
 
 	rect->width  = x2;
 	rect->height = y2;
     }
 
     bbox.p1.x = _cairo_fixed_from_int (rect->x);
     bbox.p1.y = _cairo_fixed_from_int (rect->y);
     bbox.p2.x = _cairo_fixed_from_int (rect->x + rect->width);
@@ -429,27 +454,33 @@ static cairo_int_status_t
 
 	_cairo_traps_init (&traps);
 	_cairo_traps_limit (&traps, &box);
 	status = _cairo_path_fixed_stroke_to_traps (path,
 						    style,
 						    ctm, ctm_inverse,
 						    tolerance,
 						    &traps);
-
-	if (status || traps.num_traps == 0) {
+	if (status) {
 	    _cairo_traps_fini (&traps);
 	    return status;
 	}
 
-	_cairo_traps_extents (&traps, &box);
-	extents.x = _cairo_fixed_integer_floor (box.p1.x);
-	extents.y = _cairo_fixed_integer_floor (box.p1.y);
-	extents.width = _cairo_fixed_integer_ceil (box.p2.x) - extents.x;
-	extents.height = _cairo_fixed_integer_ceil (box.p2.y) - extents.y;
+	if (traps.num_traps == 0) {
+	    extents.x = 0;
+	    extents.y = 0;
+	    extents.width = 0;
+	    extents.height = 0;
+	} else {
+	    _cairo_traps_extents (&traps, &box);
+	    extents.x = _cairo_fixed_integer_floor (box.p1.x);
+	    extents.y = _cairo_fixed_integer_floor (box.p1.y);
+	    extents.width = _cairo_fixed_integer_ceil (box.p2.x) - extents.x;
+	    extents.height = _cairo_fixed_integer_ceil (box.p2.y) - extents.y;
+	}
 	_cairo_traps_fini (&traps);
     }
 
     status = _cairo_analysis_surface_add_operation (surface, &extents, backend_status);
 
     return status;
 }
 
@@ -501,27 +532,33 @@ static cairo_int_status_t
 	box.p2.y = _cairo_fixed_from_int (extents.y + extents.height);
 
 	_cairo_traps_init (&traps);
 	_cairo_traps_limit (&traps, &box);
 	status = _cairo_path_fixed_fill_to_traps (path,
 						  fill_rule,
 						  tolerance,
 						  &traps);
-
-	if (status || traps.num_traps == 0) {
+	if (status) {
 	    _cairo_traps_fini (&traps);
 	    return status;
 	}
 
-	_cairo_traps_extents (&traps, &box);
-	extents.x = _cairo_fixed_integer_floor (box.p1.x);
-	extents.y = _cairo_fixed_integer_floor (box.p1.y);
-	extents.width = _cairo_fixed_integer_ceil (box.p2.x) - extents.x;
-	extents.height = _cairo_fixed_integer_ceil (box.p2.y) - extents.y;
+	if (traps.num_traps == 0) {
+	    extents.x = 0;
+	    extents.y = 0;
+	    extents.width = 0;
+	    extents.height = 0;
+	} else {
+	    _cairo_traps_extents (&traps, &box);
+	    extents.x = _cairo_fixed_integer_floor (box.p1.x);
+	    extents.y = _cairo_fixed_integer_floor (box.p1.y);
+	    extents.width = _cairo_fixed_integer_ceil (box.p2.x) - extents.x;
+	    extents.height = _cairo_fixed_integer_ceil (box.p2.y) - extents.y;
+	}
 
 	_cairo_traps_fini (&traps);
     }
 
     status = _cairo_analysis_surface_add_operation (surface, &extents, backend_status);
 
     return status;
 }
--- a/gfx/cairo/cairo/src/cairo-array.c
+++ b/gfx/cairo/cairo/src/cairo-array.c
@@ -105,25 +105,29 @@ void
 /**
  * _cairo_array_grow_by:
  *
  * Increase the size of @array (if needed) so that there are at least
  * @additional free spaces in the array. The actual size of the array
  * is always increased by doubling as many times as necessary.
  **/
 cairo_status_t
-_cairo_array_grow_by (cairo_array_t *array, int additional)
+_cairo_array_grow_by (cairo_array_t *array, unsigned int additional)
 {
     char *new_elements;
-    int old_size = array->size;
-    int required_size = array->num_elements + additional;
-    int new_size;
+    unsigned int old_size = array->size;
+    unsigned int required_size = array->num_elements + additional;
+    unsigned int new_size;
 
     assert (! array->is_snapshot);
 
+    /* check for integer overflow */
+    if (required_size > INT_MAX || required_size < array->num_elements)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
     if (required_size <= old_size)
 	return CAIRO_STATUS_SUCCESS;
 
     if (old_size == 0)
 	new_size = 1;
     else
 	new_size = old_size * 2;
 
deleted file mode 100644
--- a/gfx/cairo/cairo/src/cairo-atsui-font.c
+++ /dev/null
@@ -1,1035 +0,0 @@
-/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2004 Calum Robinson
- *
- * 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 Calum Robinson
- *
- * Contributor(s):
- *  Calum Robinson <calumr@mac.com>
- */
-
-#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)
-#define FixedToFloat(a)     ((float)(a) / fixed1)
-#define FloatToFixed(a)     ((Fixed)((float)(a) * fixed1))
-#endif
-
-/* If this isn't defined, we must be building on non-intel,
- * hence it will be 0.
- */
-#ifdef __BIG_ENDIAN__
-#define CG_BITMAP_BYTE_ORDER_FLAG 0
-#else    /* Little endian. */
-/* x86, and will be a 10.4u SDK; ByteOrder32Host will be defined */
-#define CG_BITMAP_BYTE_ORDER_FLAG kCGBitmapByteOrder32Host
-#endif
-
-/* Public in 10.4, present in 10.3.9 */
-CG_EXTERN CGRect CGRectApplyAffineTransform (CGRect, CGAffineTransform);
-
-/* Error code for path callbacks */
-static OSStatus CAIRO_CG_PATH_ERROR = 1001;
-
-typedef struct _cairo_atsui_font_face cairo_atsui_font_face_t;
-typedef struct _cairo_atsui_font cairo_atsui_font_t;
-typedef struct _cairo_atsui_scaled_path cairo_atsui_scaled_path_t;
-
-static cairo_status_t _cairo_atsui_font_create_scaled (cairo_font_face_t *font_face,
-						       ATSUFontID font_id,
-						       ATSUStyle style,
-						       const cairo_matrix_t *font_matrix,
-						       const cairo_matrix_t *ctm,
-						       const cairo_font_options_t *options,
-						       cairo_scaled_font_t **font_out);
-
-struct _cairo_atsui_font {
-    cairo_scaled_font_t base;
-
-    ATSUStyle style;
-    ATSUStyle unscaled_style;
-    ATSUFontID fontID;
-
-    Fixed size;
-    CGAffineTransform font_matrix;
-    CGFontRef cgfref;
-};
-
-struct _cairo_atsui_font_face {
-  cairo_font_face_t base;
-  ATSUFontID font_id;
-};
-
-struct _cairo_atsui_scaled_path {
-    cairo_path_fixed_t *path;
-    cairo_matrix_t *scale;
-};
-
-static void
-_cairo_atsui_font_face_destroy (void *abstract_face)
-{
-}
-
-static cairo_status_t
-_cairo_atsui_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 **font)
-{
-    cairo_status_t status;
-    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);
-    if (err != noErr)
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
-    err = ATSUSetAttributes(style, ARRAY_LENGTH (styleTags),
-                            styleTags, styleSizes, styleValues);
-    if (err != noErr) {
-        ATSUDisposeStyle (style);
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-    }
-
-    status = _cairo_atsui_font_create_scaled (&font_face->base, font_face->font_id, style,
-					    font_matrix, ctm, options, font);
-    if (status)
-        ATSUDisposeStyle (style);
-
-    return status;
-}
-
-static const cairo_font_face_backend_t _cairo_atsui_font_face_backend = {
-    CAIRO_FONT_TYPE_ATSUI,
-    _cairo_atsui_font_face_destroy,
-    _cairo_atsui_font_face_scaled_font_create
-};
-
-/**
- * cairo_atsui_font_face_create_for_atsu_font_id
- * @font_id: an ATSUFontID for the font.
- *
- * Creates a new font for the ATSUI font backend based on an
- * #ATSUFontID. This font can then be used with
- * cairo_set_font_face() or cairo_scaled_font_create().
- *
- * Return value: a newly created #cairo_font_face_t. Free with
- *  cairo_font_face_destroy() when you are done using it.
- *
- * Since: 1.4
- **/
-cairo_font_face_t *
-cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id)
-{
-  cairo_atsui_font_face_t *font_face;
-
-  font_face = malloc (sizeof (cairo_atsui_font_face_t));
-  if (!font_face) {
-    _cairo_error (CAIRO_STATUS_NO_MEMORY);
-    return (cairo_font_face_t *)&_cairo_font_face_nil;
-  }
-
-  font_face->font_id = font_id;
-
-    _cairo_font_face_init (&font_face->base, &_cairo_atsui_font_face_backend);
-
-    return &font_face->base;
-}
-
-static OSStatus
-CreateSizedCopyOfStyle(ATSUStyle inStyle, 
-		       const Fixed *theSize, 
-                      const CGAffineTransform *theTransform,
-                      ATSUStyle *style)
-{
-    OSStatus err;
-    const ATSUAttributeTag theFontStyleTags[] = { kATSUSizeTag, 
-                                                 kATSUFontMatrixTag };
-    const ByteCount theFontStyleSizes[] = { sizeof(Fixed), 
-                                           sizeof(CGAffineTransform) };
-    ATSUAttributeValuePtr theFontStyleValues[] = { (Fixed *)theSize, 
-                                                  (CGAffineTransform *)theTransform };
-
-    err = ATSUCreateAndCopyStyle (inStyle, style);
-    if (err != noErr)
-	return err;
-
-    err = ATSUSetAttributes(*style,
-                            sizeof(theFontStyleTags) /
-                            sizeof(ATSUAttributeTag), theFontStyleTags,
-                            theFontStyleSizes, theFontStyleValues);
-    if (err != noErr)
-	ATSUDisposeStyle (*style);
-
-    return err;
-}
-
-
-static cairo_status_t
-_cairo_atsui_font_set_metrics (cairo_atsui_font_t *font)
-{
-    cairo_status_t status;
-    ATSFontRef atsFont;
-    ATSFontMetrics metrics;
-    OSStatus err;
-
-    atsFont = FMGetATSFontRefFromFont(font->fontID);
-
-    if (atsFont) {
-        err = ATSFontGetHorizontalMetrics(atsFont, kATSOptionFlagsDefault, &metrics);
-
-        if (err == noErr) {
-	    cairo_font_extents_t extents;
-
-            extents.ascent = metrics.ascent;
-            extents.descent = -metrics.descent;
-            extents.height = extents.ascent + extents.descent + metrics.leading;
-            extents.max_x_advance = metrics.maxAdvanceWidth;
-
-            /* The FT backend doesn't handle max_y_advance either, so we'll ignore it for now. */
-            extents.max_y_advance = 0.0;
-
-	    status = _cairo_scaled_font_set_metrics (&font->base, &extents);
-
-            return status;
-        }
-    }
-
-    return _cairo_error (CAIRO_STATUS_NULL_POINTER);
-}
-
-static cairo_status_t
-_cairo_atsui_font_create_scaled (cairo_font_face_t *font_face,
-				 ATSUFontID font_id,
-				 ATSUStyle style,
-				 const cairo_matrix_t *font_matrix,
-				 const cairo_matrix_t *ctm,
-				 const cairo_font_options_t *options,
-				 cairo_scaled_font_t **font_out)
-{
-    cairo_atsui_font_t *font = NULL;
-    OSStatus err;
-    cairo_status_t status;
-    double xscale = 1.0;
-    double yscale = 1.0;
-
-    font = malloc(sizeof(cairo_atsui_font_t));
-    if (font == NULL)
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
-    memset (font, 0, sizeof(cairo_atsui_font_t));
-
-    status = _cairo_scaled_font_init (&font->base,
-				      font_face, font_matrix, ctm, options,
-				      &cairo_atsui_scaled_font_backend);
-    if (status) {
-	free (font);
-	return status;
-    }
-
-    status = _cairo_matrix_compute_scale_factors (&font->base.scale,
-						  &xscale, &yscale, 1);
-    if (status)
-	goto FAIL;
-
-    /* ATS can't handle 0-sized bits; we end up in an odd infinite loop
-     * if we send down a size of 0. */
-    if (xscale == 0.0) {
-	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	goto FAIL;
-    }
-
-    font->font_matrix = CGAffineTransformMake (1., 0.,
-					       0., yscale/xscale,
-					       0., 0.);
-    font->size = FloatToFixed (xscale);
-    font->style = NULL;
-
-    err = CreateSizedCopyOfStyle (style, &font->size, &font->font_matrix, &font->style);
-    if (err != noErr) {
-	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	goto FAIL;
-    }
-
-    {
-	Fixed theSize = FloatToFixed(1.0);
-	const ATSUAttributeTag theFontStyleTags[] = { kATSUSizeTag };
-	const ByteCount theFontStyleSizes[] = { sizeof(Fixed) };
-	ATSUAttributeValuePtr theFontStyleValues[] = { &theSize };
-
-	err = ATSUSetAttributes(style,
-				sizeof(theFontStyleTags) /
-				sizeof(ATSUAttributeTag), theFontStyleTags,
-				theFontStyleSizes, theFontStyleValues);
-	if (err != noErr) {
-	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    goto FAIL;
-	}
-    }
-
-    font->unscaled_style = style;
-    font->fontID = font_id;
-
-    *font_out = &font->base;
-
-    status = _cairo_atsui_font_set_metrics (font);
-
-    font->cgfref = 0;
-  FAIL:
-    if (status) {
-	if (font) {
-	    if (font->style)
-		ATSUDisposeStyle(font->style);
-	    _cairo_scaled_font_fini(&font->base);
-	    free (font);
-	}
-
-	return status;
-    }
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-_cairo_atsui_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 *options,
-			     cairo_scaled_font_t **font_out)
-{
-    cairo_status_t status;
-    ATSUStyle style;
-    ATSUFontID fontID;
-    OSStatus err;
-    Boolean isItalic, isBold;
-    const char *family = toy_face->family;
-    const char *full_name;
-
-    err = ATSUCreateStyle(&style);
-    if (err != noErr) {
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-    }
-
-    switch (toy_face->weight) {
-    case CAIRO_FONT_WEIGHT_BOLD:
-        isBold = true;
-        break;
-    case CAIRO_FONT_WEIGHT_NORMAL:
-    default:
-        isBold = false;
-        break;
-    }
-
-    switch (toy_face->slant) {
-    case CAIRO_FONT_SLANT_ITALIC:
-        isItalic = true;
-        break;
-    case CAIRO_FONT_SLANT_OBLIQUE:
-        isItalic = false;
-        break;
-    case CAIRO_FONT_SLANT_NORMAL:
-    default:
-        isItalic = false;
-        break;
-    }
-
-    /* The APIs for resolving a font family to a regular
-     * font face are all broken or deprecated in 10.4, so
-     * just try our best to find a sensible font.
-     * 
-     * First we try to map the CSS generic font families
-     * to fonts that should always be available. 
-     * If the family isn't a CSS family, guess that the 
-     * font family name is the same as the full name of the 
-     * regular font instance, which works in many cases. 
-     * 'Times' is one common exception to this rule, so it's
-     * handled specially.
-     */
-    if (!strcmp(family, "serif") || !strcmp(family, "Times"))
-	full_name = "Times Roman";
-    else if (!strcmp(family, "sans-serif") || !strcmp(family, "sans"))
-	full_name = "Helvetica";
-    else if (!strcmp(family, "cursive"))
-	full_name = "Apple Chancery";
-    else if (!strcmp(family, "fantasy"))
-	full_name = "American Typewriter";
-    else if (!strcmp(family, "monospace") || !strcmp(family, "mono"))
-	full_name = "Courier";
-    else
-	full_name = family;
-
-    err = ATSUFindFontFromName(family, strlen(family),
-                               kFontFullName,
-                               kFontNoPlatformCode,
-                               kFontRomanScript,
-                               kFontNoLanguageCode, &fontID);
-
-    if (err != noErr) {
-	/* Look for any font instance in the family. This may 
-	 * succeed, but select the bold or italic face. It only
-	 * selects the first loaded font instance in the family.
-	 */
-	err = ATSUFindFontFromName(family, strlen(family),
-				   kFontFamilyName,
-				   kFontNoPlatformCode,
-				   kFontRomanScript,
-				   kFontNoLanguageCode, &fontID);
-	if (err != noErr) {
-	    /* Last chance - try Courier. */
-	    full_name = "Courier";
-	    err = ATSUFindFontFromName(full_name, strlen(full_name),
-				       kFontFullName,
-				       kFontNoPlatformCode,
-				       kFontRomanScript,
-				       kFontNoLanguageCode, &fontID);
-	    if (err != noErr) {
-		ATSUDisposeStyle (style);
-		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    }
-	}
-    }
-
-    {
-	ATSUAttributeTag styleTags[] =
-	    { kATSUQDItalicTag, kATSUQDBoldfaceTag, kATSUFontTag };
-	ATSUAttributeValuePtr styleValues[] = { &isItalic, &isBold, &fontID };
-	ByteCount styleSizes[] =
-	    { sizeof(Boolean), sizeof(Boolean), sizeof(ATSUFontID) };
-
-	err = ATSUSetAttributes(style, ARRAY_LENGTH (styleTags),
-				styleTags, styleSizes, styleValues);
-	if (err != noErr) {
-	    ATSUDisposeStyle (style);
-	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	}
-    }
-
-    status = _cairo_atsui_font_create_scaled (&toy_face->base, fontID, style,
-					    font_matrix, ctm, options, font_out);
-    if (status)
-	ATSUDisposeStyle (style);
-
-    return status;
-}
-
-static void
-_cairo_atsui_font_fini(void *abstract_font)
-{
-    cairo_atsui_font_t *font = abstract_font;
-
-    if (font == NULL)
-        return;
-
-    if (font->style)
-        ATSUDisposeStyle(font->style);
-    if (font->unscaled_style)
-        ATSUDisposeStyle(font->unscaled_style);
-    if (font->cgfref)
-	CGFontRelease(font->cgfref);
-
-}
-
-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_status_t status;
-    cairo_text_extents_t extents = {0, 0, 0, 0, 0, 0};
-    OSStatus err;
-    ATSGlyphScreenMetrics metricsH;
-    GlyphID theGlyph = _cairo_atsui_scaled_glyph_index (scaled_glyph);
-    double xscale, yscale;
-
-    if (theGlyph == kATSDeletedGlyphcode) {
-	_cairo_scaled_glyph_set_metrics (scaled_glyph,
-					 &scaled_font->base,
-					 &extents);
-	return CAIRO_STATUS_SUCCESS;
-    }
-
-    /* We calculate the advance from the screen metrics. We
-     * could probably take this from the glyph path.
-     */
-    err = ATSUGlyphGetScreenMetrics (scaled_font->style,
-				     1, &theGlyph, 0, false,
-				     false, &metricsH);
-    if (err != noErr)
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
-    /* Scale down to font units.*/
-    status = _cairo_matrix_compute_scale_factors (&scaled_font->base.scale,
-						  &xscale, &yscale, 1);
-    if (status)
-	return status;
-
-    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;
-
-    _cairo_scaled_glyph_set_metrics (scaled_glyph,
-				     &scaled_font->base,
-				     &extents);
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static OSStatus
-_move_to (const Float32Point *point,
-	  void *callback_data)
-{
-    cairo_status_t status;
-    cairo_atsui_scaled_path_t *scaled_path = callback_data;
-    double x = point->x;
-    double y = point->y;
-    
-    cairo_matrix_transform_point (scaled_path->scale, &x, &y);
-    status = _cairo_path_fixed_close_path (scaled_path->path);
-    if (status)
-	return CAIRO_CG_PATH_ERROR;
-
-    status = _cairo_path_fixed_move_to (scaled_path->path,
-			       _cairo_fixed_from_double (x),
-			       _cairo_fixed_from_double (y));
-    if (status)
-	return CAIRO_CG_PATH_ERROR;
-    
-    return noErr;
-}
-
-static OSStatus
-_line_to (const Float32Point *point,
-	  void *callback_data)
-{
-    cairo_status_t status;
-    cairo_atsui_scaled_path_t *scaled_path = callback_data;
-    double x = point->x;
-    double y = point->y;
-    
-    cairo_matrix_transform_point (scaled_path->scale, &x, &y);
-
-    status = _cairo_path_fixed_line_to (scaled_path->path,
-			       _cairo_fixed_from_double (x),
-			       _cairo_fixed_from_double (y));
-    if (status)
-	return CAIRO_CG_PATH_ERROR;
-
-    return noErr;
-}
-
-static OSStatus
-_curve_to (const Float32Point *point1,
-	   const Float32Point *point2,
-	   const Float32Point *point3,
-	   void *callback_data)
-{
-    cairo_status_t status;
-    cairo_atsui_scaled_path_t *scaled_path = callback_data;
-    double x1 = point1->x;
-    double y1 = point1->y;
-    double x2 = point2->x;
-    double y2 = point2->y;
-    double x3 = point3->x;
-    double y3 = point3->y;
-    
-    cairo_matrix_transform_point (scaled_path->scale, &x1, &y1);
-    cairo_matrix_transform_point (scaled_path->scale, &x2, &y2);
-    cairo_matrix_transform_point (scaled_path->scale, &x3, &y3);
-
-    status = _cairo_path_fixed_curve_to (scaled_path->path,
-				_cairo_fixed_from_double (x1),
-				_cairo_fixed_from_double (y1),
-				_cairo_fixed_from_double (x2),
-				_cairo_fixed_from_double (y2),
-				_cairo_fixed_from_double (x3),
-				_cairo_fixed_from_double (y3));
-    if (status)
-	return CAIRO_CG_PATH_ERROR;
-
-    return noErr;
-}
-
-static OSStatus
-_close_path (void *callback_data)
-
-{
-    cairo_status_t status;
-    cairo_atsui_scaled_path_t *scaled_path = callback_data;
-
-    status = _cairo_path_fixed_close_path (scaled_path->path);
-    if (status)
-	return CAIRO_CG_PATH_ERROR;
-
-    return noErr;
-}
-
-static cairo_status_t
-_cairo_atsui_scaled_font_init_glyph_path (cairo_atsui_font_t *scaled_font,
-					  cairo_scaled_glyph_t *scaled_glyph)
-{
-    cairo_status_t status;
-    static ATSCubicMoveToUPP moveProc = NULL;
-    static ATSCubicLineToUPP lineProc = NULL;
-    static ATSCubicCurveToUPP curveProc = NULL;
-    static ATSCubicClosePathUPP closePathProc = NULL;
-    GlyphID theGlyph = _cairo_atsui_scaled_glyph_index (scaled_glyph);
-    OSStatus err;
-    cairo_atsui_scaled_path_t scaled_path;
-    cairo_matrix_t *font_to_device = &scaled_font->base.scale;
-    cairo_matrix_t unscaled_font_to_device;
-    double xscale;
-    double yscale;
-    
-    scaled_path.path = _cairo_path_fixed_create ();
-    if (!scaled_path.path)
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
-    if (theGlyph == kATSDeletedGlyphcode) {
-	_cairo_scaled_glyph_set_path (scaled_glyph, &scaled_font->base, 
-				      scaled_path.path);
-
-	return CAIRO_STATUS_SUCCESS;
-    }
-
-    /* extract the rotation/shear component of the scale matrix. */
-    status = _cairo_matrix_compute_scale_factors (font_to_device, &xscale, &yscale, 1);
-    if (status)
-	goto FAIL;
-
-    cairo_matrix_init (&unscaled_font_to_device, 
-		      font_to_device->xx, 
-		      font_to_device->yx, 
-		      font_to_device->xy, 
-		      font_to_device->yy, 0., 0.);
-    cairo_matrix_scale (&unscaled_font_to_device, 1.0/xscale, 1.0/yscale);
-
-    scaled_path.scale = &unscaled_font_to_device;
-
-    if (moveProc == NULL) {
-        moveProc = NewATSCubicMoveToUPP(_move_to);
-        lineProc = NewATSCubicLineToUPP(_line_to);
-        curveProc = NewATSCubicCurveToUPP(_curve_to);
-        closePathProc = NewATSCubicClosePathUPP(_close_path);
-    }
-
-    err = ATSUGlyphGetCubicPaths(scaled_font->style,
-				 theGlyph,
-				 moveProc,
-				 lineProc,
-				 curveProc,
-				 closePathProc, (void *)&scaled_path, &err);
-    if (err != noErr) {
-	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	goto FAIL;
-    }
-
-    _cairo_scaled_glyph_set_path (scaled_glyph, &scaled_font->base, 
-				  scaled_path.path);
-
-    return CAIRO_STATUS_SUCCESS;
-
-  FAIL:
-    _cairo_path_fixed_destroy (scaled_path.path);
-    return status;
-}
-
-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;
-
-	_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
-     * added to account for fractional sizes.
-     */
-    height = extents.ascent + extents.descent + 2.0;
-    bottom = -extents.descent - 1.0;
-
-    status = _cairo_matrix_compute_scale_factors (&base.scale,
-						  &xscale, &yscale, 1);
-    if (status)
-	return status;
-
-    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,
-				     false, &metricsH);    
-    if (err != noErr) {
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-    }
-
-    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:
-     * [1  0][xx yx][1  0]
-     * [0 -1][xy yy][0 -1]
-     */
-    transform = CGAffineTransformMake (base.scale.xx, 
-				      -base.scale.yx, 
-				      -base.scale.xy, 
-				      base.scale.yy, 
-				      0., 0.);
-    status = _cairo_matrix_compute_scale_factors (&base.scale,
-						  &xscale, &yscale, 1);
-    if (status)
-	return status;
-
-    transform = CGAffineTransformScale (transform, 1.0/xscale, 1.0/yscale);
-
-    /* Rotate the bounding box. This computes the smallest CGRect
-     * that would contain the bounding box after rotation.
-     */
-    bbox = CGRectApplyAffineTransform (CGRectMake (left, bottom, 
-						   width, height), transform);
-    /* Compute the smallest CGRect with  integer coordinates
-     * that contains the bounding box.
-     */
-    bbox = CGRectIntegral (bbox);
-
-    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;
-
-    /* Create a CGBitmapContext for the dest surface for drawing into */
-    {
-	CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray ();
-    
-	drawingContext = CGBitmapContextCreate (surface->data,
-						surface->width,
-						surface->height,
-						8,
-						surface->stride,
-						colorSpace,
-						kCGImageAlphaNone);
-	CGColorSpaceRelease (colorSpace);
-    }
-
-    if (!drawingContext) {
-	cairo_surface_destroy ((cairo_surface_t *)surface);
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-    }
-    
-    atsFont = FMGetATSFontRefFromFont (scaled_font->fontID);
-    cgFont = CGFontCreateWithPlatformFont (&atsFont);
-
-    CGContextSetFont (drawingContext, cgFont);
-
-    if (base.options.antialias ==  CAIRO_ANTIALIAS_NONE) {
-    	CGContextSetShouldAntialias (drawingContext, false);
-    }
-
-    /* solid white */
-    CGContextSetRGBFillColor (drawingContext, 1.0, 1.0, 1.0, 1.0);
-
-    CGContextSetFontSize (drawingContext, 1.0);
-    CGContextTranslateCTM (drawingContext, -left, -bottom);
-    CGContextScaleCTM (drawingContext, xscale, yscale);
-    CGContextSetTextMatrix (drawingContext, transform);
-    CGContextShowGlyphsAtPoint (drawingContext, 0, 0,  
-				&theGlyph, 1);
-
-    CGContextRelease (drawingContext);
-
-    /* correct for difference between cairo and quartz 
-     * coordinate systems.
-     */
-    cairo_surface_set_device_offset ((cairo_surface_t *)surface,
-				     -left, (bbox.size.height + bottom));
-    _cairo_scaled_glyph_set_surface (scaled_glyph,
-				     &base,
-				     surface);
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_int_status_t
-_cairo_atsui_font_scaled_glyph_init (void			*abstract_font,
-				     cairo_scaled_glyph_t	*scaled_glyph,
-				     cairo_scaled_glyph_info_t	 info)
-{
-    cairo_atsui_font_t *scaled_font = abstract_font;
-    cairo_status_t status;
-
-    if ((info & CAIRO_SCALED_GLYPH_INFO_METRICS) != 0) {
-      status = _cairo_atsui_font_init_glyph_metrics (scaled_font, scaled_glyph);
-      if (status)
-	return status;
-    }
-
-    if ((info & CAIRO_SCALED_GLYPH_INFO_PATH) != 0) {
-	status = _cairo_atsui_scaled_font_init_glyph_path (scaled_font, scaled_glyph);
-	if (status)
-	    return status;
-    }
-
-    if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
-	status = _cairo_atsui_scaled_font_init_glyph_surface (scaled_font, scaled_glyph);
-	if (status)
-	    return status;
-    }
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_int_status_t
-_cairo_atsui_font_text_to_glyphs (void		*abstract_font,
-				  double	 x,
-				  double	 y,
-				  const char	*utf8,
-				  cairo_glyph_t **glyphs,
-				  int		*num_glyphs)
-{
-    cairo_status_t status = CAIRO_STATUS_SUCCESS;
-    uint16_t *utf16;
-    int n16;
-    OSStatus err;
-    ATSUTextLayout textLayout;
-    ATSLayoutRecord *layoutRecords;
-    cairo_atsui_font_t *font = abstract_font;
-    ItemCount glyphCount;
-    int i;
-    CGPoint point;
-    double xscale, yscale;
-    CGAffineTransform device_to_user_scale;
-
-    status = _cairo_utf8_to_utf16 ((unsigned char *)utf8, -1, &utf16, &n16);
-    if (status)
-	goto BAIL3;
-
-    err = ATSUCreateTextLayout(&textLayout);
-    if (err != noErr) {
-	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	goto BAIL3;
-    }
-
-    err = ATSUSetTextPointerLocation(textLayout, utf16, 0, n16, n16);
-    if (err != noErr) {
-	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	goto BAIL2;
-    }
-
-    /* Set the style for all of the text */
-    err = ATSUSetRunStyle(textLayout,
-			  font->style, kATSUFromTextBeginning, kATSUToTextEnd);
-    if (err != noErr) {
-	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	goto BAIL2;
-    }
-
-    err = ATSUDirectGetLayoutDataArrayPtrFromTextLayout(textLayout,
-							0,
-							kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
-							(void *)&layoutRecords,
-							&glyphCount);
-    if (err != noErr) {
-	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	goto BAIL2;
-    }
-
-    status = _cairo_matrix_compute_scale_factors (&font->base.ctm,
-						  &xscale, &yscale, 1);
-    if (status)
-	goto BAIL2;
-
-    *num_glyphs = glyphCount - 1;
-    *glyphs =
-	(cairo_glyph_t *) _cairo_malloc_ab(*num_glyphs, sizeof (cairo_glyph_t));
-    if (*glyphs == NULL) {
-	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	goto BAIL1;
-    }
-
-    device_to_user_scale = 
-	CGAffineTransformInvert (CGAffineTransformMake (xscale, 0,
-							0, yscale,
-							0, 0));
-    for (i = 0; i < *num_glyphs; i++) {
-	(*glyphs)[i].index = layoutRecords[i].glyphID;
-	/* ATSLayoutRecord.realPos is in device units, convert to user units */
-	point = CGPointMake (FixedToFloat (layoutRecords[i].realPos), 0);
-	point = CGPointApplyAffineTransform (point, device_to_user_scale);
-
-	(*glyphs)[i].x = x + point.x;
-	(*glyphs)[i].y = y;
-    }
-
-  BAIL1:
-    /* TODO ignored return value. Is there anything we should do? */
-    ATSUDirectReleaseLayoutDataArrayPtr(NULL,
-					kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
-					(void *) &layoutRecords);
-  BAIL2:
-    ATSUDisposeTextLayout(textLayout);
-  BAIL3:
-    free (utf16);
-
-    return status;
-}
-
-ATSUStyle
-_cairo_atsui_scaled_font_get_atsu_style (cairo_scaled_font_t *sfont)
-{
-    cairo_atsui_font_t *afont = (cairo_atsui_font_t *) sfont;
-
-    return afont->style;
-}
-
-ATSUFontID
-_cairo_atsui_scaled_font_get_atsu_font_id (cairo_scaled_font_t *sfont)
-{
-    cairo_atsui_font_t *afont = (cairo_atsui_font_t *) sfont;
-
-    return afont->fontID;
-}
-
-CGFontRef
-_cairo_atsui_scaled_font_get_cg_font_ref (cairo_scaled_font_t *sfont)
-{
-    cairo_atsui_font_t *afont = (cairo_atsui_font_t *) sfont;
-
-    if (!afont->cgfref) {
-	ATSFontRef atsfref = FMGetATSFontRefFromFont (afont->fontID);
-	afont->cgfref = CGFontCreateWithPlatformFont (&atsfref);
-    }
-    return afont->cgfref;
-}
-
-
-static cairo_int_status_t
-_cairo_atsui_load_truetype_table (void	           *abstract_font,
-				  unsigned long     tag,
-				  long              offset,
-				  unsigned char    *buffer,
-				  unsigned long    *length)
-{
-    cairo_atsui_font_t *scaled_font = abstract_font;
-    ATSFontRef atsFont;
-    OSStatus err;
-	
-    atsFont = FMGetATSFontRefFromFont (scaled_font->fontID);
-    err = ATSFontGetTable ( atsFont, tag,
-			    (ByteOffset) offset,
-			    (ByteCount) *length,
-			    buffer,
-			    length);
-    if (err != noErr) {
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-    }
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-const cairo_scaled_font_backend_t cairo_atsui_scaled_font_backend = {
-    CAIRO_FONT_TYPE_ATSUI,
-    _cairo_atsui_font_create_toy,
-    _cairo_atsui_font_fini,
-    _cairo_atsui_font_scaled_glyph_init,
-    _cairo_atsui_font_text_to_glyphs,
-    NULL, /* ucs4_to_index */
-    NULL, /* show_glyphs */
-    _cairo_atsui_load_truetype_table,
-    NULL, /* map_glyphs_to_unicode */
-};
-
deleted file mode 100644
--- a/gfx/cairo/cairo/src/cairo-atsui.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2004 Calum Robinson
- *
- * 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 Calum Robinson
- *
- * Contributor(s):
- *	Calum Robinson <calumr@mac.com>
- */
-
-#ifndef CAIRO_ATSUI_H
-#define CAIRO_ATSUI_H
-
-#include <cairo.h>
-
-#if CAIRO_HAS_ATSUI_FONT
-
-/* ATSUI platform-specific font interface */
-
-#include <Carbon/Carbon.h>
-
-CAIRO_BEGIN_DECLS
-
-cairo_public cairo_font_face_t *
-cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id);
-
-CAIRO_END_DECLS
-
-#else  /* CAIRO_HAS_ATSUI_FONT */
-# error Cairo was not compiled with support for the atsui font backend
-#endif /* CAIRO_HAS_ATSUI_FONT */
-
-#endif /* CAIRO_ATSUI_H */
--- a/gfx/cairo/cairo/src/cairo-deprecated.h
+++ b/gfx/cairo/cairo/src/cairo-deprecated.h
@@ -45,16 +45,18 @@
  * #cairo_format_t).
  *
  * Additionally, the support for the RGB16_565 format was never
  * completely implemented. So while this format value is currently
  * deprecated, it may eventually acquire complete support in the future.
  */
 #define CAIRO_FORMAT_RGB16_565 4
 
+#define CAIRO_FONT_TYPE_ATSUI CAIRO_FONT_TYPE_QUARTZ
+
 #ifndef _CAIROINT_H_
 
 /* Obsolete functions. These definitions exist to coerce the compiler
  * into providing a little bit of guidance with its error
  * messages. The idea is to help users port their old code without
  * having to dig through lots of documentation.
  *
  * The first set of REPLACED_BY functions is for functions whose names
@@ -99,16 +101,17 @@
 #define cairo_set_pattern		 cairo_set_pattern_REPLACED_BY_cairo_set_source
 #define cairo_xlib_surface_create_for_pixmap_with_visual	cairo_xlib_surface_create_for_pixmap_with_visual_REPLACED_BY_cairo_xlib_surface_create
 #define cairo_xlib_surface_create_for_window_with_visual	cairo_xlib_surface_create_for_window_with_visual_REPLACED_BY_cairo_xlib_surface_create
 #define cairo_xcb_surface_create_for_pixmap_with_visual	cairo_xcb_surface_create_for_pixmap_with_visual_REPLACED_BY_cairo_xcb_surface_create
 #define cairo_xcb_surface_create_for_window_with_visual	cairo_xcb_surface_create_for_window_with_visual_REPLACED_BY_cairo_xcb_surface_create
 #define cairo_ps_surface_set_dpi	cairo_ps_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution
 #define cairo_pdf_surface_set_dpi	cairo_pdf_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution
 #define cairo_svg_surface_set_dpi	cairo_svg_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution
+#define cairo_atsui_font_face_create_for_atsu_font_id  cairo_atsui_font_face_create_for_atsu_font_id_REPLACED_BY_cairo_quartz_font_face_create_for_atsu_font_id
 
 #define cairo_current_path	     cairo_current_path_DEPRECATED_BY_cairo_copy_path
 #define cairo_current_path_flat	     cairo_current_path_flat_DEPRECATED_BY_cairo_copy_path_flat
 #define cairo_get_path		     cairo_get_path_DEPRECATED_BY_cairo_copy_path
 #define cairo_get_path_flat	     cairo_get_path_flat_DEPRECATED_BY_cairo_get_path_flat
 #define cairo_set_alpha		     cairo_set_alpha_DEPRECATED_BY_cairo_set_source_rgba_OR_cairo_paint_with_alpha
 #define cairo_show_surface	     cairo_show_surface_DEPRECATED_BY_cairo_set_source_surface_AND_cairo_paint
 #define cairo_copy		     cairo_copy_DEPRECATED_BY_cairo_create_AND_MANY_INDIVIDUAL_FUNCTIONS
--- a/gfx/cairo/cairo/src/cairo-features.h.in
+++ b/gfx/cairo/cairo/src/cairo-features.h.in
@@ -48,19 +48,19 @@
 #endif
 
 #ifndef cairo_public
 # define cairo_public
 #endif
 
 #define CAIRO_VERSION_MAJOR 1
 #define CAIRO_VERSION_MINOR 5
-#define CAIRO_VERSION_MICRO 12
+#define CAIRO_VERSION_MICRO 16
 
-#define CAIRO_VERSION_STRING "1.5.12"
+#define CAIRO_VERSION_STRING "1.5.16"
 
 @PS_SURFACE_FEATURE@
 
 @PDF_SURFACE_FEATURE@
 
 @SVG_SURFACE_FEATURE@
 
 @XLIB_SURFACE_FEATURE@
@@ -82,13 +82,13 @@
 @GLITZ_SURFACE_FEATURE@
 
 @DIRECTFB_SURFACE_FEATURE@
 
 @FT_FONT_FEATURE@
 
 @WIN32_FONT_FEATURE@
 
-@ATSUI_FONT_FEATURE@
+@QUARTZ_FONT_FEATURE@
 
 @PNG_FUNCTIONS_FEATURE@
 
 #endif
--- a/gfx/cairo/cairo/src/cairo-font-face.c
+++ b/gfx/cairo/cairo/src/cairo-font-face.c
@@ -428,16 +428,17 @@ cairo_font_face_t *
     if (status)
 	goto UNWIND_FONT_FACE_INIT;
 
     _cairo_toy_font_face_hash_table_unlock ();
 
     return &font_face->base;
 
  UNWIND_FONT_FACE_INIT:
+    _cairo_toy_font_face_fini (font_face);
  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;
 }
 
--- a/gfx/cairo/cairo/src/cairo-glitz-surface.c
+++ b/gfx/cairo/cairo/src/cairo-glitz-surface.c
@@ -812,17 +812,17 @@ static cairo_int_status_t
 	for (i = 0; i < gradient->n_stops; i++)
 	{
 	    pixels[i] =
 		(((int) (gradient->stops[i].color.alpha_short >> 8)) << 24) |
 		(((int) (gradient->stops[i].color.red_short   >> 8)) << 16) |
 		(((int) (gradient->stops[i].color.green_short >> 8)) << 8)  |
 		(((int) (gradient->stops[i].color.blue_short  >> 8)));
 
-	    params[n_base_params + 3 * i + 0] = gradient->stops[i].x;
+	    params[n_base_params + 3 * i + 0] = _cairo_fixed_16_16_from_double (gradient->stops[i].offset);
 	    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);
 
 	glitz_buffer_destroy (buffer);
--- a/gfx/cairo/cairo/src/cairo-gstate.c
+++ b/gfx/cairo/cairo/src/cairo-gstate.c
@@ -250,17 +250,17 @@ static cairo_status_t
  *
  * 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;
+    cairo_gstate_t *top = NULL;
     cairo_status_t status;
 
     status = _cairo_gstate_clone (*gstate, &top);
     if (status)
 	return status;
 
     top->next = *gstate;
     *gstate = top;
@@ -285,37 +285,16 @@ cairo_status_t
 
     *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;
-
-    status = _cairo_gstate_recursive_apply_clip_path (gstate, cpath->prev);
-    if (status)
-	return status;
-
-    return _cairo_clip_clip (&gstate->clip,
-			     &cpath->path,
-			     cpath->fill_rule,
-			     cpath->tolerance,
-			     cpath->antialias,
-			     gstate->target);
-}
-
 /**
  * _cairo_gstate_redirect_target:
  * @gstate: a #cairo_gstate_t
  * @child: the new child target
  *
  * 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().
--- a/gfx/cairo/cairo/src/cairo-hull.c
+++ b/gfx/cairo/cairo/src/cairo-hull.c
@@ -187,17 +187,17 @@ static void
 }
 
 /* Given a set of vertices, compute the convex hull using the Graham
    scan algorithm. */
 cairo_status_t
 _cairo_hull_compute (cairo_pen_vertex_t *vertices, int *num_vertices)
 {
     cairo_status_t status;
-    cairo_hull_t *hull;
+    cairo_hull_t *hull = NULL;
     int num_hull = *num_vertices;
 
     status = _cairo_hull_create (vertices, num_hull, &hull);
     if (status)
 	return status;
 
     qsort (hull + 1, num_hull - 1,
 	   sizeof (cairo_hull_t), _cairo_hull_vertex_compare);
--- a/gfx/cairo/cairo/src/cairo-image-surface.c
+++ b/gfx/cairo/cairo/src/cairo-image-surface.c
@@ -54,16 +54,17 @@ static cairo_format_t
     case PIXMAN_a1r5g5b5: case PIXMAN_x1r5g5b5: case PIXMAN_a1b5g5r5:
     case PIXMAN_x1b5g5r5: case PIXMAN_a4r4g4b4: case PIXMAN_x4r4g4b4:
     case PIXMAN_a4b4g4r4: case PIXMAN_x4b4g4r4: case PIXMAN_r3g3b2:
     case PIXMAN_b2g3r3:   case PIXMAN_a2r2g2b2: case PIXMAN_a2b2g2r2:
     case PIXMAN_c8:       case PIXMAN_g8:       case PIXMAN_x4a4:
     case PIXMAN_a4:       case PIXMAN_r1g2b1:   case PIXMAN_b1g2r1:
     case PIXMAN_a1r1g1b1: case PIXMAN_a1b1g1r1: case PIXMAN_c4:
     case PIXMAN_g4:       case PIXMAN_g1:
+    case PIXMAN_yuy2:     case PIXMAN_yv12:
     default:
 	return CAIRO_FORMAT_INVALID;
     }
 
     return CAIRO_FORMAT_INVALID;
 }
 
 static cairo_content_t
@@ -95,16 +96,18 @@ static cairo_content_t
     case PIXMAN_b2g3r3:
     case PIXMAN_c8:
     case PIXMAN_g8:
     case PIXMAN_r1g2b1:
     case PIXMAN_b1g2r1:
     case PIXMAN_c4:
     case PIXMAN_g4:
     case PIXMAN_g1:
+    case PIXMAN_yuy2:
+    case PIXMAN_yv12:
 	return CAIRO_CONTENT_COLOR;
     case PIXMAN_a8:
     case PIXMAN_a1:
     case PIXMAN_x4a4:
     case PIXMAN_a4:
 	return CAIRO_CONTENT_ALPHA;
     }
 
@@ -136,167 +139,144 @@ cairo_surface_t *
     surface->width = pixman_image_get_width (pixman_image);
     surface->height = pixman_image_get_height (pixman_image);
     surface->stride = pixman_image_get_stride (pixman_image);
     surface->depth = pixman_image_get_depth (pixman_image);
 
     return &surface->base;
 }
 
-/* XXX: This function should really live inside pixman. */
-pixman_format_code_t
-_pixman_format_from_masks (cairo_format_masks_t *masks)
+cairo_int_status_t
+_pixman_format_from_masks (cairo_format_masks_t *masks,
+			   pixman_format_code_t *format_ret)
 {
-    switch (masks->bpp) {
-    case 32:
-	if (masks->alpha_mask == 0xff000000 &&
-	    masks->red_mask   == 0x00ff0000 &&
-	    masks->green_mask == 0x0000ff00 &&
-	    masks->blue_mask  == 0x000000ff)
-	{
-	    return PIXMAN_a8r8g8b8;
-	}
-	if (masks->alpha_mask == 0x00000000 &&
-	    masks->red_mask   == 0x00ff0000 &&
-	    masks->green_mask == 0x0000ff00 &&
-	    masks->blue_mask  == 0x000000ff)
-	{
-	    return PIXMAN_x8r8g8b8;
-	}
-	if (masks->alpha_mask == 0xff000000 &&
-	    masks->red_mask   == 0x000000ff &&
-	    masks->green_mask == 0x0000ff00 &&
-	    masks->blue_mask  == 0x00ff0000)
-	{
-	    return PIXMAN_a8b8g8r8;
-	}
-	if (masks->alpha_mask == 0x00000000 &&
-	    masks->red_mask   == 0x000000ff &&
-	    masks->green_mask == 0x0000ff00 &&
-	    masks->blue_mask  == 0x00ff0000)
-	{
-	    return PIXMAN_x8b8g8r8;
-	}
-	break;
-    case 16:
-	if (masks->alpha_mask == 0x0000 &&
-	    masks->red_mask   == 0xf800 &&
-	    masks->green_mask == 0x07e0 &&
-	    masks->blue_mask  == 0x001f)
-	{
-	    return PIXMAN_r5g6b5;
-	}
-	if (masks->alpha_mask == 0x0000 &&
-	    masks->red_mask   == 0x7c00 &&
-	    masks->green_mask == 0x03e0 &&
-	    masks->blue_mask  == 0x001f)
-	{
-	    return PIXMAN_x1r5g5b5;
-	}
-	break;
-    case 8:
-	if (masks->alpha_mask == 0xff)
-	{
-	    return PIXMAN_a8;
-	}
-	break;
-    case 1:
-	if (masks->alpha_mask == 0x1)
-	{
-	    return PIXMAN_a1;
-	}
-	break;
+    pixman_format_code_t format;
+    int format_type;
+    int a, r, g, b;
+    cairo_format_masks_t format_masks;
+
+    a = _cairo_popcount (masks->alpha_mask);
+    r = _cairo_popcount (masks->red_mask);
+    g = _cairo_popcount (masks->green_mask);
+    b = _cairo_popcount (masks->blue_mask);
+
+    if (masks->red_mask) {
+	if (masks->red_mask > masks->blue_mask)
+	    format_type = PIXMAN_TYPE_ARGB;
+	else
+	    format_type = PIXMAN_TYPE_ABGR;
+    } else if (masks->alpha_mask) {
+	format_type = PIXMAN_TYPE_A;
+    } else {
+	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
-    fprintf (stderr,
-	     "Error: Cairo " PACKAGE_VERSION " does not yet support the requested image format:\n"
-	     "\tDepth: %d\n"
-	     "\tAlpha mask: 0x%08lx\n"
-	     "\tRed   mask: 0x%08lx\n"
-	     "\tGreen mask: 0x%08lx\n"
-	     "\tBlue  mask: 0x%08lx\n"
-	     "Please file an enhancement request (quoting the above) at:\n"
-	     PACKAGE_BUGREPORT "\n",
-	     masks->bpp, masks->alpha_mask,
-	     masks->red_mask, masks->green_mask, masks->blue_mask);
+    format = PIXMAN_FORMAT (masks->bpp, format_type, a, r, g, b);
+
+    if (! pixman_format_supported_destination (format))
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    /* Sanity check that we got out of PIXMAN_FORMAT exactly what we
+     * expected. This avoid any problems from something bizarre like
+     * alpha in the least-significant bits, or insane channel order,
+     * or whatever. */
+     _pixman_format_to_masks (format, &format_masks);
 
-    ASSERT_NOT_REACHED;
-    return 0;
+     if (masks->bpp        != format_masks.bpp        ||
+	 masks->red_mask   != format_masks.red_mask   ||
+	 masks->green_mask != format_masks.green_mask ||
+	 masks->blue_mask  != format_masks.blue_mask)
+     {
+	 return CAIRO_INT_STATUS_UNSUPPORTED;
+     }
+
+    *format_ret = format;
+    return CAIRO_STATUS_SUCCESS;
 }
 
-/* XXX: This function should really live inside pixman. */
+/* A mask consisting of N bits set to 1. */
+#define MASK(N) ((1 << (N))-1)
+
 void
-_pixman_format_to_masks (pixman_format_code_t	 pixman_format,
-			 uint32_t		*bpp,
-			 uint32_t		*red,
-			 uint32_t		*green,
-			 uint32_t		*blue)
+_pixman_format_to_masks (pixman_format_code_t	 format,
+			 cairo_format_masks_t	*masks)
 {
-    *red = 0x0;
-    *green = 0x0;
-    *blue = 0x0;
+    int a, r, g, b;
+
+    masks->bpp = PIXMAN_FORMAT_BPP (format);
 
-    switch (pixman_format)
-    {
-    case PIXMAN_a8r8g8b8:
-    case PIXMAN_x8r8g8b8:
-    default:
-	*bpp   = 32;
-	*red   = 0x00ff0000;
-	*green = 0x0000ff00;
-	*blue  = 0x000000ff;
-	break;
+    /* Number of bits in each channel */
+    a = PIXMAN_FORMAT_A (format);
+    r = PIXMAN_FORMAT_R (format);
+    g = PIXMAN_FORMAT_G (format);
+    b = PIXMAN_FORMAT_B (format);
 
-    case PIXMAN_a8b8g8r8:
-    case PIXMAN_x8b8g8r8:
-	*bpp   = 32;
-	*red   = 0x000000ff;
-	*green = 0x0000ff00;
-	*blue  = 0x00ff0000;
-	break;
-
-    case PIXMAN_r5g6b5:
-	*bpp   = 16;
-	*red   = 0xf800;
-	*green = 0x07e0;
-	*blue  = 0x001f;
-	break;
-
-    case PIXMAN_x1r5g5b5:
-	*bpp   = 16;
-	*red   = 0x7c00;
-	*green = 0x03e0;
-	*blue  = 0x001f;
-	break;
-
-    case PIXMAN_a8:
-	*bpp = 8;
-	break;
-
-    case PIXMAN_a1:
-	*bpp = 1;
-	break;
+    switch (PIXMAN_FORMAT_TYPE (format)) {
+    case PIXMAN_TYPE_ARGB:
+        masks->alpha_mask = MASK (a) << (r + g + b);
+        masks->red_mask   = MASK (r) << (g + b);
+        masks->green_mask = MASK (g) << (b);
+        masks->blue_mask  = MASK (b);
+        return;
+    case PIXMAN_TYPE_ABGR:
+        masks->alpha_mask = MASK (a) << (b + g + r);
+        masks->blue_mask  = MASK (b) << (g +r);
+        masks->green_mask = MASK (g) << (r);
+        masks->red_mask   = MASK (r);
+        return;
+    case PIXMAN_TYPE_A:
+        masks->alpha_mask = MASK (a);
+        masks->red_mask   = 0;
+        masks->green_mask = 0;
+        masks->blue_mask  = 0;
+        return;
+    case PIXMAN_TYPE_OTHER:
+    case PIXMAN_TYPE_COLOR:
+    case PIXMAN_TYPE_GRAY:
+    case PIXMAN_TYPE_YUY2:
+    case PIXMAN_TYPE_YV12:
+    default:
+        masks->alpha_mask = 0;
+        masks->red_mask   = 0;
+        masks->green_mask = 0;
+        masks->blue_mask  = 0;
+        return;
     }
 }
 
-
 /* XXX: This function really should be eliminated. We don't really
  * want to advertise a cairo image surface that supports any possible
  * format. A minimal step would be to replace this function with one
  * that accepts a #cairo_internal_format_t rather than mask values. */
 cairo_surface_t *
 _cairo_image_surface_create_with_masks (unsigned char	       *data,
 					cairo_format_masks_t   *masks,
 					int			width,
 					int			height,
 					int			stride)
 {
+    cairo_int_status_t status;
     pixman_format_code_t pixman_format;
 
-    pixman_format = _pixman_format_from_masks (masks);
+    status = _pixman_format_from_masks (masks, &pixman_format);
+    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
+	fprintf (stderr,
+		 "Error: Cairo " PACKAGE_VERSION " does not yet support the requested image format:\n"
+		 "\tDepth: %d\n"
+		 "\tAlpha mask: 0x%08lx\n"
+		 "\tRed   mask: 0x%08lx\n"
+		 "\tGreen mask: 0x%08lx\n"
+		 "\tBlue  mask: 0x%08lx\n"
+		 "Please file an enhancement request (quoting the above) at:\n"
+		 PACKAGE_BUGREPORT "\n",
+		 masks->bpp, masks->alpha_mask,
+		 masks->red_mask, masks->green_mask, masks->blue_mask);
+
+	ASSERT_NOT_REACHED;
+    }
 
     return _cairo_image_surface_create_with_pixman_format (data,
 							   pixman_format,
 							   width,
 							   height,
 							   stride);
 }
 
@@ -390,19 +370,16 @@ cairo_surface_t *
 {
     if (! CAIRO_CONTENT_VALID (content))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT));
 
     return cairo_image_surface_create (_cairo_format_from_content (content),
 				       width, height);
 }
 
-/* pixman required stride alignment in bytes.  should be power of two. */
-#define STRIDE_ALIGNMENT (sizeof (uint32_t))
-
 /**
  * cairo_format_stride_for_width:
  * @format: A #cairo_format_t value
  * @width: The desired width of an image surface to be created.
  *
  * This function provides a stride value that will respect all
  * alignment requirements of the accelerated image-rendering code
  * within cairo. Typical usage will be of the form:
@@ -434,17 +411,17 @@ cairo_format_stride_for_width (cairo_for
 	_cairo_error_throw (CAIRO_STATUS_INVALID_FORMAT);
 	return -1;
     }
 
     bpp = _cairo_format_bits_per_pixel (format);
     if ((unsigned) (width) >= (INT32_MAX - 7) / (unsigned) (bpp))
 	return -1;
 
-    return ((bpp*width+7)/8 + STRIDE_ALIGNMENT-1) & ~(STRIDE_ALIGNMENT-1);
+    return CAIRO_STRIDE_FOR_WIDTH_BPP (width, bpp);
 }
 slim_hidden_def (cairo_format_stride_for_width);
 
 /**
  * cairo_image_surface_create_for_data:
  * @data: a pointer to a buffer supplied by the application in which
  *     to write contents. This pointer must be suitably aligned for any
  *     kind of variable, (for example, a pointer returned by malloc).
@@ -493,17 +470,17 @@ cairo_image_surface_create_for_data (uns
 				     int		height,
 				     int		stride)
 {
     pixman_format_code_t pixman_format;
 
     if (! CAIRO_FORMAT_VALID (format))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT));
 
-    if ((stride & (STRIDE_ALIGNMENT-1)) != 0)
+    if ((stride & (CAIRO_STRIDE_ALIGNMENT-1)) != 0)
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE));
 
     pixman_format = _cairo_format_to_pixman_format_code (format);
 
     return _cairo_image_surface_create_with_pixman_format (data, pixman_format,
 							   width, height, stride);
 }
 slim_hidden_def (cairo_image_surface_create_for_data);
@@ -542,16 +519,17 @@ cairo_image_surface_get_data (cairo_surf
 
     if (! _cairo_surface_is_image (surface)) {
 	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 	return NULL;
     }
 
     return image_surface->data;
 }
+slim_hidden_def (cairo_image_surface_get_data);
 
 /**
  * cairo_image_surface_get_format:
  * @surface: a #cairo_image_surface_t
  *
  * Get the format of the surface.
  *
  * Return value: the format of the surface
@@ -638,16 +616,17 @@ cairo_image_surface_get_stride (cairo_su
 
     if (! _cairo_surface_is_image (surface)) {
 	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 	return 0;
     }
 
     return image_surface->stride;
 }
+slim_hidden_def (cairo_image_surface_get_stride);
 
 cairo_format_t
 _cairo_format_from_content (cairo_content_t content)
 {
     switch (content) {
     case CAIRO_CONTENT_COLOR:
 	return CAIRO_FORMAT_RGB24;
     case CAIRO_CONTENT_ALPHA:
--- a/gfx/cairo/cairo/src/cairo-meta-surface.c
+++ b/gfx/cairo/cairo/src/cairo-meta-surface.c
@@ -738,17 +738,21 @@ static cairo_status_t
 					    command->stroke.tolerance,
 					    command->stroke.antialias);
 	    break;
 	}
 	case CAIRO_COMMAND_FILL:
 	{
 	    cairo_command_t *stroke_command;
 
-	    stroke_command = (i < num_elements - 1) ? elements[i + 1] : NULL;
+	    if (type != CAIRO_META_CREATE_REGIONS)
+		stroke_command = (i < num_elements - 1) ? elements[i + 1] : NULL;
+	    else
+		stroke_command = NULL;
+
 	    if (stroke_command != NULL &&
 		type == CAIRO_META_REPLAY && region != CAIRO_META_REGION_ALL)
 	    {
 		if (stroke_command->header.region != region)
 		    stroke_command = NULL;
 	    }
 	    if (stroke_command != NULL &&
 		stroke_command->header.type == CAIRO_COMMAND_STROKE &&
@@ -778,24 +782,16 @@ static cairo_status_t
 						     stroke_command->stroke.op,
 						     &stroke_command->stroke.source.base,
 						     &stroke_command->stroke.style,
 						     &dev_ctm,
 						     &dev_ctm_inverse,
 						     stroke_command->stroke.tolerance,
 						     stroke_command->stroke.antialias);
 		i++;
-		if (type == CAIRO_META_CREATE_REGIONS) {
-		    if (status == CAIRO_STATUS_SUCCESS) {
-			stroke_command->header.region = CAIRO_META_REGION_NATIVE;
-		    } else if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK) {
-			stroke_command->header.region = CAIRO_META_REGION_IMAGE_FALLBACK;
-			status = CAIRO_STATUS_SUCCESS;
-		    }
-		}
 	    } else
 		status = _cairo_surface_fill (target,
 					      command->fill.op,
 					      &command->fill.source.base,
 					      dev_path,
 					      command->fill.fill_rule,
 					      command->fill.tolerance,
 					      command->fill.antialias);
--- a/gfx/cairo/cairo/src/cairo-output-stream-private.h
+++ b/gfx/cairo/cairo/src/cairo-output-stream-private.h
@@ -106,19 +106,16 @@ cairo_private void
 			    const void *data, size_t length);
 
 cairo_private void
 _cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
 				       const char *data,
 				       size_t length);
 
 cairo_private void
-_cairo_dtostr (char *buffer, size_t size, double d);
-
-cairo_private void
 _cairo_output_stream_vprintf (cairo_output_stream_t *stream,
 			      const char *fmt,
 			      va_list ap) CAIRO_PRINTF_FORMAT ( 2, 0);
 
 cairo_private void
 _cairo_output_stream_printf (cairo_output_stream_t *stream,
 			     const char *fmt,
 			     ...) CAIRO_PRINTF_FORMAT (2, 3);
--- a/gfx/cairo/cairo/src/cairo-output-stream.c
+++ b/gfx/cairo/cairo/src/cairo-output-stream.c
@@ -39,16 +39,36 @@
 #include "cairo-output-stream-private.h"
 #include "cairo-compiler-private.h"
 
 #include <stdio.h>
 #include <locale.h>
 #include <ctype.h>
 #include <errno.h>
 
+/* Numbers printed with %f are printed with this number of significant
+ * digits after the decimal.
+ */
+#define SIGNIFICANT_DIGITS_AFTER_DECIMAL 6
+
+/* Numbers printed with %g are assumed to only have CAIRO_FIXED_FRAC_BITS
+ * bits of precision available after the decimal point.
+ *
+ * FIXED_POINT_DECIMAL_DIGITS specifies the minimum number of decimal
+ * digits after the decimal point required to preserve the available
+ * precision.
+ *
+ * The conversion is:
+ *
+ * FIXED_POINT_DECIMAL_DIGITS = ceil( CAIRO_FIXED_FRAC_BITS * ln(2)/ln(10) )
+ *
+ * We can replace ceil(x) with (int)(x+1) since x will never be an
+ * integer for any likely value of CAIRO_FIXED_FRAC_BITS.
+ */
+#define FIXED_POINT_DECIMAL_DIGITS ((int)(CAIRO_FIXED_FRAC_BITS*0.301029996 + 1))
 
 void
 _cairo_output_stream_init (cairo_output_stream_t            *stream,
 			   cairo_output_stream_write_func_t  write_func,
 			   cairo_output_stream_close_func_t  close_func)
 {
     stream->write_func = write_func;
     stream->close_func = close_func;
@@ -231,28 +251,26 @@ void
 	    column = 0;
 	}
 	buffer[0] = hex_chars[(data[i] >> 4) & 0x0f];
 	buffer[1] = hex_chars[data[i] & 0x0f];
 	_cairo_output_stream_write (stream, buffer, 2);
     }
 }
 
-#define SIGNIFICANT_DIGITS_AFTER_DECIMAL 6
-
 /* Format a double in a locale independent way and trim trailing
  * zeros.  Based on code from Alex Larson <alexl@redhat.com>.
  * http://mail.gnome.org/archives/gtk-devel-list/2001-October/msg00087.html
  *
  * The code in the patch is copyright Red Hat, Inc under the LGPL, but
  * has been relicensed under the LGPL/MPL dual license for inclusion
  * into cairo (see COPYING). -- Kristian Høgsberg <krh@redhat.com>
  */
-void
-_cairo_dtostr (char *buffer, size_t size, double d)
+static void
+_cairo_dtostr (char *buffer, size_t size, double d, cairo_bool_t limited_precision)
 {
     struct lconv *locale_data;
     const char *decimal_point;
     int decimal_point_len;
     char *p;
     int decimal_len;
     int num_zeros, decimal_digits;
 
@@ -261,50 +279,54 @@ void
 	d = 0.0;
 
     locale_data = localeconv ();
     decimal_point = locale_data->decimal_point;
     decimal_point_len = strlen (decimal_point);
 
     assert (decimal_point_len != 0);
 
-    /* Using "%f" to print numbers less than 0.1 will result in
-     * reduced precision due to the default 6 digits after the
-     * decimal point.
-     *
-     * For numbers is < 0.1, we print with maximum precision and count
-     * the number of zeros between the decimal point and the first
-     * significant digit. We then print the number again with the
-     * number of decimal places that gives us the required number of
-     * significant digits. This ensures the number is correctly
-     * rounded.
-     */
-    if (fabs (d) >= 0.1) {
-	snprintf (buffer, size, "%f", d);
+    if (limited_precision) {
+	snprintf (buffer, size, "%.*f", FIXED_POINT_DECIMAL_DIGITS, d);
     } else {
-	snprintf (buffer, size, "%.18f", d);
-	p = buffer;
+	/* Using "%f" to print numbers less than 0.1 will result in
+	 * reduced precision due to the default 6 digits after the
+	 * decimal point.
+	 *
+	 * For numbers is < 0.1, we print with maximum precision and count
+	 * the number of zeros between the decimal point and the first
+	 * significant digit. We then print the number again with the
+	 * number of decimal places that gives us the required number of
+	 * significant digits. This ensures the number is correctly
+	 * rounded.
+	 */
+	if (fabs (d) >= 0.1) {
+	    snprintf (buffer, size, "%f", d);
+	} else {
+	    snprintf (buffer, size, "%.18f", d);
+	    p = buffer;
 
-	if (*p == '+' || *p == '-')
-	    p++;
+	    if (*p == '+' || *p == '-')
+		p++;
 
-	while (isdigit (*p))
-	    p++;
+	    while (isdigit (*p))
+		p++;
 
-	if (strncmp (p, decimal_point, decimal_point_len) == 0)
-	    p += decimal_point_len;
+	    if (strncmp (p, decimal_point, decimal_point_len) == 0)
+		p += decimal_point_len;
 
-	num_zeros = 0;
-	while (*p++ == '0')
-	    num_zeros++;
+	    num_zeros = 0;
+	    while (*p++ == '0')
+		num_zeros++;
 
-	decimal_digits = num_zeros + SIGNIFICANT_DIGITS_AFTER_DECIMAL;
+	    decimal_digits = num_zeros + SIGNIFICANT_DIGITS_AFTER_DECIMAL;
 
-	if (decimal_digits < 18)
-	    snprintf (buffer, size, "%.*f", decimal_digits, d);
+	    if (decimal_digits < 18)
+		snprintf (buffer, size, "%.*f", decimal_digits, d);
+	}
     }
     p = buffer;
 
     if (*p == '+' || *p == '-')
 	p++;
 
     while (isdigit (*p))
 	p++;
@@ -436,17 +458,20 @@ void
                           single_fmt, va_arg (ap, long int));
             }
 	    break;
 	case 's':
 	    snprintf (buffer, sizeof buffer,
 		      single_fmt, va_arg (ap, const char *));
 	    break;
 	case 'f':
-	    _cairo_dtostr (buffer, sizeof buffer, va_arg (ap, double));
+	    _cairo_dtostr (buffer, sizeof buffer, va_arg (ap, double), FALSE);
+	    break;
+	case 'g':
+	    _cairo_dtostr (buffer, sizeof buffer, va_arg (ap, double), TRUE);
 	    break;
 	case 'c':
 	    buffer[0] = va_arg (ap, int);
 	    buffer[1] = 0;
 	    break;
 	default:
 	    ASSERT_NOT_REACHED;
 	}
--- a/gfx/cairo/cairo/src/cairo-path-fixed.c
+++ b/gfx/cairo/cairo/src/cairo-path-fixed.c
@@ -608,18 +608,20 @@ cairo_bool_t
     other_buf = &other->buf_head.base;
     for (path_buf = &path->buf_head.base;
 	 path_buf != NULL;
 	 path_buf = path_buf->next)
     {
 	if (other_buf == NULL ||
 	    path_buf->num_ops != other_buf->num_ops ||
 	    path_buf->num_points != other_buf->num_points ||
-	    memcmp (path_buf->op, other_buf->op, path_buf->num_ops) != 0 ||
-	    memcmp (path_buf->points, other_buf->points, path_buf->num_points != 0))
+	    memcmp (path_buf->op, other_buf->op,
+		    sizeof (cairo_path_op_t) * path_buf->num_ops) != 0 ||
+	    memcmp (path_buf->points, other_buf->points,
+		    sizeof (cairo_point_t) * path_buf->num_points) != 0)
 	{
 	    return FALSE;
 	}
 	other_buf = other_buf->next;
     }
     return TRUE;
 }
 
--- a/gfx/cairo/cairo/src/cairo-pattern.c
+++ b/gfx/cairo/cairo/src/cairo-pattern.c
@@ -816,42 +816,40 @@ static void
 _cairo_pattern_add_color_stop (cairo_gradient_pattern_t *pattern,
 			       double			 offset,
 			       double			 red,
 			       double			 green,
 			       double			 blue,
 			       double			 alpha)
 {
     cairo_gradient_stop_t *stops;
-    cairo_fixed_t	   x;
     unsigned int	   i;
 
     if (pattern->n_stops >= pattern->stops_size) {
         cairo_status_t status = _cairo_pattern_gradient_grow (pattern);
 	if (status) {
 	    status = _cairo_pattern_set_error (&pattern->base, status);
 	    return;
 	}
     }
 
     stops = pattern->stops;
 
-    x = _cairo_fixed_from_double (offset);
     for (i = 0; i < pattern->n_stops; i++)
     {
-	if (x < stops[i].x)
+	if (offset < stops[i].offset)
 	{
 	    memmove (&stops[i + 1], &stops[i],
 		     sizeof (cairo_gradient_stop_t) * (pattern->n_stops - i));
 
 	    break;
 	}
     }
 
-    stops[i].x = x;
+    stops[i].offset = offset;
 
     stops[i].color.red   = red;
     stops[i].color.green = green;
     stops[i].color.blue  = blue;
     stops[i].color.alpha = alpha;
 
     stops[i].color.red_short   = _cairo_color_double_to_short (red);
     stops[i].color.green_short = _cairo_color_double_to_short (green);
@@ -1203,17 +1201,17 @@ static cairo_int_status_t
 
     if (pattern->n_stops > ARRAY_LENGTH(pixman_stops_static)) {
 	pixman_stops = _cairo_malloc_ab (pattern->n_stops, sizeof(pixman_gradient_stop_t));
 	if (pixman_stops == NULL)
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     for (i = 0; i < pattern->n_stops; i++) {
-	pixman_stops[i].x = _cairo_fixed_to_16_16 (pattern->stops[i].x);
+	pixman_stops[i].x = _cairo_fixed_16_16_from_double (pattern->stops[i].offset);
 	pixman_stops[i].color.red = pattern->stops[i].color.red_short;
 	pixman_stops[i].color.green = pattern->stops[i].color.green_short;
 	pixman_stops[i].color.blue = pattern->stops[i].color.blue_short;
 	pixman_stops[i].color.alpha = pattern->stops[i].color.alpha_short;
     }
 
     if (pattern->base.type == CAIRO_PATTERN_TYPE_LINEAR)
     {
@@ -2150,17 +2148,17 @@ cairo_pattern_get_color_stop_rgba (cairo
     if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR &&
 	pattern->type != CAIRO_PATTERN_TYPE_RADIAL)
 	return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
 
     if (index < 0 || (unsigned int) index >= gradient->n_stops)
 	return _cairo_error (CAIRO_STATUS_INVALID_INDEX);
 
     if (offset)
-	*offset = _cairo_fixed_to_double(gradient->stops[index].x);
+	*offset = gradient->stops[index].offset;
     if (red)
 	*red = gradient->stops[index].color.red;
     if (green)
 	*green = gradient->stops[index].color.green;
     if (blue)
 	*blue = gradient->stops[index].color.blue;
     if (alpha)
 	*alpha = gradient->stops[index].color.alpha;
--- a/gfx/cairo/cairo/src/cairo-pdf-operators.c
+++ b/gfx/cairo/cairo/src/cairo-pdf-operators.c
@@ -103,16 +103,17 @@ void
  */
 typedef struct _word_wrap_stream {
     cairo_output_stream_t base;
     cairo_output_stream_t *output;
     int max_column;
     int column;
     cairo_bool_t last_write_was_space;
     cairo_bool_t in_hexstring;
+    cairo_bool_t empty_hexstring;
 } word_wrap_stream_t;
 
 static int
 _count_word_up_to (const unsigned char *s, int length)
 {
     int word = 0;
 
     while (length--) {
@@ -131,21 +132,25 @@ static int
 /* Count up to either the end of the ASCII hexstring or the number
  * of columns remaining.
  */
 static int
 _count_hexstring_up_to (const unsigned char *s, int length, int columns)
 {
     int word = 0;
 
-    while (length-- && columns--) {
+    while (length--) {
 	if (*s++ != '>')
 	    word++;
 	else
 	    return word;
+
+	columns--;
+	if (columns < 0 && word > 1)
+	    return word;
     }
 
     return word;
 }
 
 static cairo_status_t
 _word_wrap_stream_write (cairo_output_stream_t  *base,
 			 const unsigned char	*data,
@@ -153,58 +158,68 @@ static cairo_status_t
 {
     word_wrap_stream_t *stream = (word_wrap_stream_t *) base;
     cairo_bool_t newline;
     int word;
 
     while (length) {
 	if (*data == '<') {
 	    stream->in_hexstring = TRUE;
+	    stream->empty_hexstring = TRUE;
+	    stream->last_write_was_space = FALSE;
 	    data++;
 	    length--;
 	    _cairo_output_stream_printf (stream->output, "<");
+	    stream->column++;
 	} else if (*data == '>') {
 	    stream->in_hexstring = FALSE;
+	    stream->last_write_was_space = FALSE;
 	    data++;
 	    length--;
 	    _cairo_output_stream_printf (stream->output, ">");
+	    stream->column++;
 	} else if (isspace (*data)) {
 	    newline =  (*data == '\n' || *data == '\r');
 	    if (! newline && stream->column >= stream->max_column) {
 		_cairo_output_stream_printf (stream->output, "\n");
 		stream->column = 0;
 	    }
 	    _cairo_output_stream_write (stream->output, data, 1);
 	    data++;
 	    length--;
-	    if (newline)
+	    if (newline) {
 		stream->column = 0;
+	    }
 	    else
 		stream->column++;
 	    stream->last_write_was_space = TRUE;
 	} else {
 	    if (stream->in_hexstring) {
 		word = _count_hexstring_up_to (data, length,
 					       MAX (stream->max_column - stream->column, 0));
 	    } else {
 		word = _count_word_up_to (data, length);
 	    }
 	    /* Don't wrap if this word is a continuation of a non hex
 	     * string word from a previous call to write. */
-	    if (stream->column + word >= stream->max_column &&
-		(stream->last_write_was_space || stream->in_hexstring))
-	    {
-		_cairo_output_stream_printf (stream->output, "\n");
-		stream->column = 0;
+	    if (stream->column + word >= stream->max_column) {
+		if (stream->last_write_was_space ||
+		    (stream->in_hexstring && !stream->empty_hexstring))
+		{
+		    _cairo_output_stream_printf (stream->output, "\n");
+		    stream->column = 0;
+		}
 	    }
 	    _cairo_output_stream_write (stream->output, data, word);
 	    data += word;
 	    length -= word;
 	    stream->column += word;
 	    stream->last_write_was_space = FALSE;
+	    if (stream->in_hexstring)
+		stream->empty_hexstring = FALSE;
 	}
     }
 
     return _cairo_output_stream_get_status (stream->output);
 }
 
 static cairo_status_t
 _word_wrap_stream_close (cairo_output_stream_t *base)
@@ -231,16 +246,17 @@ static cairo_output_stream_t *
     _cairo_output_stream_init (&stream->base,
 			       _word_wrap_stream_write,
 			       _word_wrap_stream_close);
     stream->output = output;
     stream->max_column = max_column;
     stream->column = 0;
     stream->last_write_was_space = FALSE;
     stream->in_hexstring = FALSE;
+    stream->empty_hexstring = TRUE;
 
     return &stream->base;
 }
 
 typedef struct _pdf_path_info {
     cairo_output_stream_t   *output;
     cairo_matrix_t	    *path_transform;
     cairo_line_cap_t         line_cap;
@@ -254,17 +270,17 @@ static cairo_status_t
     pdf_path_info_t *info = closure;
     double x = _cairo_fixed_to_double (point->x);
     double y = _cairo_fixed_to_double (point->y);
 
     info->last_move_to_point = *point;
     info->has_sub_path = FALSE;
     cairo_matrix_transform_point (info->path_transform, &x, &y);
     _cairo_output_stream_printf (info->output,
-				 "%f %f m ", x, y);
+				 "%g %g m ", x, y);
 
     return _cairo_output_stream_get_status (info->output);
 }
 
 static cairo_status_t
 _cairo_pdf_path_line_to (void *closure, cairo_point_t *point)
 {
     pdf_path_info_t *info = closure;
@@ -277,17 +293,17 @@ static cairo_status_t
 	point->y == info->last_move_to_point.y)
     {
 	return CAIRO_STATUS_SUCCESS;
     }
 
     info->has_sub_path = TRUE;
     cairo_matrix_transform_point (info->path_transform, &x, &y);
     _cairo_output_stream_printf (info->output,
-				 "%f %f l ", x, y);
+				 "%g %g l ", x, y);
 
     return _cairo_output_stream_get_status (info->output);
 }
 
 static cairo_status_t
 _cairo_pdf_path_curve_to (void          *closure,
 			  cairo_point_t *b,
 			  cairo_point_t *c,
@@ -301,17 +317,17 @@ static cairo_status_t
     double dx = _cairo_fixed_to_double (d->x);
     double dy = _cairo_fixed_to_double (d->y);
 
     info->has_sub_path = TRUE;
     cairo_matrix_transform_point (info->path_transform, &bx, &by);
     cairo_matrix_transform_point (info->path_transform, &cx, &cy);
     cairo_matrix_transform_point (info->path_transform, &dx, &dy);
     _cairo_output_stream_printf (info->output,
-				 "%f %f %f %f %f %f c ",
+				 "%g %g %g %g %g %g c ",
 				 bx, by, cx, cy, dx, dy);
     return _cairo_output_stream_get_status (info->output);
 }
 
 static cairo_status_t
 _cairo_pdf_path_close_path (void *closure)
 {
     pdf_path_info_t *info = closure;
@@ -334,46 +350,46 @@ static cairo_status_t
     double x1 = _cairo_fixed_to_double (box->p1.x);
     double y1 = _cairo_fixed_to_double (box->p1.y);
     double x2 = _cairo_fixed_to_double (box->p2.x);
     double y2 = _cairo_fixed_to_double (box->p2.y);
 
     cairo_matrix_transform_point (info->path_transform, &x1, &y1);
     cairo_matrix_transform_point (info->path_transform, &x2, &y2);
     _cairo_output_stream_printf (info->output,
-				 "%f %f %f %f re ",
+				 "%g %g %g %g re ",
 				 x1, y1, x2 - x1, y2 - y1);
 
     return _cairo_output_stream_get_status (info->output);
 }
 
 /* The line cap value is needed to workaround the fact that PostScript
  * and PDF semantics for stroking degenerate sub-paths do not match
  * cairo semantics. (PostScript draws something for any line cap
  * value, while cairo draws something only for round caps).
  *
  * When using this function to emit a path to be filled, rather than
  * stroked, simply pass %CAIRO_LINE_CAP_ROUND which will guarantee that
  * the stroke workaround will not modify the path being emitted.
  */
 static cairo_status_t
-_cairo_pdf_operators_emit_path (cairo_pdf_operators_t 	*pdf_operators,
+_cairo_pdf_operators_emit_path (cairo_pdf_operators_t	*pdf_operators,
 				cairo_path_fixed_t      *path,
 				cairo_matrix_t          *path_transform,
 				cairo_line_cap_t         line_cap)
 {
     cairo_output_stream_t *word_wrap;
     cairo_status_t status, status2;
     pdf_path_info_t info;
     cairo_box_t box;
 
-    word_wrap = _word_wrap_stream_create (pdf_operators->stream, 79);
+    word_wrap = _word_wrap_stream_create (pdf_operators->stream, 72);
     status = _cairo_output_stream_get_status (word_wrap);
     if (status)
-	return status;
+	return _cairo_output_stream_destroy (word_wrap);
 
     info.output = word_wrap;
     info.path_transform = path_transform;
     info.line_cap = line_cap;
     if (_cairo_path_fixed_is_rectangle (path, &box)) {
 	status = _cairo_pdf_path_rectangle (&info, &box);
     } else {
 	status = _cairo_path_fixed_interpret (path,
@@ -459,17 +475,18 @@ static int
     default:
 	ASSERT_NOT_REACHED;
 	return 0;
     }
 }
 
 static cairo_int_status_t
 _cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t	*pdf_operators,
-					cairo_stroke_style_t	*style)
+					cairo_stroke_style_t	*style,
+					double			 scale)
 {
     double *dash = style->dash;
     int num_dashes = style->num_dashes;
     double dash_offset = style->dash_offset;
 
     /* PostScript has "special needs" when it comes to zero-length
      * dash segments with butt caps. It apparently (at least
      * according to ghostscript) draws hairlines for this
@@ -530,80 +547,171 @@ static cairo_int_status_t
 		if (i == 2)
 		    i = -2;
 	    }
 	}
     }
 
     _cairo_output_stream_printf (pdf_operators->stream,
 				 "%f w\n",
-				 style->line_width);
+				 style->line_width * scale);
 
     _cairo_output_stream_printf (pdf_operators->stream,
 				 "%d J\n",
 				 _cairo_pdf_line_cap (style->line_cap));
 
     _cairo_output_stream_printf (pdf_operators->stream,
 				 "%d j\n",
 				 _cairo_pdf_line_join (style->line_join));
 
     if (num_dashes) {
 	int d;
 
 	_cairo_output_stream_printf (pdf_operators->stream, "[");
 	for (d = 0; d < num_dashes; d++)
-	    _cairo_output_stream_printf (pdf_operators->stream, " %f", dash[d]);
+	    _cairo_output_stream_printf (pdf_operators->stream, " %f", dash[d] * scale);
 	_cairo_output_stream_printf (pdf_operators->stream, "] %f d\n",
-				     dash_offset);
+				     dash_offset * scale);
     } else {
 	_cairo_output_stream_printf (pdf_operators->stream, "[] 0.0 d\n");
     }
     if (dash != style->dash)
         free (dash);
 
     _cairo_output_stream_printf (pdf_operators->stream,
 				 "%f M ",
 				 style->miter_limit < 1.0 ? 1.0 : style->miter_limit);
 
     return _cairo_output_stream_get_status (pdf_operators->stream);
 }
 
+/* Scale the matrix so the largest absolute value of the non
+ * translation components is 1.0. Return the scale required to restore
+ * the matrix to the original values.
+ *
+ * eg the matrix  [ 100  0  0  50   20   10  ]
+ *
+ * is rescaled to [  1   0  0  0.5  0.2  0.1 ]
+ * and the scale returned is 100
+ */
+static void
+_cairo_matrix_factor_out_scale (cairo_matrix_t *m, double *scale)
+{
+    double s;
+
+    s = fabs (m->xx);
+    if (fabs (m->xy) > s)
+	s = fabs (m->xy);
+    if (fabs (m->yx) > s)
+	s = fabs (m->yx);
+    if (fabs (m->yy) > s)
+	s = fabs (m->yy);
+    *scale = s;
+    s = 1.0/s;
+    cairo_matrix_scale (m, s, s);
+}
+
+static cairo_int_status_t
+_cairo_pdf_operators_emit_stroke (cairo_pdf_operators_t	*pdf_operators,
+				  cairo_path_fixed_t	*path,
+				  cairo_stroke_style_t	*style,
+				  cairo_matrix_t	*ctm,
+				  cairo_matrix_t	*ctm_inverse,
+				  const char 		*pdf_operator)
+{
+    cairo_status_t status;
+    cairo_matrix_t m, path_transform;
+    cairo_bool_t has_ctm = TRUE;
+    double scale = 1.0;
+
+    /* Optimize away the stroke ctm when it does not affect the
+     * stroke. There are other ctm cases that could be optimized
+     * however this is the most common.
+     */
+    if (fabs(ctm->xx) == 1.0 && fabs(ctm->yy) == 1.0 &&
+	fabs(ctm->xy) == 0.0 && fabs(ctm->yx) == 0.0)
+    {
+	has_ctm = FALSE;
+    }
+
+    /* The PDF CTM is transformed to the user space CTM when stroking
+     * so the corect pen shape will be used. This also requires that
+     * the path be transformed to user space when emitted. The
+     * conversion of path coordinates to user space may cause rounding
+     * errors. For example the device space point (1.234, 3.142) when
+     * transformed to a user space CTM of [100 0 0 100 0 0] will be
+     * emitted as (0.012, 0.031).
+     *
+     * To avoid the rounding problem we scale the user space CTM
+     * matrix so that all the non translation components of the matrix
+     * are <= 1. The line width and and dashes are scaled by the
+     * inverse of the scale applied to the CTM. This maintains the
+     * shape of the stroke pen while keeping the user space CTM within
+     * the range that maximizes the precision of the emitted path.
+     */
+    if (has_ctm) {
+	m = *ctm;
+	/* Zero out the translation since it does not affect the pen
+	 * shape however it may cause unnecessary digits to be emitted.
+	 */
+	m.x0 = 0.0;
+	m.y0 = 0.0;
+	_cairo_matrix_factor_out_scale (&m, &scale);
+	path_transform = m;
+	status = cairo_matrix_invert (&path_transform);
+	if (status)
+	    return status;
+
+	cairo_matrix_multiply (&m, &m, &pdf_operators->cairo_to_pdf);
+    }
+
+    status = _cairo_pdf_operators_emit_stroke_style (pdf_operators, style, scale);
+    if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
+	return CAIRO_STATUS_SUCCESS;
+    if (status)
+	return status;
+
+    if (has_ctm) {
+	_cairo_output_stream_printf (pdf_operators->stream,
+				     "q %f %f %f %f %f %f cm\n",
+				     m.xx, m.yx, m.xy, m.yy,
+				     m.x0, m.y0);
+    } else {
+	path_transform = pdf_operators->cairo_to_pdf;
+    }
+
+    status = _cairo_pdf_operators_emit_path (pdf_operators,
+					     path,
+					     &path_transform,
+					     style->line_cap);
+    if (status)
+	return status;
+
+    _cairo_output_stream_printf (pdf_operators->stream, "%s", pdf_operator);
+    if (has_ctm)
+	_cairo_output_stream_printf (pdf_operators->stream, " Q");
+
+    _cairo_output_stream_printf (pdf_operators->stream, "\n");
+
+    return _cairo_output_stream_get_status (pdf_operators->stream);
+}
 
 cairo_int_status_t
 _cairo_pdf_operators_stroke (cairo_pdf_operators_t	*pdf_operators,
 			     cairo_path_fixed_t		*path,
 			     cairo_stroke_style_t	*style,
 			     cairo_matrix_t		*ctm,
 			     cairo_matrix_t		*ctm_inverse)
 {
-    cairo_status_t status;
-    cairo_matrix_t m;
-
-    status = _cairo_pdf_operators_emit_stroke_style (pdf_operators, style);
-    if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
-	return CAIRO_STATUS_SUCCESS;
-    if (status)
-	return status;
-
-    cairo_matrix_multiply (&m, ctm, &pdf_operators->cairo_to_pdf);
-    _cairo_output_stream_printf (pdf_operators->stream,
-				 "q %f %f %f %f %f %f cm\n",
-				 m.xx, m.yx, m.xy, m.yy,
-				 m.x0, m.y0);
-
-    status = _cairo_pdf_operators_emit_path (pdf_operators,
+    return _cairo_pdf_operators_emit_stroke (pdf_operators,
 					     path,
+					     style,
+					     ctm,
 					     ctm_inverse,
-					     style->line_cap);
-    if (status)
-	return status;
-
-    _cairo_output_stream_printf (pdf_operators->stream, "S Q\n");
-
-    return _cairo_output_stream_get_status (pdf_operators->stream);
+					     "S");
 }
 
 cairo_int_status_t
 _cairo_pdf_operators_fill (cairo_pdf_operators_t	*pdf_operators,
 			   cairo_path_fixed_t		*path,
 			   cairo_fill_rule_t		fill_rule)
 {
     const char *pdf_operator;
@@ -637,55 +745,35 @@ cairo_int_status_t
 cairo_int_status_t
 _cairo_pdf_operators_fill_stroke (cairo_pdf_operators_t 	*pdf_operators,
 				  cairo_path_fixed_t		*path,
 				  cairo_fill_rule_t	 	 fill_rule,
 				  cairo_stroke_style_t	        *style,
 				  cairo_matrix_t		*ctm,
 				  cairo_matrix_t		*ctm_inverse)
 {
-    const char *pdf_operator;
-    cairo_status_t status;
-    cairo_matrix_t m;
-
-    status = _cairo_pdf_operators_emit_stroke_style (pdf_operators, style);
-    if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
-	return CAIRO_STATUS_SUCCESS;
-    if (status)
-	return status;
-
-    cairo_matrix_multiply (&m, ctm, &pdf_operators->cairo_to_pdf);
-    _cairo_output_stream_printf (pdf_operators->stream,
-				 "q %f %f %f %f %f %f cm\n",
-				 m.xx, m.yx, m.xy, m.yy,
-				 m.x0, m.y0);
-
-    status = _cairo_pdf_operators_emit_path (pdf_operators,
-					     path,
-					     ctm_inverse,
-					     style->line_cap);
-    if (status)
-	return status;
+    const char *operator;
 
     switch (fill_rule) {
     case CAIRO_FILL_RULE_WINDING:
-	pdf_operator = "B";
+	operator = "B";
 	break;
     case CAIRO_FILL_RULE_EVEN_ODD:
-	pdf_operator = "B*";
+	operator = "B*";
 	break;
     default:
 	ASSERT_NOT_REACHED;
     }
 
-    _cairo_output_stream_printf (pdf_operators->stream,
-				 "%s Q\n",
-				 pdf_operator);
-
-    return _cairo_output_stream_get_status (pdf_operators->stream);
+    return _cairo_pdf_operators_emit_stroke (pdf_operators,
+					     path,
+					     style,
+					     ctm,
+					     ctm_inverse,
+					     operator);
 }
 
 #define GLYPH_POSITION_TOLERANCE 0.001
 
 cairo_int_status_t
 _cairo_pdf_operators_show_glyphs (cairo_pdf_operators_t		*pdf_operators,
 				  cairo_glyph_t			*glyphs,
 				  int				 num_glyphs,
@@ -698,20 +786,20 @@ cairo_int_status_t
     double Tlm_x = 0, Tlm_y = 0;
     double Tm_x = 0, y;
     int i, hex_width;
     cairo_output_stream_t *word_wrap_stream;
 
     for (i = 0; i < num_glyphs; i++)
 	cairo_matrix_transform_point (&pdf_operators->cairo_to_pdf, &glyphs[i].x, &glyphs[i].y);
 
-    word_wrap_stream = _word_wrap_stream_create (pdf_operators->stream, 79);
+    word_wrap_stream = _word_wrap_stream_create (pdf_operators->stream, 72);
     status = _cairo_output_stream_get_status (word_wrap_stream);
     if (status)
-	return status;
+	return _cairo_output_stream_destroy (word_wrap_stream);
 
     _cairo_output_stream_printf (word_wrap_stream,
 				 "BT\n");
 
     if (scaled_font->scale.xy == 0.0 &&
         scaled_font->scale.yx == 0.0)
         diagonal = TRUE;
     else
@@ -794,38 +882,62 @@ cairo_int_status_t
                                                  "[<%0*x",
                                                  hex_width,
                                                  subset_glyph.subset_glyph_index);
                     Tm_x += subset_glyph.x_advance;
                     in_TJ = TRUE;
                 } else {
                     if (fabs((glyphs[i].x - Tm_x)/scaled_font->scale.xx) > GLYPH_POSITION_TOLERANCE) {
                         double delta = glyphs[i].x - Tm_x;
+			int rounded_delta;
 
-                        _cairo_output_stream_printf (word_wrap_stream,
-                                                     "> %f <",
-                                                     -1000.0*delta/scaled_font->scale.xx);
+			delta = -1000.0*delta/scaled_font->scale.xx;
+			/* As the delta is in 1/1000 of a unit of text
+			 * space, rounding to an integer should still
+			 * provide sufficient precision. We round the
+			 * delta before adding to Tm_x so that we keep
+			 * track of the accumulated rounding error in
+			 * the PDF interpreter and compensate for it
+			 * when calculating subsequent deltas.
+			 */
+			rounded_delta = _cairo_lround (delta);
+			if (rounded_delta != 0) {
+			    _cairo_output_stream_printf (word_wrap_stream,
+							 "> %d <",
+							 rounded_delta);
+			}
+
+			/* Convert the rounded delta back to cairo
+			 * space before adding to the current text
+			 * position. */
+			delta = rounded_delta*scaled_font->scale.xx/-1000.0;
                         Tm_x += delta;
                     }
                     _cairo_output_stream_printf (word_wrap_stream,
                                                  "%0*x",
                                                  hex_width,
                                                  subset_glyph.subset_glyph_index);
                     Tm_x += subset_glyph.x_advance;
                 }
             }
             else
             {
                 if (in_TJ) {
                     if (fabs((glyphs[i].x - Tm_x)/scaled_font->scale.xx) > GLYPH_POSITION_TOLERANCE) {
                         double delta = glyphs[i].x - Tm_x;
+			int rounded_delta;
 
-                        _cairo_output_stream_printf (word_wrap_stream,
-                                                     "> %f <",
-                                                     -1000.0*delta/scaled_font->scale.xx);
+			delta = -1000.0*delta/scaled_font->scale.xx;
+			rounded_delta = _cairo_lround (delta);
+			if (rounded_delta != 0) {
+			    _cairo_output_stream_printf (word_wrap_stream,
+							 "> %d <",
+							 rounded_delta);
+			}
+			delta = rounded_delta*scaled_font->scale.xx/-1000.0;
                         Tm_x += delta;
                     }
                     _cairo_output_stream_printf (word_wrap_stream,
                                                  "%0*x>] TJ\n",
                                                  hex_width,
                                                  subset_glyph.subset_glyph_index);
                     Tm_x += subset_glyph.x_advance;
                     in_TJ = FALSE;
--- a/gfx/cairo/cairo/src/cairo-pdf-surface.c
+++ b/gfx/cairo/cairo/src/cairo-pdf-surface.c
@@ -388,20 +388,25 @@ static cairo_bool_t
  * target. Otherwise return %CAIRO_STATUS_SURFACE_TYPE_MISMATCH.
  */
 static cairo_status_t
 _extract_pdf_surface (cairo_surface_t		 *surface,
 		      cairo_pdf_surface_t	**pdf_surface)
 {
     cairo_surface_t *target;
 
+    if (surface->status)
+	return surface->status;
+
     if (! _cairo_surface_is_paginated (surface))
 	return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 
     target = _cairo_paginated_surface_get_target (surface);
+    if (target->status)
+	return target->status;
 
     if (! _cairo_surface_is_pdf (target))
 	return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 
     *pdf_surface = (cairo_pdf_surface_t *) target;
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -1240,46 +1245,39 @@ static cairo_status_t
     cairo_status_t status = CAIRO_STATUS_SUCCESS;
     char *alpha;
     unsigned long alpha_size;
     uint32_t *pixel32;
     uint8_t *pixel8;
     int i, x, y;
     cairo_bool_t opaque;
     uint8_t a;
-    int src_bit, dst_bit;
 
     /* This is the only image format we support, which simplifies things. */
     assert (image->format == CAIRO_FORMAT_ARGB32 ||
 	    image->format == CAIRO_FORMAT_A8 ||
 	    image->format == CAIRO_FORMAT_A1 );
 
     stream_ret->id = 0;
 
     if (image->format == CAIRO_FORMAT_A1) {
-	/* We allocate using slightly different math so that we can get
-	 * the overflow checking from _cairo_malloc_ab, but alpha_size
-	 * needs to be the correct size for emitting the data in the PDF.
-	 */
-	alpha_size = (image->width*image->height + 7) / 8;
+	alpha_size = (image->width + 7) / 8 * image->height;
 	alpha = _cairo_malloc_ab ((image->width+7) / 8, image->height);
     } else {
 	alpha_size = image->height * image->width;
 	alpha = _cairo_malloc_ab (image->height, image->width);
     }
 
     if (alpha == NULL) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto CLEANUP;
     }
 
     opaque = TRUE;
     i = 0;
-    src_bit = 0;
-    dst_bit = 7;
     for (y = 0; y < image->height; y++) {
 	if (image->format == CAIRO_FORMAT_ARGB32) {
 	    pixel32 = (uint32_t *) (image->data + y * image->stride);
 
 	    for (x = 0; x < image->width; x++, pixel32++) {
 		a = (*pixel32 & 0xff000000) >> 24;
 		alpha[i++] = a;
 		if (a != 0xff)
@@ -1292,31 +1290,22 @@ static cairo_status_t
 		a = *pixel8;
 		alpha[i++] = a;
 		if (a != 0xff)
 		    opaque = FALSE;
 	    }
 	} else { /* image->format == CAIRO_FORMAT_A1 */
 	    pixel8 = (uint8_t *) (image->data + y * image->stride);
 
-	    for (x = 0; x < image->width; x++, pixel8++) {
-		if (dst_bit == 7)
-		    alpha[i] = 0;
-		if ((*pixel8 >> src_bit) & 1) {
-			opaque = FALSE;
-			alpha[i] |= (1 << dst_bit);
-		}
-		if (++src_bit > 7) {
-		    src_bit = 0;
-		    pixel8++;
-		}
-		if (--dst_bit < 0) {
-		    dst_bit = 7;
-		    i++;
-		}
+	    for (x = 0; x < (image->width + 7) / 8; x++, pixel8++) {
+		a = *pixel8;
+		a = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (a);
+		alpha[i++] = a;
+		if (a != 0xff)
+		    opaque = FALSE;
 	    }
 	}
     }
 
     /* Bail out without emitting smask if it's all opaque. */
     if (opaque)
 	goto CLEANUP_ALPHA;
 
@@ -1489,28 +1478,30 @@ BAIL:
 static cairo_status_t
 _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t  *surface,
 				      cairo_surface_t      *meta_surface,
 				      cairo_pdf_resource_t *resource)
 {
     double old_width, old_height;
     cairo_matrix_t old_cairo_to_pdf;
     cairo_paginated_mode_t old_paginated_mode;
+    cairo_clip_t *old_clip;
     cairo_rectangle_int_t meta_extents;
-    cairo_status_t status;
+    cairo_status_t status, status2;
     int alpha = 0;
 
     status = _cairo_surface_get_extents (meta_surface, &meta_extents);
     if (status)
 	return status;
 
     old_width = surface->width;
     old_height = surface->height;
     old_cairo_to_pdf = surface->cairo_to_pdf;
     old_paginated_mode = surface->paginated_mode;
+    old_clip = _cairo_surface_get_clip (&surface->base);
     surface->width = meta_extents.width;
     surface->height = meta_extents.height;
     /* Patterns are emitted after fallback images. The paginated mode
      * needs to be set to _RENDER while the meta surface is replayed
      * back to this surface.
      */
     surface->paginated_mode = CAIRO_PAGINATED_MODE_RENDER;
     cairo_matrix_init (&surface->cairo_to_pdf, 1, 0, 0, -1, 0, surface->height);
@@ -1543,16 +1534,20 @@ static cairo_status_t
 
     status = _cairo_pdf_surface_close_content_stream (surface);
 
  CLEANUP_GROUP:
     surface->width = old_width;
     surface->height = old_height;
     surface->paginated_mode = old_paginated_mode;
     surface->cairo_to_pdf = old_cairo_to_pdf;
+    status2 = _cairo_surface_set_clip (&surface->base, old_clip);
+    if (status == CAIRO_STATUS_SUCCESS)
+	status = status2;
+
     _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
 						  &surface->cairo_to_pdf);
 
     return status;
 }
 
 static cairo_status_t
 _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t	*surface,
@@ -1976,17 +1971,17 @@ static cairo_status_t
 
     for (i = 0; i < n_stops; i++) {
 	stops[i].color[0] = pattern->stops[i].color.red;
 	stops[i].color[1] = pattern->stops[i].color.green;
 	stops[i].color[2] = pattern->stops[i].color.blue;
 	stops[i].color[3] = pattern->stops[i].color.alpha;
         if (!CAIRO_ALPHA_IS_OPAQUE (stops[i].color[3]))
             emit_alpha = TRUE;
-	stops[i].offset = _cairo_fixed_to_double (pattern->stops[i].x);
+	stops[i].offset = pattern->stops[i].offset;
     }
 
     if (pattern->base.extend == CAIRO_EXTEND_REPEAT ||
 	pattern->base.extend == CAIRO_EXTEND_REFLECT) {
 	if (stops[0].offset > COLOR_STOP_EPSILON) {
 	    if (pattern->base.extend == CAIRO_EXTEND_REFLECT)
 		memcpy (allstops, stops, sizeof (cairo_pdf_color_stop_t));
 	    else
@@ -2215,18 +2210,18 @@ static cairo_status_t
     extend = cairo_pattern_get_extend (pdf_pattern->pattern);
 
     pat_to_pdf = pattern->base.base.matrix;
     status = cairo_matrix_invert (&pat_to_pdf);
     /* cairo_pattern_set_matrix ensures the matrix is invertible */
     assert (status == CAIRO_STATUS_SUCCESS);
 
     cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &surface->cairo_to_pdf);
-    first_stop = _cairo_fixed_to_double (gradient->stops[0].x);
-    last_stop = _cairo_fixed_to_double (gradient->stops[gradient->n_stops - 1].x);
+    first_stop = gradient->stops[0].offset;
+    last_stop = gradient->stops[gradient->n_stops - 1].offset;
 
     if (pattern->base.base.extend == CAIRO_EXTEND_REPEAT ||
 	pattern->base.base.extend == CAIRO_EXTEND_REFLECT) {
 	double dx, dy;
 	int x_rep = 0, y_rep = 0;
 
 	x1 = _cairo_fixed_to_double (pattern->p1.x);
 	y1 = _cairo_fixed_to_double (pattern->p1.y);
@@ -4143,35 +4138,41 @@ static cairo_int_status_t
 				      cairo_pattern_t      *pattern)
 {
     if (surface->force_fallbacks && surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     if (! _pattern_supported (pattern))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    if (op == CAIRO_OPERATOR_OVER || op == CAIRO_OPERATOR_SOURCE) {
+    if (op == CAIRO_OPERATOR_OVER) {
 	if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
 	    cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) pattern;
+
 	    if ( _cairo_surface_is_meta (surface_pattern->surface))
 		return CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN;
 	}
     }
 
     if (op == CAIRO_OPERATOR_OVER)
 	return CAIRO_STATUS_SUCCESS;
 
     /* The SOURCE operator is supported if the pattern is opaque or if
      * there is nothing painted underneath. */
     if (op == CAIRO_OPERATOR_SOURCE) {
 	if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
 	    cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) pattern;
 
-	    return _cairo_pdf_surface_analyze_surface_pattern_transparency (surface,
-									    surface_pattern);
+	    if (_cairo_surface_is_meta (surface_pattern->surface)) {
+		if (_cairo_pattern_is_opaque (pattern))
+		    return CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN;
+	    } else {
+		return _cairo_pdf_surface_analyze_surface_pattern_transparency (surface,
+										surface_pattern);
+	    }
 	}
 
 	if (_cairo_pattern_is_opaque (pattern))
 	    return CAIRO_STATUS_SUCCESS;
 	else
 	    return CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
     }
 
@@ -4531,29 +4532,24 @@ static cairo_int_status_t
      * for us. During render we may still encounter unsupported
      * combinations of fill/stroke patterns. However we can return
      * unsupported anytime to let the _fill and _stroke functions take
      * over.
      */
     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    /* Fill-stroke with patterns requiring an SMask are not currently
-     * implemented. Non opaque stroke patterns are not supported
-     * because the PDF fill-stroke operator does not blend a
-     * transparent stroke with the fill.
+    /* PDF rendering of fill-stroke is not the same as cairo when
+     * either the fill or stroke is not opaque.
      */
-    if (fill_source->type == CAIRO_PATTERN_TYPE_LINEAR ||
-        fill_source->type == CAIRO_PATTERN_TYPE_RADIAL)
+    if ( !_cairo_pattern_is_opaque (fill_source) ||
+	 !_cairo_pattern_is_opaque (stroke_source))
     {
-        if (!_cairo_pattern_is_opaque (fill_source))
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
-    if (!_cairo_pattern_is_opaque (stroke_source))
-	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     fill_pattern_res.id = 0;
     gstate_res.id = 0;
     status = _cairo_pdf_surface_add_pdf_pattern (surface, fill_source,
 						 &fill_pattern_res,
 						 &gstate_res);
     if (status)
 	return status;
--- a/gfx/cairo/cairo/src/cairo-png.c
+++ b/gfx/cairo/cairo/src/cairo-png.c
@@ -206,19 +206,18 @@ write_png (cairo_surface_t	*surface,
     png_set_IHDR (png, info,
 		  image->width,
 		  image->height, depth,
 		  png_color_type,
 		  PNG_INTERLACE_NONE,
 		  PNG_COMPRESSION_TYPE_DEFAULT,
 		  PNG_FILTER_TYPE_DEFAULT);
 
-    white.red = 0xff;
-    white.blue = 0xff;
-    white.green = 0xff;
+    white.gray = (1 << depth) - 1;
+    white.red = white.blue = white.green = white.gray;
     png_set_bKGD (png, info, &white);
 
     png_convert_from_time_t (&pt, time (NULL));
     png_set_tIME (png, info, &pt);
 
     /* We have to call png_write_info() before setting up the write
      * transformation, since it stores data internally in 'png'
      * that is needed for the write transformation functions to work.
--- a/gfx/cairo/cairo/src/cairo-ps-surface.c
+++ b/gfx/cairo/cairo/src/cairo-ps-surface.c
@@ -175,21 +175,22 @@ static void
 				 "/Tf { pop /cairo_font exch def } bind def\n"
 				 "/BT { } bind def\n"
 				 "/ET { } bind def\n"
 				 "/Tj { show } bind def\n"
 				 "/TJ {\n"
 				 "  {\n"
 				 "    dup\n"
 				 "    type /stringtype eq\n"
-				 "    { show } { -0.0001 mul 0 rmoveto } ifelse\n"
+				 "    { show } { -0.001 mul 0 cairo_font_matrix dtransform rmoveto } ifelse\n"
 				 "  } forall\n"
 				 "} bind def\n"
 				 "/Td { moveto } bind def\n"
-				 "/Tm { 6 array astore cairo_font exch selectfont 0 0 moveto } bind def\n"
+				 "/Tm { 6 array astore dup /cairo_font_matrix exch def\n"
+				 "      cairo_font exch selectfont 0 0 moveto } bind def\n"
 				 "/g { setgray } bind def\n"
 				 "/rg { setrgbcolor } bind def\n");
 
     _cairo_output_stream_printf (surface->final_stream,
 				 "%%%%EndProlog\n");
 
     num_comments = _cairo_array_num_elements (&surface->dsc_setup_comments);
     if (num_comments) {
@@ -853,20 +854,25 @@ static cairo_bool_t
  * target. Otherwise return %CAIRO_STATUS_SURFACE_TYPE_MISMATCH.
  */
 static cairo_status_t
 _extract_ps_surface (cairo_surface_t	 *surface,
 		     cairo_ps_surface_t **ps_surface)
 {
     cairo_surface_t *target;
 
+    if (surface->status)
+	return surface->status;
+
     if (! _cairo_surface_is_paginated (surface))
 	return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 
     target = _cairo_paginated_surface_get_target (surface);
+    if (target->status)
+	return target->status;
 
     if (! _cairo_surface_is_ps (target))
 	return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 
     *ps_surface = (cairo_ps_surface_t *) target;
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -2024,27 +2030,29 @@ bail1:
 
 static cairo_status_t
 _cairo_ps_surface_emit_meta_surface (cairo_ps_surface_t  *surface,
 				     cairo_surface_t      *meta_surface)
 {
     double old_width, old_height;
     cairo_matrix_t old_cairo_to_ps;
     cairo_content_t old_content;
+    cairo_clip_t *old_clip;
     cairo_rectangle_int_t meta_extents;
     cairo_status_t status;
 
     status = _cairo_surface_get_extents (meta_surface, &meta_extents);
     if (status)
 	return status;
 
     old_content = surface->content;
     old_width = surface->width;
     old_height = surface->height;
     old_cairo_to_ps = surface->cairo_to_ps;
+    old_clip = _cairo_surface_get_clip (&surface->base);
     surface->width = meta_extents.width;
     surface->height = meta_extents.height;
     cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, -1, 0, surface->height);
     _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
 						  &surface->cairo_to_ps);
     _cairo_output_stream_printf (surface->stream,
 				 "  q\n"
 				 "  0 0 %f %f rectclip\n",
@@ -2066,16 +2074,20 @@ static cairo_status_t
 	return status;
 
     _cairo_output_stream_printf (surface->stream,
 				 "  Q\n");
     surface->content = old_content;
     surface->width = old_width;
     surface->height = old_height;
     surface->cairo_to_ps = old_cairo_to_ps;
+    status = _cairo_surface_set_clip (&surface->base, old_clip);
+    if (status)
+	return status;
+
     _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
 						  &surface->cairo_to_ps);
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static void
 _cairo_ps_surface_flatten_transparency (cairo_ps_surface_t	*surface,
@@ -2130,27 +2142,33 @@ static cairo_status_t
 {
     cairo_status_t          status;
 
     if (_cairo_surface_is_meta (pattern->surface)) {
 	cairo_surface_t *meta_surface = pattern->surface;
 	cairo_rectangle_int_t pattern_extents;
 
 	status = _cairo_surface_get_extents (meta_surface, &pattern_extents);
+	if (status)
+	    return status;
+
 	*width = pattern_extents.width;
 	*height = pattern_extents.height;
     } else {
 	status = _cairo_surface_acquire_source_image (pattern->surface,
 						      &surface->image,
 						      &surface->image_extra);
+	if (status)
+	    return status;
+
 	*width = surface->image->width;
 	*height = surface->image->height;
     }
 
-    return status;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
 _cairo_ps_surface_emit_surface (cairo_ps_surface_t      *surface,
 				cairo_surface_pattern_t *pattern,
 				cairo_operator_t	 op)
 {
     cairo_status_t status;
@@ -2201,16 +2219,24 @@ static cairo_status_t
 	_cairo_output_stream_printf (surface->stream,
 				     "%% Fallback Image: x=%f, y=%f, w=%d, h=%d res=%fdpi size=%ld\n",
 				     -cairo_p2d.x0/scale,
 				     -cairo_p2d.y0/scale,
 				     (int)(width/scale),
 				     (int)(height/scale),
 				     scale*72,
 				     (long)width*height*3);
+    } else {
+	if (op == CAIRO_OPERATOR_SOURCE) {
+	    _cairo_output_stream_printf (surface->stream,
+					 "%d g 0 0 %f %f rectfill\n",
+					 surface->content == CAIRO_CONTENT_COLOR ? 0 : 1,
+					 surface->width,
+					 surface->height);
+	}
     }
 
     status = cairo_matrix_invert (&cairo_p2d);
     /* cairo_pattern_set_matrix ensures the matrix is invertible */
     assert (status == CAIRO_STATUS_SUCCESS);
 
     ps_p2d = surface->cairo_to_ps;
     cairo_matrix_multiply (&ps_p2d, &cairo_p2d, &ps_p2d);
@@ -2307,16 +2333,22 @@ static cairo_status_t
 	ystep = 0;
     }
 
     _cairo_output_stream_printf (surface->stream,
 				 "/CairoPattern {\n");
 
     old_use_string_datasource = surface->use_string_datasource;
     surface->use_string_datasource = TRUE;
+    if (op == CAIRO_OPERATOR_SOURCE) {
+	_cairo_output_stream_printf (surface->stream,
+				     "%d g 0 0 %f %f rectfill\n",
+				     surface->content == CAIRO_CONTENT_COLOR ? 0 : 1,
+				     xstep, ystep);
+    }
     status = _cairo_ps_surface_emit_surface (surface, pattern, op);
     if (status)
 	return status;
 
     surface->use_string_datasource = old_use_string_datasource;
     _cairo_output_stream_printf (surface->stream,
 				 "} bind def\n");
 
@@ -2338,20 +2370,27 @@ static cairo_status_t
 				     "      [-1 0 0  1 %d 0] concat CairoPattern\n"
 				     "      CairoPattern\n"
 				     "   } bind\n",
 				     pattern_width*2, pattern_height*2,
 				     pattern_width*2,
 				     pattern_height*2,
 				     pattern_width*2);
     } else {
+	if (op == CAIRO_OPERATOR_SOURCE) {
+	    _cairo_output_stream_printf (surface->stream,
+					 "   /BBox [0 0 %f %f]\n",
+					 xstep, ystep);
+	} else {
+	    _cairo_output_stream_printf (surface->stream,
+					 "   /BBox [0 0 %d %d]\n",
+					 pattern_width, pattern_height);
+	}
 	_cairo_output_stream_printf (surface->stream,
-				     "   /BBox [0 0 %d %d]\n"
-				     "   /PaintProc { CairoPattern }\n",
-				     pattern_width, pattern_height);
+				     "   /PaintProc { CairoPattern }\n");
     }
 
     _cairo_output_stream_printf (surface->stream,
 				 ">>\n");
 
     status = _cairo_surface_get_extents (&surface->base, &surface_extents);
     if (status)
 	return status;
@@ -2461,17 +2500,17 @@ static cairo_status_t
 
     for (i = 0; i < n_stops; i++) {
 	cairo_gradient_stop_t *stop = &pattern->stops[i];
 
 	stops[i].color[0] = stop->color.red;
 	stops[i].color[1] = stop->color.green;
 	stops[i].color[2] = stop->color.blue;
 	stops[i].color[3] = stop->color.alpha;
-	stops[i].offset = _cairo_fixed_to_double (pattern->stops[i].x);
+	stops[i].offset = pattern->stops[i].offset;
     }
 
     if (pattern->base.extend == CAIRO_EXTEND_REPEAT ||
 	pattern->base.extend == CAIRO_EXTEND_REFLECT) {
 	if (stops[0].offset > COLOR_STOP_EPSILON) {
 	    if (pattern->base.extend == CAIRO_EXTEND_REFLECT)
 		memcpy (allstops, stops, sizeof (cairo_ps_color_stop_t));
 	    else
@@ -2580,18 +2619,18 @@ static cairo_status_t
     extend = cairo_pattern_get_extend (&pattern->base.base);
 
     pat_to_ps = pattern->base.base.matrix;
     status = cairo_matrix_invert (&pat_to_ps);
     /* cairo_pattern_set_matrix ensures the matrix is invertible */
     assert (status == CAIRO_STATUS_SUCCESS);
 
     cairo_matrix_multiply (&pat_to_ps, &pat_to_ps, &surface->cairo_to_ps);
-    first_stop = _cairo_fixed_to_double (gradient->stops[0].x);
-    last_stop = _cairo_fixed_to_double (gradient->stops[gradient->n_stops - 1].x);
+    first_stop = gradient->stops[0].offset;
+    last_stop = gradient->stops[gradient->n_stops - 1].offset;
 
     if (pattern->base.base.extend == CAIRO_EXTEND_REPEAT ||
 	pattern->base.base.extend == CAIRO_EXTEND_REFLECT) {
 	double dx, dy;
 	int x_rep = 0, y_rep = 0;
 
 	x1 = _cairo_fixed_to_double (pattern->p1.x);
 	y1 = _cairo_fixed_to_double (pattern->p1.y);
@@ -2856,45 +2895,38 @@ static void
 
 static cairo_int_status_t
 _cairo_ps_surface_paint (void			*abstract_surface,
 			 cairo_operator_t	 op,
 			 cairo_pattern_t	*source)
 {
     cairo_ps_surface_t *surface = abstract_surface;
     cairo_output_stream_t *stream = surface->stream;
-    cairo_rectangle_int_t extents, surface_extents;
+    cairo_rectangle_int_t extents;
     cairo_status_t status;
 
     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
 	return _cairo_ps_surface_analyze_operation (surface, op, source);
 
     assert (_cairo_ps_surface_operation_supported (surface, op, source));
 
 #if DEBUG_PS
     _cairo_output_stream_printf (stream,
 				 "%% _cairo_ps_surface_paint\n");
 #endif
 
-    status = _cairo_surface_get_extents (&surface->base, &surface_extents);
-    if (status)
-	return status;
-
-    status = _cairo_pattern_get_extents (source, &extents);
+    status = _cairo_surface_get_extents (&surface->base, &extents);
     if (status)
 	return status;
 
-    _cairo_rectangle_intersect (&extents, &surface_extents);
-
     if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
-	source->extend == CAIRO_EXTEND_NONE)
+	(source->extend == CAIRO_EXTEND_NONE ||
+	 source->extend == CAIRO_EXTEND_PAD))
     {
-	_cairo_output_stream_printf (stream, "q %d %d %d %d rectclip\n",
-				     extents.x,
-				     surface_extents.height - extents.y - extents.height,
+	_cairo_output_stream_printf (stream, "q 0 0 %d %d rectclip\n",
 				     extents.width,
 				     extents.height);
 
 	status = _cairo_ps_surface_paint_surface (surface,
 						 (cairo_surface_pattern_t *) source,
 						 op);
 	if (status)
 	    return status;
@@ -2903,19 +2935,17 @@ static cairo_int_status_t
     } else {
 	status = _cairo_ps_surface_emit_pattern (surface, source, op);
 	if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
 	    return CAIRO_STATUS_SUCCESS;
 
 	if (status)
 	    return status;
 
-	_cairo_output_stream_printf (stream, "%d %d %d %d rectfill\n",
-				     extents.x,
-				     surface_extents.height - extents.y - extents.height,
+	_cairo_output_stream_printf (stream, "0 0 %d %d rectfill\n",
 				     extents.width,
 				     extents.height);
     }
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_int_status_t
@@ -2971,17 +3001,18 @@ static cairo_int_status_t
     assert (_cairo_ps_surface_operation_supported (surface, op, source));
 
 #if DEBUG_PS
     _cairo_output_stream_printf (surface->stream,
 				 "%% _cairo_ps_surface_fill\n");
 #endif
 
     if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
-	source->extend == CAIRO_EXTEND_NONE)
+	(source->extend == CAIRO_EXTEND_NONE ||
+	 source->extend == CAIRO_EXTEND_PAD))
     {
 	_cairo_output_stream_printf (surface->stream, "q\n");
 
 	status =  _cairo_pdf_operators_clip (&surface->pdf_operators,
 					     path,
 					     fill_rule);
 	if (status)
 	    return status;
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/cairo/src/cairo-quartz-font.c
@@ -0,0 +1,794 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright � 2008 Mozilla Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation.
+ *
+ * Contributor(s):
+ *	Vladimir Vukicevic <vladimir@mozilla.com>
+ */
+
+#include "cairoint.h"
+
+#include <dlfcn.h>
+
+#include "cairo-quartz.h"
+#include "cairo-quartz-private.h"
+
+/* CreateWithFontName exists in 10.5, but not in 10.4; CreateWithName isn't public in 10.4 */
+static CGFontRef (*CGFontCreateWithFontNamePtr) (CFStringRef) = NULL;
+static CGFontRef (*CGFontCreateWithNamePtr) (const char *) = NULL;
+
+/* These aren't public before 10.5, and some have different names in 10.4 */
+static int (*CGFontGetUnitsPerEmPtr) (CGFontRef) = NULL;
+static bool (*CGFontGetGlyphAdvancesPtr) (CGFontRef, const CGGlyph[], size_t, int[]) = NULL;
+static bool (*CGFontGetGlyphBBoxesPtr) (CGFontRef, const CGGlyph[], size_t, CGRect[]) = NULL;
+static CGRect (*CGFontGetFontBBoxPtr) (CGFontRef) = NULL;
+
+/* Not public, but present */
+static void (*CGFontGetGlyphsForUnicharsPtr) (CGFontRef, const UniChar[], const CGGlyph[], size_t) = NULL;
+
+/* Not public in the least bit */
+static CGPathRef (*CGFontGetGlyphPathPtr) (CGFontRef fontRef, CGAffineTransform *textTransform, int unknown, CGGlyph glyph) = NULL;
+
+/* CGFontGetHMetrics isn't public, but the other functions are public/present in 10.5 */
+typedef struct {
+    int ascent;
+    int descent;
+    int leading;
+} quartz_CGFontMetrics;
+static quartz_CGFontMetrics* (*CGFontGetHMetricsPtr) (CGFontRef fontRef) = NULL;
+static int (*CGFontGetAscentPtr) (CGFontRef fontRef) = NULL;
+static int (*CGFontGetDescentPtr) (CGFontRef fontRef) = NULL;
+static int (*CGFontGetLeadingPtr) (CGFontRef fontRef) = NULL;
+
+static cairo_bool_t _cairo_quartz_font_symbol_lookup_done = FALSE;
+static cairo_bool_t _cairo_quartz_font_symbols_present = FALSE;
+
+static void
+quartz_font_ensure_symbols(void)
+{
+    if (_cairo_quartz_font_symbol_lookup_done)
+	return;
+
+    /* Look for the 10.5 versions first */
+    CGFontGetGlyphBBoxesPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphBBoxes");
+    if (!CGFontGetGlyphBBoxesPtr)
+	CGFontGetGlyphBBoxesPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphBoundingBoxes");
+
+    CGFontGetGlyphsForUnicharsPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphsForUnichars");
+    if (!CGFontGetGlyphsForUnicharsPtr)
+	CGFontGetGlyphsForUnicharsPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphsForUnicodes");
+
+    CGFontGetFontBBoxPtr = dlsym(RTLD_DEFAULT, "CGFontGetFontBBox");
+
+    /* We just need one of these two */
+    CGFontCreateWithFontNamePtr = dlsym(RTLD_DEFAULT, "CGFontCreateWithFontName");
+    CGFontCreateWithNamePtr = dlsym(RTLD_DEFAULT, "CGFontCreateWithName");
+
+    /* These have the same name in 10.4 and 10.5 */
+    CGFontGetUnitsPerEmPtr = dlsym(RTLD_DEFAULT, "CGFontGetUnitsPerEm");
+    CGFontGetGlyphAdvancesPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphAdvances");
+    CGFontGetGlyphPathPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphPath");
+
+    CGFontGetHMetricsPtr = dlsym(RTLD_DEFAULT, "CGFontGetHMetrics");
+    CGFontGetAscentPtr = dlsym(RTLD_DEFAULT, "CGFontGetAscent");
+    CGFontGetDescentPtr = dlsym(RTLD_DEFAULT, "CGFontGetDescent");
+    CGFontGetLeadingPtr = dlsym(RTLD_DEFAULT, "CGFontGetLeading");
+
+    if ((CGFontCreateWithFontNamePtr || CGFontCreateWithNamePtr) &&
+	CGFontGetGlyphBBoxesPtr &&
+	CGFontGetGlyphsForUnicharsPtr &&
+	CGFontGetUnitsPerEmPtr &&
+	CGFontGetGlyphAdvancesPtr &&
+	CGFontGetGlyphPathPtr &&
+	(CGFontGetHMetricsPtr || (CGFontGetAscentPtr && CGFontGetDescentPtr && CGFontGetLeadingPtr)))
+	_cairo_quartz_font_symbols_present = TRUE;
+
+    _cairo_quartz_font_symbol_lookup_done = TRUE;
+}
+
+typedef struct _cairo_quartz_font_face cairo_quartz_font_face_t;
+typedef struct _cairo_quartz_scaled_font cairo_quartz_scaled_font_t;
+
+struct _cairo_quartz_scaled_font {
+    cairo_scaled_font_t base;
+};
+
+struct _cairo_quartz_font_face {
+    cairo_font_face_t base;
+
+    CGFontRef cgFont;
+};
+
+/**
+ ** font face backend
+ **/
+
+static void
+_cairo_quartz_font_face_destroy (void *abstract_face)
+{
+    cairo_quartz_font_face_t *font_face = (cairo_quartz_font_face_t*) abstract_face;
+
+    CGFontRelease (font_face->cgFont);
+}
+
+static cairo_status_t
+_cairo_quartz_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 **font_out)
+{
+    cairo_quartz_font_face_t *font_face = abstract_face;
+    cairo_quartz_scaled_font_t *font = NULL;
+    cairo_status_t status;
+    cairo_font_extents_t fs_metrics;
+    double ems;
+    CGRect bbox;
+
+    quartz_font_ensure_symbols();
+    if (!_cairo_quartz_font_symbols_present)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    font = malloc(sizeof(cairo_quartz_scaled_font_t));
+    if (font == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    memset (font, 0, sizeof(cairo_quartz_scaled_font_t));
+
+    status = _cairo_scaled_font_init (&font->base,
+				      &font_face->base, font_matrix, ctm, options,
+				      &cairo_quartz_scaled_font_backend);
+    if (status)
+	goto FINISH;
+
+    ems = CGFontGetUnitsPerEmPtr (font_face->cgFont);
+
+    /* initialize metrics */
+    if (CGFontGetFontBBoxPtr && CGFontGetAscentPtr) {
+	fs_metrics.ascent = (CGFontGetAscentPtr (font_face->cgFont) / ems);
+	fs_metrics.descent = - (CGFontGetDescentPtr (font_face->cgFont) / ems);
+	fs_metrics.height = fs_metrics.ascent + fs_metrics.descent +
+	    (CGFontGetLeadingPtr (font_face->cgFont) / ems);
+
+	bbox = CGFontGetFontBBoxPtr (font_face->cgFont);
+	fs_metrics.max_x_advance = CGRectGetMaxX(bbox) / ems;
+	fs_metrics.max_y_advance = 0.0;
+    } else {
+	CGGlyph wGlyph;
+	UniChar u;
+
+	quartz_CGFontMetrics *m;
+	m = CGFontGetHMetricsPtr (font_face->cgFont);
+
+	fs_metrics.ascent = (m->ascent / ems);
+	fs_metrics.descent = - (m->descent / ems);
+	fs_metrics.height = fs_metrics.ascent + fs_metrics.descent + (m->leading / ems);
+
+	/* We kind of have to guess here; W's big, right? */
+	u = (UniChar) 'W';
+	CGFontGetGlyphsForUnicharsPtr (font_face->cgFont, &u, &wGlyph, 1);
+	if (wGlyph && CGFontGetGlyphBBoxesPtr (font_face->cgFont, &wGlyph, 1, &bbox)) {
+	    fs_metrics.max_x_advance = CGRectGetMaxX(bbox) / ems;
+	    fs_metrics.max_y_advance = 0.0;
+	} else {
+	    fs_metrics.max_x_advance = 0.0;
+	    fs_metrics.max_y_advance = 0.0;
+	}
+    }
+
+    status = _cairo_scaled_font_set_metrics (&font->base, &fs_metrics);
+
+FINISH:
+    if (status != CAIRO_STATUS_SUCCESS) {
+	free (font);
+    } else {
+	*font_out = (cairo_scaled_font_t*) font;
+    }
+
+    return status;
+}
+
+static const cairo_font_face_backend_t _cairo_quartz_font_face_backend = {
+    CAIRO_FONT_TYPE_QUARTZ,
+    _cairo_quartz_font_face_destroy,
+    _cairo_quartz_font_face_scaled_font_create
+};
+
+/**
+ * cairo_quartz_font_face_create_for_cgfont
+ * @font: a #CGFontRef obtained through a method external to cairo.
+ *
+ * Creates a new font for the Quartz font backend based on a
+ * #CGFontRef.  This font can then be used with
+ * cairo_set_font_face() or cairo_scaled_font_create().
+ *
+ * Return value: a newly created #cairo_font_face_t. Free with
+ *  cairo_font_face_destroy() when you are done using it.
+ *
+ * Since: 1.6
+ */
+cairo_font_face_t *
+cairo_quartz_font_face_create_for_cgfont (CGFontRef font)
+{
+    cairo_quartz_font_face_t *font_face;
+
+    quartz_font_ensure_symbols();
+
+    font_face = malloc (sizeof (cairo_quartz_font_face_t));
+    if (!font_face) {
+	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+	return (cairo_font_face_t *)&_cairo_font_face_nil;
+    }
+
+    font_face->cgFont = CGFontRetain (font);
+
+    _cairo_font_face_init (&font_face->base, &_cairo_quartz_font_face_backend);
+
+    return &font_face->base;
+}
+
+/**
+ ** scaled font backend
+ **/
+
+static cairo_quartz_font_face_t *
+_cairo_quartz_scaled_to_face (void *abstract_font)
+{
+    cairo_quartz_scaled_font_t *sfont = (cairo_quartz_scaled_font_t*) abstract_font;
+    cairo_font_face_t *font_face = cairo_scaled_font_get_font_face (&sfont->base);
+    if (!font_face || font_face->backend->type != CAIRO_FONT_TYPE_QUARTZ)
+	return NULL;
+
+    return (cairo_quartz_font_face_t*) font_face;
+}
+
+static cairo_status_t
+_cairo_quartz_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 *options,
+			      cairo_scaled_font_t **font_out)
+{
+    const char *family = toy_face->family;
+    char *full_name = malloc(strlen(family) + 64); // give us a bit of room to tack on Bold, Oblique, etc.
+    CFStringRef cgFontName = NULL;
+    CGFontRef cgFont = NULL;
+    int loop;
+
+    cairo_status_t status;
+    cairo_font_face_t *face;
+    cairo_scaled_font_t *scaled_font;
+
+    quartz_font_ensure_symbols();
+    if (!_cairo_quartz_font_symbols_present)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    /* handle CSS-ish faces */
+    if (!strcmp(family, "serif") || !strcmp(family, "Times Roman"))
+	family = "Times";
+    else if (!strcmp(family, "sans-serif") || !strcmp(family, "sans"))
+	family = "Helvetica";
+    else if (!strcmp(family, "cursive"))
+	family = "Apple Chancery";
+    else if (!strcmp(family, "fantasy"))
+	family = "Papyrus";
+    else if (!strcmp(family, "monospace") || !strcmp(family, "mono"))
+	family = "Courier";
+
+    /* Try to build up the full name, e.g. "Helvetica Bold Oblique" first,
+     * then drop the bold, then drop the slant, then drop both.. finally
+     * just use "Helvetica".  And if Helvetica doesn't exist, give up.
+     */
+    for (loop = 0; loop < 5; loop++) {
+	if (loop == 4)
+	    family = "Helvetica";
+
+	strcpy (full_name, family);
+
+	if (loop < 3 && (loop & 1) == 0) {
+	    if (toy_face->weight == CAIRO_FONT_WEIGHT_BOLD)
+		strcat (full_name, " Bold");
+	}
+
+	if (loop < 3 && (loop & 2) == 0) {
+	    if (toy_face->slant == CAIRO_FONT_SLANT_ITALIC)
+		strcat (full_name, " Italic");
+	    else if (toy_face->slant == CAIRO_FONT_SLANT_OBLIQUE)
+		strcat (full_name, " Oblique");
+	}
+
+	if (CGFontCreateWithFontNamePtr) {
+	    cgFontName = CFStringCreateWithCString (NULL, full_name, kCFStringEncodingASCII);
+	    cgFont = CGFontCreateWithFontNamePtr (cgFontName);
+	    CFRelease (cgFontName);
+	} else {
+	    cgFont = CGFontCreateWithNamePtr (full_name);
+	}
+
+	if (cgFont)
+	    break;
+    }
+
+    if (!cgFont) {
+	/* Give up */
+	return CAIRO_STATUS_NO_MEMORY;
+    }
+
+    face = cairo_quartz_font_face_create_for_cgfont (cgFont);
+    if (face->status)
+	return face->status;
+
+    status = _cairo_quartz_font_face_scaled_font_create (face,
+							 font_matrix, ctm,
+							 options,
+							 &scaled_font);
+    cairo_font_face_destroy (face);
+    if (status)
+	return status;
+
+    *font_out = scaled_font;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static void
+_cairo_quartz_font_fini(void *abstract_font)
+{
+}
+
+#define INVALID_GLYPH 0x00
+
+static inline CGGlyph
+_cairo_quartz_scaled_glyph_index (cairo_scaled_glyph_t *scaled_glyph) {
+    unsigned long index = _cairo_scaled_glyph_index (scaled_glyph);
+    if (index > 0xffff)
+	return INVALID_GLYPH;
+    return (CGGlyph) index;
+}
+
+static inline cairo_status_t
+_cairo_matrix_to_unit_quartz_matrix (const cairo_matrix_t *m, CGAffineTransform *txout,
+				     double *xout, double *yout)
+{
+    CGAffineTransform transform;
+    double xscale, yscale;
+    cairo_status_t status;
+
+    status = _cairo_matrix_compute_scale_factors (m, &xscale, &yscale, 1);
+    if (status)
+	return status;
+
+    transform = CGAffineTransformMake (m->xx, - m->yx,
+				       - m->xy, m->yy,
+				       0.0f, 0.0f);
+    if (xout)
+	*xout = xscale;
+    if (yout)
+	*yout = yscale;
+
+    if (xscale)
+	xscale = 1.0 / xscale;
+    if (yscale)
+	yscale = 1.0 / yscale;
+
+    *txout = CGAffineTransformScale (transform, xscale, yscale);
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+_cairo_quartz_init_glyph_metrics (cairo_quartz_scaled_font_t *font,
+				  cairo_scaled_glyph_t *scaled_glyph)
+{
+    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
+
+    cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
+    cairo_text_extents_t extents = {0, 0, 0, 0, 0, 0};
+    CGAffineTransform textMatrix;
+    CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
+    int advance;
+    CGRect bbox;
+    double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont);
+    double xscale, yscale;
+    double xmin, ymin, xmax, ymax;
+
+    if (glyph == INVALID_GLYPH)
+	goto FAIL;
+
+    if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) ||
+	!CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox))
+	goto FAIL;
+
+    status = _cairo_matrix_compute_scale_factors (&font->base.scale,
+						  &xscale, &yscale, 1);
+    if (status)
+	goto FAIL;
+
+    bbox = CGRectMake (bbox.origin.x / emscale,
+		       bbox.origin.y / emscale,
+		       bbox.size.width / emscale,
+		       bbox.size.height / emscale);
+
+    /* Should we want to always integer-align glyph extents, we can do so in this way */
+#if 0
+    {
+	CGAffineTransform textMatrix;
+	textMatrix = CGAffineTransformMake (font->base.scale.xx,
+					    -font->base.scale.yx,
+					    -font->base.scale.xy,
+					    font->base.scale.yy,
+					    0.0f, 0.0f);
+
+	bbox = CGRectApplyAffineTransform (bbox, textMatrix);
+	bbox = CGRectIntegral (bbox);
+	bbox = CGRectApplyAffineTransform (bbox, CGAffineTransformInvert (textMatrix));
+    }
+#endif
+
+#if 0
+    fprintf (stderr, "[0x%04x] bbox: %f %f %f %f\n", glyph,
+	     bbox.origin.x / emscale, bbox.origin.y / emscale,
+	     bbox.size.width / emscale, bbox.size.height / emscale);
+#endif
+
+    xmin = CGRectGetMinX(bbox);
+    ymin = CGRectGetMinY(bbox);
+    xmax = CGRectGetMaxX(bbox);
+    ymax = CGRectGetMaxY(bbox);
+
+    extents.x_bearing = xmin;
+    extents.y_bearing = - ymax;
+    extents.width = xmax - xmin;
+    extents.height = ymax - ymin;
+
+    extents.x_advance = (double) advance / emscale;
+    extents.y_advance = 0.0;
+
+#if 0
+    fprintf (stderr, "[0x%04x] extents: bearings: %f %f dim: %f %f adv: %f\n\n", glyph,
+	     extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance);
+#endif
+
+  FAIL:
+    _cairo_scaled_glyph_set_metrics (scaled_glyph,
+				     &font->base,
+				     &extents);
+
+    return status;
+}
+
+static void
+_cairo_quartz_path_apply_func (void *info, const CGPathElement *el)
+{
+    cairo_path_fixed_t *path = (cairo_path_fixed_t *) info;
+
+    switch (el->type) {
+	case kCGPathElementMoveToPoint:
+	    _cairo_path_fixed_move_to (path,
+				       _cairo_fixed_from_double(el->points[0].x),
+				       _cairo_fixed_from_double(el->points[0].y));
+	    break;
+	case kCGPathElementAddLineToPoint:
+	    _cairo_path_fixed_line_to (path,
+				       _cairo_fixed_from_double(el->points[0].x),
+				       _cairo_fixed_from_double(el->points[0].y));
+	    break;
+	case kCGPathElementAddQuadCurveToPoint: {
+	    cairo_fixed_t fx, fy;
+	    double x, y;
+	    if (!_cairo_path_fixed_get_current_point (path, &fx, &fy))
+		fx = fy = 0;
+	    x = _cairo_fixed_to_double (fx);
+	    y = _cairo_fixed_to_double (fy);
+
+	    _cairo_path_fixed_curve_to (path,
+					_cairo_fixed_from_double((x + el->points[0].x * 2.0) / 3.0),
+					_cairo_fixed_from_double((y + el->points[0].y * 2.0) / 3.0),
+					_cairo_fixed_from_double((el->points[0].x * 2.0 + el->points[1].x) / 3.0),
+					_cairo_fixed_from_double((el->points[0].y * 2.0 + el->points[1].y) / 3.0),
+					_cairo_fixed_from_double(el->points[1].x),
+					_cairo_fixed_from_double(el->points[1].y));
+	}
+	    break;
+	case kCGPathElementAddCurveToPoint:
+	    _cairo_path_fixed_curve_to (path,
+					_cairo_fixed_from_double(el->points[0].x),
+					_cairo_fixed_from_double(el->points[0].y),
+					_cairo_fixed_from_double(el->points[1].x),
+					_cairo_fixed_from_double(el->points[1].y),
+					_cairo_fixed_from_double(el->points[2].x),
+					_cairo_fixed_from_double(el->points[2].y));
+	    break;
+	case kCGPathElementCloseSubpath:
+	    _cairo_path_fixed_close_path (path);
+	    break;
+    }
+}
+
+static cairo_int_status_t
+_cairo_quartz_init_glyph_path (cairo_quartz_scaled_font_t *font,
+			       cairo_scaled_glyph_t *scaled_glyph)
+{
+    cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
+    CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
+    CGAffineTransform textMatrix;
+    CGPathRef glyphPath;
+    cairo_path_fixed_t *path;
+
+    if (glyph == INVALID_GLYPH) {
+	_cairo_scaled_glyph_set_path (scaled_glyph, &font->base, _cairo_path_fixed_create());
+	return CAIRO_STATUS_SUCCESS;
+    }
+
+    textMatrix = CGAffineTransformMake (font->base.scale.xx,
+					-font->base.scale.yx,
+					-font->base.scale.xy,
+					font->base.scale.yy,
+					font->base.scale.x0,
+					font->base.scale.y0);
+
+    textMatrix = CGAffineTransformConcat (textMatrix, CGAffineTransformMake (1.0, 0.0, 0.0, -1.0, 0.0, 0.0));
+
+    glyphPath = CGFontGetGlyphPathPtr (font_face->cgFont, &textMatrix, 0, glyph);
+    if (!glyphPath)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    path = _cairo_path_fixed_create ();
+    if (!path) {
+	CGPathRelease (glyphPath);
+	return _cairo_error(CAIRO_STATUS_NO_MEMORY);
+    }
+
+    CGPathApply (glyphPath, path, _cairo_quartz_path_apply_func);
+
+    CGPathRelease (glyphPath);
+
+    _cairo_scaled_glyph_set_path (scaled_glyph, &font->base, path);
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+_cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
+				  cairo_scaled_glyph_t *scaled_glyph)
+{
+    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
+
+    cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font);
+
+    cairo_image_surface_t *surface = NULL;
+
+    CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
+
+    int advance;
+    CGRect bbox;
+    double width, height;
+    double xscale, yscale;
+    double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont);
+
+    CGColorSpaceRef gray;
+    CGContextRef cgContext = NULL;
+    CGAffineTransform textMatrix;
+    CGRect glyphRect, glyphRectInt;
+    CGPoint glyphOrigin;
+
+    //fprintf (stderr, "scaled_glyph: %p surface: %p\n", scaled_glyph, scaled_glyph->surface);
+
+    /* Create blank 2x2 image if we don't have this character.
+     * Maybe we should draw a better missing-glyph slug or something,
+     * but this is ok for now.
+     */
+    if (glyph == INVALID_GLYPH) {
+	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;
+
+	_cairo_scaled_glyph_set_surface (scaled_glyph,
+					 &font->base,
+					 surface);
+	return CAIRO_STATUS_SUCCESS;
+    }
+
+    if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) ||
+	!CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox))
+    {
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+    }
+
+    status = _cairo_matrix_compute_scale_factors (&font->base.scale,
+						  &xscale, &yscale, 1);
+    if (status)
+	return status;
+
+    textMatrix = CGAffineTransformMake (font->base.scale.xx,
+					-font->base.scale.yx,
+					-font->base.scale.xy,
+					font->base.scale.yy,
+					0.0f, 0.0f);
+    glyphRect = CGRectMake (bbox.origin.x / emscale,
+			    bbox.origin.y / emscale,
+			    bbox.size.width / emscale,
+			    bbox.size.height / emscale);
+
+    glyphRect = CGRectApplyAffineTransform (glyphRect, textMatrix);
+
+    /* Round the rectangle outwards, so that we don't have to deal
+     * with non-integer-pixel origins or dimensions.
+     */
+    glyphRectInt = CGRectIntegral (glyphRect);
+
+#if 0
+    fprintf (stderr, "glyphRect[o]: %f %f %f %f\n",
+	     glyphRect.origin.x, glyphRect.origin.y, glyphRect.size.width, glyphRect.size.height);
+    fprintf (stderr, "glyphRectInt: %f %f %f %f\n",
+	     glyphRectInt.origin.x, glyphRectInt.origin.y, glyphRectInt.size.width, glyphRectInt.size.height);
+#endif
+
+    glyphOrigin = glyphRectInt.origin;
+
+    //textMatrix = CGAffineTransformConcat (textMatrix, CGAffineTransformInvert (ctm));
+
+    width = glyphRectInt.size.width;
+    height = glyphRectInt.size.height;
+
+    //fprintf (stderr, "glyphRect[n]: %f %f %f %f\n", glyphRect.origin.x, glyphRect.origin.y, glyphRect.size.width, glyphRect.size.height);
+
+    surface = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
+    if (surface->base.status)
+	return surface->base.status;
+
+    gray = CGColorSpaceCreateDeviceGray ();
+    cgContext = CGBitmapContextCreate (surface->data,
+				       surface->width,
+				       surface->height,
+				       8,
+				       surface->stride,
+				       gray,
+				       kCGImageAlphaNone);
+    CGColorSpaceRelease (gray);
+
+    CGContextSetFont (cgContext, font_face->cgFont);
+    CGContextSetFontSize (cgContext, 1.0);
+    CGContextSetTextMatrix (cgContext, textMatrix);
+
+    CGContextClearRect (cgContext, CGRectMake (0.0f, 0.0f, width, height));
+
+    if (font->base.options.antialias == CAIRO_ANTIALIAS_NONE)
+	CGContextSetShouldAntialias (cgContext, false);
+
+    CGContextSetRGBFillColor (cgContext, 1.0, 1.0, 1.0, 1.0);
+    CGContextShowGlyphsAtPoint (cgContext, - glyphOrigin.x, - glyphOrigin.y, &glyph, 1);
+
+    CGContextRelease (cgContext);
+
+    cairo_surface_set_device_offset (&surface->base,
+				     - glyphOrigin.x,
+				     height + glyphOrigin.y);
+
+    _cairo_scaled_glyph_set_surface (scaled_glyph, &font->base, surface);
+
+    return status;
+}
+
+static cairo_int_status_t
+_cairo_quartz_font_scaled_glyph_init (void *abstract_font,
+				      cairo_scaled_glyph_t *scaled_glyph,
+				      cairo_scaled_glyph_info_t info)
+{
+    cairo_quartz_scaled_font_t *font = (cairo_quartz_scaled_font_t *) abstract_font;
+    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
+
+    if (!status && (info & CAIRO_SCALED_GLYPH_INFO_METRICS))
+	status = _cairo_quartz_init_glyph_metrics (font, scaled_glyph);
+
+    if (!status && (info & CAIRO_SCALED_GLYPH_INFO_PATH))
+	status = _cairo_quartz_init_glyph_path (font, scaled_glyph);
+
+    if (!status && (info & CAIRO_SCALED_GLYPH_INFO_SURFACE))
+	status = _cairo_quartz_init_glyph_surface (font, scaled_glyph);
+
+    return status;
+}
+
+static unsigned long
+_cairo_quartz_ucs4_to_index (void *abstract_font,
+			     uint32_t ucs4)
+{
+    cairo_quartz_scaled_font_t *font = (cairo_quartz_scaled_font_t*) abstract_font;
+    cairo_quartz_font_face_t *ffont = _cairo_quartz_scaled_to_face(font);
+    UniChar u = (UniChar) ucs4;
+    CGGlyph glyph;
+
+    CGFontGetGlyphsForUnicharsPtr (ffont->cgFont, &u, &glyph, 1);
+
+    return glyph;
+}
+
+const cairo_scaled_font_backend_t cairo_quartz_scaled_font_backend = {
+    CAIRO_FONT_TYPE_QUARTZ,
+    _cairo_quartz_font_create_toy,
+    _cairo_quartz_font_fini,
+    _cairo_quartz_font_scaled_glyph_init,
+    NULL, /* text_to_glyphs */
+    _cairo_quartz_ucs4_to_index,
+    NULL, /* show_glyphs */
+    NULL, /* load_truetype_table */
+    NULL, /* map_glyphs_to_unicode */
+};
+
+/*
+ * private methods that the quartz surface uses
+ */
+
+CGFontRef
+_cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *abstract_font)
+{
+    cairo_quartz_font_face_t *ffont = _cairo_quartz_scaled_to_face(abstract_font);
+
+    return ffont->cgFont;
+}
+
+
+/*
+ * compat with old ATSUI backend
+ */
+
+/**
+ * cairo_quartz_font_face_create_for_atsu_font_id
+ * @font_id: an ATSUFontID for the font.
+ *
+ * Creates a new font for the Quartz font backend based on an
+ * #ATSUFontID. This font can then be used with
+ * cairo_set_font_face() or cairo_scaled_font_create().
+ *
+ * Return value: a newly created #cairo_font_face_t. Free with
+ *  cairo_font_face_destroy() when you are done using it.
+ *
+ * Since: 1.6
+ **/
+cairo_font_face_t *
+cairo_quartz_font_face_create_for_atsu_font_id (ATSUFontID font_id)
+{
+    ATSFontRef atsFont = FMGetATSFontRefFromFont (font_id);
+    CGFontRef cgFont = CGFontCreateWithPlatformFont (&atsFont);
+
+    return cairo_quartz_font_face_create_for_cgfont (cgFont);
+}
+
+/* This is the old name for the above function, exported for compat purposes */
+cairo_font_face_t *cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id);
+
+cairo_font_face_t *
+cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id)
+{
+    return cairo_quartz_font_face_create_for_atsu_font_id (font_id);
+}
--- a/gfx/cairo/cairo/src/cairo-quartz-private.h
+++ b/gfx/cairo/cairo/src/cairo-quartz-private.h
@@ -87,22 +87,19 @@ CGImageRef
 			      unsigned int height,
 			      unsigned int stride,
 			      void *data,
 			      cairo_bool_t interpolate,
 			      CGColorSpaceRef colorSpaceOverride,
 			      CGDataProviderReleaseDataCallback releaseCallback,
 			      void *releaseInfo);
 
+CGFontRef
+_cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *sfont);
+
 #endif /* CAIRO_HAS_QUARTZ_SURFACE */
 
-#if CAIRO_HAS_ATSUI_FONT
-ATSUStyle
-_cairo_atsui_scaled_font_get_atsu_style (cairo_scaled_font_t *sfont);
-
-ATSUFontID
-_cairo_atsui_scaled_font_get_atsu_font_id (cairo_scaled_font_t *sfont);
-
+#if CAIRO_HAS_CGFONT_FONT
 CGFontRef
-_cairo_atsui_scaled_font_get_cg_font_ref (cairo_scaled_font_t *sfont);
-#endif /* CAIRO_HAS_ATSUI_FONT */
+_cairo_cgfont_scaled_font_get_cg_font_ref (cairo_scaled_font_t *sfont);
+#endif /* CAIRO_HAS_CGFONT_FONT */
 
 #endif /* CAIRO_QUARTZ_PRIVATE_H */
--- a/gfx/cairo/cairo/src/cairo-quartz-surface.c
+++ b/gfx/cairo/cairo/src/cairo-quartz-surface.c
@@ -43,17 +43,16 @@
 /* The 10.5 SDK includes a funky new definition of FloatToFixed which
  * causes all sorts of breakage; so reset to old-style definition
  */
 #ifdef FloatToFixed
 #undef FloatToFixed
 #define FloatToFixed(a)     ((Fixed)((float)(a) * fixed1))
 #endif
 
-#include <Carbon/Carbon.h>
 #include <limits.h>
 
 #undef QUARTZ_DEBUG
 
 #ifdef QUARTZ_DEBUG
 #define ND(_x)	fprintf _x
 #else
 #define ND(_x)	do {} while(0)
@@ -97,30 +96,33 @@ CG_EXTERN CGSize CGContextGetPatternPhas
 
 typedef uint32_t CGBitmapInfo;
 
 /* public in 10.4, present in 10.3.9 */
 CG_EXTERN void CGContextReplacePathWithStrokedPath (CGContextRef);
 CG_EXTERN CGImageRef CGBitmapContextCreateImage (CGContextRef);
 #endif
 
-/* Only present in 10.4+ */
+/* Some of these are present in earlier versions of the OS than where
+ * they are public; others are not public at all (CGContextCopyPath,
+ * CGContextReplacePathWithClipPath, many of the getters, etc.)
+ */
 static void (*CGContextClipToMaskPtr) (CGContextRef, CGRect, CGImageRef) = NULL;
-/* Only present in 10.5+ */
 static void (*CGContextDrawTiledImagePtr) (CGContextRef, CGRect, CGImageRef) = NULL;
 static unsigned int (*CGContextGetTypePtr) (CGContextRef) = NULL;
 static void (*CGContextSetShouldAntialiasFontsPtr) (CGContextRef, bool) = NULL;
-static void (*CGContextSetShouldSmoothFontsPtr) (CGContextRef, bool) = NULL;
 static bool (*CGContextGetShouldAntialiasFontsPtr) (CGContextRef) = NULL;
 static bool (*CGContextGetShouldSmoothFontsPtr) (CGContextRef) = NULL;
 static void (*CGContextSetAllowsFontSmoothingPtr) (CGContextRef, bool) = NULL;
 static bool (*CGContextGetAllowsFontSmoothingPtr) (CGContextRef) = NULL;
 static CGPathRef (*CGContextCopyPathPtr) (CGContextRef) = NULL;
 static void (*CGContextReplacePathWithClipPathPtr) (CGContextRef) = NULL;
 
+static SInt32 _cairo_quartz_osx_version = 0x0;
+
 static cairo_bool_t _cairo_quartz_symbol_lookup_done = FALSE;
 
 /*
  * Utility functions
  */
 
 #ifdef QUARTZ_DEBUG
 static void quartz_surface_to_png (cairo_quartz_surface_t *nq, char *dest);
@@ -138,24 +140,28 @@ static void quartz_ensure_symbols(void)
 {
     if (_cairo_quartz_symbol_lookup_done)
 	return;
 
     CGContextClipToMaskPtr = dlsym(RTLD_DEFAULT, "CGContextClipToMask");
     CGContextDrawTiledImagePtr = dlsym(RTLD_DEFAULT, "CGContextDrawTiledImage");
     CGContextGetTypePtr = dlsym(RTLD_DEFAULT, "CGContextGetType");
     CGContextSetShouldAntialiasFontsPtr = dlsym(RTLD_DEFAULT, "CGContextSetShouldAntialiasFonts");
-    CGContextSetShouldSmoothFontsPtr = dlsym(RTLD_DEFAULT, "CGContextSetShouldSmoothFonts");
     CGContextGetShouldAntialiasFontsPtr = dlsym(RTLD_DEFAULT, "CGContextGetShouldAntialiasFonts");
     CGContextGetShouldSmoothFontsPtr = dlsym(RTLD_DEFAULT, "CGContextGetShouldSmoothFonts");
     CGContextCopyPathPtr = dlsym(RTLD_DEFAULT, "CGContextCopyPath");
     CGContextReplacePathWithClipPathPtr = dlsym(RTLD_DEFAULT, "CGContextReplacePathWithClipPath");
     CGContextGetAllowsFontSmoothingPtr = dlsym(RTLD_DEFAULT, "CGContextGetAllowsFontSmoothing");
     CGContextSetAllowsFontSmoothingPtr = dlsym(RTLD_DEFAULT, "CGContextSetAllowsFontSmoothing");
 
+    if (Gestalt(gestaltSystemVersion, &_cairo_quartz_osx_version) != noErr) {
+	// assume 10.4
+	_cairo_quartz_osx_version = 0x1040;
+    }
+
     _cairo_quartz_symbol_lookup_done = TRUE;
 }
 
 static inline cairo_bool_t
 _cairo_quartz_is_cgcontext_bitmap_context (CGContextRef cgc) {
     if (cgc == NULL)
 	return FALSE;
 
@@ -474,16 +480,20 @@ static void
 	    CGContextEOFillPath (cgc);
     } else if (op->op == UNBOUNDED_SHOW_GLYPHS) {
 	CGContextSetFont (cgc, op->u.show_glyphs.font);
 	CGContextSetFontSize (cgc, 1.0);
 	CGContextSetTextMatrix (cgc, op->u.show_glyphs.textTransform);
 	CGContextTranslateCTM (cgc, op->u.show_glyphs.origin.x, op->u.show_glyphs.origin.y);
 
 	if (op->u.show_glyphs.isClipping) {
+	    /* Note that the comment in show_glyphs about kCGTextClip
+	     * and the text transform still applies here; however, the
+	     * cg_advances we have were already transformed, so we
+	     * don't have to do anything. */
 	    CGContextSetTextDrawingMode (cgc, kCGTextClip);
 	    CGContextSaveGState (cgc);
 	}
 
 	CGContextShowGlyphsWithAdvances (cgc,
 					 op->u.show_glyphs.cg_glyphs,
 					 op->u.show_glyphs.cg_advances,
 					 op->u.show_glyphs.nglyphs);
@@ -535,49 +545,46 @@ static void
 /*
  * Source -> Quartz setup and finish functions
  */
 
 static void
 ComputeGradientValue (void *info, const float *in, float *out)
 {
     double fdist = *in;
-    cairo_fixed_t fdist_fix;
     cairo_gradient_pattern_t *grad = (cairo_gradient_pattern_t*) info;
     unsigned int i;
 
     /* Put fdist back in the 0.0..1.0 range if we're doing
      * REPEAT/REFLECT
      */
     if (grad->base.extend == CAIRO_EXTEND_REPEAT) {
 	fdist = fdist - floor(fdist);
     } else if (grad->base.extend == CAIRO_EXTEND_REFLECT) {
 	fdist = fmod(fabs(fdist), 2.0);
 	if (fdist > 1.0) {
 	    fdist = 2.0 - fdist;
 	}
     }
 
-    fdist_fix = _cairo_fixed_from_double(fdist);
-
     for (i = 0; i < grad->n_stops; i++) {
-	if (grad->stops[i].x > fdist_fix)
+	if (grad->stops[i].offset > fdist)
 	    break;
     }
 
     if (i == 0 || i == grad->n_stops) {
 	if (i == grad->n_stops)
 	    --i;
 	out[0] = grad->stops[i].color.red;
 	out[1] = grad->stops[i].color.green;
 	out[2] = grad->stops[i].color.blue;
 	out[3] = grad->stops[i].color.alpha;
     } else {
-	float ax = _cairo_fixed_to_double(grad->stops[i-1].x);
-	float bx = _cairo_fixed_to_double(grad->stops[i].x) - ax;
+	float ax = grad->stops[i-1].offset;
+	float bx = grad->stops[i].offset - ax;
 	float bp = (fdist - ax)/bx;
 	float ap = 1.0 - bp;
 
 	out[0] =
 	    grad->stops[i-1].color.red * ap +
 	    grad->stops[i].color.red * bp;
 	out[1] =
 	    grad->stops[i-1].color.green * ap +
@@ -1726,17 +1733,17 @@ static cairo_int_status_t
 			      cairo_matrix_t *ctm_inverse,
 			      double tolerance,
 			      cairo_antialias_t antialias)
 {
     cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
     cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
     cairo_quartz_action_t action;
     quartz_stroke_t stroke;
-    CGAffineTransform strokeTransform;
+    CGAffineTransform origCTM, strokeTransform;
     CGPathRef path_for_unbounded = NULL;
 
     ND((stderr, "%p _cairo_quartz_surface_stroke op %d source->type %d\n", surface, op, source->type));
 
     if (IS_EMPTY(surface))
 	return CAIRO_STATUS_SUCCESS;
 
     if (op == CAIRO_OPERATOR_DEST)
@@ -1747,16 +1754,19 @@ static cairo_int_status_t
     // Turning antialiasing off used to cause misrendering with
     // single-pixel lines (e.g. 20,10.5 -> 21,10.5 end up being rendered as 2 pixels).
     // That's been since fixed in at least 10.5, and in the latest 10.4 dot releases.
     CGContextSetShouldAntialias (surface->cgContext, (antialias != CAIRO_ANTIALIAS_NONE));
     CGContextSetLineWidth (surface->cgContext, style->line_width);
     CGContextSetLineCap (surface->cgContext, _cairo_quartz_cairo_line_cap_to_quartz (style->line_cap));
     CGContextSetLineJoin (surface->cgContext, _cairo_quartz_cairo_line_join_to_quartz (style->line_join));
     CGContextSetMiterLimit (surface->cgContext, style->miter_limit);
+
+    origCTM = CGContextGetCTM (surface->cgContext);
+
     _cairo_quartz_cairo_matrix_to_quartz (ctm, &strokeTransform);
     CGContextConcatCTM (surface->cgContext, strokeTransform);
 
     if (style->dash && style->num_dashes) {
 #define STATIC_DASH 32
 	float sdash[STATIC_DASH];
 	float *fdash = sdash;
 	unsigned int max_dashes = style->num_dashes;
@@ -1793,28 +1803,32 @@ static cairo_int_status_t
 	path_for_unbounded = CGContextCopyPathPtr (surface->cgContext);
 
     if (action == DO_SOLID || action == DO_PATTERN) {
 	CGContextStrokePath (surface->cgContext);
     } else if (action == DO_IMAGE || action == DO_TILED_IMAGE) {
 	CGContextReplacePathWithStrokedPath (surface->cgContext);
 	CGContextClip (surface->cgContext);
 
+	CGContextSetCTM (surface->cgContext, origCTM);
+
 	CGContextConcatCTM (surface->cgContext, surface->sourceTransform);
 	CGContextTranslateCTM (surface->cgContext, 0, surface->sourceImageRect.size.height);
 	CGContextScaleCTM (surface->cgContext, 1, -1);
 
 	if (action == DO_IMAGE)
 	    CGContextDrawImage (surface->cgContext, surface->sourceImageRect, surface->sourceImage);
 	else
 	    CGContextDrawTiledImagePtr (surface->cgContext, surface->sourceImageRect, surface->sourceImage);
     } else if (action == DO_SHADING) {
 	CGContextReplacePathWithStrokedPath (surface->cgContext);
 	CGContextClip (surface->cgContext);
 
+	CGContextSetCTM (surface->cgContext, origCTM);
+
 	CGContextConcatCTM (surface->cgContext, surface->sourceTransform);
 	CGContextDrawShading (surface->cgContext, surface->sourceShading);
     } else if (action != DO_NOTHING) {
 	rv = CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
   BAIL:
     _cairo_quartz_teardown_source (surface, source);
@@ -1849,17 +1863,17 @@ static cairo_int_status_t
 
 	CGPathRelease (path_for_unbounded);
     }
 
     ND((stderr, "-- stroke\n"));
     return rv;
 }
 
-#if CAIRO_HAS_ATSUI_FONT
+#if CAIRO_HAS_QUARTZ_FONT
 static cairo_int_status_t
 _cairo_quartz_surface_show_glyphs (void *abstract_surface,
 				   cairo_operator_t op,
 				   cairo_pattern_t *source,
 				   cairo_glyph_t *glyphs,
 				   int num_glyphs,
 				   cairo_scaled_font_t *scaled_font)
 {
@@ -1884,17 +1898,17 @@ static cairo_int_status_t
 	return CAIRO_STATUS_SUCCESS;
 
     if (num_glyphs <= 0)
 	return CAIRO_STATUS_SUCCESS;
 
     if (op == CAIRO_OPERATOR_DEST)
 	return CAIRO_STATUS_SUCCESS;
 
-    if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_ATSUI)
+    if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_QUARTZ)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     CGContextSaveGState (surface->cgContext);
 
     action = _cairo_quartz_setup_source (surface, source);
     if (action == DO_SOLID || action == DO_PATTERN) {
 	CGContextSetTextDrawingMode (surface->cgContext, kCGTextFill);
     } else if (action == DO_IMAGE || action == DO_TILED_IMAGE || action == DO_SHADING) {
@@ -1904,43 +1918,41 @@ static cairo_int_status_t
 	if (action != DO_NOTHING)
 	    rv = CAIRO_INT_STATUS_UNSUPPORTED;
 	goto BAIL;
     }
 
     CGContextSetCompositeOperation (surface->cgContext, _cairo_quartz_cairo_operator_to_quartz (op));
 
     /* this doesn't addref */
-    cgfref = _cairo_atsui_scaled_font_get_cg_font_ref (scaled_font);
+    cgfref = _cairo_quartz_scaled_font_get_cg_font_ref (scaled_font);
     CGContextSetFont (surface->cgContext, cgfref);
     CGContextSetFontSize (surface->cgContext, 1.0);
 
-    if (CGContextSetShouldAntialiasFontsPtr) {
-	switch (scaled_font->options.antialias) {
-	    case CAIRO_ANTIALIAS_SUBPIXEL:
-		CGContextSetShouldAntialiasFontsPtr (surface->cgContext, TRUE);
-		CGContextSetShouldSmoothFontsPtr (surface->cgContext, TRUE);
-		if (CGContextSetAllowsFontSmoothingPtr &&
-		    !CGContextGetAllowsFontSmoothingPtr (surface->cgContext))
-		{
-		    didForceFontSmoothing = TRUE;
-		    CGContextSetAllowsFontSmoothingPtr (surface->cgContext, TRUE);
-		}
-		break;
-	    case CAIRO_ANTIALIAS_NONE:
-		CGContextSetShouldAntialiasFontsPtr (surface->cgContext, FALSE);
-		break;
-	    case CAIRO_ANTIALIAS_GRAY:
-		CGContextSetShouldAntialiasFontsPtr (surface->cgContext, TRUE);
-		CGContextSetShouldSmoothFontsPtr (surface->cgContext, FALSE);
-		break;
-	    case CAIRO_ANTIALIAS_DEFAULT:
-		/* Don't do anything */
-		break;
-	}
+    switch (scaled_font->options.antialias) {
+	case CAIRO_ANTIALIAS_SUBPIXEL:
+	    CGContextSetShouldAntialias (surface->cgContext, TRUE);
+	    CGContextSetShouldSmoothFonts (surface->cgContext, TRUE);
+	    if (CGContextSetAllowsFontSmoothingPtr &&
+		!CGContextGetAllowsFontSmoothingPtr (surface->cgContext))
+	    {
+		didForceFontSmoothing = TRUE;
+		CGContextSetAllowsFontSmoothingPtr (surface->cgContext, TRUE);
+	    }
+	    break;
+	case CAIRO_ANTIALIAS_NONE:
+	    CGContextSetShouldAntialias (surface->cgContext, FALSE);
+	    break;
+	case CAIRO_ANTIALIAS_GRAY:
+	    CGContextSetShouldAntialias (surface->cgContext, TRUE);
+	    CGContextSetShouldSmoothFonts (surface->cgContext, FALSE);
+	    break;
+	case CAIRO_ANTIALIAS_DEFAULT:
+	    /* Don't do anything */
+	    break;
     }
 
     if (num_glyphs > STATIC_BUF_SIZE) {
 	cg_glyphs = (CGGlyph*) _cairo_malloc_ab (num_glyphs, sizeof(CGGlyph));
 	if (cg_glyphs == NULL) {
 	    rv = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto BAIL;
 	}
@@ -1979,20 +1991,23 @@ static cairo_int_status_t
 	float yf = glyphs[i].y;
 	cg_glyphs[i] = glyphs[i].index;
 	cg_advances[i-1].width = xf - xprev;
 	cg_advances[i-1].height = yf - yprev;
 	xprev = xf;
 	yprev = yf;
     }
 
-    if (isClipping) {
-	/* If we're clipping, we get multiplied by the inverse of our text matrix; no,
-	 * I don't understand why this is any different.  So pre-apply our textTransform.
-	 * Note that the new CGContextShowGlyphsAtPositions has a similar problem. */
+    if (_cairo_quartz_osx_version >= 0x1050 && isClipping) {
+	/* If we're clipping, OSX 10.5 (at least as of 10.5.2) has a
+	 * bug (apple bug ID #5834794) where the glyph
+	 * advances/positions are not transformed by the text matrix
+	 * if kCGTextClip is being used.  So, we pre-transform here.
+	 * 10.4 does not have this problem (as of 10.4.11).
+	 */
 	for (i = 0; i < num_glyphs - 1; i++)
 	    cg_advances[i] = CGSizeApplyAffineTransform(cg_advances[i], textTransform);
     }
 
 #if 0
     for (i = 0; i < num_glyphs; i++) {
 	ND((stderr, "[%d: %d %f,%f]\n", i, cg_glyphs[i], cg_advances[i].width, cg_advances[i].height));
     }
@@ -2055,17 +2070,17 @@ BAIL:
     }
 
     if (cg_glyphs != &glyphs_static[0]) {
 	free (cg_glyphs);
     }
 
     return rv;
 }
-#endif /* CAIRO_HAS_ATSUI_FONT */
+#endif /* CAIRO_HAS_QUARTZ_FONT */
 
 static cairo_int_status_t
 _cairo_quartz_surface_mask_with_surface (cairo_quartz_surface_t *surface,
                                          cairo_operator_t op,
                                          cairo_pattern_t *source,
                                          cairo_surface_pattern_t *mask)
 {
     cairo_rectangle_int_t extents;
@@ -2288,21 +2303,21 @@ static const struct _cairo_surface_backe
     NULL, /* mark_dirty_rectangle */
     NULL, /* scaled_font_fini */
     NULL, /* scaled_glyph_fini */
 
     _cairo_quartz_surface_paint,
     _cairo_quartz_surface_mask,
     _cairo_quartz_surface_stroke,
     _cairo_quartz_surface_fill,
-#if CAIRO_HAS_ATSUI_FONT
+#if CAIRO_HAS_QUARTZ_FONT
     _cairo_quartz_surface_show_glyphs,
 #else
-    NULL, /* surface_show_glyphs */
-#endif /* CAIRO_HAS_ATSUI_FONT */
+    NULL, /* show_glyphs */
+#endif
 
     NULL, /* snapshot */
     NULL, /* is_similar */
     NULL, /* reset */
     NULL  /* fill_stroke */
 };
 
 cairo_quartz_surface_t *
@@ -2353,32 +2368,30 @@ cairo_quartz_surface_t *
 
 /**
  * cairo_quartz_surface_create_for_cg_context
  * @cgContext: the existing CGContext for which to create the surface
  * @width: width of the surface, in pixels
  * @height: height of the surface, in pixels
  *
  * Creates a Quartz surface that wraps the given CGContext.  The
- * CGContext is assumed to be in the QuickDraw coordinate space (that
- * is, with the origin at the upper left and the Y axis increasing
- * downward.)  If the CGContext is in the Quartz coordinate space (with
- * the origin at the bottom left), then it should be flipped before
- * this function is called:
+ * CGContext is assumed to be in the standard Cairo coordinate space
+ * (that is, with the origin at the upper left and the Y axis
+ * increasing downward).  If the CGContext is in the Quartz coordinate
+ * space (with the origin at the bottom left), then it should be
+ * flipped before this function is called.  The flip can be accomplished
+ * using a translate and a scale; for example:
  *
  * <informalexample><programlisting>
  * CGContextTranslateCTM (cgContext, 0.0, height);
  * CGContextScaleCTM (cgContext, 1.0, -1.0);
  * </programlisting></informalexample>
  *
- * A very small number of Cairo operations cannot be translated to
- * Quartz operations; those operations will fail on this surface.
- * If all Cairo operations are required to succeed, consider rendering
- * to a surface created by cairo_quartz_surface_create() and then copying
- * the result to the CGContext.
+ * All Cairo operations are implemented in terms of Quartz operations,
+ * as long as Quartz-compatible elements are used (such as Quartz fonts).
  *
  * Return value: the newly created Cairo surface.
  *
  * Since: 1.4
  **/
 
 cairo_surface_t *
 cairo_quartz_surface_create_for_cg_context (CGContextRef cgContext,
--- a/gfx/cairo/cairo/src/cairo-quartz.h
+++ b/gfx/cairo/cairo/src/cairo-quartz.h
@@ -35,32 +35,48 @@
 
 #ifndef CAIRO_QUARTZ_H
 #define CAIRO_QUARTZ_H
 
 #include <cairo.h>
 
 #if CAIRO_HAS_QUARTZ_SURFACE
 
-#include <Carbon/Carbon.h>
+#include <ApplicationServices/ApplicationServices.h>
 
 CAIRO_BEGIN_DECLS
 
 cairo_public cairo_surface_t *
 cairo_quartz_surface_create (cairo_format_t format,
                              unsigned int width,
                              unsigned int height);
 
 cairo_public cairo_surface_t *
 cairo_quartz_surface_create_for_cg_context (CGContextRef cgContext,
                                             unsigned int width,
                                             unsigned int height);
 
 cairo_public CGContextRef
 cairo_quartz_surface_get_cg_context (cairo_surface_t *surface);
 
+/*
+ * Quartz font support
+ */
+
+#ifdef CAIRO_HAS_QUARTZ_FONT
+
+cairo_public cairo_font_face_t *
+cairo_quartz_font_face_create_for_cgfont (CGFontRef font);
+
+cairo_public cairo_font_face_t *
+cairo_quartz_font_face_create_for_atsu_font_id (ATSUFontID font_id);
+
+#endif /* CAIRO_HAS_QUARTZ_FONT */
+
 CAIRO_END_DECLS
 
-#else  /* CAIRO_HAS_QUARTZ_SURFACE */
+#else
+
 # error Cairo was not compiled with support for the quartz backend
+
 #endif /* CAIRO_HAS_QUARTZ_SURFACE */
 
 #endif /* CAIRO_QUARTZ_H */
--- a/gfx/cairo/cairo/src/cairo-rectangle.c
+++ b/gfx/cairo/cairo/src/cairo-rectangle.c
@@ -103,17 +103,17 @@ void
  * we're in fixed point, this function does a bit more work to avoid having to
  * do the division -- we don't care about the actual intersection point, so
  * it's of no interest to us.
  */
 
 cairo_bool_t
 _cairo_box_intersects_line_segment (cairo_box_t *box, cairo_line_t *line)
 {
-    cairo_fixed_t t1, t2, t3, t4;
+    cairo_fixed_t t1=0, t2=0, t3=0, t4=0;
     cairo_int64_t t1y, t2y, t3x, t4x;
 
     cairo_fixed_t xlen, ylen;
 
     if (_cairo_box_contains_point(box, &line->p1) ||
 	_cairo_box_contains_point(box, &line->p2))
 	return TRUE;
 
--- a/gfx/cairo/cairo/src/cairo-surface-fallback.c
+++ b/gfx/cairo/cairo/src/cairo-surface-fallback.c
@@ -1146,19 +1146,19 @@ cairo_status_t
     y2 = rects[0].y + rects[0].height;
 
     for (i = 1; i < num_rects; i++) {
 	if (rects[i].x < x1)
 	    x1 = rects[i].x;
 	if (rects[i].y < y1)
 	    y1 = rects[i].y;
 
-	if (rects[i].x + rects[i].width > x2)
+	if ((int)(rects[i].x + rects[i].width) > x2)
 	    x2 = rects[i].x + rects[i].width;
-	if (rects[i].y + rects[i].height > y2)
+	if ((int)(rects[i].y + rects[i].height) > y2)
 	    y2 = rects[i].y + rects[i].height;
     }
 
     status = _fallback_init (&state, surface, x1, y1, x2 - x1, y2 - y1);
     if (status) {
 	if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
 	    return CAIRO_STATUS_SUCCESS;
 	return status;
--- a/gfx/cairo/cairo/src/cairo-surface.c
+++ b/gfx/cairo/cairo/src/cairo-surface.c
@@ -1980,16 +1980,22 @@ static cairo_status_t
     if (status == CAIRO_STATUS_SUCCESS)
 	surface->current_clip_serial = serial;
 
     _cairo_path_fixed_fini (&path);
 
     return _cairo_surface_set_error (surface, status);
 }
 
+cairo_clip_t *
+_cairo_surface_get_clip (cairo_surface_t *surface)
+{
+    return surface->clip;
+}
+
 cairo_status_t
 _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip)
 {
     unsigned int serial = 0;
 
     if (surface->status)
 	return surface->status;
 
@@ -2482,16 +2488,34 @@ cairo_surface_t *
     case CAIRO_STATUS_WRITE_ERROR:
 	return (cairo_surface_t *) &_cairo_surface_nil_write_error;
     case CAIRO_STATUS_FILE_NOT_FOUND:
 	return (cairo_surface_t *) &_cairo_surface_nil_file_not_found;
     case CAIRO_STATUS_TEMP_FILE_ERROR:
 	return (cairo_surface_t *) &_cairo_surface_nil_temp_file_error;
     case CAIRO_STATUS_INVALID_STRIDE:
 	return (cairo_surface_t *) &_cairo_surface_nil_invalid_stride;
+    case CAIRO_STATUS_SUCCESS:
+	ASSERT_NOT_REACHED;
+	/* fall-through */
+    case CAIRO_STATUS_INVALID_RESTORE:
+    case CAIRO_STATUS_INVALID_POP_GROUP:
+    case CAIRO_STATUS_NO_CURRENT_POINT:
+    case CAIRO_STATUS_INVALID_MATRIX:
+    case CAIRO_STATUS_INVALID_STATUS:
+    case CAIRO_STATUS_NULL_POINTER:
+    case CAIRO_STATUS_INVALID_STRING:
+    case CAIRO_STATUS_INVALID_PATH_DATA:
+    case CAIRO_STATUS_SURFACE_FINISHED:
+    case CAIRO_STATUS_SURFACE_TYPE_MISMATCH:
+    case CAIRO_STATUS_PATTERN_TYPE_MISMATCH:
+    case CAIRO_STATUS_INVALID_DASH:
+    case CAIRO_STATUS_INVALID_DSC_COMMENT:
+    case CAIRO_STATUS_INVALID_INDEX:
+    case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE:
     default:
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t *) &_cairo_surface_nil;
     }
 }
 
 /*  LocalWords:  rasterized
  */
--- a/gfx/cairo/cairo/src/cairo-svg-surface.c
+++ b/gfx/cairo/cairo/src/cairo-svg-surface.c
@@ -228,20 +228,25 @@ static cairo_bool_t
  * target. Otherwise return %CAIRO_STATUS_SURFACE_TYPE_MISMATCH.
  */
 static cairo_status_t
 _extract_svg_surface (cairo_surface_t		 *surface,
 		      cairo_svg_surface_t	**svg_surface)
 {
     cairo_surface_t *target;
 
+    if (surface->status)
+	return surface->status;
+
     if (! _cairo_surface_is_paginated (surface))
 	return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 
     target = _cairo_paginated_surface_get_target (surface);
+    if (target->status)
+	return target->status;
 
     if (! _cairo_surface_is_svg (target))
 	return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
 
     *svg_surface = (cairo_svg_surface_t *) target;
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -481,25 +486,31 @@ static cairo_int_status_t
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static void
 _cairo_svg_surface_emit_transform (cairo_output_stream_t *output,
 				   char const		 *attribute_str,
-				   cairo_matrix_t	 *matrix)
+				   const cairo_matrix_t	 *object_matrix,
+				   const cairo_matrix_t  *parent_matrix)
 {
-    if (!_cairo_matrix_is_identity (matrix))
+    cairo_matrix_t matrix = *object_matrix;
+
+    if (parent_matrix != NULL)
+	cairo_matrix_multiply (&matrix, &matrix, parent_matrix);
+
+    if (!_cairo_matrix_is_identity (&matrix))
 	_cairo_output_stream_printf (output,
 				     "%s=\"matrix(%f,%f,%f,%f,%f,%f)\"",
 				     attribute_str,
-				     matrix->xx, matrix->yx,
-				     matrix->xy, matrix->yy,
-				     matrix->x0, matrix->y0);
+				     matrix.xx, matrix.yx,
+				     matrix.xy, matrix.yy,
+				     matrix.x0, matrix.y0);
 }
 
 typedef struct
 {
     cairo_output_stream_t *output;
     cairo_matrix_t *ctm_inverse;
 } svg_path_info_t;
 
@@ -649,17 +660,18 @@ static cairo_int_status_t
     image = scaled_glyph->surface;
     if (image->format != CAIRO_FORMAT_A1) {
 	image = _cairo_image_surface_clone (image, CAIRO_FORMAT_A1);
 	if (cairo_surface_status (&image->base))
 	    return cairo_surface_status (&image->base);
     }
 
     _cairo_output_stream_printf (document->xml_node_glyphs, "<g");
-    _cairo_svg_surface_emit_transform (document->xml_node_glyphs, " transform", &image->base.device_transform_inverse);
+    _cairo_svg_surface_emit_transform (document->xml_node_glyphs, " transform",
+				       &image->base.device_transform_inverse, NULL);
     _cairo_output_stream_printf (document->xml_node_glyphs, ">/n");
 
     for (y = 0, row = image->data, rows = image->height; rows; row += image->stride, rows--, y++) {
 	for (x = 0, byte = row, cols = (image->width + 7) / 8; cols; byte++, cols--) {
 	    unsigned char output_byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte);
 	    for (bit = 7; bit >= 0 && x < image->width; bit--, x++) {
 		if (output_byte & (1 << bit)) {
 		    _cairo_output_stream_printf (document->xml_node_glyphs,
@@ -944,17 +956,18 @@ static cairo_int_status_t
 
     return status;
 }
 
 static cairo_status_t
 _cairo_svg_surface_emit_composite_image_pattern (cairo_output_stream_t   *output,
 						 cairo_svg_surface_t	 *svg_surface,
 						 cairo_surface_pattern_t *pattern,
-						 int	 		  pattern_id,
+						 int			  pattern_id,
+						 const cairo_matrix_t	 *parent_matrix,
 						 const char		 *extra_attributes)
 {
     cairo_surface_t *surface;
     cairo_surface_attributes_t surface_attr;
     cairo_rectangle_int_t extents;
     cairo_status_t status;
     cairo_matrix_t p2u;
 
@@ -962,53 +975,54 @@ static cairo_status_t
 					     (cairo_surface_t *)svg_surface,
 					     0, 0, (unsigned int)-1, (unsigned int)-1,
 					     &surface, &surface_attr);
     if (status)
 	return status;
 
     status = _cairo_surface_get_extents (surface, &extents);
     if (status)
-	return status;
+	goto FAIL;
 
     p2u = pattern->base.matrix;
     status = cairo_matrix_invert (&p2u);
     /* cairo_pattern_set_matrix ensures the matrix is invertible */
     assert (status == CAIRO_STATUS_SUCCESS);
 
     if (pattern_id != invalid_pattern_id) {
 	_cairo_output_stream_printf (output,
 				     "<pattern id=\"pattern%d\" "
 				     "patternUnits=\"userSpaceOnUse\" "
 				     "width=\"%d\" height=\"%d\"",
 				     pattern_id,
 				     extents.width, extents.height);
-	_cairo_svg_surface_emit_transform (output, " patternTransform", &p2u);
+	_cairo_svg_surface_emit_transform (output, " patternTransform", &p2u, parent_matrix);
 	_cairo_output_stream_printf (output, ">\n");
     }
 
     _cairo_output_stream_printf (output,
 				 "  <image width=\"%d\" height=\"%d\"",
 				 extents.width, extents.height);
 
     if (pattern_id == invalid_pattern_id)
-	_cairo_svg_surface_emit_transform (output, " transform", &p2u);
+	_cairo_svg_surface_emit_transform (output, " transform", &p2u, parent_matrix);
 
     if (extra_attributes)
 	_cairo_output_stream_printf (output, " %s", extra_attributes);
 
     _cairo_output_stream_printf (output, " xlink:href=\"");
 
     status = _cairo_surface_base64_encode (surface, output);
 
     _cairo_output_stream_printf (output, "\"/>\n");
 
     if (pattern_id != invalid_pattern_id)
 	_cairo_output_stream_printf (output, "</pattern>\n");
 
+  FAIL:
     _cairo_pattern_release_surface ((cairo_pattern_t *)pattern,
 				    surface, &surface_attr);
 
     return status;
 }
 
 static cairo_status_t
 _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document,
@@ -1139,16 +1153,17 @@ static cairo_status_t
     return status;
 }
 
 static cairo_status_t
 _cairo_svg_surface_emit_composite_meta_pattern (cairo_output_stream_t	*output,
 						cairo_svg_surface_t	*surface,
 						cairo_surface_pattern_t	*pattern,
 						int			 pattern_id,
+						const cairo_matrix_t	*parent_matrix,
 						const char		*extra_attributes)
 {
     cairo_svg_document_t *document = surface->document;
     cairo_meta_surface_t *meta_surface;
     cairo_matrix_t p2u;
     cairo_status_t status;
     int id = 0;
 
@@ -1166,26 +1181,26 @@ static cairo_status_t
     if (pattern_id != invalid_pattern_id) {
 	_cairo_output_stream_printf (output,
 				     "<pattern id=\"pattern%d\" "
 				     "patternUnits=\"userSpaceOnUse\" "
 				     "width=\"%d\" height=\"%d\"",
 				     pattern_id,
 				     meta_surface->width_pixels,
 				     meta_surface->height_pixels);
-	_cairo_svg_surface_emit_transform (output, " patternTransform", &p2u);
+	_cairo_svg_surface_emit_transform (output, " patternTransform", &p2u, parent_matrix);
 	_cairo_output_stream_printf (output, ">\n");
     }
 
     _cairo_output_stream_printf (output,
 				 "<use xlink:href=\"#surface%d\"",
 				 id);
 
     if (pattern_id == invalid_pattern_id)
-	_cairo_svg_surface_emit_transform (output, " transform", &p2u);
+	_cairo_svg_surface_emit_transform (output, " transform", &p2u, parent_matrix);
 
     if (extra_attributes)
 	_cairo_output_stream_printf (output, " %s", extra_attributes);
 
     _cairo_output_stream_printf (output, "/>\n");
 
     if (pattern_id != invalid_pattern_id)
 	_cairo_output_stream_printf (output, "</pattern>\n");
@@ -1193,26 +1208,27 @@ static cairo_status_t
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
 _cairo_svg_surface_emit_composite_pattern (cairo_output_stream_t   *output,
 					   cairo_svg_surface_t	   *surface,
 					   cairo_surface_pattern_t *pattern,
 					   int			    pattern_id,
+					   const cairo_matrix_t	   *parent_matrix,
 					   const char		   *extra_attributes)
 {
 
     if (_cairo_surface_is_meta (pattern->surface)) {
 	return _cairo_svg_surface_emit_composite_meta_pattern (output, surface, pattern,
-					    pattern_id, extra_attributes);
+					    pattern_id, parent_matrix, extra_attributes);
     }
 
     return _cairo_svg_surface_emit_composite_image_pattern (output, surface, pattern,
-					 pattern_id, extra_attributes);
+					 pattern_id, parent_matrix, extra_attributes);
 }
 
 static void
 _cairo_svg_surface_emit_operator (cairo_output_stream_t *output,
 				  cairo_svg_surface_t   *surface,
 				  cairo_operator_t	 op)
 {
     char const *op_str[] = {
@@ -1248,32 +1264,33 @@ static cairo_status_t
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
 _cairo_svg_surface_emit_surface_pattern (cairo_svg_surface_t	 *surface,
 					 cairo_surface_pattern_t *pattern,
 					 cairo_output_stream_t   *style,
-					 cairo_bool_t		  is_stroke)
+					 cairo_bool_t		  is_stroke,
+					 const cairo_matrix_t	 *parent_matrix)
 {
     cairo_svg_document_t *document = surface->document;
     cairo_status_t status;
     int pattern_id;
 
     pattern_id = document->pattern_id++;
     status = _cairo_svg_surface_emit_composite_pattern (document->xml_node_defs,
 	                                                surface, pattern,
-							pattern_id, NULL);
+							pattern_id, parent_matrix, NULL);
     if (status)
 	return status;
 
     _cairo_output_stream_printf (style,
 				 "%s: url(#pattern%d);",
-				 is_stroke ? "color" : "fill",
+				 is_stroke ? "stroke" : "fill",
 				 pattern_id);
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
 _cairo_svg_surface_emit_pattern_stops (cairo_output_stream_t          *output,
 				       cairo_gradient_pattern_t const *pattern,
@@ -1289,86 +1306,83 @@ static cairo_status_t
     if (pattern->n_stops < 1)
 	return CAIRO_STATUS_SUCCESS;
 
     if (pattern->n_stops == 1) {
 	    _cairo_output_stream_printf (output,
 					 "<stop offset=\"%f\" style=\""
 					 "stop-color: rgb(%f%%,%f%%,%f%%); "
 					 "stop-opacity: %f;\"/>\n",
-					 _cairo_fixed_to_double (pattern->stops[0].x),
+					 pattern->stops[0].offset,
 					 pattern->stops[0].color.red   * 100.0,
 					 pattern->stops[0].color.green * 100.0,
 					 pattern->stops[0].color.blue  * 100.0,
 					 pattern->stops[0].color.alpha);
 	    return CAIRO_STATUS_SUCCESS;
     }
 
     if (emulate_reflect || reverse_stops) {
 	n_stops = emulate_reflect ? pattern->n_stops * 2 - 2: pattern->n_stops;
 	stops = _cairo_malloc_ab (n_stops, sizeof (cairo_gradient_stop_t));
 	if (stops == NULL)
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	for (i = 0; i < pattern->n_stops; i++) {
 	    if (reverse_stops) {
 		stops[i] = pattern->stops[pattern->n_stops - i - 1];
-		stops[i].x = _cairo_fixed_from_double (1.0 - _cairo_fixed_to_double (stops[i].x));
+		stops[i].offset = 1.0 - stops[i].offset;
 	    } else
 		stops[i] = pattern->stops[i];
 	    if (emulate_reflect) {
-		stops[i].x /= 2;
+		stops[i].offset /= 2;
 		if (i > 0 && i < (pattern->n_stops - 1)) {
 		    if (reverse_stops) {
 			stops[i + pattern->n_stops - 1] = pattern->stops[i];
-			stops[i + pattern->n_stops - 1].x =
-			    _cairo_fixed_from_double (0.5 + 0.5
-				* _cairo_fixed_to_double (stops[i + pattern->n_stops - 1].x));
+			stops[i + pattern->n_stops - 1].offset =
+			    0.5 + 0.5 * stops[i + pattern->n_stops - 1].offset;
 		    } else {
 			stops[i + pattern->n_stops - 1] = pattern->stops[pattern->n_stops - i - 1];
-			stops[i + pattern->n_stops - 1].x =
-			    _cairo_fixed_from_double (1 - 0.5
-				* _cairo_fixed_to_double (stops [i + pattern->n_stops - 1].x));
+			stops[i + pattern->n_stops - 1].offset =
+			    1 - 0.5 * stops[i + pattern->n_stops - 1].offset;
 		    }
 		}
 	    }
 	}
     } else {
 	n_stops = pattern->n_stops;
 	stops = pattern->stops;
     }
 
     if (start_offset >= 0.0)
 	for (i = 0; i < n_stops; i++) {
-	    offset = start_offset + (1 - start_offset ) *
-		_cairo_fixed_to_double (stops[i].x);
+	    offset = start_offset + (1 - start_offset ) * stops[i].offset;
 	    _cairo_output_stream_printf (output,
 					 "<stop offset=\"%f\" style=\""
 					 "stop-color: rgb(%f%%,%f%%,%f%%); "
 					 "stop-opacity: %f;\"/>\n",
 					 offset,
 					 stops[i].color.red   * 100.0,
 					 stops[i].color.green * 100.0,
 					 stops[i].color.blue  * 100.0,
 					 stops[i].color.alpha);
 	}
     else {
 	cairo_bool_t found = FALSE;
 	unsigned int offset_index;
 	cairo_color_t offset_color_start, offset_color_stop;
 
 	for (i = 0; i < n_stops; i++) {
-	    if (_cairo_fixed_to_double (stops[i].x) >= -start_offset) {
+	    if (stops[i].offset >= -start_offset) {
 		if (i > 0) {
-		    if (stops[i].x != stops[i-1].x) {
+		    if (stops[i].offset != stops[i-1].offset) {
 			double x0, x1;
 			cairo_color_t *color0, *color1;
 
-			x0 = _cairo_fixed_to_double (stops[i-1].x);
-			x1 = _cairo_fixed_to_double (stops[i].x);
+			x0 = stops[i-1].offset;
+			x1 = stops[i].offset;
 			color0 = &stops[i-1].color;
 			color1 = &stops[i].color;
 			offset_color_start.red = color0->red + (color1->red - color0->red)
 			    * (-start_offset - x0) / (x1 - x0);
 			offset_color_start.green = color0->green + (color1->green - color0->green)
 			    * (-start_offset - x0) / (x1 - x0);
 			offset_color_start.blue = color0->blue + (color1->blue - color0->blue)
 			    * (-start_offset - x0) / (x1 - x0);
@@ -1400,28 +1414,28 @@ static cairo_status_t
 				     offset_color_start.green * 100.0,
 				     offset_color_start.blue  * 100.0,
 				     offset_color_start.alpha);
 	for (i = offset_index; i < n_stops; i++) {
 	    _cairo_output_stream_printf (output,
 					 "<stop offset=\"%f\" style=\""
 					 "stop-color: rgb(%f%%,%f%%,%f%%); "
 					 "stop-opacity: %f;\"/>\n",
-					 _cairo_fixed_to_double (stops[i].x) + start_offset,
+					 stops[i].offset + start_offset,
 					 stops[i].color.red   * 100.0,
 					 stops[i].color.green * 100.0,
 					 stops[i].color.blue  * 100.0,
 					 stops[i].color.alpha);
 	}
 	for (i = 0; i < offset_index; i++) {
 	    _cairo_output_stream_printf (output,
 					 "<stop offset=\"%f\" style=\""
 					 "stop-color: rgb(%f%%,%f%%,%f%%); "
 					 "stop-opacity: %f;\"/>\n",
-					 1.0 + _cairo_fixed_to_double (stops[i].x) + start_offset,
+					 1.0 + stops[i].offset + start_offset,
 					 stops[i].color.red   * 100.0,
 					 stops[i].color.green * 100.0,
 					 stops[i].color.blue  * 100.0,
 					 stops[i].color.alpha);
 	}
 
 	_cairo_output_stream_printf (output,
 				     "<stop offset=\"1\" style=\""
@@ -1456,17 +1470,18 @@ static void
 	    break;
     }
 }
 
 static cairo_status_t
 _cairo_svg_surface_emit_linear_pattern (cairo_svg_surface_t    *surface,
 					cairo_linear_pattern_t *pattern,
 					cairo_output_stream_t  *style,
-					cairo_bool_t	        is_stroke)
+					cairo_bool_t	        is_stroke,
+					const cairo_matrix_t   *parent_matrix)
 {
     cairo_svg_document_t *document = surface->document;
     double x0, y0, x1, y1;
     cairo_matrix_t p2u;
     cairo_status_t status;
 
     p2u = pattern->base.base.matrix;
     status = cairo_matrix_invert (&p2u);
@@ -1481,43 +1496,44 @@ static cairo_status_t
     _cairo_output_stream_printf (document->xml_node_defs,
 				 "<linearGradient id=\"linear%d\" "
 				 "gradientUnits=\"userSpaceOnUse\" "
 				 "x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" ",
 				 document->linear_pattern_id,
 				 x0, y0, x1, y1);
 
     _cairo_svg_surface_emit_pattern_extend (document->xml_node_defs, &pattern->base.base),
-    _cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u);
+    _cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u, parent_matrix);
     _cairo_output_stream_printf (document->xml_node_defs, ">\n");
 
     status = _cairo_svg_surface_emit_pattern_stops (document->xml_node_defs,
 	                                            &pattern->base, 0.0,
 						    FALSE, FALSE);
     if (status)
 	return status;
 
     _cairo_output_stream_printf (document->xml_node_defs,
 				 "</linearGradient>\n");
 
     _cairo_output_stream_printf (style,
 				 "%s: url(#linear%d);",
-				 is_stroke ? "color" : "fill",
+				 is_stroke ? "stroke" : "fill",
 				 document->linear_pattern_id);
 
     document->linear_pattern_id++;
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
 _cairo_svg_surface_emit_radial_pattern (cairo_svg_surface_t    *surface,
 					cairo_radial_pattern_t *pattern,
 					cairo_output_stream_t  *style,
-					cairo_bool_t            is_stroke)
+					cairo_bool_t            is_stroke,
+					const cairo_matrix_t   *parent_matrix)
 {
     cairo_svg_document_t *document = surface->document;
     cairo_matrix_t p2u;
     cairo_extend_t extend;
     double x0, y0, x1, y1, r0, r1;
     double fx, fy;
     cairo_bool_t reverse_stops;
     cairo_status_t status;
@@ -1558,17 +1574,17 @@ static cairo_status_t
 	_cairo_output_stream_printf (document->xml_node_defs,
 				     "<radialGradient id=\"radial%d\" "
 				     "gradientUnits=\"userSpaceOnUse\" "
 				     "cx=\"%f\" cy=\"%f\" "
 				     "fx=\"%f\" fy=\"%f\" r=\"%f\" ",
 				     document->radial_pattern_id,
 				     x1, y1,
 				     x1, y1, r1);
-	_cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u);
+	_cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u, parent_matrix);
 	_cairo_output_stream_printf (document->xml_node_defs, ">\n");
 
 	if (extend == CAIRO_EXTEND_NONE || n_stops < 1)
 	    _cairo_output_stream_printf (document->xml_node_defs,
 					 "<stop offset=\"0\" style=\""
 					 "stop-color: rgb(0%%,0%%,0%%); "
 					 "stop-opacity: 0;\"/>\n");
 	else {
@@ -1642,17 +1658,17 @@ static cairo_status_t
 				     document->radial_pattern_id,
 				     x1, y1,
 				     fx, fy, r1);
 
 	if (emulate_reflect)
 	    _cairo_output_stream_printf (document->xml_node_defs, "spreadMethod=\"repeat\" ");
 	else
 	    _cairo_svg_surface_emit_pattern_extend (document->xml_node_defs, &pattern->base.base);
-	_cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u);
+	_cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u, parent_matrix);
 	_cairo_output_stream_printf (document->xml_node_defs, ">\n");
 
 	/* To support cairo's EXTEND_NONE, (for which SVG has no similar
 	 * notion), we add transparent color stops on either end of the
 	 * user-provided stops. */
 	if (extend == CAIRO_EXTEND_NONE) {
 	    _cairo_output_stream_printf (document->xml_node_defs,
 					 "<stop offset=\"0\" style=\""
@@ -1679,67 +1695,74 @@ static cairo_status_t
 					 "stop-opacity: 0;\"/>\n");
     }
 
     _cairo_output_stream_printf (document->xml_node_defs,
 				 "</radialGradient>\n");
 
     _cairo_output_stream_printf (style,
 				 "%s: url(#radial%d);",
-				 is_stroke ? "color" : "fill",
+				 is_stroke ? "stroke" : "fill",
 				 document->radial_pattern_id);
 
     document->radial_pattern_id++;
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
 _cairo_svg_surface_emit_pattern (cairo_svg_surface_t   *surface,
 				 cairo_pattern_t       *pattern,
 				 cairo_output_stream_t *output,
-				 cairo_bool_t		is_stroke)
+				 cairo_bool_t		is_stroke,
+				 const cairo_matrix_t  *parent_matrix)
 {
     switch (pattern->type) {
     case CAIRO_PATTERN_TYPE_SOLID:
-	return _cairo_svg_surface_emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern, output, is_stroke);
+	return _cairo_svg_surface_emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern,
+						      output, is_stroke);
 
     case CAIRO_PATTERN_TYPE_SURFACE:
-	return _cairo_svg_surface_emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern, output, is_stroke);
+	return _cairo_svg_surface_emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern,
+							output, is_stroke, parent_matrix);
 
     case CAIRO_PATTERN_TYPE_LINEAR:
-	return _cairo_svg_surface_emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern, output, is_stroke);
+	return _cairo_svg_surface_emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern,
+						       output, is_stroke, parent_matrix);
 
     case CAIRO_PATTERN_TYPE_RADIAL:
-	return _cairo_svg_surface_emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern, output, is_stroke);
+	return _cairo_svg_surface_emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern,
+						       output, is_stroke, parent_matrix);
     }
     return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
 }
 
 static cairo_status_t
 _cairo_svg_surface_emit_fill_style (cairo_output_stream_t *output,
 				    cairo_svg_surface_t   *surface,
 				    cairo_operator_t       op,
 				    cairo_pattern_t	  *source,
-				    cairo_fill_rule_t	   fill_rule)
+				    cairo_fill_rule_t	   fill_rule,
+				    cairo_matrix_t	  *parent_matrix)
 {
     _cairo_output_stream_printf (output,
 				 "fill-rule: %s; ",
 				 fill_rule == CAIRO_FILL_RULE_EVEN_ODD ?
 				 "evenodd" : "nonzero");
     _cairo_svg_surface_emit_operator (output, surface, op);
-    return _cairo_svg_surface_emit_pattern (surface, source, output, FALSE);
+    return _cairo_svg_surface_emit_pattern (surface, source, output, FALSE, parent_matrix);
 }
 
 static cairo_status_t
 _cairo_svg_surface_emit_stroke_style (cairo_output_stream_t *output,
 				      cairo_svg_surface_t   *surface,
 				      cairo_operator_t	     op,
 				      cairo_pattern_t	    *source,
-				      cairo_stroke_style_t  *stroke_style)
+				      cairo_stroke_style_t  *stroke_style,
+				      cairo_matrix_t	    *parent_matrix)
 {
     cairo_status_t status;
     const char *line_cap, *line_join;
     unsigned int i;
 
     switch (stroke_style->line_cap) {
 	case CAIRO_LINE_CAP_BUTT:
 	    line_cap = "butt";
@@ -1771,17 +1794,17 @@ static cairo_status_t
     _cairo_output_stream_printf (output,
 				 "stroke-width: %f; "
 				 "stroke-linecap: %s; "
 				 "stroke-linejoin: %s; ",
 				 stroke_style->line_width,
 				 line_cap,
 				 line_join);
 
-     status = _cairo_svg_surface_emit_pattern (surface, source, output, TRUE);
+     status = _cairo_svg_surface_emit_pattern (surface, source, output, TRUE, parent_matrix);
      if (status)
 	 return status;
 
      _cairo_svg_surface_emit_operator (output, surface, op);
 
     if (stroke_style->num_dashes > 0) {
 	_cairo_output_stream_printf (output, "stroke-dasharray: ");
 	for (i = 0; i < stroke_style->num_dashes; i++) {
@@ -1821,31 +1844,33 @@ static cairo_int_status_t
 				cairo_matrix_t		*stroke_ctm_inverse,
 				double			 stroke_tolerance,
 				cairo_antialias_t	 stroke_antialias)
 {
     cairo_svg_surface_t *surface = abstract_surface;
     cairo_status_t status;
 
     _cairo_output_stream_printf (surface->xml_node, "<path style=\"");
-    status = _cairo_svg_surface_emit_fill_style (surface->xml_node, surface, fill_op, fill_source, fill_rule);
+    status = _cairo_svg_surface_emit_fill_style (surface->xml_node, surface, fill_op,
+						 fill_source, fill_rule, stroke_ctm_inverse);
     if (status)
 	return status;
 
-    status = _cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, stroke_op, stroke_source, stroke_style);
+    status = _cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, stroke_op,
+						   stroke_source, stroke_style, stroke_ctm_inverse);
     if (status)
 	return status;
 
     _cairo_output_stream_printf (surface->xml_node, "\" ");
 
     status = _cairo_svg_surface_emit_path (surface->xml_node, path, stroke_ctm_inverse);
     if (status)
 	return status;
 
-    _cairo_svg_surface_emit_transform (surface->xml_node, " transform", stroke_ctm);
+    _cairo_svg_surface_emit_transform (surface->xml_node, " transform", stroke_ctm, NULL);
     _cairo_output_stream_printf (surface->xml_node, "/>\n");
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_int_status_t
 _cairo_svg_surface_fill (void			*abstract_surface,
 			 cairo_operator_t	 op,
@@ -1859,17 +1884,17 @@ static cairo_int_status_t
     cairo_status_t status;
 
     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
 	return _cairo_svg_surface_analyze_operation (surface, op, source);
 
     assert (_cairo_svg_surface_operation_supported (surface, op, source));
 
     _cairo_output_stream_printf (surface->xml_node, "<path style=\" stroke:none;");
-    status = _cairo_svg_surface_emit_fill_style (surface->xml_node, surface, op, source, fill_rule);
+    status = _cairo_svg_surface_emit_fill_style (surface->xml_node, surface, op, source, fill_rule, NULL);
     if (status)
 	return status;
 
     _cairo_output_stream_printf (surface->xml_node, "\" ");
 
     status = _cairo_svg_surface_emit_path (surface->xml_node, path, NULL);
     if (status)
 	return status;
@@ -1908,25 +1933,26 @@ static cairo_status_t
     cairo_status_t status;
 
     if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
 	source->extend == CAIRO_EXTEND_NONE)
 	return _cairo_svg_surface_emit_composite_pattern (output,
 				       surface,
 				       (cairo_surface_pattern_t *) source,
 				       invalid_pattern_id,
+				       NULL,
 				       extra_attributes);
 
     _cairo_output_stream_printf (output,
 				 "<rect x=\"0\" y=\"0\" "
 				 "width=\"%f\" height=\"%f\" "
 				 "style=\"",
 				 surface->width, surface->height);
     _cairo_svg_surface_emit_operator (output, surface, op);
-    status = _cairo_svg_surface_emit_pattern (surface, source, output, FALSE);
+    status = _cairo_svg_surface_emit_pattern (surface, source, output, FALSE, NULL);
     if (status)
 	return status;
 
     _cairo_output_stream_printf (output, " stroke: none;\"");
 
     if (extra_attributes)
 	_cairo_output_stream_printf (output, " %s", extra_attributes);
 
@@ -2081,24 +2107,28 @@ static cairo_int_status_t
     cairo_status_t status;
 
     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
 	return _cairo_svg_surface_analyze_operation (surface, op, source);
 
     assert (_cairo_svg_surface_operation_supported (surface, op, source));
 
     _cairo_output_stream_printf (surface->xml_node, "<path style=\"fill: none; ");
-    status = _cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, op, source, stroke_style);
+    status = _cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, op,
+						   source, stroke_style, ctm_inverse);
+    if (status)
+	return status;
+
     _cairo_output_stream_printf (surface->xml_node, "\" ");
 
     status = _cairo_svg_surface_emit_path (surface->xml_node, path, ctm_inverse);
     if (status)
 	return status;
 
-    _cairo_svg_surface_emit_transform (surface->xml_node, " transform", ctm);
+    _cairo_svg_surface_emit_transform (surface->xml_node, " transform", ctm, NULL);
     _cairo_output_stream_printf (surface->xml_node, "/>\n");
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_int_status_t
 _cairo_svg_surface_show_glyphs (void			*abstract_surface,
 				cairo_operator_t	 op,
@@ -2125,17 +2155,17 @@ static cairo_int_status_t
     /* FIXME it's probably possible to apply a pattern of a gradient to
      * a group of symbols, but I don't know how yet. Gradients or patterns
      * are translated by x and y properties of use element. */
     if (pattern->type != CAIRO_PATTERN_TYPE_SOLID)
 	goto FALLBACK;
 
     _cairo_output_stream_printf (surface->xml_node, "<g style=\"");
     status = _cairo_svg_surface_emit_pattern (surface, pattern,
-	                                      surface->xml_node, FALSE);
+	                                      surface->xml_node, FALSE, NULL);
     if (status)
 	return status;
 
     _cairo_output_stream_printf (surface->xml_node, "\">\n");
 
     for (i = 0; i < num_glyphs; i++) {
 	status = _cairo_scaled_font_subsets_map_glyph (document->font_subsets,
 						       scaled_font, glyphs[i].index,
--- a/gfx/cairo/cairo/src/cairo-truetype-subset.c
+++ b/gfx/cairo/cairo/src/cairo-truetype-subset.c
@@ -80,18 +80,20 @@ struct _cairo_truetype_font {
     cairo_array_t string_offsets;
     unsigned long last_offset;
     unsigned long last_boundary;
     int *parent_to_subset;
     cairo_status_t status;
 
 };
 
-static int
-cairo_truetype_font_use_glyph (cairo_truetype_font_t *font, int glyph);
+static cairo_status_t
+cairo_truetype_font_use_glyph (cairo_truetype_font_t	    *font,
+	                       unsigned short		     glyph,
+			       unsigned short		    *out);
 
 #define SFNT_VERSION			0x00010000
 #define SFNT_STRING_MAX_LENGTH  65535
 
 static cairo_status_t
 _cairo_truetype_font_set_error (cairo_truetype_font_t *font,
 			        cairo_status_t status)
 {
@@ -486,51 +488,65 @@ cairo_truetype_font_write_generic_table 
     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
 						 tag, 0, buffer, &size);
     if (status)
 	return _cairo_truetype_font_set_error (font, status);
 
     return CAIRO_STATUS_SUCCESS;
 }
 
-static void
-cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font,
-					   unsigned char         *buffer)
+static cairo_status_t
+cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t	*font,
+					   unsigned char		*buffer,
+					   unsigned long		 size)
 {
     tt_glyph_data_t *glyph_data;
-    tt_composite_glyph_t *composite_glyph;
+    tt_composite_glyph_t *composite_glyph, *last_glyph;
     int num_args;
     int has_more_components;
     unsigned short flags;
     unsigned short index;
+    cairo_status_t status;
 
     if (font->status)
-	return;
+	return font->status;
+
+    if (size < sizeof (tt_glyph_data_t))
+	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     glyph_data = (tt_glyph_data_t *) buffer;
     if ((int16_t)be16_to_cpu (glyph_data->num_contours) >= 0)
-        return;
+        return CAIRO_STATUS_SUCCESS;
 
     composite_glyph = &glyph_data->glyph;
+    last_glyph = (tt_composite_glyph_t *) (buffer + size);
     do {
         flags = be16_to_cpu (composite_glyph->flags);
         has_more_components = flags & TT_MORE_COMPONENTS;
-        index = cairo_truetype_font_use_glyph (font, be16_to_cpu (composite_glyph->index));
+        status = cairo_truetype_font_use_glyph (font, be16_to_cpu (composite_glyph->index), &index);
+	if (status)
+	    return status;
+
         composite_glyph->index = cpu_to_be16 (index);
         num_args = 1;
         if (flags & TT_ARG_1_AND_2_ARE_WORDS)
             num_args += 1;
         if (flags & TT_WE_HAVE_A_SCALE)
             num_args += 1;
         else if (flags & TT_WE_HAVE_AN_X_AND_Y_SCALE)
             num_args += 2;
         else if (flags & TT_WE_HAVE_A_TWO_BY_TWO)
             num_args += 3;
         composite_glyph = (tt_composite_glyph_t *) &(composite_glyph->args[num_args]);
+
+	if (has_more_components && composite_glyph >= last_glyph)
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
     } while (has_more_components);
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
 cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font,
 				      unsigned long          tag)
 {
     unsigned long start_offset, index, size, next;
     tt_head_t header;
@@ -575,16 +591,22 @@ cairo_truetype_font_write_glyf_table (ca
 	    begin = be16_to_cpu (u.short_offsets[index]) * 2;
 	    end = be16_to_cpu (u.short_offsets[index + 1]) * 2;
 	}
 	else {
 	    begin = be32_to_cpu (u.long_offsets[index]);
 	    end = be32_to_cpu (u.long_offsets[index + 1]);
 	}
 
+	/* quick sanity check... */
+	if (end < begin) {
+	    status = CAIRO_INT_STATUS_UNSUPPORTED;
+	    goto FAIL;
+	}
+
 	size = end - begin;
         status = cairo_truetype_font_align_output (font, &next);
 	if (status)
 	    goto FAIL;
 
         status = cairo_truetype_font_check_boundary (font, next);
 	if (status)
 	    goto FAIL;
@@ -596,17 +618,19 @@ cairo_truetype_font_write_glyf_table (ca
 	    goto FAIL;
 
         if (size != 0) {
             status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
 							 TT_TAG_glyf, begin, buffer, &size);
 	    if (status)
 		goto FAIL;
 
-            cairo_truetype_font_remap_composite_glyph (font, buffer);
+            status = cairo_truetype_font_remap_composite_glyph (font, buffer, size);
+	    if (status)
+		goto FAIL;
         }
     }
 
     status = cairo_truetype_font_align_output (font, &next);
     if (status)
 	goto FAIL;
 
     font->glyphs[i].location = next - start_offset;
@@ -927,26 +951,32 @@ cairo_truetype_font_generate (cairo_true
 	*string_offsets = _cairo_array_index (&font->string_offsets, 0);
     else
 	*string_offsets = NULL;
 
  FAIL:
     return _cairo_truetype_font_set_error (font, status);
 }
 
-static int
-cairo_truetype_font_use_glyph (cairo_truetype_font_t *font, int glyph)
+static cairo_status_t
+cairo_truetype_font_use_glyph (cairo_truetype_font_t	    *font,
+	                       unsigned short		     glyph,
+			       unsigned short		    *out)
 {
+    if (glyph >= font->num_glyphs_in_face)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
     if (font->parent_to_subset[glyph] == 0) {
 	font->parent_to_subset[glyph] = font->base.num_glyphs;
 	font->glyphs[font->base.num_glyphs].parent_index = glyph;
 	font->base.num_glyphs++;
     }
 
-    return font->parent_to_subset[glyph];
+    *out = font->parent_to_subset[glyph];
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static void
 cairo_truetype_font_add_truetype_table (cairo_truetype_font_t *font,
            unsigned long tag,
            cairo_status_t (*write) (cairo_truetype_font_t *font, unsigned long tag),
            int pos)
 {
@@ -1032,28 +1062,29 @@ cairo_truetype_font_create_truetype_tabl
 cairo_status_t
 _cairo_truetype_subset_init (cairo_truetype_subset_t    *truetype_subset,
 			     cairo_scaled_font_subset_t	*font_subset)
 {
     cairo_truetype_font_t *font = NULL;
     cairo_status_t status;
     const char *data = NULL; /* squelch bogus compiler warning */
     unsigned long length = 0; /* squelch bogus compiler warning */
-    unsigned long parent_glyph, offsets_length;
+    unsigned long offsets_length;
     unsigned int i;
     const unsigned long *string_offsets = NULL;
     unsigned long num_strings = 0;
 
     status = _cairo_truetype_font_create (font_subset, &font);
     if (status)
 	return status;
 
     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
-	parent_glyph = font->scaled_font_subset->glyphs[i];
-	cairo_truetype_font_use_glyph (font, parent_glyph);
+	unsigned short parent_glyph = font->scaled_font_subset->glyphs[i];
+	status = cairo_truetype_font_use_glyph (font, parent_glyph, &parent_glyph);
+	assert (status == CAIRO_STATUS_SUCCESS);
     }
 
     cairo_truetype_font_create_truetype_table_list (font);
     status = cairo_truetype_font_generate (font, &data, &length,
                                            &string_offsets, &num_strings);
     if (status)
 	goto fail1;
 
--- a/gfx/cairo/cairo/src/cairo-win32-font.c
+++ b/gfx/cairo/cairo/src/cairo-win32-font.c
@@ -1902,17 +1902,17 @@ cairo_win32_font_face_create_for_logfont
  *
  * 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_win32_font_face_create_for_hfont (HFONT font)
 {
     LOGFONTW logfont;
-    GetObject (font, sizeof(logfont), &logfont);
+    GetObjectW (font, sizeof(logfont), &logfont);
 
     if (logfont.lfEscapement != 0 || logfont.lfOrientation != 0 ||
         logfont.lfWidth != 0) {
         /* We can't use this font because that optimization requires that
          * lfEscapement, lfOrientation and lfWidth be zero. */
         font = NULL;
     }
 
--- a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
+++ b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
@@ -752,17 +752,17 @@ static cairo_int_status_t
 	    vert[i*2].x = vert[i*2-1].x;
 	    vert[i*2].Red = vert[i*2-1].Red;
 	    vert[i*2].Green = vert[i*2-1].Green;
 	    vert[i*2].Blue = vert[i*2-1].Blue;
 	    vert[i*2].Alpha = vert[i*2-1].Alpha;
 	}
 
 	stop = i%num_rects + 1;
-	vert[i*2+1].x = (LONG)(d*(range_start + i/num_rects + _cairo_fixed_to_double (pattern->base.stops[stop].x)));
+	vert[i*2+1].x = (LONG)(d*(range_start + i/num_rects + pattern->base.stops[stop].offset));
 	vert[i*2+1].y = (LONG) clip.bottom;
 	if (extend == CAIRO_EXTEND_REFLECT && (range_start+(i/num_rects))%2)
 	    stop = num_rects - stop;
 	vertex_set_color (&vert[i*2+1], &pattern->base.stops[stop].color);
 
 	rect[i].UpperLeft = i*2;
 	rect[i].LowerRight = i*2 + 1;
     }
@@ -1414,28 +1414,42 @@ static cairo_surface_t *
     return _cairo_meta_surface_create (content, width, height);
 }
 
 static cairo_int_status_t
 _cairo_win32_printing_surface_start_page (void *abstract_surface)
 {
     cairo_win32_surface_t *surface = abstract_surface;
     XFORM xform;
+    double x_res, y_res;
+    cairo_matrix_t inverse_ctm;
+    cairo_status_t status;
 
     SaveDC (surface->dc); /* Save application context first, before doing MWT */
 
     SetGraphicsMode (surface->dc, GM_ADVANCED);
     GetWorldTransform(surface->dc, &xform);
     surface->ctm.xx = xform.eM11;
     surface->ctm.xy = xform.eM21;
     surface->ctm.yx = xform.eM12;
     surface->ctm.yy = xform.eM22;
     surface->ctm.x0 = xform.eDx;
     surface->ctm.y0 = xform.eDy;
     surface->has_ctm = !_cairo_matrix_is_identity (&surface->ctm);
+
+    inverse_ctm = surface->ctm;
+    status = cairo_matrix_invert (&inverse_ctm);
+    if (status)
+	return status;
+
+    x_res = (double) GetDeviceCaps(surface->dc, LOGPIXELSX);
+    y_res = (double) GetDeviceCaps(surface->dc, LOGPIXELSY);
+    cairo_matrix_transform_distance (&inverse_ctm, &x_res, &y_res);
+    _cairo_surface_set_resolution (&surface->base, x_res, y_res);
+
     if (!ModifyWorldTransform (surface->dc, NULL, MWT_IDENTITY))
 	return _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_start_page:ModifyWorldTransform");
 
     SaveDC (surface->dc); /* Then save Cairo's known-good clip state, so the clip path can be reset */
 
     return CAIRO_STATUS_SUCCESS;
 }
 
@@ -1463,17 +1477,16 @@ static void
  * associated methods must be used for correct output.
  *
  * Return value: the newly created surface
  **/
 cairo_surface_t *
 cairo_win32_printing_surface_create (HDC hdc)
 {
     cairo_win32_surface_t *surface;
-    int xr, yr;
     RECT rect;
 
     surface = malloc (sizeof (cairo_win32_surface_t));
     if (surface == NULL)
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
     if (_cairo_win32_save_initial_clip (hdc, surface) != CAIRO_STATUS_SUCCESS) {
 	free (surface);
@@ -1499,20 +1512,16 @@ cairo_win32_printing_surface_create (HDC
 
     surface->flags = _cairo_win32_flags_for_dc (surface->dc);
     surface->flags |= CAIRO_WIN32_SURFACE_FOR_PRINTING;
 
     _cairo_win32_printing_surface_init_ps_mode (surface);
     _cairo_surface_init (&surface->base, &cairo_win32_printing_surface_backend,
                          CAIRO_CONTENT_COLOR_ALPHA);
 
-    xr = GetDeviceCaps(hdc, LOGPIXELSX);
-    yr = GetDeviceCaps(hdc, LOGPIXELSY);
-    _cairo_surface_set_resolution (&surface->base, (double) xr, (double) yr);
-
     return _cairo_paginated_surface_create (&surface->base,
                                             CAIRO_CONTENT_COLOR_ALPHA,
 					    surface->extents.width,
 					    surface->extents.height,
                                             &cairo_win32_surface_paginated_backend);
 }
 
 cairo_bool_t
--- a/gfx/cairo/cairo/src/cairo-win32-surface.c
+++ b/gfx/cairo/cairo/src/cairo-win32-surface.c
@@ -405,19 +405,25 @@ static cairo_surface_t *
 	/* otherwise, create a ddb */
 	HBITMAP ddb = CreateCompatibleBitmap (src->dc, width, height);
 	HDC ddb_dc = CreateCompatibleDC (src->dc);
 	HBITMAP saved_dc_bitmap;
 
 	saved_dc_bitmap = SelectObject (ddb_dc, ddb);
 
 	new_surf = (cairo_win32_surface_t*) cairo_win32_surface_create (ddb_dc);
-	new_surf->bitmap = ddb;
-	new_surf->saved_dc_bitmap = saved_dc_bitmap;
-	new_surf->is_dib = FALSE;
+	if (new_surf->base.status == CAIRO_STATUS_SUCCESS) {
+	    new_surf->bitmap = ddb;
+	    new_surf->saved_dc_bitmap = saved_dc_bitmap;
+	    new_surf->is_dib = FALSE;
+	} else {
+	    SelectObject (ddb_dc, saved_dc_bitmap);
+	    DeleteDC (ddb_dc);
+	    DeleteObject (ddb);
+	}
     }
 
     return (cairo_surface_t*) new_surf;
 }
 
 cairo_surface_t *
 _cairo_win32_surface_create_similar (void	    *abstract_src,
 				     cairo_content_t content,
--- a/gfx/cairo/cairo/src/cairo-xlib-private.h
+++ b/gfx/cairo/cairo/src/cairo-xlib-private.h
@@ -65,28 +65,36 @@ struct _cairo_xlib_display {
     cairo_freelist_t wq_freelist;
 
     cairo_freelist_t hook_freelist;
     cairo_xlib_hook_t *close_display_hooks;
     unsigned int buggy_repeat :1;
     unsigned int closed :1;
 };
 
+typedef struct _cairo_xlib_visual_info {
+    VisualID visualid;
+    XColor colors[256];
+    unsigned long rgb333_to_pseudocolor[512];
+} cairo_xlib_visual_info_t;
+
 struct _cairo_xlib_screen_info {
     cairo_xlib_screen_info_t *next;
     cairo_reference_count_t ref_count;
 
     cairo_xlib_display_t *display;
     Screen *screen;
     cairo_bool_t has_render;
 
     cairo_font_options_t font_options;
 
     GC gc[9];
     unsigned int gc_needs_clip_reset;
+
+    cairo_array_t visuals;
 };
 
 cairo_private cairo_xlib_display_t *
 _cairo_xlib_display_get (Display *display);
 
 cairo_private cairo_xlib_display_t *
 _cairo_xlib_display_reference (cairo_xlib_display_t *info);
 cairo_private void
@@ -120,9 +128,23 @@ cairo_private void
 cairo_private void
 _cairo_xlib_screen_info_close_display (cairo_xlib_screen_info_t *info);
 
 cairo_private GC
 _cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info, int depth);
 cairo_private cairo_status_t
 _cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info, int depth, GC gc, cairo_bool_t reset_clip);
 
+cairo_private cairo_status_t
+_cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info,
+				    Visual *visual,
+				    cairo_xlib_visual_info_t **out);
+
+cairo_private cairo_status_t
+_cairo_xlib_visual_info_create (Display *dpy,
+	                        int screen,
+				VisualID visualid,
+				cairo_xlib_visual_info_t **out);
+
+cairo_private void
+_cairo_xlib_visual_info_destroy (Display *dpy, cairo_xlib_visual_info_t *info);
+
 #endif /* CAIRO_XLIB_PRIVATE_H */
--- a/gfx/cairo/cairo/src/cairo-xlib-screen.c
+++ b/gfx/cairo/cairo/src/cairo-xlib-screen.c
@@ -264,35 +264,42 @@ void
     }
 }
 
 void
 _cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info)
 {
     cairo_xlib_screen_info_t **prev;
     cairo_xlib_screen_info_t *list;
+    cairo_xlib_visual_info_t **visuals;
+    int i;
 
     assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&info->ref_count));
 
     if (! _cairo_reference_count_dec_and_test (&info->ref_count))
 	return;
 
     CAIRO_MUTEX_LOCK (info->display->mutex);
     for (prev = &info->display->screens; (list = *prev); prev = &list->next) {
 	if (list == info) {
 	    *prev = info->next;
 	    break;
 	}
     }
+    visuals = _cairo_array_index (&info->visuals, 0);
+    for (i = 0; i < _cairo_array_num_elements (&info->visuals); i++)
+	_cairo_xlib_visual_info_destroy (info->display->display, visuals[i]);
     CAIRO_MUTEX_UNLOCK (info->display->mutex);
 
     _cairo_xlib_screen_info_close_display (info);
 
     _cairo_xlib_display_destroy (info->display);
 
+    _cairo_array_fini (&info->visuals);
+
     free (info);
 }
 
 cairo_xlib_screen_info_t *
 _cairo_xlib_screen_info_get (Display *dpy, Screen *screen)
 {
     cairo_xlib_display_t *display;
     cairo_xlib_screen_info_t *info = NULL, **prev;
@@ -330,16 +337,19 @@ cairo_xlib_screen_info_t *
 	    CAIRO_REFERENCE_COUNT_INIT (&info->ref_count, 2); /* Add one for display cache */
 	    info->display = _cairo_xlib_display_reference (display);
 	    info->screen = screen;
 	    info->has_render = FALSE;
 	    _cairo_font_options_init_default (&info->font_options);
 	    memset (info->gc, 0, sizeof (info->gc));
 	    info->gc_needs_clip_reset = 0;
 
+	    _cairo_array_init (&info->visuals,
+			       sizeof (cairo_xlib_visual_info_t*));
+
 	    if (screen) {
 		int event_base, error_base;
 		info->has_render = (XRenderQueryExtension (dpy, &event_base, &error_base) &&
 			(XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != 0));
 		_cairo_xlib_init_screen_font_options (dpy, info);
 	    }
 
 	    CAIRO_MUTEX_LOCK (display->mutex);
@@ -406,8 +416,67 @@ cairo_status_t
     info->gc[depth] = gc;
     if (reset_clip)
 	info->gc_needs_clip_reset |= 1 << depth;
     else
 	info->gc_needs_clip_reset &= ~(1 << depth);
 
     return status;
 }
+
+cairo_status_t
+_cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info,
+				    Visual *visual,
+				    cairo_xlib_visual_info_t **out)
+{
+    cairo_xlib_visual_info_t **visuals, *ret = NULL;
+    cairo_status_t status;
+    int i, n_visuals;
+
+    CAIRO_MUTEX_LOCK (info->display->mutex);
+    visuals = _cairo_array_index (&info->visuals, 0);
+    n_visuals = _cairo_array_num_elements (&info->visuals);
+    for (i = 0; i < n_visuals; i++) {
+	if (visuals[i]->visualid == visual->visualid) {
+	    ret = visuals[i];
+	    break;
+	}
+    }
+    CAIRO_MUTEX_UNLOCK (info->display->mutex);
+
+    if (ret != NULL) {
+	*out = ret;
+	return CAIRO_STATUS_SUCCESS;
+    }
+
+    status = _cairo_xlib_visual_info_create (info->display->display,
+					     XScreenNumberOfScreen (info->screen),
+					     visual->visualid,
+					     &ret);
+    if (status)
+	return status;
+
+    CAIRO_MUTEX_LOCK (info->display->mutex);
+    if (n_visuals != _cairo_array_num_elements (&info->visuals)) {
+	/* check that another thread has not added our visual */
+	int new_visuals = _cairo_array_num_elements (&info->visuals);
+	visuals = _cairo_array_index (&info->visuals, 0);
+	for (i = n_visuals; i < new_visuals; i++) {
+	    if (visuals[i]->visualid == visual->visualid) {
+		_cairo_xlib_visual_info_destroy (info->display->display, ret);
+		ret = visuals[i];
+		break;
+	    }
+	}
+	if (i == new_visuals)
+	    status = _cairo_array_append (&info->visuals, &ret);
+    } else
+	status = _cairo_array_append (&info->visuals, &ret);
+    CAIRO_MUTEX_UNLOCK (info->display->mutex);
+
+    if (status) {
+	_cairo_xlib_visual_info_destroy (info->display->display, ret);
+	return status;
+    }
+
+    *out = ret;
+    return CAIRO_STATUS_SUCCESS;
+}
--- a/gfx/cairo/cairo/src/cairo-xlib-surface-private.h
+++ b/gfx/cairo/cairo/src/cairo-xlib-surface-private.h
@@ -86,16 +86,21 @@ struct _cairo_xlib_surface {
     XRectangle embedded_clip_rects[4];
     XRectangle *clip_rects;
     int num_clip_rects;
 
     XRenderPictFormat *xrender_format;
     cairo_filter_t filter;
     int repeat;
     XTransform xtransform;
+
+    uint32_t a_mask;
+    uint32_t r_mask;
+    uint32_t g_mask;
+    uint32_t b_mask;
 };
 
 enum {
     CAIRO_XLIB_SURFACE_CLIP_DIRTY_GC      = 0x01,
     CAIRO_XLIB_SURFACE_CLIP_DIRTY_PICTURE = 0x02,
     CAIRO_XLIB_SURFACE_CLIP_DIRTY_ALL     = 0x03
 };
 
--- a/gfx/cairo/cairo/src/cairo-xlib-surface.c
+++ b/gfx/cairo/cairo/src/cairo-xlib-surface.c
@@ -43,16 +43,26 @@
 #include "cairo-clip-private.h"
 
 #include <X11/Xutil.h> /* for XDestroyImage */
 
 /* Xlib doesn't define a typedef, so define one ourselves */
 typedef int (*cairo_xlib_error_func_t) (Display     *display,
 					XErrorEvent *event);
 
+static cairo_surface_t *
+_cairo_xlib_surface_create_internal (Display		       *dpy,
+				     Drawable		        drawable,
+				     Screen		       *screen,
+				     Visual		       *visual,
+				     XRenderPictFormat	       *xrender_format,
+				     int			width,
+				     int			height,
+				     int			depth);
+
 static cairo_status_t
 _cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface);
 
 static void
 _cairo_xlib_surface_ensure_src_picture (cairo_xlib_surface_t *surface);
 
 static void
 _cairo_xlib_surface_ensure_dst_picture (cairo_xlib_surface_t *surface);
@@ -66,20 +76,16 @@ static cairo_bool_t
 static cairo_int_status_t
 _cairo_xlib_surface_show_glyphs (void                *abstract_dst,
 				 cairo_operator_t     op,
 				 cairo_pattern_t     *src_pattern,
 				 cairo_glyph_t       *glyphs,
 				 int		      num_glyphs,
 				 cairo_scaled_font_t *scaled_font);
 
-#if CAIRO_HAS_XLIB_XRENDER_SURFACE
-slim_hidden_proto (cairo_xlib_surface_create_with_xrender_format);
-#endif
-
 /*
  * Instead of taking two round trips for each blending request,
  * assume that if a particular drawable fails GetImage that it will
  * fail for a "while"; use temporary pixmaps to avoid the errors
  */
 
 #define CAIRO_ASSUME_PIXMAP	20
 
@@ -168,19 +174,21 @@ static cairo_surface_t *
 	return NULL;
     }
 
     pix = XCreatePixmap (dpy, src->drawable,
 			 width <= 0 ? 1 : width, height <= 0 ? 1 : height,
 			 depth);
 
     surface = (cairo_xlib_surface_t *)
-	cairo_xlib_surface_create_with_xrender_format (dpy, pix, src->screen,
-						       xrender_format,
-						       width, height);
+	      _cairo_xlib_surface_create_internal (dpy, pix,
+		                                   src->screen, src->visual,
+						   xrender_format,
+						   width, height,
+						   depth);
     if (surface->base.status) {
 	XFreePixmap (dpy, pix);
 	return &surface->base;
     }
 
     surface->owns_pixmap = TRUE;
 
     return &surface->base;
@@ -246,20 +254,21 @@ static cairo_surface_t *
     /* We've got a compatible XRenderFormat now, which means the
      * similar surface will match the existing surface as closely in
      * visual/depth etc. as possible. */
     pix = XCreatePixmap (src->dpy, src->drawable,
 			 width <= 0 ? 1 : width, height <= 0 ? 1 : height,
 			 xrender_format->depth);
 
     surface = (cairo_xlib_surface_t *)
-	cairo_xlib_surface_create_with_xrender_format (src->dpy, pix,
-						       src->screen,
-						       xrender_format,
-						       width, height);
+	      _cairo_xlib_surface_create_internal (src->dpy, pix,
+		                                   src->screen, src->visual,
+						   xrender_format,
+						   width, height,
+						   xrender_format->depth);
     if (surface->base.status != CAIRO_STATUS_SUCCESS) {
 	XFreePixmap (src->dpy, pix);
 	return &surface->base;
     }
 
     surface->owns_pixmap = TRUE;
 
     return &surface->base;
@@ -450,28 +459,80 @@ static void
     case 4:
 	_swap_ximage_4bytes (ximage);
 	break;
     default:
 	ASSERT_NOT_REACHED;
     }
 }
 
+/* Given a mask, (with a single sequence of contiguous 1 bits), return
+ * the number of 1 bits in 'width' and the number of 0 bits to its
+ * right in 'shift'. */
+static inline void
+_characterize_field (uint32_t mask, int *width, int *shift)
+{
+    *width = _cairo_popcount (mask);
+    /* The final '& 31' is to force a 0 mask to result in 0 shift. */
+    *shift = _cairo_popcount ((mask - 1) & ~mask) & 31;
+}
+
+/* Convert a field of 'width' bits to 'new_width' bits with correct
+ * rounding. */
+static inline uint32_t
+_resize_field (uint32_t field, int width, int new_width)
+{
+    if (width == 0)
+	return 0;
+
+    if (width >= new_width) {
+	return field >> (width - new_width);
+    } else {
+	uint32_t result = field << (new_width - width);
+
+	while (width < new_width) {
+	    result |= result >> width;
+	    width <<= 1;
+	}
+	return result;
+    }
+}
+
+/* Given a shifted field value, (described by 'width' and 'shift),
+ * resize it 8-bits and return that value.
+ *
+ * Note that the original field value must not have any non-field bits
+ * set.
+ */
+static inline uint32_t
+_field_to_8 (uint32_t field, int width, int shift)
+{
+    return _resize_field (field >> shift, width, 8);
+}
+
+/* Given an 8-bit value, convert it to a field of 'width', shift it up
+ *  to 'shift, and return it. */
+static inline uint32_t
+_field_from_8 (uint32_t field, int width, int shift)
+{
+    return _resize_field (field, 8, width) << shift;
+}
+
 static cairo_status_t
 _get_image_surface (cairo_xlib_surface_t    *surface,
 		    cairo_rectangle_int_t   *interest_rect,
 		    cairo_image_surface_t  **image_out,
 		    cairo_rectangle_int_t   *image_rect)
 {
+    cairo_int_status_t status;
     cairo_image_surface_t *image;
     XImage *ximage;
-    short x1, y1, x2, y2;
-    cairo_format_masks_t masks;
+    unsigned short x1, y1, x2, y2;
     pixman_format_code_t pixman_format;
-    cairo_status_t status;
+    cairo_format_masks_t xlib_masks;
 
     x1 = 0;
     y1 = 0;
     x2 = surface->width;
     y2 = surface->height;
 
     if (interest_rect) {
 	cairo_rectangle_int_t rect;
@@ -562,65 +623,137 @@ static cairo_status_t
 	    XFreePixmap (surface->dpy, pixmap);
 	}
     }
     if (!ximage)
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     _swap_ximage_to_native (ximage);
 
-    /*
-     * Compute the pixel format masks from either a XrenderFormat or
-     * else from a visual; failing that we assume the drawable is an
-     * alpha-only pixmap as it could only have been created that way
-     * through the cairo_xlib_surface_create_for_bitmap function.
-     */
-    if (surface->xrender_format) {
-	masks.bpp = ximage->bits_per_pixel;
-	masks.red_mask =   (unsigned long) surface->xrender_format->direct.redMask
-	    << surface->xrender_format->direct.red;
-	masks.green_mask = (unsigned long) surface->xrender_format->direct.greenMask
-	    << surface->xrender_format->direct.green;
-	masks.blue_mask =  (unsigned long) surface->xrender_format->direct.blueMask
-	    << surface->xrender_format->direct.blue;
-	masks.alpha_mask = (unsigned long) surface->xrender_format->direct.alphaMask
-	    << surface->xrender_format->direct.alpha;
-    } else if (surface->visual) {
-	masks.bpp = ximage->bits_per_pixel;
-	masks.alpha_mask = 0;
-	masks.red_mask = surface->visual->red_mask;
-	masks.green_mask = surface->visual->green_mask;
-	masks.blue_mask = surface->visual->blue_mask;
+    xlib_masks.bpp = ximage->bits_per_pixel;
+    xlib_masks.alpha_mask = surface->a_mask;
+    xlib_masks.red_mask = surface->r_mask;
+    xlib_masks.green_mask = surface->g_mask;
+    xlib_masks.blue_mask = surface->b_mask;
+
+    status = _pixman_format_from_masks (&xlib_masks, &pixman_format);
+    if (status == CAIRO_STATUS_SUCCESS) {
+	image = (cairo_image_surface_t*)
+	    _cairo_image_surface_create_with_pixman_format ((unsigned char *) ximage->data,
+							    pixman_format,
+							    ximage->width,
+							    ximage->height,
+							    ximage->bytes_per_line);
+	status = image->base.status;
+	if (status) {
+	    XDestroyImage (ximage);
+	    return status;
+	}
+
+	/* Let the surface take ownership of the data */
+	_cairo_image_surface_assume_ownership_of_data (image);
+	ximage->data = NULL;
     } else {
-	masks.bpp = ximage->bits_per_pixel;
-	masks.red_mask = 0;
-	masks.green_mask = 0;
-	masks.blue_mask = 0;
-	if (surface->depth < 32)
-	    masks.alpha_mask = (1 << surface->depth) - 1;
-	else
-	    masks.alpha_mask = 0xffffffff;
+	cairo_format_t format;
+	unsigned char *data;
+	uint32_t *row;
+	uint32_t in_pixel, out_pixel;
+	unsigned int rowstride;
+	uint32_t a_mask=0, r_mask=0, g_mask=0, b_mask=0;
+	int a_width=0, r_width=0, g_width=0, b_width=0;
+	int a_shift=0, r_shift=0, g_shift=0, b_shift=0;
+	int x, y;
+	XColor *colors = NULL;
+
+	/* The visual we are dealing with is not supported by the
+	 * standard pixman formats. So we must first convert the data
+	 * to a supported format. */
+	if (surface->visual->class == TrueColor) {
+	    cairo_bool_t has_color;
+	    cairo_bool_t has_alpha;
+
+	    has_color = (surface->r_mask ||
+			 surface->g_mask ||
+			 surface->b_mask);
+	    has_alpha = surface->a_mask;
+
+	    if (has_color) {
+		if (has_alpha) {
+		    format = CAIRO_FORMAT_ARGB32;
+		} else {
+		    format = CAIRO_FORMAT_RGB24;
+		}
+	    } else {
+		/* XXX: Using CAIRO_FORMAT_A8 here would be more
+		 * efficient, but would require slightly different code in
+		 * the image conversion to put the alpha channel values
+		 * into the right place. */
+		format = CAIRO_FORMAT_ARGB32;
+	    }
+
+	    a_mask = surface->a_mask;
+	    r_mask = surface->r_mask;
+	    g_mask = surface->g_mask;
+	    b_mask = surface->b_mask;
+
+	    _characterize_field (a_mask, &a_width, &a_shift);
+	    _characterize_field (r_mask, &r_width, &r_shift);
+	    _characterize_field (g_mask, &g_width, &g_shift);
+	    _characterize_field (b_mask, &b_width, &b_shift);
+
+	} else {
+	    cairo_xlib_visual_info_t *visual_info;
+
+	    format = CAIRO_FORMAT_RGB24;
+
+	    status = _cairo_xlib_screen_get_visual_info (surface->screen_info,
+							 surface->visual,
+							 &visual_info);
+	    if (status) {
+		XDestroyImage (ximage);
+		return status;
+	    }
+
+	    colors = visual_info->colors;
+	}
+
+	image = (cairo_image_surface_t *) cairo_image_surface_create
+	    (format, ximage->width, ximage->height);
+	status = image->base.status;
+	if (status) {
+	    XDestroyImage (ximage);
+	    return status;
+	}
+
+	data = cairo_image_surface_get_data (&image->base);
+	rowstride = cairo_image_surface_get_stride (&image->base) >> 2;
+	row = (uint32_t *) data;
+	for (y = 0; y < ximage->height; y++) {
+	    for (x = 0; x < ximage->width; x++) {
+		in_pixel = XGetPixel (ximage, x, y);
+		if (surface->visual->class == TrueColor) {
+		    out_pixel = (
+			_field_to_8 (in_pixel & a_mask, a_width, a_shift) << 24 |
+			_field_to_8 (in_pixel & r_mask, r_width, r_shift) << 16 |
+			_field_to_8 (in_pixel & g_mask, g_width, g_shift) << 8 |
+			_field_to_8 (in_pixel & b_mask, b_width, b_shift));
+		} else {
+		    XColor *color;
+		    color = &colors[in_pixel & 0xff];
+		    out_pixel = (
+			_field_to_8 (color->red,   16, 0) << 16 |
+			_field_to_8 (color->green, 16, 0) << 8 |
+			_field_to_8 (color->blue,  16, 0));
+		}
+		row[x] = out_pixel;
+	    }
+	    row += rowstride;
+	}
     }
 
-    pixman_format = _pixman_format_from_masks (&masks);
-    image = (cairo_image_surface_t*)
-	_cairo_image_surface_create_with_pixman_format ((unsigned char *) ximage->data,
-							pixman_format,
-							ximage->width,
-							ximage->height,
-							ximage->bytes_per_line);
-    status = image->base.status;
-    if (status) {
-	XDestroyImage (ximage);
-	return status;
-    }
-
-    /* Let the surface take ownership of the data */
-    _cairo_image_surface_assume_ownership_of_data (image);
-    ximage->data = NULL;
     XDestroyImage (ximage);
 
     *image_out = image;
     return CAIRO_STATUS_SUCCESS;
 }
 
 static void
 _cairo_xlib_surface_ensure_src_picture (cairo_xlib_surface_t    *surface)
@@ -714,49 +847,128 @@ static cairo_status_t
 		     int                    src_x,
 		     int                    src_y,
 		     int                    width,
 		     int                    height,
 		     int                    dst_x,
 		     int                    dst_y)
 {
     XImage ximage;
-    uint32_t bpp, red, green, blue;
+    cairo_format_masks_t image_masks;
     int native_byte_order = _native_byte_order_lsb () ? LSBFirst : MSBFirst;
     cairo_status_t status;
-
-    _pixman_format_to_masks (image->pixman_format, &bpp, &red, &green, &blue);
-    
+    cairo_bool_t own_data;
+    unsigned long *rgb333_to_pseudocolor = NULL;
+
+    _pixman_format_to_masks (image->pixman_format, &image_masks);
+
     ximage.width = image->width;
     ximage.height = image->height;
     ximage.format = ZPixmap;
-    ximage.data = (char *)image->data;
     ximage.byte_order = native_byte_order;
     ximage.bitmap_unit = 32;	/* always for libpixman */
     ximage.bitmap_bit_order = native_byte_order;
     ximage.bitmap_pad = 32;	/* always for libpixman */
-    ximage.depth = image->depth;
-    ximage.bytes_per_line = image->stride;
-    ximage.bits_per_pixel = bpp;
-    ximage.red_mask = red;
-    ximage.green_mask = green;
-    ximage.blue_mask = blue;
+    ximage.depth = surface->depth;
+    ximage.red_mask = surface->r_mask;
+    ximage.green_mask = surface->g_mask;
+    ximage.blue_mask = surface->b_mask;
     ximage.xoffset = 0;
 
-    XInitImage (&ximage);
+    if (image_masks.red_mask   == surface->r_mask &&
+	image_masks.green_mask == surface->g_mask &&
+	image_masks.blue_mask  == surface->b_mask)
+    {
+	ximage.bits_per_pixel = image_masks.bpp;
+	ximage.bytes_per_line = image->stride;
+	ximage.data = (char *)image->data;
+	own_data = FALSE;
+	XInitImage (&ximage);
+    } else {
+	unsigned int stride, rowstride;
+	int x, y;
+	uint32_t in_pixel, out_pixel, *row;
+	int a_width=0, r_width=0, g_width=0, b_width=0;
+	int a_shift=0, r_shift=0, g_shift=0, b_shift=0;
+
+	if (surface->depth > 16) {
+	    ximage.bits_per_pixel = 32;
+	} else if (surface->depth > 8) {
+	    ximage.bits_per_pixel = 16;
+	} else if (surface->depth > 1) {
+	    ximage.bits_per_pixel = 8;
+	} else {
+	    ximage.bits_per_pixel = 1;
+	}
+	stride = CAIRO_STRIDE_FOR_WIDTH_BPP (ximage.width,
+					     ximage.bits_per_pixel);
+	ximage.bytes_per_line = stride;
+	ximage.data = _cairo_malloc_ab (stride, ximage.height);
+	if (ximage.data == NULL)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+	own_data = TRUE;
+
+	XInitImage (&ximage);
+
+	if (surface->visual->class == TrueColor) {
+	    _characterize_field (surface->a_mask, &a_width, &a_shift);
+	    _characterize_field (surface->r_mask, &r_width, &r_shift);
+	    _characterize_field (surface->g_mask, &g_width, &g_shift);
+	    _characterize_field (surface->b_mask, &b_width, &b_shift);
+	} else {
+	    cairo_xlib_visual_info_t *visual_info;
+
+	    status = _cairo_xlib_screen_get_visual_info (surface->screen_info,
+							 surface->visual,
+							 &visual_info);
+	    if (status)
+		goto BAIL;
+
+	    rgb333_to_pseudocolor = visual_info->rgb333_to_pseudocolor;
+	}
+
+	rowstride = cairo_image_surface_get_stride (&image->base) >> 2;
+	row = (uint32_t *) cairo_image_surface_get_data (&image->base);
+	for (y = 0; y < ximage.height; y++) {
+	    for (x = 0; x < ximage.width; x++) {
+		int a, r, g, b;
+		in_pixel = row[x];
+		a = (in_pixel >> 24) & 0xff;
+		r = (in_pixel >> 16) & 0xff;
+		g = (in_pixel >>  8) & 0xff;
+		b = (in_pixel      ) & 0xff;
+		if (surface->visual->class == TrueColor)
+		    out_pixel = (_field_from_8 (a, a_width, a_shift) |
+				 _field_from_8 (r, r_width, r_shift) |
+				 _field_from_8 (g, g_width, g_shift) |
+				 _field_from_8 (b, b_width, b_shift));
+		else
+		    out_pixel = rgb333_to_pseudocolor[_field_from_8 (r, 3, 6) |
+						      _field_from_8 (g, 3, 3) |
+						      _field_from_8 (b, 3, 0)];
+		XPutPixel (&ximage, x, y, out_pixel);
+	    }
+	    row += rowstride;
+	}
+    }
 
     status = _cairo_xlib_surface_ensure_gc (surface);
     if (status)
-	return status;
+	goto BAIL;
+
     XPutImage(surface->dpy, surface->drawable, surface->gc,
 	      &ximage, src_x, src_y, dst_x, dst_y,
 	      width, height);
 
-    return CAIRO_STATUS_SUCCESS;
-
+  BAIL:
+    if (own_data)
+	free (ximage.data);
+
+    return status;
 }
 
 static cairo_status_t
 _cairo_xlib_surface_acquire_source_image (void                    *abstract_surface,
 					  cairo_image_surface_t  **image_out,
 					  void                   **image_extra)
 {
     cairo_xlib_surface_t *surface = abstract_surface;
@@ -2027,16 +2239,50 @@ static cairo_surface_t *
     surface->filter = CAIRO_FILTER_NEAREST;
     surface->repeat = FALSE;
     surface->xtransform = identity;
 
     surface->have_clip_rects = FALSE;
     surface->clip_rects = surface->embedded_clip_rects;
     surface->num_clip_rects = 0;
 
+    /*
+     * Compute the pixel format masks from either a XrenderFormat or
+     * else from a visual; failing that we assume the drawable is an
+     * alpha-only pixmap as it could only have been created that way
+     * through the cairo_xlib_surface_create_for_bitmap function.
+     */
+    if (xrender_format) {
+	surface->a_mask = (unsigned long)
+	    surface->xrender_format->direct.alphaMask
+	    << surface->xrender_format->direct.alpha;
+	surface->r_mask = (unsigned long)
+	    surface->xrender_format->direct.redMask
+	    << surface->xrender_format->direct.red;
+	surface->g_mask = (unsigned long)
+	    surface->xrender_format->direct.greenMask
+	    << surface->xrender_format->direct.green;
+	surface->b_mask = (unsigned long)
+	    surface->xrender_format->direct.blueMask
+	    << surface->xrender_format->direct.blue;
+    } else if (visual) {
+	surface->a_mask = 0;
+	surface->r_mask = visual->red_mask;
+	surface->g_mask = visual->green_mask;
+	surface->b_mask = visual->blue_mask;
+    } else {
+	if (depth < 32)
+	    surface->a_mask = (1 << depth) - 1;
+	else
+	    surface->a_mask = 0xffffffff;
+	surface->r_mask = 0;
+	surface->g_mask = 0;
+	surface->b_mask = 0;
+    }
+
     return (cairo_surface_t *) surface;
 }
 
 static Screen *
 _cairo_xlib_screen_from_visual (Display *dpy, Visual *visual)
 {
     int	    s;
     int	    d;
@@ -2150,17 +2396,16 @@ cairo_xlib_surface_create_with_xrender_f
 					       Screen		    *screen,
 					       XRenderPictFormat    *format,
 					       int		    width,
 					       int		    height)
 {
     return _cairo_xlib_surface_create_internal (dpy, drawable, screen,
 						NULL, format, width, height, 0);
 }
-slim_hidden_def (cairo_xlib_surface_create_with_xrender_format);
 
 /**
  * cairo_xlib_surface_get_xrender_format:
  * @surface: an xlib surface
  *
  * Gets the X Render picture format that @surface uses for rendering with the
  * X Render extension. If the surface was created by
  * cairo_xlib_surface_create_with_xrender_format() originally, the return
@@ -2660,17 +2905,16 @@ static cairo_status_t
     cairo_status_t status = CAIRO_STATUS_SUCCESS;
     cairo_xlib_surface_font_private_t *font_private;
     cairo_scaled_glyph_t *scaled_glyph = *pscaled_glyph;
     cairo_image_surface_t *glyph_surface = scaled_glyph->surface;
     cairo_bool_t already_had_glyph_surface;
     cairo_xlib_font_glyphset_info_t *glyphset_info;
 
     if (!glyph_surface) {
-
 	status = _cairo_scaled_glyph_lookup (scaled_font,
 					     _cairo_scaled_glyph_index (scaled_glyph),
 					     CAIRO_SCALED_GLYPH_INFO_METRICS |
 					     CAIRO_SCALED_GLYPH_INFO_SURFACE,
 					     pscaled_glyph);
 	if (status != CAIRO_STATUS_SUCCESS)
 	    return status;
 
@@ -2689,27 +2933,28 @@ static cairo_status_t
     font_private = scaled_font->surface_private;
 
     glyphset_info = _cairo_xlib_scaled_font_get_glyphset_info_for_format (scaled_font,
 									  glyph_surface->format);
 
     /* If the glyph surface has zero height or width, we create
      * a clear 1x1 surface, to avoid various X server bugs.
      */
-    if ((glyph_surface->width == 0) || (glyph_surface->height == 0)) {
+    if (glyph_surface->width == 0 || glyph_surface->height == 0) {
 	cairo_t *cr;
 	cairo_surface_t *tmp_surface;
 
 	tmp_surface = cairo_image_surface_create (glyphset_info->format, 1, 1);
+	if (tmp_surface->status)
+	    goto BAIL;
+
 	cr = cairo_create (tmp_surface);
 	cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
 	cairo_paint (cr);
-
 	status = cairo_status (cr);
-
 	cairo_destroy (cr);
 
 	tmp_surface->device_transform = glyph_surface->base.device_transform;
 	tmp_surface->device_transform_inverse = glyph_surface->base.device_transform_inverse;
 
 	glyph_surface = (cairo_image_surface_t *) tmp_surface;
 
 	if (status)
@@ -2722,27 +2967,27 @@ static cairo_status_t
      */
     if (glyph_surface->format != glyphset_info->format) {
 	cairo_t *cr;
 	cairo_surface_t *tmp_surface;
 
 	tmp_surface = cairo_image_surface_create (glyphset_info->format,
 						  glyph_surface->width,
 						  glyph_surface->height);
+	if (tmp_surface->status)
+	    goto BAIL;
+
 	tmp_surface->device_transform = glyph_surface->base.device_transform;
 	tmp_surface->device_transform_inverse = glyph_surface->base.device_transform_inverse;
 
 	cr = cairo_create (tmp_surface);
-
 	cairo_set_source_surface (cr, &glyph_surface->base, 0, 0);
 	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
 	cairo_paint (cr);
-
 	status = cairo_status (cr);
-
 	cairo_destroy (cr);
 
 	glyph_surface = (cairo_image_surface_t *) tmp_surface;
 
 	if (status)
 	    goto BAIL;
     }
 
@@ -2816,17 +3061,17 @@ static cairo_status_t
 	ASSERT_NOT_REACHED;
 	break;
     }
     /* XXX assume X server wants pixman padding. Xft assumes this as well */
 
     glyph_index = _cairo_scaled_glyph_index (scaled_glyph);
 
     XRenderAddGlyphs (dpy, glyphset_info->glyphset,
-		      &glyph_index, &(glyph_info), 1,
+		      &glyph_index, &glyph_info, 1,
 		      (char *) data,
 		      glyph_surface->stride * glyph_surface->height);
 
     _cairo_xlib_scaled_glyph_set_glyphset_info (scaled_glyph, glyphset_info);
 
     if (data != glyph_surface->data)
 	free (data);
 
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/cairo/src/cairo-xlib-visual.c
@@ -0,0 +1,148 @@
+/* Cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Red Hat, Inc.
+ *
+ * Contributor(s):
+ *	Carl D. Worth <cworth@cworth.org>
+ */
+
+#include "cairoint.h"
+
+#include "cairo-xlib-private.h"
+
+/* A perceptual distance metric between two colors. No sqrt needed
+ * since the square of the distance is still a valid metric. */
+
+/* XXX: This is currently using linear distance in RGB space which is
+ * decidedly not perceptually linear. If someone cared a lot about the
+ * quality, they might choose something else here. Then again, they
+ * might also choose not to use a PseudoColor visual... */
+static inline int
+_color_distance (unsigned short r1, unsigned short g1, unsigned short b1,
+		 unsigned short r2, unsigned short g2, unsigned short b2)
+{
+    r1 >>= 8; g1 >>= 8; b1 >>= 8;
+    r2 >>= 8; g2 >>= 8; b2 >>= 8;
+
+    return ((r2 - r1) * (r2 - r1) +
+	    (g2 - g1) * (g2 - g1) +
+	    (b2 - b1) * (b2 - b1));
+}
+
+cairo_status_t
+_cairo_xlib_visual_info_create (Display *dpy,
+	                        int screen,
+				VisualID visualid,
+				cairo_xlib_visual_info_t **out)
+{
+    cairo_xlib_visual_info_t *info;
+    Colormap colormap = DefaultColormap (dpy, screen);
+    XColor color;
+    int gray, red, green, blue;
+    int i, index, distance, min_distance = 0;
+
+    const unsigned short index5_to_short[5] = {
+	0x0000, 0x4000, 0x8000, 0xc000, 0xffff
+    };
+    const unsigned short index8_to_short[8] = {
+	0x0000, 0x2492, 0x4924, 0x6db6,
+	0x9249, 0xb6db, 0xdb6d, 0xffff
+    };
+
+    info = malloc (sizeof (cairo_xlib_visual_info_t));
+    if (info == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    info->visualid = visualid;
+
+    /* Allocate a 16-entry gray ramp and a 5x5x5 color cube. Give up
+     * as soon as failures start. */
+    for (gray = 0; gray < 16; gray++) {
+	color.red   = (gray << 12) | (gray << 8) | (gray << 4) | gray;
+	color.green = (gray << 12) | (gray << 8) | (gray << 4) | gray;
+	color.blue  = (gray << 12) | (gray << 8) | (gray << 4) | gray;
+	if (! XAllocColor (dpy, colormap, &color))
+	    goto DONE_ALLOCATE;
+    }
+
+    /* XXX: Could do this in a more clever order to have the best
+     * possible results from early failure. Could also choose a cube
+     * uniformly distributed in a better space than RGB. */
+    for (red = 0; red < 5; red++) {
+	for (green = 0; green < 5; green++) {
+	    for (blue = 0; blue < 5; blue++) {
+		color.red = index5_to_short[red];
+		color.green = index5_to_short[green];
+		color.blue = index5_to_short[blue];
+		color.pixel = 0;
+		color.flags = 0;
+		color.pad = 0;
+		if (! XAllocColor (dpy, colormap, &color))
+		    goto DONE_ALLOCATE;
+	    }
+	}
+    }
+  DONE_ALLOCATE:
+
+    for (i = 0; i < ARRAY_LENGTH (info->colors); i++)
+	info->colors[i].pixel = i;
+    XQueryColors (dpy, colormap, info->colors, ARRAY_LENGTH (info->colors));
+
+    /* Search for nearest colors within allocated colormap. */
+    for (red = 0; red < 8; red++) {
+	for (green = 0; green < 8; green++) {
+	    for (blue = 0; blue < 8; blue++) {
+		index = (red << 6) | (green << 3) | (blue);
+		for (i = 0; i < 256; i++) {
+		    distance = _color_distance (index8_to_short[red],
+						index8_to_short[green],
+						index8_to_short[blue],
+						info->colors[i].red,
+						info->colors[i].green,
+						info->colors[i].blue);
+		    if (i == 0 || distance < min_distance) {
+			info->rgb333_to_pseudocolor[index] = info->colors[i].pixel;
+			min_distance = distance;
+		    }
+		}
+	    }
+	}
+    }
+
+    *out = info;
+    return CAIRO_STATUS_SUCCESS;
+}
+
+void
+_cairo_xlib_visual_info_destroy (Display *dpy, cairo_xlib_visual_info_t *info)
+{
+    /* No need for XFreeColors() whilst using DefaultColormap */
+    free (info);
+}
--- a/gfx/cairo/cairo/src/cairo.c
+++ b/gfx/cairo/cairo/src/cairo.c
@@ -2290,20 +2290,25 @@ cairo_in_fill (cairo_t *cr, double x, do
  * Computes a bounding box in user coordinates covering the area that
  * would be affected, (the "inked" area), by a cairo_stroke()
  * operation operation given the current path and stroke
  * parameters. If the current path is empty, returns an empty
  * rectangle ((0,0), (0,0)). Surface dimensions and clipping are not
  * taken into account.
  *
  * Note that if the line width is set to exactly zero, then
- * cairo_stroke_extents will return an empty rectangle. Contrast with
+ * cairo_stroke_extents() will return an empty rectangle. Contrast with
  * cairo_path_extents() which can be used to compute the non-empty
  * bounds as the line width approaches zero.
  *
+ * Note that cairo_stroke_extents() must necessarily do more work to
+ * compute the precise inked areas in light of the stroke parameters,
+ * so cairo_path_extents() may be more desirable for sake of
+ * performance if non-inked path extents are desired.
+ *
  * See cairo_stroke(), cairo_set_line_width(), cairo_set_line_join(),
  * cairo_set_line_cap(), cairo_set_dash(), and
  * cairo_stroke_preserve().
  **/
 void
 cairo_stroke_extents (cairo_t *cr,
                       double *x1, double *y1, double *x2, double *y2)
 {
@@ -2339,18 +2344,23 @@ cairo_stroke_extents (cairo_t *cr,
  *
  * Computes a bounding box in user coordinates covering the area that
  * would be affected, (the "inked" area), by a cairo_fill() operation
  * given the current path and fill parameters. If the current path is
  * empty, returns an empty rectangle ((0,0), (0,0)). Surface
  * dimensions and clipping are not taken into account.
  *
  * Contrast with cairo_path_extents(), which is similar, but returns
- * non-zero extents for some paths no inked area, (such as a simple
- * line segment).
+ * non-zero extents for some paths with no inked area, (such as a
+ * simple line segment).
+ *
+ * Note that cairo_fill_extents() must necessarily do more work to
+ * compute the precise inked areas in light of the fill rule, so
+ * cairo_path_extents() may be more desirable for sake of performance
+ * if the non-inked path extents are desired.
  *
  * See cairo_fill(), cairo_set_fill_rule() and cairo_fill_preserve().
  **/
 void
 cairo_fill_extents (cairo_t *cr,
                     double *x1, double *y1, double *x2, double *y2)
 {
     cairo_status_t status;
--- a/gfx/cairo/cairo/src/cairo.h
+++ b/gfx/cairo/cairo/src/cairo.h
@@ -1143,17 +1143,17 @@ cairo_font_face_get_reference_count (cai
 cairo_public cairo_status_t
 cairo_font_face_status (cairo_font_face_t *font_face);
 
 /**
  * cairo_font_type_t:
  * @CAIRO_FONT_TYPE_TOY: The font was created using cairo's toy font api
  * @CAIRO_FONT_TYPE_FT: The font is of type FreeType
  * @CAIRO_FONT_TYPE_WIN32: The font is of type Win32
- * @CAIRO_FONT_TYPE_ATSUI: The font is of type ATSUI
+ * @CAIRO_FONT_TYPE_QUARTZ: The font is of type Quartz (Since: 1.6)
  *
  * #cairo_font_type_t is used to describe the type of a given font
  * face or scaled font. The font types are also known as "font
  * backends" within cairo.
  *
  * The type of a font face is determined by the function used to
  * create it, which will generally be of the form
  * cairo_<emphasis>type</emphasis>_font_face_create. The font face type can be queried
@@ -1178,17 +1178,17 @@ cairo_font_face_status (cairo_font_face_
  * New entries may be added in future versions.
  *
  * Since: 1.2
  **/
 typedef enum _cairo_font_type {
     CAIRO_FONT_TYPE_TOY,
     CAIRO_FONT_TYPE_FT,
     CAIRO_FONT_TYPE_WIN32,
-    CAIRO_FONT_TYPE_ATSUI
+    CAIRO_FONT_TYPE_QUARTZ
 } cairo_font_type_t;
 
 cairo_public cairo_font_type_t
 cairo_font_face_get_type (cairo_font_face_t *font_face);
 
 cairo_public void *
 cairo_font_face_get_user_data (cairo_font_face_t	   *font_face,
 			       const cairo_user_data_key_t *key);
--- a/gfx/cairo/cairo/src/cairoint.h
+++ b/gfx/cairo/cairo/src/cairoint.h
@@ -142,16 +142,37 @@ do {					\
 #define CAIRO_COLOR_IS_OPAQUE(color) CAIRO_ALPHA_SHORT_IS_OPAQUE ((color)->alpha_short)
 
 /* Reverse the bits in a byte with 7 operations (no 64-bit):
  * Devised by Sean Anderson, July 13, 2001.
  * Source: http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits
  */
 #define CAIRO_BITSWAP8(c) ((((c) * 0x0802LU & 0x22110LU) | ((c) * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16)
 
+/* Return the number of 1 bits in mask.
+ *
+ * GCC 3.4 supports a "population count" builtin, which on many targets is
+ * implemented with a single instruction. There is a fallback definition
+ * in libgcc in case a target does not have one, which should be just as
+ * good as the open-coded solution below, (which is "HACKMEM 169").
+ */
+static inline int
+_cairo_popcount (uint32_t mask)
+{
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+    return __builtin_popcount (mask);
+#else
+    register int y;
+
+    y = (mask >> 1) &033333333333;
+    y = mask - y - ((y >>1) & 033333333333);
+    return (((y + (y >> 3)) & 030707070707) % 077);
+#endif
+}
+
 #ifdef WORDS_BIGENDIAN
 #define CAIRO_BITSWAP8_IF_LITTLE_ENDIAN(c) (c)
 #else
 #define CAIRO_BITSWAP8_IF_LITTLE_ENDIAN(c) CAIRO_BITSWAP8(c)
 #endif
 
 #ifdef WORDS_BIGENDIAN
 
@@ -212,17 +233,17 @@ cairo_private void
 cairo_private void
 _cairo_array_init_snapshot (cairo_array_t	*array,
 			    const cairo_array_t *other);
 
 cairo_private void
 _cairo_array_fini (cairo_array_t *array);
 
 cairo_private cairo_status_t
-_cairo_array_grow_by (cairo_array_t *array, int additional);
+_cairo_array_grow_by (cairo_array_t *array, unsigned int additional);
 
 cairo_private void
 _cairo_array_truncate (cairo_array_t *array, unsigned int num_elements);
 
 cairo_private cairo_status_t
 _cairo_array_append (cairo_array_t *array, const void *element);
 
 cairo_private cairo_status_t
@@ -434,19 +455,19 @@ extern const cairo_private struct _cairo
 #endif
 
 #if CAIRO_HAS_WIN32_FONT
 
 extern const cairo_private struct _cairo_scaled_font_backend cairo_win32_scaled_font_backend;
 
 #endif
 
-#if CAIRO_HAS_ATSUI_FONT
-
-extern const cairo_private struct _cairo_scaled_font_backend cairo_atsui_scaled_font_backend;
+#if CAIRO_HAS_QUARTZ_FONT
+
+extern const cairo_private struct _cairo_scaled_font_backend cairo_quartz_scaled_font_backend;
 
 #endif
 
 struct _cairo_surface_backend {
     cairo_surface_type_t type;
 
     cairo_surface_t *
     (*create_similar)		(void			*surface,
@@ -771,17 +792,17 @@ extern const cairo_private cairo_solid_p
 
 typedef struct _cairo_surface_pattern {
     cairo_pattern_t base;
 
     cairo_surface_t *surface;
 } cairo_surface_pattern_t;
 
 typedef struct _cairo_gradient_stop {
-    cairo_fixed_t x;
+    double offset;
     cairo_color_t color;
 } cairo_gradient_stop_t;
 
 typedef struct _cairo_gradient_pattern {
     cairo_pattern_t base;
 
     unsigned int	    n_stops;
     unsigned int	    stops_size;
@@ -843,28 +864,28 @@ typedef struct _cairo_traps {
     cairo_bool_t has_limits;
     cairo_box_t limits;
 } cairo_traps_t;
 
 #define CAIRO_FONT_SLANT_DEFAULT   CAIRO_FONT_SLANT_NORMAL
 #define CAIRO_FONT_WEIGHT_DEFAULT  CAIRO_FONT_WEIGHT_NORMAL
 
 #define CAIRO_WIN32_FONT_FAMILY_DEFAULT "Arial"
-#define CAIRO_ATSUI_FONT_FAMILY_DEFAULT  "Helvetica"
+#define CAIRO_QUARTZ_FONT_FAMILY_DEFAULT  "Helvetica"
 #define CAIRO_FT_FONT_FAMILY_DEFAULT     ""
 
 #if   CAIRO_HAS_WIN32_FONT
 
 #define CAIRO_FONT_FAMILY_DEFAULT CAIRO_WIN32_FONT_FAMILY_DEFAULT
 #define CAIRO_SCALED_FONT_BACKEND_DEFAULT &cairo_win32_scaled_font_backend
 
-#elif CAIRO_HAS_ATSUI_FONT
-
-#define CAIRO_FONT_FAMILY_DEFAULT CAIRO_ATSUI_FONT_FAMILY_DEFAULT
-#define CAIRO_SCALED_FONT_BACKEND_DEFAULT &cairo_atsui_scaled_font_backend
+#elif CAIRO_HAS_QUARTZ_FONT
+
+#define CAIRO_FONT_FAMILY_DEFAULT CAIRO_QUARTZ_FONT_FAMILY_DEFAULT
+#define CAIRO_SCALED_FONT_BACKEND_DEFAULT &cairo_quartz_scaled_font_backend
 
 #elif CAIRO_HAS_FT_FONT
 
 #define CAIRO_FONT_FAMILY_DEFAULT CAIRO_FT_FONT_FAMILY_DEFAULT
 #define CAIRO_SCALED_FONT_BACKEND_DEFAULT &cairo_ft_scaled_font_backend
 
 #else
 
@@ -1731,16 +1752,19 @@ cairo_private cairo_status_t
 
 cairo_private cairo_int_status_t
 _cairo_surface_intersect_clip_path (cairo_surface_t    *surface,
 				    cairo_path_fixed_t *path,
 				    cairo_fill_rule_t   fill_rule,
 				    double		tolerance,
 				    cairo_antialias_t	antialias);
 
+cairo_private cairo_clip_t *
+_cairo_surface_get_clip (cairo_surface_t *surface);
+
 cairo_private cairo_status_t
 _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip);
 
 cairo_private cairo_status_t
 _cairo_surface_get_extents (cairo_surface_t         *surface,
 			    cairo_rectangle_int_t   *rectangle);
 
 cairo_private cairo_status_t
@@ -1831,16 +1855,21 @@ cairo_private cairo_bool_t
  * format, then %CAIRO_FORMAT_VALID needs to be adjusted to include
  * it. But that should not happen before all necessary code is fixed
  * to support it (at least cairo_surface_write_to_png() and a few spots
  * in cairo-xlib-surface.c--again see -Wswitch-enum).
  */
 #define CAIRO_FORMAT_INVALID ((unsigned int) -1)
 #define CAIRO_FORMAT_VALID(format) ((format) <= CAIRO_FORMAT_A1)
 
+/* pixman-required stride alignment in bytes. */
+#define CAIRO_STRIDE_ALIGNMENT (sizeof (uint32_t))
+#define CAIRO_STRIDE_FOR_WIDTH_BPP(w,bpp) \
+   (((bpp)*(w)+7)/8 + CAIRO_STRIDE_ALIGNMENT-1) & ~(CAIRO_STRIDE_ALIGNMENT-1)
+
 #define CAIRO_CONTENT_VALID(content) ((content) && 			         \
 				      (((content) & ~(CAIRO_CONTENT_COLOR |      \
 						      CAIRO_CONTENT_ALPHA |      \
 						      CAIRO_CONTENT_COLOR_ALPHA))\
 				       == 0))
 
 cairo_private int
 _cairo_format_bits_per_pixel (cairo_format_t format);
@@ -1850,25 +1879,23 @@ cairo_private cairo_format_t
 
 cairo_private cairo_content_t
 _cairo_content_from_format (cairo_format_t format);
 
 cairo_private cairo_surface_t *
 _cairo_image_surface_create_for_pixman_image (pixman_image_t		*pixman_image,
 					      pixman_format_code_t	 pixman_format);
 
-cairo_private pixman_format_code_t
-_pixman_format_from_masks (cairo_format_masks_t *masks);
+cairo_private cairo_int_status_t
+_pixman_format_from_masks (cairo_format_masks_t *masks,
+			   pixman_format_code_t *format_ret);
 
 cairo_private void
 _pixman_format_to_masks (pixman_format_code_t	 pixman_format,
-			 uint32_t		*bpp,
-			 uint32_t		*red,
-			 uint32_t		*green,
-			 uint32_t		*blue);
+			 cairo_format_masks_t	*masks);
 
 cairo_private cairo_surface_t *
 _cairo_image_surface_create_with_pixman_format (unsigned char		*data,
 						pixman_format_code_t	 pixman_format,
 						int			 width,
 						int			 height,
 						int			 stride);
 
@@ -2204,17 +2231,17 @@ cairo_private cairo_antialias_t
 /* cairo_unicode.c */
 
 cairo_private cairo_status_t
 _cairo_utf8_to_ucs4 (const unsigned char *str,
 		     int		  len,
 		     uint32_t	        **result,
 		     int		 *items_written);
 
-#if CAIRO_HAS_WIN32_FONT+0 || CAIRO_HAS_ATSUI_FONT+0
+#if CAIRO_HAS_WIN32_FONT+0 || CAIRO_HAS_QUARTZ_FONT+0
 # define CAIRO_HAS_UTF8_TO_UTF16 1
 #endif
 #if CAIRO_HAS_UTF8_TO_UTF16
 cairo_private cairo_status_t
 _cairo_utf8_to_utf16 (const unsigned char *str,
 		      int		   len,
 		      uint16_t		 **result,
 		      int		  *items_written);
@@ -2248,17 +2275,19 @@ slim_hidden_proto (cairo_font_options_se
 slim_hidden_proto (cairo_font_options_set_hint_style);
 slim_hidden_proto (cairo_font_options_set_subpixel_order);
 slim_hidden_proto (cairo_font_options_status);
 slim_hidden_proto (cairo_get_current_point);
 slim_hidden_proto (cairo_get_matrix);
 slim_hidden_proto (cairo_get_tolerance);
 slim_hidden_proto (cairo_image_surface_create);
 slim_hidden_proto (cairo_image_surface_create_for_data);
+slim_hidden_proto (cairo_image_surface_get_data);
 slim_hidden_proto (cairo_image_surface_get_height);
+slim_hidden_proto (cairo_image_surface_get_stride);
 slim_hidden_proto (cairo_image_surface_get_width);
 slim_hidden_proto (cairo_format_stride_for_width);
 slim_hidden_proto (cairo_line_to);
 slim_hidden_proto (cairo_mask);
 slim_hidden_proto (cairo_matrix_init);
 slim_hidden_proto (cairo_matrix_init_identity);
 slim_hidden_proto (cairo_matrix_init_rotate);
 slim_hidden_proto (cairo_matrix_init_scale);
--- a/gfx/thebes/src/gfxAtsuiFonts.cpp
+++ b/gfx/thebes/src/gfxAtsuiFonts.cpp
@@ -49,17 +49,17 @@
 #include "gfxContext.h"
 #include "gfxPlatform.h"
 #include "gfxPlatformMac.h"
 #include "gfxAtsuiFonts.h"
 
 #include "gfxFontTest.h"
 #include "gfxFontUtils.h"
 
-#include "cairo-atsui.h"
+#include "cairo-quartz.h"
 
 #include "gfxQuartzSurface.h"
 #include "gfxQuartzFontCache.h"
 
 #include "nsUnicodeRange.h"
 
 // Uncomment this to dump all text runs created to stdout
 // #define DUMP_TEXT_RUNS
@@ -111,17 +111,17 @@ gfxAtsuiFont::gfxAtsuiFont(MacOSFontEntr
     if (!mFontEntry->IsBold()
         && ((weightDistance == 0 && targetWeight >= 600) || (weightDistance > 0 && aNeedsBold))) 
     {
         mSyntheticBoldOffset = 1;  // devunit offset when double-striking text to fake boldness   
     }
 
     InitMetrics(fontID, fontRef);
 
-    mFontFace = cairo_atsui_font_face_create_for_atsu_font_id(fontID);
+    mFontFace = cairo_quartz_font_face_create_for_atsu_font_id(fontID);
 
     cairo_matrix_t sizeMatrix, ctm;
     cairo_matrix_init_identity(&ctm);
     cairo_matrix_init_scale(&sizeMatrix, mAdjustedSize, mAdjustedSize);
 
     // synthetic oblique by skewing via the font matrix
     PRBool needsOblique = (!mFontEntry->IsItalicStyle() && (mFontStyle->style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)));