b=421422, cairo upgrade ; r=me
authorvladimir@pobox.com
Fri, 14 Mar 2008 20:44:23 -0700
changeset 13107 e413593ee1deba9698bd92a3663148a4d4fe75e9
parent 13106 1d117b877a463b8d528cb21ec7f7a4fd68f6aff0
child 13108 518206c497f5f24108ad5f2d72dc1e06ce01551e
push idunknown
push userunknown
push dateunknown
reviewersme
bugs421422
milestone1.9b5pre
b=421422, cairo upgrade ; r=me
configure.in
gfx/cairo/README
gfx/cairo/cairo/src/Makefile.in
gfx/cairo/cairo/src/cairo-atsui-font.c
gfx/cairo/cairo/src/cairo-cff-subset.c
gfx/cairo/cairo/src/cairo-clip.c
gfx/cairo/cairo/src/cairo-features.h.in
gfx/cairo/cairo/src/cairo-font-face.c
gfx/cairo/cairo/src/cairo-ft-font.c
gfx/cairo/cairo/src/cairo-hull.c
gfx/cairo/cairo/src/cairo-image-surface.c
gfx/cairo/cairo/src/cairo-output-stream.c
gfx/cairo/cairo/src/cairo-paginated-surface.c
gfx/cairo/cairo/src/cairo-path-stroke.c
gfx/cairo/cairo/src/cairo-pattern.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-image-surface.c
gfx/cairo/cairo/src/cairo-quartz-image.h
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-scaled-font-subsets.c
gfx/cairo/cairo/src/cairo-svg-surface.c
gfx/cairo/cairo/src/cairo-truetype-subset.c
gfx/cairo/cairo/src/cairo-type1-fallback.c
gfx/cairo/cairo/src/cairo-type1-subset.c
gfx/cairo/cairo/src/cairo-types-private.h
gfx/cairo/cairo/src/cairo-win32-printing-surface.c
gfx/cairo/cairo/src/cairo-win32-surface.c
gfx/cairo/cairo/src/cairo-xlib-display.c
gfx/cairo/cairo/src/cairo-xlib-surface.c
gfx/cairo/cairo/src/cairoint.h
gfx/cairo/libpixman/src/Makefile.in
gfx/cairo/libpixman/src/pixman-compose.c
gfx/cairo/libpixman/src/pixman-mmx.c
gfx/cairo/libpixman/src/pixman-pict.c
gfx/cairo/pixman-fbFetchTransformed-backout.patch
gfx/thebes/src/gfxQuartzImageSurface.cpp
--- a/configure.in
+++ b/configure.in
@@ -7109,16 +7109,17 @@ if test "$MOZ_TREE_CAIRO"; then
         PS_SURFACE_FEATURE="#define CAIRO_HAS_PS_SURFACE 1"
         PDF_SURFACE_FEATURE="#define CAIRO_HAS_PDF_SURFACE 1"
         FT_FONT_FEATURE="#define CAIRO_HAS_FT_FONT 1"
         MOZ_ENABLE_CAIRO_FT=1
         CAIRO_FT_CFLAGS="$FT2_CFLAGS"
     fi
     if test "$MOZ_WIDGET_TOOLKIT" = "mac" -o "$MOZ_WIDGET_TOOLKIT" = "cocoa"; then
         QUARTZ_SURFACE_FEATURE="#define CAIRO_HAS_QUARTZ_SURFACE 1"
+        QUARTZ_IMAGE_SURFACE_FEATURE="#define CAIRO_HAS_QUARTZ_IMAGE_SURFACE 1"
         ATSUI_FONT_FEATURE="#define CAIRO_HAS_ATSUI_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
@@ -7150,17 +7151,17 @@ if test "$MOZ_TREE_CAIRO"; then
     PNG_FUNCTIONS_FEATURE="#define CAIRO_HAS_PNG_FUNCTIONS 1"
 
     AC_SUBST(PS_SURFACE_FEATURE)
     AC_SUBST(PDF_SURFACE_FEATURE)
     AC_SUBST(SVG_SURFACE_FEATURE)
     AC_SUBST(XLIB_SURFACE_FEATURE)
     AC_SUBST(XLIB_XRENDER_SURFACE_FEATURE)
     AC_SUBST(QUARTZ_SURFACE_FEATURE)
-    AC_SUBST(NQUARTZ_SURFACE_FEATURE)
+    AC_SUBST(QUARTZ_IMAGE_SURFACE_FEATURE)
     AC_SUBST(XCB_SURFACE_FEATURE)
     AC_SUBST(WIN32_SURFACE_FEATURE)
     AC_SUBST(OS2_SURFACE_FEATURE)
     AC_SUBST(BEOS_SURFACE_FEATURE)
     AC_SUBST(GLITZ_SURFACE_FEATURE)
     AC_SUBST(DIRECTFB_SURFACE_FEATURE)
     AC_SUBST(FT_FONT_FEATURE)
     AC_SUBST(WIN32_FONT_FEATURE)
--- a/gfx/cairo/README
+++ b/gfx/cairo/README
@@ -3,17 +3,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.5.x - 1.5.12-14-gd89edde)
-  pixman (0.9.x - pixman-0.9.6-37-g8d79c48)
+  pixman (0.9.x - pixman-0.9.6-43-gddfb69a)
   glitz 0.5.2 (cvs - 2006-01-10)
 
 ***** NOTE FOR VISUAL C++ 6.0 *****
 
 VC6 is not supported.  Please upgrade to VC8.
 
 ==== Patches ====
 
@@ -26,9 +26,8 @@ win32-logical-font-scale.patch: set CAIR
 nonfatal-assertions.patch: Make assertions non-fatal
 
 buggy-repeat.patch: Unconditionally turn on buggy-repeat handling to bandaid bug 413583.
 
 ==== pixman patches ====
 
 endian.patch: include cairo-platform.h for endian macros
 
-pixman-fbFetchTransformed-backout.patch: back out bad pixman commit, see http://lists.cairographics.org/archives/cairo/2008-March/013294.html
--- a/gfx/cairo/cairo/src/Makefile.in
+++ b/gfx/cairo/cairo/src/Makefile.in
@@ -160,17 +160,17 @@ 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
+EXPORTS += cairo-quartz.h cairo-atsui.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)
--- a/gfx/cairo/cairo/src/cairo-atsui-font.c
+++ b/gfx/cairo/cairo/src/cairo-atsui-font.c
@@ -315,17 +315,17 @@ static cairo_status_t
     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);
+	    _cairo_scaled_font_fini(&font->base);
 	    free (font);
 	}
 
 	return status;
     }
 
     return CAIRO_STATUS_SUCCESS;
 }
--- a/gfx/cairo/cairo/src/cairo-cff-subset.c
+++ b/gfx/cairo/cairo/src/cairo-cff-subset.c
@@ -29,16 +29,17 @@
  *
  * The Initial Developer of the Original Code is Adrian Johnson.
  *
  * Contributor(s):
  *	Adrian Johnson <ajohnson@redneon.com>
  *      Eugeniy Meshcheryakov <eugen@debian.org>
  */
 
+#define _BSD_SOURCE /* for snprintf(), strdup() */
 #include "cairoint.h"
 #include "cairo-scaled-font-subsets-private.h"
 #include "cairo-truetype-subset-private.h"
 #include <string.h>
 
 /* CFF Dict Operators. If the high byte is 0 the command is encoded
  * with a single byte. */
 #define BASEFONTNAME_OP  0x0c16
@@ -439,41 +440,41 @@ cff_dict_init (cairo_hash_table_t **dict
 
 static void
 _cairo_dict_init_key (cff_dict_operator_t *key, int operator)
 {
     key->base.hash = (unsigned long) operator;
     key->operator = operator;
 }
 
-static cff_dict_operator_t *
+static cairo_status_t
 cff_dict_create_operator (int            operator,
                           unsigned char *operand,
-                          int            operand_length)
+                          int            operand_length,
+			  cff_dict_operator_t **out)
 {
     cff_dict_operator_t *op;
 
     op = malloc (sizeof (cff_dict_operator_t));
-    if (op == NULL) {
-	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
-        return NULL;
-    }
+    if (op == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     _cairo_dict_init_key (op, operator);
     op->operand = malloc (operand_length);
     if (op->operand == NULL) {
         free (op);
-	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
-        return NULL;
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
+
     memcpy (op->operand, operand, operand_length);
     op->operand_length = operand_length;
     op->operand_offset = -1;
 
-    return op;
+    *out = op;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
 cff_dict_read (cairo_hash_table_t *dict, unsigned char *p, int dict_size)
 {
     unsigned char *end;
     cairo_array_t operands;
     cff_dict_operator_t *op;
@@ -484,29 +485,31 @@ cff_dict_read (cairo_hash_table_t *dict,
     end = p + dict_size;
     _cairo_array_init (&operands, 1);
     while (p < end) {
         size = operand_length (p);
         if (size != 0) {
             status = _cairo_array_append_multiple (&operands, p, size);
             if (status)
                 goto fail;
+
             p += size;
         } else {
             p = decode_operator (p, &operator);
-            op = cff_dict_create_operator (operator,
-                                           _cairo_array_index (&operands, 0),
-                                           _cairo_array_num_elements (&operands));
-            if (op == NULL) {
-                status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+            status = cff_dict_create_operator (operator,
+                                          _cairo_array_index (&operands, 0),
+                                          _cairo_array_num_elements (&operands),
+					  &op);
+            if (status)
                 goto fail;
-            }
+
             status = _cairo_hash_table_insert (dict, &op->base);
             if (status)
                 goto fail;
+
             _cairo_array_truncate (&operands, 0);
         }
     }
 
 fail:
     _cairo_array_fini (&operands);
 
     return status;
@@ -563,19 +566,19 @@ cff_dict_set_operands (cairo_hash_table_
 	if (op->operand == NULL)
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
         memcpy (op->operand, operand, size);
         op->operand_length = size;
     }
     else
     {
-        op = cff_dict_create_operator (operator, operand, size);
-        if (op == NULL)
-	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+        status = cff_dict_create_operator (operator, operand, size, &op);
+        if (status)
+	    return status;
 
 	status = _cairo_hash_table_insert (dict, &op->base);
 	if (status)
 	    return status;
     }
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -833,31 +836,32 @@ cairo_cff_font_read_cid_fontdict (cairo_
         cff_index_init (&font->fd_local_sub_index[i]);
         status = cairo_cff_font_read_private_dict (font,
                                                    font->fd_private_dict[i],
                                                    &font->fd_local_sub_index[i],
                                                    font->data + offset,
                                                    size);
         if (status)
             goto fail;
+
         /* Set integer operand to max value to use max size encoding to reserve
          * space for any value later */
         end_buf = encode_integer_max (buf, 0);
         end_buf = encode_integer_max (end_buf, 0);
         status = cff_dict_set_operands (font->fd_dict[i], PRIVATE_OP, buf, end_buf - buf);
         if (status)
             goto fail;
     }
 
     return CAIRO_STATUS_SUCCESS;
 
 fail:
     cff_index_fini (&index);
 
-    return _cairo_error (status);
+    return status;
 }
 
 static cairo_int_status_t
 cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
 {
     cairo_array_t index;
     cff_index_element_t *element;
     unsigned char buf[20];
@@ -1886,17 +1890,17 @@ fail4:
     free (font->font_name);
 fail3:
     free (font->subset_font_name);
 fail2:
     _cairo_array_fini (&font->output);
     free (font);
 fail1:
     free (name);
-    return _cairo_error (status);
+    return status;
 }
 
 static void
 cairo_cff_font_destroy (cairo_cff_font_t *font)
 {
     unsigned int i;
 
     free (font->widths);
@@ -2006,17 +2010,17 @@ cairo_status_t
 
  fail3:
     free (cff_subset->widths);
  fail2:
     free (cff_subset->base_font);
  fail1:
     cairo_cff_font_destroy (font);
 
-    return _cairo_error (status);
+    return status;
 }
 
 void
 _cairo_cff_subset_fini (cairo_cff_subset_t *subset)
 {
     free (subset->base_font);
     free (subset->widths);
     free (subset->data);
@@ -2103,17 +2107,17 @@ fail4:
     free (font->widths);
 fail3:
     free (font->font_name);
 fail2:
     free (font->subset_font_name);
 fail1:
     _cairo_array_fini (&font->output);
     free (font);
-    return _cairo_error (status);
+    return status;
 }
 
 static cairo_int_status_t
 cairo_cff_font_fallback_generate (cairo_cff_font_t           *font,
                                   cairo_type2_charstrings_t  *type2_subset,
                                   const char                **data,
                                   unsigned long              *length)
 {
--- a/gfx/cairo/cairo/src/cairo-clip.c
+++ b/gfx/cairo/cairo/src/cairo-clip.c
@@ -739,18 +739,20 @@ cairo_rectangle_list_t *
 {
     cairo_rectangle_list_t *list;
     cairo_rectangle_t *rectangles = NULL;
     int n_boxes = 0;
 
     if (clip->all_clipped)
 	goto DONE;
 
-    if (clip->path || clip->surface)
+    if (clip->path || clip->surface) {
+	_cairo_error_throw (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
 	return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
+    }
 
     if (clip->has_region) {
 	cairo_box_int_t *boxes;
         int i;
 
 	if (_cairo_region_get_boxes (&clip->region, &n_boxes, &boxes))
 	    return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
 
@@ -763,16 +765,17 @@ cairo_rectangle_list_t *
 	    }
 
 	    for (i = 0; i < n_boxes; ++i) {
 		cairo_rectangle_int_t clip_rect = { boxes[i].p1.x, boxes[i].p1.y,
 						    boxes[i].p2.x - boxes[i].p1.x,
 						    boxes[i].p2.y - boxes[i].p1.y };
 
 		if (!_cairo_clip_int_rect_to_user(gstate, &clip_rect, &rectangles[i])) {
+		    _cairo_error_throw (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
 		    _cairo_region_boxes_fini (&clip->region, boxes);
 		    free (rectangles);
 		    return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
 		}
 	    }
 	}
 
 	_cairo_region_boxes_fini (&clip->region, boxes);
@@ -785,26 +788,27 @@ cairo_rectangle_list_t *
 	if (rectangles == NULL) {
 	    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	    return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
 	}
 
 	if (_cairo_surface_get_extents (_cairo_gstate_get_target (gstate), &extents) ||
 	    !_cairo_clip_int_rect_to_user(gstate, &extents, rectangles))
 	{
+	    _cairo_error_throw (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
 	    free (rectangles);
 	    return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
 	}
     }
 
  DONE:
     list = malloc (sizeof (cairo_rectangle_list_t));
     if (list == NULL) {
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
         free (rectangles);
-	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
         return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
     }
 
     list->status = CAIRO_STATUS_SUCCESS;
     list->rectangles = rectangles;
     list->num_rectangles = n_boxes;
     return list;
 }
--- a/gfx/cairo/cairo/src/cairo-features.h.in
+++ b/gfx/cairo/cairo/src/cairo-features.h.in
@@ -64,16 +64,18 @@
 @SVG_SURFACE_FEATURE@
 
 @XLIB_SURFACE_FEATURE@
 
 @XLIB_XRENDER_SURFACE_FEATURE@
 
 @QUARTZ_SURFACE_FEATURE@
 
+@QUARTZ_IMAGE_SURFACE_FEATURE@
+
 @XCB_SURFACE_FEATURE@
 
 @WIN32_SURFACE_FEATURE@
 
 @OS2_SURFACE_FEATURE@
 
 @BEOS_SURFACE_FEATURE@
 
--- a/gfx/cairo/cairo/src/cairo-font-face.c
+++ b/gfx/cairo/cairo/src/cairo-font-face.c
@@ -33,16 +33,17 @@
  * California.
  *
  * Contributor(s):
  *	Carl D. Worth <cworth@cworth.org>
  *      Graydon Hoare <graydon@redhat.com>
  *      Owen Taylor <otaylor@redhat.com>
  */
 
+#define _BSD_SOURCE /* for strdup() */
 #include "cairoint.h"
 
 /* Forward declare so we can use it as an arbitrary backend for
  * _cairo_font_face_nil.
  */
 static const cairo_font_face_backend_t _cairo_toy_font_face_backend;
 
 /* #cairo_font_face_t */
--- a/gfx/cairo/cairo/src/cairo-ft-font.c
+++ b/gfx/cairo/cairo/src/cairo-ft-font.c
@@ -32,16 +32,17 @@
  *
  * Contributor(s):
  *      Graydon Hoare <graydon@redhat.com>
  *	Owen Taylor <otaylor@redhat.com>
  *      Keith Packard <keithp@keithp.com>
  *      Carl Worth <cworth@cworth.org>
  */
 
+#define _BSD_SOURCE /* for strdup() */
 #include "cairoint.h"
 
 #include "cairo-ft-private.h"
 
 #include <float.h>
 
 #include <fontconfig/fontconfig.h>
 #include <fontconfig/fcfreetype.h>
@@ -2331,17 +2332,17 @@ static cairo_font_face_t *
 	    break;
 	}
     }
 
     /* No match found, create a new one */
     font_face = malloc (sizeof (cairo_ft_font_face_t));
     if (!font_face) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
-	return NULL;
+	return (cairo_font_face_t *)&_cairo_font_face_nil;
     }
 
     font_face->unscaled = unscaled;
     _cairo_unscaled_font_reference (&unscaled->base);
 
     font_face->ft_options = *ft_options;
 
     font_face->next = unscaled->faces;
@@ -2509,20 +2510,17 @@ cairo_ft_font_face_create_for_pattern (F
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_font_face_t *)&_cairo_font_face_nil;
     }
 
     _get_pattern_ft_options (pattern, &ft_options);
     font_face = _cairo_ft_font_face_create (unscaled, &ft_options);
     _cairo_unscaled_font_destroy (&unscaled->base);
 
-    if (font_face)
-	return font_face;
-    else
-	return (cairo_font_face_t *)&_cairo_font_face_nil;
+    return font_face;
 }
 
 /**
  * cairo_ft_font_face_create_for_ft_face:
  * @face: A FreeType face object, already opened. This must
  *   be kept around until the face's ref_count drops to
  *   zero and it is freed. Since the face may be referenced
  *   internally to Cairo, the best way to determine when it
@@ -2562,20 +2560,17 @@ cairo_ft_font_face_create_for_ft_face (F
 
     ft_options.load_flags = load_flags;
     ft_options.extra_flags = 0;
     _cairo_font_options_init_default (&ft_options.base);
 
     font_face = _cairo_ft_font_face_create (unscaled, &ft_options);
     _cairo_unscaled_font_destroy (&unscaled->base);
 
-    if (font_face)
-	return font_face;
-    else
-	return (cairo_font_face_t *)&_cairo_font_face_nil;
+    return font_face;
 }
 
 /**
  * cairo_ft_scaled_font_lock_face:
  * @scaled_font: A #cairo_scaled_font_t from the FreeType font backend. Such an
  *   object can be created by calling cairo_scaled_font_create() on a
  *   FreeType backend font face (see cairo_ft_font_face_create_for_pattern(),
  *   cairo_ft_font_face_create_for_face()).
--- a/gfx/cairo/cairo/src/cairo-hull.c
+++ b/gfx/cairo/cairo/src/cairo-hull.c
@@ -39,18 +39,20 @@
 typedef struct cairo_hull
 {
     cairo_point_t point;
     cairo_slope_t slope;
     int discard;
     int id;
 } cairo_hull_t;
 
-static cairo_hull_t *
-_cairo_hull_create (cairo_pen_vertex_t *vertices, int num_vertices)
+static cairo_status_t
+_cairo_hull_create (cairo_pen_vertex_t	     *vertices,
+	            int			      num_vertices,
+		    cairo_hull_t	    **out)
 {
     int i;
     cairo_hull_t *hull;
     cairo_point_t *p, *extremum, tmp;
 
     extremum = &vertices[0].point;
     for (i = 1; i < num_vertices; i++) {
 	p = &vertices[i].point;
@@ -58,37 +60,36 @@ static cairo_hull_t *
 	    extremum = p;
     }
     /* Put the extremal point at the beginning of the array */
     tmp = *extremum;
     *extremum = vertices[0].point;
     vertices[0].point = tmp;
 
     hull = _cairo_malloc_ab (num_vertices, sizeof (cairo_hull_t));
-    if (hull == NULL) {
-	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
-	return NULL;
-    }
+    if (hull == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     for (i = 0; i < num_vertices; i++) {
 	hull[i].point = vertices[i].point;
 	_cairo_slope_init (&hull[i].slope, &hull[0].point, &hull[i].point);
 
         /* give each point a unique id for later comparison */
         hull[i].id = i;
 
         /* Don't discard by default */
         hull[i].discard = 0;
 
 	/* Discard all points coincident with the extremal point */
 	if (i != 0 && hull[i].slope.dx == 0 && hull[i].slope.dy == 0)
 	    hull[i].discard = 1;
     }
 
-    return hull;
+    *out = hull;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static int
 _cairo_hull_vertex_compare (const void *av, const void *bv)
 {
     cairo_hull_t *a = (cairo_hull_t *) av;
     cairo_hull_t *b = (cairo_hull_t *) bv;
     int ret;
@@ -185,22 +186,23 @@ static void
     *num_vertices = j;
 }
 
 /* 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;
     int num_hull = *num_vertices;
 
-    hull = _cairo_hull_create (vertices, num_hull);
-    if (hull == NULL)
-	return CAIRO_STATUS_NO_MEMORY;
+    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);
 
     _cairo_hull_eliminate_concave (hull, num_hull);
 
     _cairo_hull_to_pen (hull, vertices, num_vertices);
 
--- a/gfx/cairo/cairo/src/cairo-image-surface.c
+++ b/gfx/cairo/cairo/src/cairo-image-surface.c
@@ -126,16 +126,17 @@ cairo_surface_t *
 
     surface->pixman_image = pixman_image;
 
     surface->pixman_format = pixman_format;
     surface->format = _cairo_format_from_pixman_format (pixman_format);
     surface->data = (unsigned char *) pixman_image_get_data (pixman_image);
     surface->owns_data = FALSE;
     surface->has_clip = FALSE;
+    surface->transparency = CAIRO_IMAGE_UNKNOWN;
 
     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;
 }
@@ -413,28 +414,39 @@ cairo_surface_t *
  *
  * stride = cairo_format_stride_for_width (format, width);
  * data = malloc (stride * height);
  * surface = cairo_image_surface_create_for_data (data, format,
  *						  width, height);
  * </programlisting></informalexample>
  *
  * Return value: the appropriate stride to use given the desired
- * format and width.
+ * format and width, or -1 if either the format is invalid or the width
+ * too large.
  *
  * Since: 1.6
  **/
 int
 cairo_format_stride_for_width (cairo_format_t	format,
 			       int		width)
 {
-    int bpp = _cairo_format_bits_per_pixel (format);
+    int bpp;
+
+    if (! CAIRO_FORMAT_VALID (format)) {
+	_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);
 }
+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).
  * @format: the format of pixels in the buffer
  * @width: the width of the image to be stored in the buffer
@@ -1305,24 +1317,61 @@ cairo_image_surface_t *
     double x, y;
 
     clone = (cairo_image_surface_t *)
 	cairo_image_surface_create (format,
 				    surface->width, surface->height);
 
     cairo_surface_get_device_offset (&surface->base, &x, &y);
     cairo_surface_set_device_offset (&clone->base, x, y);
+    clone->transparency = CAIRO_IMAGE_UNKNOWN;
 
     /* XXX Use _cairo_surface_composite directly */
     cr = cairo_create (&clone->base);
     cairo_set_source_surface (cr, &surface->base, 0, 0);
     cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
     cairo_paint (cr);
     status = cairo_status (cr);
     cairo_destroy (cr);
 
     if (status) {
 	cairo_surface_destroy (&clone->base);
 	return (cairo_image_surface_t *) _cairo_surface_create_in_error (status);
     }
 
     return clone;
 }
+
+cairo_image_transparency_t
+_cairo_image_analyze_transparency (cairo_image_surface_t      *image)
+{
+    int x, y;
+
+    if (image->transparency != CAIRO_IMAGE_UNKNOWN)
+	return image->transparency;
+
+    if (image->format == CAIRO_FORMAT_RGB24) {
+	image->transparency = CAIRO_IMAGE_IS_OPAQUE;
+	return CAIRO_IMAGE_IS_OPAQUE;
+    }
+
+    if (image->format != CAIRO_FORMAT_ARGB32) {
+	image->transparency = CAIRO_IMAGE_HAS_ALPHA;
+	return CAIRO_IMAGE_HAS_ALPHA;
+    }
+
+    image->transparency = CAIRO_IMAGE_IS_OPAQUE;
+    for (y = 0; y < image->height; y++) {
+	uint32_t *pixel = (uint32_t *) (image->data + y * image->stride);
+
+	for (x = 0; x < image->width; x++, pixel++) {
+	    int a = (*pixel & 0xff000000) >> 24;
+	    if (a > 0 && a < 255) {
+		image->transparency = CAIRO_IMAGE_HAS_ALPHA;
+		return CAIRO_IMAGE_HAS_ALPHA;
+	    } else if (a == 0) {
+		image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
+	    }
+	}
+    }
+
+    return image->transparency;
+}
--- a/gfx/cairo/cairo/src/cairo-output-stream.c
+++ b/gfx/cairo/cairo/src/cairo-output-stream.c
@@ -28,16 +28,17 @@
  * The Original Code is the cairo graphics library.
  *
  * The Initial Developer of the Original Code is Red Hat, Inc.
  *
  * Author(s):
  *	Kristian Høgsberg <krh@redhat.com>
  */
 
+#define _BSD_SOURCE /* for snprintf() */
 #include "cairoint.h"
 
 #include "cairo-output-stream-private.h"
 #include "cairo-compiler-private.h"
 
 #include <stdio.h>
 #include <locale.h>
 #include <ctype.h>
--- a/gfx/cairo/cairo/src/cairo-paginated-surface.c
+++ b/gfx/cairo/cairo/src/cairo-paginated-surface.c
@@ -253,18 +253,18 @@ static cairo_int_status_t
     cairo_surface_t *image;
     cairo_pattern_t *pattern;
 
     x = box->p1.x;
     y = box->p1.y;
     width = box->p2.x - x;
     height = box->p2.y - y;
     image = _cairo_paginated_surface_create_image_surface (surface,
-							   width  * x_scale,
-							   height * y_scale);
+							   ceil (width  * x_scale),
+							   ceil (height * y_scale));
     _cairo_surface_set_device_scale (image, x_scale, y_scale);
     /* set_device_offset just sets the x0/y0 components of the matrix;
      * so we have to do the scaling manually. */
     cairo_surface_set_device_offset (image, -x*x_scale, -y*y_scale);
 
     status = _cairo_meta_surface_replay (surface->meta, image);
     if (status)
 	goto CLEANUP_IMAGE;
--- a/gfx/cairo/cairo/src/cairo-path-stroke.c
+++ b/gfx/cairo/cairo/src/cairo-path-stroke.c
@@ -626,37 +626,40 @@ static inline cairo_bool_t
 
     if (mag_out)
 	*mag_out = mag;
 
     return TRUE;
 }
 
 static void
-_compute_face (cairo_point_t *point, double slope_dx, double slope_dy, cairo_stroker_t *stroker, cairo_stroke_face_t *face);
+_compute_face (cairo_point_t *point, cairo_slope_t *dev_slope,
+	       double slope_dx, double slope_dy,
+	       cairo_stroker_t *stroker, cairo_stroke_face_t *face);
 
 static cairo_status_t
 _cairo_stroker_add_caps (cairo_stroker_t *stroker)
 {
     cairo_status_t status;
     /* check for a degenerative sub_path */
     if (stroker->has_initial_sub_path
 	&& !stroker->has_first_face
 	&& !stroker->has_current_face
 	&& stroker->style->line_cap == CAIRO_LINE_JOIN_ROUND)
     {
 	/* pick an arbitrary slope to use */
 	double dx = 1.0, dy = 0.0;
+	cairo_slope_t slope = { CAIRO_FIXED_ONE, 0 };
 	cairo_stroke_face_t face;
 
 	_compute_normalized_device_slope (&dx, &dy, stroker->ctm_inverse, NULL);
 
 	/* arbitrarily choose first_point
 	 * first_point and current_point should be the same */
-	_compute_face (&stroker->first_point, dx, dy, stroker, &face);
+	_compute_face (&stroker->first_point, &slope, dx, dy, stroker, &face);
 
 	status = _cairo_stroker_add_leading_cap (stroker, &face);
 	if (status)
 	    return status;
 	status = _cairo_stroker_add_trailing_cap (stroker, &face);
 	if (status)
 	    return status;
     }
@@ -672,17 +675,19 @@ static cairo_status_t
 	if (status)
 	    return status;
     }
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static void
-_compute_face (cairo_point_t *point, double slope_dx, double slope_dy, cairo_stroker_t *stroker, cairo_stroke_face_t *face)
+_compute_face (cairo_point_t *point, cairo_slope_t *dev_slope,
+	       double slope_dx, double slope_dy,
+	       cairo_stroker_t *stroker, cairo_stroke_face_t *face)
 {
     double face_dx, face_dy;
     cairo_point_t offset_ccw, offset_cw;
 
     /*
      * rotate to get a line_width/2 vector along the face, note that
      * the vector must be rotated the right direction in device space,
      * but by 90° in user space. So, the rotation depends on
@@ -714,33 +719,32 @@ static void
     face->point = *point;
 
     face->cw = *point;
     _translate_point (&face->cw, &offset_cw);
 
     face->usr_vector.x = slope_dx;
     face->usr_vector.y = slope_dy;
 
-    face->dev_vector.dx = _cairo_fixed_from_double (slope_dx);
-    face->dev_vector.dy = _cairo_fixed_from_double (slope_dy);
+    face->dev_vector = *dev_slope;
 }
 
 static cairo_status_t
 _cairo_stroker_add_sub_edge (cairo_stroker_t *stroker, cairo_point_t *p1, cairo_point_t *p2,
-			     double slope_dx, double slope_dy, cairo_stroke_face_t *start,
-			     cairo_stroke_face_t *end)
+			     cairo_slope_t *dev_slope, double slope_dx, double slope_dy,
+			     cairo_stroke_face_t *start, cairo_stroke_face_t *end)
 {
     cairo_point_t rectangle[4];
 
-    _compute_face (p1, slope_dx, slope_dy, stroker, start);
+    _compute_face (p1, dev_slope, slope_dx, slope_dy, stroker, start);
 
     /* XXX: This could be optimized slightly by not calling
        _compute_face again but rather  translating the relevant
        fields from start. */
-    _compute_face (p2, slope_dx, slope_dy, stroker, end);
+    _compute_face (p2, dev_slope, slope_dx, slope_dy, stroker, end);
 
     if (p1->x == p2->x && p1->y == p2->y)
 	return CAIRO_STATUS_SUCCESS;
 
     rectangle[0] = start->cw;
     rectangle[1] = start->ccw;
     rectangle[2] = end->ccw;
     rectangle[3] = end->cw;
@@ -782,28 +786,30 @@ static cairo_status_t
 static cairo_status_t
 _cairo_stroker_line_to (void *closure, cairo_point_t *point)
 {
     cairo_status_t status;
     cairo_stroker_t *stroker = closure;
     cairo_stroke_face_t start, end;
     cairo_point_t *p1 = &stroker->current_point;
     cairo_point_t *p2 = point;
+    cairo_slope_t dev_slope;
     double slope_dx, slope_dy;
 
     stroker->has_initial_sub_path = TRUE;
 
     if (p1->x == p2->x && p1->y == p2->y)
 	return CAIRO_STATUS_SUCCESS;
 
+    _cairo_slope_init (&dev_slope, p1, p2);
     slope_dx = _cairo_fixed_to_double (p2->x - p1->x);
     slope_dy = _cairo_fixed_to_double (p2->y - p1->y);
     _compute_normalized_device_slope (&slope_dx, &slope_dy, stroker->ctm_inverse, NULL);
 
-    status = _cairo_stroker_add_sub_edge (stroker, p1, p2, slope_dx, slope_dy, &start, &end);
+    status = _cairo_stroker_add_sub_edge (stroker, p1, p2, &dev_slope, slope_dx, slope_dy, &start, &end);
     if (status)
 	return status;
 
     if (stroker->has_current_face) {
 	/* Join with final face from previous segment */
 	status = _cairo_stroker_join (stroker, &stroker->current_face, &start);
 	if (status)
 	    return status;
@@ -829,31 +835,34 @@ static cairo_status_t
     cairo_status_t status = CAIRO_STATUS_SUCCESS;
     cairo_stroker_t *stroker = closure;
     double mag, remain, step_length = 0;
     double slope_dx, slope_dy;
     double dx2, dy2;
     cairo_stroke_face_t sub_start, sub_end;
     cairo_point_t *p1 = &stroker->current_point;
     cairo_point_t *p2 = point;
+    cairo_slope_t dev_slope;
     cairo_bool_t fully_in_bounds = TRUE;
     cairo_line_t segment;
 
     stroker->has_initial_sub_path = stroker->dash_starts_on;
 
     if (p1->x == p2->x && p1->y == p2->y)
 	return CAIRO_STATUS_SUCCESS;
 
     if (stroker->has_bounds &&
 	(!_cairo_box_contains_point (&stroker->bounds, p1) ||
 	 !_cairo_box_contains_point (&stroker->bounds, p2)))
     {
 	fully_in_bounds = FALSE;
     }
 
+    _cairo_slope_init (&dev_slope, p1, p2);
+
     slope_dx = _cairo_fixed_to_double (p2->x - p1->x);
     slope_dy = _cairo_fixed_to_double (p2->y - p1->y);
 
     if (!_compute_normalized_device_slope (&slope_dx, &slope_dy, stroker->ctm_inverse, &mag))
 	return CAIRO_STATUS_SUCCESS;
 
     remain = mag;
     segment.p1 = *p1;
@@ -865,17 +874,17 @@ static cairo_status_t
 	cairo_matrix_transform_distance (stroker->ctm, &dx2, &dy2);
 	segment.p2.x = _cairo_fixed_from_double (dx2) + p1->x;
 	segment.p2.y = _cairo_fixed_from_double (dy2) + p1->y;
 
 	if (fully_in_bounds ||
 	    _cairo_box_intersects_line_segment (&stroker->bounds, &segment))
 	{
 	    if (stroker->dash_on) {
-		status = _cairo_stroker_add_sub_edge (stroker, &segment.p1, &segment.p2, slope_dx, slope_dy, &sub_start, &sub_end);
+		status = _cairo_stroker_add_sub_edge (stroker, &segment.p1, &segment.p2, &dev_slope, slope_dx, slope_dy, &sub_start, &sub_end);
 		if (status)
 		    return status;
 
 		if (stroker->has_current_face) {
 		    /* Join with final face from previous segment */
 		    status = _cairo_stroker_join (stroker, &stroker->current_face, &sub_start);
 		    stroker->has_current_face = FALSE;
 		    if (status)
@@ -918,17 +927,17 @@ static cairo_status_t
     if (stroker->dash_on && !stroker->has_current_face) {
 	/* This segment ends on a transition to dash_on, compute a new face
 	 * and add cap for the begining of the next dash_on step.
 	 *
 	 * Note: this will create a degenerate cap if this is not the last line
 	 * in the path. Whether this behaviour is desirable or not is debatable.
 	 * On one side these degnerate caps can not be reproduced with regular path stroking.
 	 * On the other side Acroread 7 also produces the degenerate caps. */
-	_compute_face (point, slope_dx, slope_dy, stroker, &stroker->current_face);
+	_compute_face (point, &dev_slope, slope_dx, slope_dy, stroker, &stroker->current_face);
 	stroker->has_current_face = TRUE;
 	status = _cairo_stroker_add_leading_cap (stroker, &stroker->current_face);
 	if (status)
 	    return status;
     }
 
     stroker->current_point = *point;
 
@@ -960,20 +969,20 @@ static cairo_status_t
 	goto CLEANUP_SPLINE;
 
     initial_slope_dx = _cairo_fixed_to_double (spline.initial_slope.dx);
     initial_slope_dy = _cairo_fixed_to_double (spline.initial_slope.dy);
     final_slope_dx = _cairo_fixed_to_double (spline.final_slope.dx);
     final_slope_dy = _cairo_fixed_to_double (spline.final_slope.dy);
 
     if (_compute_normalized_device_slope (&initial_slope_dx, &initial_slope_dy, stroker->ctm_inverse, NULL))
-	_compute_face (a, initial_slope_dx, initial_slope_dy, stroker, &start);
+	_compute_face (a, &spline.initial_slope, initial_slope_dx, initial_slope_dy, stroker, &start);
 
     if (_compute_normalized_device_slope (&final_slope_dx, &final_slope_dy, stroker->ctm_inverse, NULL))
-	_compute_face (d, final_slope_dx, final_slope_dy, stroker, &end);
+	_compute_face (d, &spline.final_slope, final_slope_dx, final_slope_dy, stroker, &end);
 
     if (stroker->has_current_face) {
 	status = _cairo_stroker_join (stroker, &stroker->current_face, &start);
 	if (status)
 	    goto CLEANUP_PEN;
     } else if (!stroker->has_first_face) {
 	stroker->first_face = start;
 	stroker->has_first_face = TRUE;
--- a/gfx/cairo/cairo/src/cairo-pattern.c
+++ b/gfx/cairo/cairo/src/cairo-pattern.c
@@ -336,19 +336,20 @@ cairo_pattern_t *
 
     CAIRO_MUTEX_UNLOCK (_cairo_pattern_solid_pattern_cache_lock);
 
     if (pattern == NULL) {
 	/* None cached, need to create a new pattern. */
 	pattern = malloc (sizeof (cairo_solid_pattern_t));
     }
 
-    if (pattern == NULL)
+    if (pattern == NULL) {
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	pattern = (cairo_solid_pattern_t *) &_cairo_pattern_nil;
-    else
+    } else
 	_cairo_pattern_init_solid (pattern, color, content);
 
     return &pattern->base;
 }
 
 static void
 _cairo_pattern_reset_solid_pattern_cache (void)
 {
@@ -401,33 +402,27 @@ static const cairo_pattern_t *
  *
  * This function will always return a valid pointer, but if an error
  * occurred the pattern status will be set to an error.  To inspect
  * the status of a pattern use cairo_pattern_status().
  **/
 cairo_pattern_t *
 cairo_pattern_create_rgb (double red, double green, double blue)
 {
-    cairo_pattern_t *pattern;
     cairo_color_t color;
 
     _cairo_restrict_value (&red,   0.0, 1.0);
     _cairo_restrict_value (&green, 0.0, 1.0);
     _cairo_restrict_value (&blue,  0.0, 1.0);
 
     _cairo_color_init_rgb (&color, red, green, blue);
 
     CAIRO_MUTEX_INITIALIZE ();
 
-    pattern = _cairo_pattern_create_solid (&color,
-					   CAIRO_CONTENT_COLOR);
-    if (pattern->status)
-	_cairo_error_throw (pattern->status);
-
-    return pattern;
+    return _cairo_pattern_create_solid (&color, CAIRO_CONTENT_COLOR);
 }
 slim_hidden_def (cairo_pattern_create_rgb);
 
 /**
  * cairo_pattern_create_rgba:
  * @red: red component of the color
  * @green: green component of the color
  * @blue: blue component of the color
@@ -446,34 +441,28 @@ slim_hidden_def (cairo_pattern_create_rg
  * This function will always return a valid pointer, but if an error
  * occurred the pattern status will be set to an error.  To inspect
  * the status of a pattern use cairo_pattern_status().
  **/
 cairo_pattern_t *
 cairo_pattern_create_rgba (double red, double green, double blue,
 			   double alpha)
 {
-    cairo_pattern_t *pattern;
     cairo_color_t color;
 
     _cairo_restrict_value (&red,   0.0, 1.0);
     _cairo_restrict_value (&green, 0.0, 1.0);
     _cairo_restrict_value (&blue,  0.0, 1.0);
     _cairo_restrict_value (&alpha, 0.0, 1.0);
 
     _cairo_color_init_rgba (&color, red, green, blue, alpha);
 
     CAIRO_MUTEX_INITIALIZE ();
 
-    pattern = _cairo_pattern_create_solid (&color,
-					   CAIRO_CONTENT_COLOR_ALPHA);
-    if (pattern->status)
-	_cairo_error_throw (pattern->status);
-
-    return pattern;
+    return _cairo_pattern_create_solid (&color, CAIRO_CONTENT_COLOR_ALPHA);
 }
 slim_hidden_def (cairo_pattern_create_rgba);
 
 /**
  * cairo_pattern_create_for_surface:
  * @surface: the surface
  *
  * Create a new #cairo_pattern_t for the given surface.
@@ -487,18 +476,20 @@ slim_hidden_def (cairo_pattern_create_rg
  * occurred the pattern status will be set to an error.  To inspect
  * the status of a pattern use cairo_pattern_status().
  **/
 cairo_pattern_t *
 cairo_pattern_create_for_surface (cairo_surface_t *surface)
 {
     cairo_surface_pattern_t *pattern;
 
-    if (surface == NULL)
+    if (surface == NULL) {
+	_cairo_error_throw (CAIRO_STATUS_NULL_POINTER);
 	return (cairo_pattern_t*) &_cairo_pattern_nil_null_pointer;
+    }
 
     if (surface->status)
 	return (cairo_pattern_t*) _cairo_pattern_create_in_error (surface->status);
 
     pattern = malloc (sizeof (cairo_surface_pattern_t));
     if (pattern == NULL) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_pattern_t *)&_cairo_pattern_nil.base;
--- a/gfx/cairo/cairo/src/cairo-pdf-surface.c
+++ b/gfx/cairo/cairo/src/cairo-pdf-surface.c
@@ -34,16 +34,17 @@
  * California.
  *
  * Contributor(s):
  *	Kristian Høgsberg <krh@redhat.com>
  *	Carl Worth <cworth@cworth.org>
  *	Adrian Johnson <ajohnson@redneon.com>
  */
 
+#define _BSD_SOURCE /* for snprintf() */
 #include "cairoint.h"
 #include "cairo-pdf.h"
 #include "cairo-pdf-surface-private.h"
 #include "cairo-pdf-operators-private.h"
 #include "cairo-scaled-font-subsets-private.h"
 #include "cairo-paginated-private.h"
 #include "cairo-output-stream-private.h"
 #include "cairo-meta-surface-private.h"
@@ -4016,16 +4017,45 @@ static cairo_status_t
 
     status = _cairo_pdf_surface_write_patterns_and_smask_groups (surface);
     if (status)
 	return status;
 
     return CAIRO_STATUS_SUCCESS;
 }
 
+static cairo_int_status_t
+_cairo_pdf_surface_analyze_surface_pattern_transparency (cairo_pdf_surface_t      *surface,
+							 cairo_surface_pattern_t *pattern)
+{
+    cairo_image_surface_t  *image;
+    void		   *image_extra;
+    cairo_int_status_t      status;
+    cairo_image_transparency_t transparency;
+
+    status = _cairo_surface_acquire_source_image (pattern->surface,
+						  &image,
+						  &image_extra);
+    if (status)
+	return status;
+
+    if (image->base.status)
+	return image->base.status;
+
+    transparency = _cairo_image_analyze_transparency (image);
+    if (transparency == CAIRO_IMAGE_IS_OPAQUE)
+	status = CAIRO_STATUS_SUCCESS;
+    else
+	status = CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
+
+    _cairo_surface_release_source_image (pattern->surface, image, image_extra);
+
+    return status;
+}
+
 static cairo_bool_t
 _surface_pattern_supported (cairo_surface_pattern_t *pattern)
 {
     cairo_extend_t extend;
 
     if (_cairo_surface_is_meta (pattern->surface))
 	return TRUE;
 
@@ -4124,19 +4154,26 @@ static cairo_int_status_t
 	    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 supported if the pattern is opaque or if
+    /* 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_pattern_is_opaque (pattern))
 	    return CAIRO_STATUS_SUCCESS;
 	else
 	    return CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
     }
 
     return CAIRO_INT_STATUS_UNSUPPORTED;
 }
--- a/gfx/cairo/cairo/src/cairo-png.c
+++ b/gfx/cairo/cairo/src/cairo-png.c
@@ -28,16 +28,17 @@
  * The Original Code is the cairo graphics library.
  *
  * The Initial Developer of the Original Code is University of Southern
  * California.
  *
  * Contributor(s):
  *	Carl D. Worth <cworth@cworth.org>
  *	Kristian Høgsberg <krh@redhat.com>
+ *	Chris Wilson <chris@chris-wilson.co.uk>
  */
 
 #include "cairoint.h"
 
 #include <errno.h>
 #include <png.h>
 
 /* Unpremultiplies data and converts native endian ARGB => RGBA bytes */
@@ -103,16 +104,23 @@ png_simple_error_callback (png_structp p
 
     /* if we get here, then we have to choice but to abort ... */
 }
 
 static void
 png_simple_warning_callback (png_structp png,
 	                     png_const_charp error_msg)
 {
+    cairo_status_t *error = png_get_error_ptr (png);
+
+    /* default to the most likely error */
+    if (*error == CAIRO_STATUS_SUCCESS)
+	*error = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    /* png does not expect to abort and will try to tidy up after a warning */
 }
 
 
 static cairo_status_t
 write_png (cairo_surface_t	*surface,
 	   png_rw_ptr		write_func,
 	   void			*closure)
 {
@@ -133,18 +141,20 @@ write_png (cairo_surface_t	*surface,
 						  &image_extra);
 
     if (status == CAIRO_INT_STATUS_UNSUPPORTED)
 	return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
     else if (status)
         return status;
 
     /* PNG complains about "Image width or height is zero in IHDR" */
-    if (image->width == 0 || image->height == 0)
-	return _cairo_error (CAIRO_STATUS_WRITE_ERROR);
+    if (image->width == 0 || image->height == 0) {
+	status = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
+	goto BAIL1;
+    }
 
     rows = _cairo_malloc_ab (image->height, sizeof (png_byte*));
     if (rows == NULL) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto BAIL1;
     }
 
     for (i = 0; i < image->height; i++)
@@ -217,18 +227,17 @@ write_png (cairo_surface_t	*surface,
 
     if (image->format == CAIRO_FORMAT_ARGB32)
 	png_set_write_user_transform_fn (png, unpremultiply_data);
     else if (image->format == CAIRO_FORMAT_RGB24)
 	png_set_write_user_transform_fn (png, convert_data_to_bytes);
     if (image->format == CAIRO_FORMAT_RGB24)
 	png_set_filler (png, 0, PNG_FILLER_AFTER);
 
-    if (rows)
-	png_write_image (png, rows);
+    png_write_image (png, rows);
     png_write_end (png, info);
 
 BAIL3:
     png_destroy_write_struct (&png, &info);
 BAIL2:
     free (rows);
 BAIL1:
     _cairo_surface_release_source_image (surface, image, image_extra);
@@ -243,17 +252,18 @@ stdio_write_func (png_structp png, png_b
 
     fp = png_get_io_ptr (png);
     while (size) {
 	size_t ret = fwrite (data, 1, size, fp);
 	size -= ret;
 	data += ret;
 	if (size && ferror (fp)) {
 	    cairo_status_t *error = png_get_error_ptr (png);
-	    *error = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
+	    if (*error == CAIRO_STATUS_SUCCESS)
+		*error = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
 	    png_error (png, NULL);
 	}
     }
 }
 
 /**
  * cairo_surface_write_to_png:
  * @surface: a #cairo_surface_t with pixel contents
@@ -290,31 +300,32 @@ cairo_surface_write_to_png (cairo_surfac
 
     if (fclose (fp) && status == CAIRO_STATUS_SUCCESS)
 	status = _cairo_error (CAIRO_STATUS_WRITE_ERROR);
 
     return status;
 }
 
 struct png_write_closure_t {
-    cairo_write_func_t	write_func;
+    cairo_write_func_t		 write_func;
     void			*closure;
 };
 
 static void
 stream_write_func (png_structp png, png_bytep data, png_size_t size)
 {
     cairo_status_t status;
     struct png_write_closure_t *png_closure;
 
     png_closure = png_get_io_ptr (png);
     status = png_closure->write_func (png_closure->closure, data, size);
     if (status) {
 	cairo_status_t *error = png_get_error_ptr (png);
-	*error = status;
+	if (*error == CAIRO_STATUS_SUCCESS)
+	    *error = status;
 	png_error (png, NULL);
     }
 }
 
 /**
  * cairo_surface_write_to_png_stream:
  * @surface: a #cairo_surface_t with pixel contents
  * @write_func: a #cairo_write_func_t
@@ -353,51 +364,69 @@ multiply_alpha (int alpha, int color)
 static void
 premultiply_data (png_structp   png,
                   png_row_infop row_info,
                   png_bytep     data)
 {
     unsigned int i;
 
     for (i = 0; i < row_info->rowbytes; i += 4) {
-	uint8_t *base = &data[i];
+	uint8_t *base  = &data[i];
 	uint8_t  alpha = base[3];
 	uint32_t p;
 
 	if (alpha == 0) {
 	    p = 0;
 	} else {
-	    uint8_t  red = base[0];
+	    uint8_t  red   = base[0];
 	    uint8_t  green = base[1];
-	    uint8_t  blue = base[2];
+	    uint8_t  blue  = base[2];
 
 	    if (alpha != 0xff) {
-		red = multiply_alpha (alpha, red);
+		red   = multiply_alpha (alpha, red);
 		green = multiply_alpha (alpha, green);
-		blue = multiply_alpha (alpha, blue);
+		blue  = multiply_alpha (alpha, blue);
 	    }
 	    p = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
 	}
 	memcpy (base, &p, sizeof (uint32_t));
     }
 }
 
+/* Converts RGBx bytes to native endian xRGB */
+static void
+convert_bytes_to_data (png_structp png, png_row_infop row_info, png_bytep data)
+{
+    unsigned int i;
+
+    for (i = 0; i < row_info->rowbytes; i += 4) {
+	uint8_t *base  = &data[i];
+	uint8_t  red   = base[0];
+	uint8_t  green = base[1];
+	uint8_t  blue  = base[2];
+	uint32_t pixel;
+
+	pixel = (0xff << 24) | (red << 16) | (green << 8) | (blue << 0);
+	memcpy (base, &pixel, sizeof (uint32_t));
+    }
+}
+
 static cairo_surface_t *
 read_png (png_rw_ptr	read_func,
 	  void		*closure)
 {
     cairo_surface_t *surface;
     png_struct *png = NULL;
     png_info *info;
     png_byte *data = NULL;
     png_byte **row_pointers = NULL;
-    png_uint_32 png_width, png_height, stride;
-    int depth, color_type, interlace;
+    png_uint_32 png_width, png_height;
+    int depth, color_type, interlace, stride;
     unsigned int i;
-    unsigned int pixel_size;
+    cairo_format_t format;
     cairo_status_t status;
 
     /* XXX: Perhaps we'll want some other error handlers? */
     png = png_create_read_struct (PNG_LIBPNG_VER_STRING,
                                   &status,
 	                          png_simple_error_callback,
 	                          png_simple_warning_callback);
     if (png == NULL) {
@@ -421,75 +450,105 @@ read_png (png_rw_ptr	read_func,
     }
 #endif
 
     png_read_info (png, info);
 
     png_get_IHDR (png, info,
                   &png_width, &png_height, &depth,
                   &color_type, &interlace, NULL, NULL);
-    stride = 4 * png_width;
+    if (status) { /* catch any early warnings */
+	surface = _cairo_surface_create_in_error (status);
+	goto BAIL;
+    }
 
     /* convert palette/gray image to rgb */
     if (color_type == PNG_COLOR_TYPE_PALETTE)
         png_set_palette_to_rgb (png);
 
     /* expand gray bit depth if needed */
-    if (color_type == PNG_COLOR_TYPE_GRAY && depth < 8)
+    if (color_type == PNG_COLOR_TYPE_GRAY) {
 #if PNG_LIBPNG_VER >= 10209
         png_set_expand_gray_1_2_4_to_8 (png);
 #else
         png_set_gray_1_2_4_to_8 (png);
 #endif
+    }
+
     /* transform transparency to alpha */
     if (png_get_valid (png, info, PNG_INFO_tRNS))
         png_set_tRNS_to_alpha (png);
 
     if (depth == 16)
         png_set_strip_16 (png);
 
     if (depth < 8)
         png_set_packing (png);
 
     /* convert grayscale to RGB */
-    if (color_type == PNG_COLOR_TYPE_GRAY
-        || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
-        png_set_gray_to_rgb (png);
+    if (color_type == PNG_COLOR_TYPE_GRAY ||
+	color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+    {
+	png_set_gray_to_rgb (png);
+    }
 
     if (interlace != PNG_INTERLACE_NONE)
         png_set_interlace_handling (png);
 
-    png_set_filler (png, 0xff, PNG_FILLER_AFTER);
+    switch (color_type) {
+	default:
+	case PNG_COLOR_TYPE_GRAY_ALPHA:
+	case PNG_COLOR_TYPE_RGB_ALPHA:
+	    format = CAIRO_FORMAT_ARGB32;
+	    png_set_read_user_transform_fn (png, premultiply_data);
+	    break;
 
-    png_set_read_user_transform_fn (png, premultiply_data);
+	case PNG_COLOR_TYPE_GRAY:
+	case PNG_COLOR_TYPE_PALETTE:
+	case PNG_COLOR_TYPE_RGB:
+	    format = CAIRO_FORMAT_RGB24;
+	    png_set_read_user_transform_fn (png, convert_bytes_to_data);
+	    png_set_filler (png, 0xff, PNG_FILLER_AFTER);
+	    break;
+    }
 
     png_read_update_info (png, info);
 
-    pixel_size = 4;
-    data = _cairo_malloc_abc (png_height, png_width, pixel_size);
+    stride = cairo_format_stride_for_width (format, png_width);
+    if (stride < 0) {
+	surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE));
+	goto BAIL;
+    }
+
+    data = _cairo_malloc_ab (png_height, stride);
     if (data == NULL) {
 	surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 	goto BAIL;
     }
 
     row_pointers = _cairo_malloc_ab (png_height, sizeof (char *));
     if (row_pointers == NULL) {
 	surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 	goto BAIL;
     }
 
     for (i = 0; i < png_height; i++)
-        row_pointers[i] = &data[i * png_width * pixel_size];
+        row_pointers[i] = &data[i * stride];
 
     png_read_image (png, row_pointers);
     png_read_end (png, info);
 
-    surface = cairo_image_surface_create_for_data (data,
-						   CAIRO_FORMAT_ARGB32,
-						   png_width, png_height, stride);
+    if (status) { /* catch any late warnings - probably hit an error already */
+	surface = _cairo_surface_create_in_error (status);
+	goto BAIL;
+    }
+
+    surface = cairo_image_surface_create_for_data (data, format,
+						   png_width, png_height,
+						   stride);
     if (surface->status)
 	goto BAIL;
 
     _cairo_image_surface_assume_ownership_of_data ((cairo_image_surface_t*)surface);
     data = NULL;
 
  BAIL:
     if (row_pointers)
@@ -509,17 +568,18 @@ stdio_read_func (png_structp png, png_by
 
     fp = png_get_io_ptr (png);
     while (size) {
 	size_t ret = fread (data, 1, size, fp);
 	size -= ret;
 	data += ret;
 	if (size && (feof (fp) || ferror (fp))) {
 	    cairo_status_t *error = png_get_error_ptr (png);
-	    *error = _cairo_error (CAIRO_STATUS_READ_ERROR);
+	    if (*error == CAIRO_STATUS_SUCCESS)
+		*error = _cairo_error (CAIRO_STATUS_READ_ERROR);
 	    png_error (png, NULL);
 	}
     }
 }
 
 /**
  * cairo_image_surface_create_from_png:
  * @filename: name of PNG file to load
@@ -562,31 +622,32 @@ cairo_image_surface_create_from_png (con
     surface = read_png (stdio_read_func, fp);
 
     fclose (fp);
 
     return surface;
 }
 
 struct png_read_closure_t {
-    cairo_read_func_t	read_func;
+    cairo_read_func_t		 read_func;
     void			*closure;
 };
 
 static void
 stream_read_func (png_structp png, png_bytep data, png_size_t size)
 {
     cairo_status_t status;
     struct png_read_closure_t *png_closure;
 
     png_closure = png_get_io_ptr (png);
     status = png_closure->read_func (png_closure->closure, data, size);
     if (status) {
 	cairo_status_t *error = png_get_error_ptr (png);
-	*error = status;
+	if (*error == CAIRO_STATUS_SUCCESS)
+	    *error = status;
 	png_error (png, NULL);
     }
 }
 
 /**
  * cairo_image_surface_create_from_png_stream:
  * @read_func: function called to read the data of the file
  * @closure: data to pass to @read_func.
--- a/gfx/cairo/cairo/src/cairo-ps-surface.c
+++ b/gfx/cairo/cairo/src/cairo-ps-surface.c
@@ -35,16 +35,17 @@
  *
  * Contributor(s):
  *	Carl D. Worth <cworth@cworth.org>
  *	Kristian Høgsberg <krh@redhat.com>
  *	Keith Packard <keithp@keithp.com>
  *	Adrian Johnson <ajohnson@redneon.com>
  */
 
+#define _BSD_SOURCE /* for ctime_r(), snprintf(), strdup() */
 #include "cairoint.h"
 #include "cairo-ps.h"
 #include "cairo-ps-surface-private.h"
 #include "cairo-pdf-operators-private.h"
 #include "cairo-scaled-font-subsets-private.h"
 #include "cairo-paginated-private.h"
 #include "cairo-meta-surface-private.h"
 #include "cairo-output-stream-private.h"
@@ -56,22 +57,16 @@
 #include <errno.h>
 
 #define DEBUG_PS 0
 
 #ifndef HAVE_CTIME_R
 #define ctime_r(T, BUF) ctime (T)
 #endif
 
-typedef enum _cairo_image_transparency {
-    CAIRO_IMAGE_IS_OPAQUE,
-    CAIRO_IMAGE_HAS_BILEVEL_ALPHA,
-    CAIRO_IMAGE_HAS_ALPHA
-} cairo_image_transparency_t;
-
 static const cairo_surface_backend_t cairo_ps_surface_backend;
 static const cairo_paginated_surface_backend_t cairo_ps_surface_paginated_backend;
 
 static const cairo_ps_level_t _cairo_ps_levels[] =
 {
     CAIRO_PS_LEVEL_2,
     CAIRO_PS_LEVEL_3
 };
@@ -1344,50 +1339,16 @@ static cairo_bool_t
 color_is_gray (double red, double green, double blue)
 {
     const double epsilon = 0.00001;
 
     return (fabs (red - green) < epsilon &&
 	    fabs (red - blue) < epsilon);
 }
 
-static cairo_image_transparency_t
-_analyze_image_transparency (cairo_image_surface_t      *image)
-{
-    int x, y;
-    cairo_image_transparency_t transparency;
-
-    if (image->format == CAIRO_FORMAT_RGB24)
-	return CAIRO_IMAGE_IS_OPAQUE;
-
-    if (image->format != CAIRO_FORMAT_ARGB32) {
-	/* If the PS surface does not support the image format, assume
-	 * that it does have alpha. The image will be converted to
-	 * rgb24 when the PS surface blends the image into the page
-	 * color to remove the transparency. */
-	return CAIRO_IMAGE_HAS_ALPHA;
-    }
-
-    transparency = CAIRO_IMAGE_IS_OPAQUE;
-    for (y = 0; y < image->height; y++) {
-	uint32_t *pixel = (uint32_t *) (image->data + y * image->stride);
-
-	for (x = 0; x < image->width; x++, pixel++) {
-	    int a = (*pixel & 0xff000000) >> 24;
-	    if (a > 0 && a < 255) {
-		return CAIRO_IMAGE_HAS_ALPHA;
-	    } else if (a == 0) {
-		transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
-	    }
-	}
-    }
-
-    return transparency;
-}
-
 static cairo_int_status_t
 _cairo_ps_surface_analyze_surface_pattern_transparency (cairo_ps_surface_t      *surface,
 						       cairo_surface_pattern_t *pattern)
 {
     cairo_image_surface_t  *image;
     void		   *image_extra;
     cairo_int_status_t      status;
     cairo_image_transparency_t transparency;
@@ -1396,17 +1357,17 @@ static cairo_int_status_t
 						  &image,
 						  &image_extra);
     if (status)
 	return status;
 
     if (image->base.status)
 	return image->base.status;
 
-    transparency = _analyze_image_transparency (image);
+    transparency = _cairo_image_analyze_transparency (image);
     switch (transparency) {
     case CAIRO_IMAGE_IS_OPAQUE:
 	status = CAIRO_STATUS_SUCCESS;
 	break;
 
     case CAIRO_IMAGE_HAS_BILEVEL_ALPHA:
 	if (surface->ps_level == CAIRO_PS_LEVEL_2) {
 	    status = CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
@@ -1414,16 +1375,19 @@ static cairo_int_status_t
 	    surface->ps_level_used = CAIRO_PS_LEVEL_3;
 	    status = CAIRO_STATUS_SUCCESS;
 	}
 	break;
 
     case CAIRO_IMAGE_HAS_ALPHA:
 	status = CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
 	break;
+
+    case CAIRO_IMAGE_UNKNOWN:
+	ASSERT_NOT_REACHED;
     }
 
     _cairo_surface_release_source_image (pattern->surface, image, image_extra);
 
     return status;
 }
 
 static cairo_bool_t
@@ -1842,17 +1806,17 @@ static cairo_status_t
     cairo_image_transparency_t transparency;
     cairo_bool_t use_mask;
     uint32_t *pixel;
     int bit;
 
     if (image->base.status)
 	return image->base.status;
 
-    transparency = _analyze_image_transparency (image);
+    transparency = _cairo_image_analyze_transparency (image);
 
     /* PostScript can not represent the alpha channel, so we blend the
        current image over a white (or black for CONTENT_COLOR
        surfaces) RGB surface to eliminate it. */
 
     if (op == CAIRO_OPERATOR_SOURCE ||
 	transparency == CAIRO_IMAGE_HAS_ALPHA ||
 	(transparency == CAIRO_IMAGE_HAS_BILEVEL_ALPHA &&
@@ -2225,16 +2189,30 @@ static cairo_status_t
 						pattern,
 						&width,
 						&height,
 						op);
     if (status)
 	return status;
 
     cairo_p2d = pattern->base.matrix;
+
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_FALLBACK) {
+	double scale = cairo_p2d.xx;
+
+	_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);
+    }
+
     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);
     cairo_matrix_translate (&ps_p2d, 0.0, height);
     cairo_matrix_scale (&ps_p2d, 1.0, -1.0);
--- a/gfx/cairo/cairo/src/cairo-quartz-image-surface.c
+++ b/gfx/cairo/cairo/src/cairo-quartz-image-surface.c
@@ -31,28 +31,25 @@
  * The Initial Developer of the Original Code is Mozilla Corporation.
  *
  * Contributor(s):
  *	Vladimir Vukicevic <vladimir@mozilla.com>
  */
 
 #include "cairoint.h"
 
+#ifdef CAIRO_HAS_QUARTZ_IMAGE_SURFACE
+#include "cairo-quartz-image.h"
+#endif
+
 #include "cairo-quartz-private.h"
 
 #define SURFACE_ERROR_NO_MEMORY (_cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY)))
 #define SURFACE_ERROR_INVALID_FORMAT (_cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_INVALID_FORMAT)))
 
-static void
-DataProviderReleaseCallback (void *info, const void *data, size_t size)
-{
-    cairo_surface_t *surface = (cairo_surface_t *) info;
-    cairo_surface_destroy (surface);
-}
-
 CGImageRef
 _cairo_quartz_create_cgimage (cairo_format_t format,
 			      unsigned int width,
 			      unsigned int height,
 			      unsigned int stride,
 			      void *data,
 			      cairo_bool_t interpolate,
 			      CGColorSpaceRef colorSpaceOverride,
@@ -124,16 +121,24 @@ FINISH:
     CGDataProviderRelease (dataProvider);
 
     if (colorSpace != colorSpaceOverride)
 	CGColorSpaceRelease (colorSpace);
 
     return image;
 }
 
+#ifdef CAIRO_HAS_QUARTZ_IMAGE_SURFACE
+
+static void
+DataProviderReleaseCallback (void *info, const void *data, size_t size)
+{
+    cairo_surface_t *surface = (cairo_surface_t *) info;
+    cairo_surface_destroy (surface);
+}
 
 static cairo_surface_t *
 _cairo_quartz_image_surface_create_similar (void *asurface,
 					    cairo_content_t content,
 					    int width,
 					    int height)
 {
     cairo_surface_t *result;
@@ -215,17 +220,17 @@ static cairo_status_t
     /* To be released by the ReleaseCallback */
     cairo_surface_reference ((cairo_surface_t*) surface->imageSurface);
 
     newImage = _cairo_quartz_create_cgimage (surface->imageSurface->format,
 					     surface->imageSurface->width,
 					     surface->imageSurface->height,
 					     surface->imageSurface->stride,
 					     surface->imageSurface->data,
-					     FALSE,
+					     TRUE,
 					     NULL,
 					     DataProviderReleaseCallback,
 					     surface->imageSurface);
 
     surface->image = newImage;
     CGImageRelease (oldImage);
 
     return CAIRO_STATUS_SUCCESS;
@@ -284,20 +289,16 @@ static const cairo_surface_backend_t cai
  */
 cairo_surface_t *
 cairo_quartz_image_surface_create (cairo_surface_t *surface)
 {
     cairo_quartz_image_surface_t *qisurf;
 
     CGImageRef image;
 
-    CGContextRef cgContext;
-    CGColorSpaceRef cgColorspace;
-    CGBitmapInfo bitinfo;
-
     cairo_image_surface_t *image_surface;
     int width, height, stride;
     cairo_format_t format;
     unsigned char *data;
 
     if (cairo_surface_get_type(surface) != CAIRO_SURFACE_TYPE_IMAGE)
 	return SURFACE_ERROR_NO_MEMORY;
 
@@ -328,17 +329,17 @@ cairo_quartz_image_surface_create (cairo
      * case of failure.)
      */
     cairo_surface_reference (surface);
 
     image = _cairo_quartz_create_cgimage (format,
 					  width, height,
 					  stride,
 					  data,
-					  FALSE,
+					  TRUE,
 					  NULL,
 					  DataProviderReleaseCallback,
 					  surface);
 
     if (!image) {
 	free (qisurf);
 	return SURFACE_ERROR_NO_MEMORY;
     }
@@ -363,8 +364,10 @@ cairo_quartz_image_surface_get_image (ca
 {
     cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t*) asurface;
 
     if (cairo_surface_get_type(asurface) != CAIRO_SURFACE_TYPE_QUARTZ_IMAGE)
 	return NULL;
 
     return (cairo_surface_t*) surface->imageSurface;
 }
+
+#endif /* CAIRO_HAS_QUARTZ_IMAGE_SURFACE */
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/cairo/src/cairo-quartz-image.h
@@ -0,0 +1,59 @@
+/* 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>
+ */
+
+#ifndef CAIRO_QUARTZ_IMAGE_H
+#define CAIRO_QUARTZ_IMAGE_H
+
+#include <cairo.h>
+
+#if CAIRO_HAS_QUARTZ_IMAGE_SURFACE
+
+#include <Carbon/Carbon.h>
+
+CAIRO_BEGIN_DECLS
+
+cairo_public cairo_surface_t *
+cairo_quartz_image_surface_create (cairo_surface_t *image_surface);
+
+cairo_public cairo_surface_t *
+cairo_quartz_image_surface_get_image (cairo_surface_t *surface);
+
+CAIRO_END_DECLS
+
+#else  /* CAIRO_HAS_QUARTZ_IMAGE_SURFACE */
+# error Cairo was not compiled with support for the quartz-image backend
+#endif /* CAIRO_HAS_QUARTZ_IMAGE_SURFACE */
+
+#endif /* CAIRO_QUARTZ_IMAGE_H */
--- a/gfx/cairo/cairo/src/cairo-quartz-private.h
+++ b/gfx/cairo/cairo/src/cairo-quartz-private.h
@@ -52,19 +52,20 @@ typedef struct cairo_quartz_surface {
     void *imageData;
     cairo_surface_t *imageSurfaceEquiv;
 
     cairo_rectangle_int_t extents;
 
     /* These are stored while drawing operations are in place, set up
      * by quartz_setup_source() and quartz_finish_source()
      */
+    CGAffineTransform sourceTransform;
+
     CGImageRef sourceImage;
     cairo_surface_t *sourceImageSurface;
-    CGAffineTransform sourceImageTransform;
     CGRect sourceImageRect;
 
     CGShadingRef sourceShading;
     CGPatternRef sourcePattern;
 
     CGInterpolationQuality oldInterpolationQuality;
 } cairo_quartz_surface_t;
 
--- a/gfx/cairo/cairo/src/cairo-quartz-surface.c
+++ b/gfx/cairo/cairo/src/cairo-quartz-surface.c
@@ -102,41 +102,59 @@ CG_EXTERN void CGContextReplacePathWithS
 CG_EXTERN CGImageRef CGBitmapContextCreateImage (CGContextRef);
 #endif
 
 /* Only present in 10.4+ */
 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 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);
 static void quartz_image_to_png (CGImageRef, char *dest);
+#endif
 
 static cairo_quartz_surface_t *
 _cairo_quartz_surface_create_internal (CGContextRef cgContext,
 				       cairo_content_t content,
 				       unsigned int width,
 				       unsigned int height);
 
 /* Load all extra symbols */
 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, "CGContextGetTypePtr");
+    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");
 
     _cairo_quartz_symbol_lookup_done = TRUE;
 }
 
 static inline cairo_bool_t
 _cairo_quartz_is_cgcontext_bitmap_context (CGContextRef cgc) {
     if (CGContextGetTypePtr) {
 	/* 4 is the type value of a bitmap context */
@@ -362,28 +380,186 @@ static inline void
     dst->a = src->xx;
     dst->b = src->yx;
     dst->c = src->xy;
     dst->d = src->yy;
     dst->tx = src->x0;
     dst->ty = src->y0;
 }
 
+typedef struct {
+    bool isClipping;
+    CGGlyph *cg_glyphs;
+    CGSize *cg_advances;
+    size_t nglyphs;
+    CGAffineTransform textTransform;
+    CGFontRef font;
+    CGPoint origin;
+} unbounded_show_glyphs_t;
+
+typedef struct {
+    CGPathRef cgPath;
+    cairo_fill_rule_t fill_rule;
+} unbounded_stroke_fill_t;
+
+typedef struct {
+    CGImageRef mask;
+    CGAffineTransform maskTransform;
+} unbounded_mask_t;
+
+typedef enum {
+    UNBOUNDED_STROKE_FILL,
+    UNBOUNDED_SHOW_GLYPHS,
+    UNBOUNDED_MASK
+} unbounded_op_t;
+
+typedef struct {
+    unbounded_op_t op;
+    union {
+	unbounded_stroke_fill_t stroke_fill;
+	unbounded_show_glyphs_t show_glyphs;
+	unbounded_mask_t mask;
+    } u;
+} unbounded_op_data_t;
+
+static void
+_cairo_quartz_fixup_unbounded_operation (cairo_quartz_surface_t *surface,
+					 unbounded_op_data_t *op,
+					 cairo_antialias_t antialias)
+{
+    CGColorSpaceRef gray;
+    CGRect clipBox, clipBoxRound;
+    CGContextRef cgc;
+    CGImageRef maskImage;
+
+    if (!CGContextClipToMaskPtr)
+	return;
+
+    clipBox = CGContextGetClipBoundingBox (surface->cgContext);
+    clipBoxRound = CGRectIntegral (clipBox);
+
+    gray = CGColorSpaceCreateDeviceGray ();
+    cgc = CGBitmapContextCreate (NULL,
+				 clipBoxRound.size.width,
+				 clipBoxRound.size.height,
+				 8,
+				 clipBoxRound.size.width,
+				 gray,
+				 kCGImageAlphaNone);
+    CGColorSpaceRelease (gray);
+
+    if (!cgc)
+	return;
+
+    /* We want to mask out whatever we just rendered, so we fill the
+     * surface with white, and then we'll render with black.
+     */
+    CGContextSetRGBFillColor (cgc, 1.0f, 1.0f, 1.0f, 1.0f);
+    CGContextFillRect (cgc, CGRectMake (0, 0, clipBoxRound.size.width, clipBoxRound.size.height));
+
+    CGContextSetRGBFillColor (cgc, 0.0f, 0.0f, 0.0f, 1.0f);
+    CGContextSetShouldAntialias (cgc, (antialias != CAIRO_ANTIALIAS_NONE));
+
+    CGContextTranslateCTM (cgc, -clipBoxRound.origin.x, -clipBoxRound.origin.y);
+
+    /* We need to either render the path that was given to us, or the glyph op */
+    if (op->op == UNBOUNDED_STROKE_FILL) {
+	CGContextBeginPath (cgc);
+	CGContextAddPath (cgc, op->u.stroke_fill.cgPath);
+
+	if (op->u.stroke_fill.fill_rule == CAIRO_FILL_RULE_WINDING)
+	    CGContextFillPath (cgc);
+	else
+	    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) {
+	    CGContextSetTextDrawingMode (cgc, kCGTextClip);
+	    CGContextSaveGState (cgc);
+	}
+
+	CGContextShowGlyphsWithAdvances (cgc,
+					 op->u.show_glyphs.cg_glyphs,
+					 op->u.show_glyphs.cg_advances,
+					 op->u.show_glyphs.nglyphs);
+
+	if (op->u.show_glyphs.isClipping) {
+	    CGContextFillRect (cgc, CGRectMake (0.0, 0.0, clipBoxRound.size.width, clipBoxRound.size.height));
+	    CGContextRestoreGState (cgc);
+	}
+    } else if (op->op == UNBOUNDED_MASK) {
+	CGContextSaveGState (cgc);
+	CGContextConcatCTM (cgc, op->u.mask.maskTransform);
+	CGContextClipToMask (cgc, CGRectMake (0.0f, 0.0f,
+					      CGImageGetWidth(op->u.mask.mask), CGImageGetHeight(op->u.mask.mask)),
+			     op->u.mask.mask);
+	CGContextFillRect (cgc, CGRectMake (0.0, 0.0, clipBoxRound.size.width, clipBoxRound.size.height));
+	CGContextRestoreGState (cgc);
+    }
+
+    /* Also mask out the portion of the clipbox that we rounded out, if any */
+    if (!CGRectEqualToRect (clipBox, clipBoxRound)) {
+	CGContextBeginPath (cgc);
+	CGContextAddRect (cgc, CGRectMake (0.0, 0.0, clipBoxRound.size.width, clipBoxRound.size.height));
+	CGContextAddRect (cgc, CGRectMake (clipBoxRound.origin.x - clipBox.origin.x,
+					   clipBoxRound.origin.y - clipBox.origin.y,
+					   clipBox.size.width,
+					   clipBox.size.height));
+	CGContextEOFillPath (cgc);
+    }
+
+    maskImage = CGBitmapContextCreateImage (cgc);
+    CGContextRelease (cgc);
+
+    if (!maskImage)
+	return;
+
+    /* Then render with the mask */
+    CGContextSaveGState (surface->cgContext);
+
+    CGContextSetCompositeOperation (surface->cgContext, kPrivateCGCompositeCopy);
+    CGContextClipToMaskPtr (surface->cgContext, clipBoxRound, maskImage);
+    CGImageRelease (maskImage);
+
+    /* Finally, clear out the entire clipping region through our mask */
+    CGContextClearRect (surface->cgContext, clipBoxRound);
+
+    CGContextRestoreGState (surface->cgContext);
+}
+
 /*
  * Source -> Quartz setup and finish functions
  */
 
 static void
 ComputeGradientValue (void *info, const float *in, float *out)
 {
-    float fdist = *in; /* 0.0 .. 1.0 */
-    cairo_fixed_t fdist_fix = _cairo_fixed_from_double(*in);
+    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)
 	    break;
     }
 
     if (i == 0 || i == grad->n_stops) {
 	if (i == grad->n_stops)
 	    --i;
@@ -410,22 +586,100 @@ ComputeGradientValue (void *info, const 
 	    grad->stops[i-1].color.alpha * ap +
 	    grad->stops[i].color.alpha * bp;
     }
 }
 
 static CGFunctionRef
 CreateGradientFunction (cairo_gradient_pattern_t *gpat)
 {
-    static const float input_value_range[2] = { 0.f, 1.f };
-    static const float output_value_ranges[8] = { 0.f, 1.f, 0.f, 1.f, 0.f, 1.f, 0.f, 1.f };
-    static const CGFunctionCallbacks callbacks = {
+    float input_value_range[2] = { 0.f, 1.f };
+    float output_value_ranges[8] = { 0.f, 1.f, 0.f, 1.f, 0.f, 1.f, 0.f, 1.f };
+    CGFunctionCallbacks callbacks = {
+	0, ComputeGradientValue, (CGFunctionReleaseInfoCallback) cairo_pattern_destroy
+    };
+
+    return CGFunctionCreate (gpat,
+			     1,
+			     input_value_range,
+			     4,
+			     output_value_ranges,
+			     &callbacks);
+}
+
+static CGFunctionRef
+CreateRepeatingGradientFunction (cairo_quartz_surface_t *surface,
+				 cairo_gradient_pattern_t *gpat,
+				 CGPoint *start, CGPoint *end,
+				 CGAffineTransform matrix)
+{
+    float input_value_range[2];
+    float output_value_ranges[8] = { 0.f, 1.f, 0.f, 1.f, 0.f, 1.f, 0.f, 1.f };
+    CGFunctionCallbacks callbacks = {
 	0, ComputeGradientValue, (CGFunctionReleaseInfoCallback) cairo_pattern_destroy
     };
 
+    CGPoint mstart, mend;
+
+    double dx, dy;
+    int x_rep_start = 0, x_rep_end = 0;
+    int y_rep_start = 0, y_rep_end = 0;
+
+    int rep_start, rep_end;
+
+    // figure out how many times we'd need to repeat the gradient pattern
+    // to cover the whole (transformed) surface area
+    mstart = CGPointApplyAffineTransform (*start, matrix);
+    mend = CGPointApplyAffineTransform (*end, matrix);
+
+    dx = fabs (mend.x - mstart.x);
+    dy = fabs (mend.y - mstart.y);
+
+    if (dx > 1e-6) {
+	x_rep_start = (int) ceil(MIN(mstart.x, mend.x) / dx);
+	x_rep_end = (int) ceil((surface->extents.width - MAX(mstart.x, mend.x)) / dx);
+
+	if (mend.x < mstart.x) {
+	    int swap = x_rep_end;
+	    x_rep_end = x_rep_start;
+	    x_rep_start = swap;
+	}
+    }
+
+    if (dy > 1e-6) {
+	y_rep_start = (int) ceil(MIN(mstart.y, mend.y) / dy);
+	y_rep_end = (int) ceil((surface->extents.width - MAX(mstart.y, mend.y)) / dy);
+
+	if (mend.y < mstart.y) {
+	    int swap = y_rep_end;
+	    y_rep_end = y_rep_start;
+	    y_rep_start = swap;
+	}
+    }
+
+    rep_start = MAX(x_rep_start, y_rep_start);
+    rep_end = MAX(x_rep_end, y_rep_end);
+
+    // extend the line between start and end by rep_start times from the start
+    // and rep_end times from the end
+
+    dx = end->x - start->x;
+    dy = end->y - start->y;
+
+    start->x = start->x - dx * rep_start;
+    start->y = start->y - dy * rep_start;
+
+    end->x = end->x + dx * rep_end;
+    end->y = end->y + dy * rep_end;
+
+    // set the input range for the function -- the function knows how to
+    // map values outside of 0.0 .. 1.0 to that range for REPEAT/REFLECT.
+    input_value_range[0] = 0.0 - 1.0 * rep_start;
+    input_value_range[1] = 1.0 + 1.0 * rep_end;
+
     return CGFunctionCreate (gpat,
 			     1,
 			     input_value_range,
 			     4,
 			     output_value_ranges,
 			     &callbacks);
 }
 
@@ -442,36 +696,38 @@ static CGImageRef
 
     if (stype == CAIRO_SURFACE_TYPE_QUARTZ_IMAGE) {
 	cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) source;
 	return CGImageRetain (surface->image);
     }
 
     if (stype == CAIRO_SURFACE_TYPE_QUARTZ) {
 	cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) source;
-	image = CGBitmapContextCreateImage (surface->cgContext);
-	if (image)
-	    return image;
+	if (_cairo_quartz_is_cgcontext_bitmap_context (surface->cgContext)) {
+	    image = CGBitmapContextCreateImage (surface->cgContext);
+	    if (image)
+		return image;
+	}
     }
 
     if (stype != CAIRO_SURFACE_TYPE_IMAGE) {
 	cairo_status_t status =
 	    _cairo_surface_acquire_source_image (source, &isurf, &image_extra);
 	if (status)
 	    return NULL;
     } else {
 	isurf = (cairo_image_surface_t *) source;
     }
 
     image2 = _cairo_quartz_create_cgimage (isurf->format,
 					   isurf->width,
 					   isurf->height,
 					   isurf->stride,
 					   isurf->data,
-					   FALSE,
+					   TRUE,
 					   NULL, NULL, NULL);
 
     image = CGImageCreateCopy (image2);
     CGImageRelease (image2);
 
     if ((cairo_surface_t*) isurf != source)
 	_cairo_surface_release_source_image (source, isurf, image_extra);
 
@@ -631,121 +887,170 @@ typedef enum {
     DO_PATTERN,
     DO_IMAGE,
     DO_UNSUPPORTED,
     DO_NOTHING,
     DO_TILED_IMAGE
 } cairo_quartz_action_t;
 
 static cairo_quartz_action_t
+_cairo_quartz_setup_fallback_source (cairo_quartz_surface_t *surface,
+				     cairo_pattern_t *source)
+{
+    CGRect clipBox = CGContextGetClipBoundingBox (surface->cgContext);
+    CGAffineTransform ctm;
+    double x0, y0, w, h;
+
+    cairo_surface_t *fallback;
+    cairo_t *fallback_cr;
+    CGImageRef img;
+
+    if (clipBox.size.width == 0.0f ||
+	clipBox.size.height == 0.0f)
+	return DO_NOTHING;
+
+    // the clipBox is in userspace, so:
+    ctm = CGContextGetCTM (surface->cgContext);
+    ctm = CGAffineTransformInvert (ctm);
+    clipBox = CGRectApplyAffineTransform (clipBox, ctm);
+
+    // get the Y flip right -- the CTM will always have a Y flip in place
+    clipBox.origin.y = surface->extents.height - (clipBox.origin.y + clipBox.size.height);
+
+    x0 = floor(clipBox.origin.x);
+    y0 = floor(clipBox.origin.y);
+    w = ceil(clipBox.origin.x + clipBox.size.width) - x0;
+    h = ceil(clipBox.origin.y + clipBox.size.height) - y0;
+
+    /* Create a temporary the size of the clip surface, and position
+     * it so that the device origin coincides with the original surface */
+    fallback = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, (int) w, (int) h);
+    cairo_surface_set_device_offset (fallback, -x0, -y0);
+
+    /* Paint the source onto our temporary */
+    fallback_cr = cairo_create (fallback);
+    cairo_set_operator (fallback_cr, CAIRO_OPERATOR_SOURCE);
+    cairo_set_source (fallback_cr, source);
+    cairo_paint (fallback_cr);
+    cairo_destroy (fallback_cr);
+
+    img = _cairo_surface_to_cgimage ((cairo_surface_t*) surface, fallback);
+
+    surface->sourceImageRect = CGRectMake (0.0, 0.0, w, h);
+    surface->sourceImage = img;
+    surface->sourceImageSurface = fallback;
+    surface->sourceTransform = CGAffineTransformMakeTranslation (x0, y0);
+
+    return DO_IMAGE;
+}
+
+static cairo_quartz_action_t
 _cairo_quartz_setup_linear_source (cairo_quartz_surface_t *surface,
 				   cairo_linear_pattern_t *lpat)
 {
     cairo_pattern_t *abspat = (cairo_pattern_t *) lpat;
     cairo_matrix_t mat;
-    double x0, y0;
     CGPoint start, end;
     CGFunctionRef gradFunc;
     CGColorSpaceRef rgb;
     bool extend = abspat->extend == CAIRO_EXTEND_PAD;
 
-    /* bandaid for mozilla bug 379321, also visible in the
-     * linear-gradient-reflect test.
-     */
-    if (abspat->extend == CAIRO_EXTEND_REFLECT ||
-	abspat->extend == CAIRO_EXTEND_REPEAT)
-	return DO_UNSUPPORTED;
-
-    /* We can only do this if we have an identity pattern matrix;
-     * otherwise fall back through to the generic pattern case.
-     * XXXperf we could optimize this by creating a pattern with the shading;
-     * but we'd need to know the extents to do that.
-     * ... but we don't care; we can use the surface extents for it
-     * XXXtodo - implement gradients with non-identity pattern matrices
-     */
-    cairo_pattern_get_matrix (abspat, &mat);
-    if (mat.xx != 1.0 || mat.yy != 1.0 || mat.xy != 0.0 || mat.yx != 0.0)
-	return DO_UNSUPPORTED;
-
-    if (!lpat->base.n_stops) {
+    if (lpat->base.n_stops == 0) {
 	CGContextSetRGBStrokeColor (surface->cgContext, 0., 0., 0., 0.);
 	CGContextSetRGBFillColor (surface->cgContext, 0., 0., 0., 0.);
 	return DO_SOLID;
     }
 
-    x0 = mat.x0;
-    y0 = mat.y0;
+    cairo_pattern_get_matrix (abspat, &mat);
+    cairo_matrix_invert (&mat);
+    _cairo_quartz_cairo_matrix_to_quartz (&mat, &surface->sourceTransform);
+
     rgb = CGColorSpaceCreateDeviceRGB();
 
-    start = CGPointMake (_cairo_fixed_to_double (lpat->p1.x) - x0,
-			 _cairo_fixed_to_double (lpat->p1.y) - y0);
-    end = CGPointMake (_cairo_fixed_to_double (lpat->p2.x) - x0,
-		       _cairo_fixed_to_double (lpat->p2.y) - y0);
-
-    cairo_pattern_reference (abspat);
-    gradFunc = CreateGradientFunction ((cairo_gradient_pattern_t*) lpat);
+    start = CGPointMake (_cairo_fixed_to_double (lpat->p1.x),
+			 _cairo_fixed_to_double (lpat->p1.y));
+    end = CGPointMake (_cairo_fixed_to_double (lpat->p2.x),
+		       _cairo_fixed_to_double (lpat->p2.y));
+
+    // ref will be released by the CGShading's destructor
+    cairo_pattern_reference ((cairo_pattern_t*) lpat);
+
+    if (abspat->extend == CAIRO_EXTEND_NONE ||
+	abspat->extend == CAIRO_EXTEND_PAD)
+    {
+	gradFunc = CreateGradientFunction ((cairo_gradient_pattern_t*) lpat);
+    } else {
+	gradFunc = CreateRepeatingGradientFunction (surface,
+						    (cairo_gradient_pattern_t*) lpat,
+						    &start, &end, surface->sourceTransform);
+    }
+
     surface->sourceShading = CGShadingCreateAxial (rgb,
 						   start, end,
 						   gradFunc,
 						   extend, extend);
+
     CGColorSpaceRelease(rgb);
     CGFunctionRelease(gradFunc);
 
     return DO_SHADING;
 }
 
 static cairo_quartz_action_t
 _cairo_quartz_setup_radial_source (cairo_quartz_surface_t *surface,
 				   cairo_radial_pattern_t *rpat)
 {
     cairo_pattern_t *abspat = (cairo_pattern_t *)rpat;
     cairo_matrix_t mat;
-    double x0, y0;
     CGPoint start, end;
     CGFunctionRef gradFunc;
-    CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
+    CGColorSpaceRef rgb;
     bool extend = abspat->extend == CAIRO_EXTEND_PAD;
 
-    /* bandaid for mozilla bug 379321, also visible in the
-     * linear-gradient-reflect test.
-     */
-    if (abspat->extend == CAIRO_EXTEND_REFLECT ||
-	abspat->extend == CAIRO_EXTEND_REPEAT)
-	return DO_UNSUPPORTED;
-
-    /* XXXtodo - implement gradients with non-identity pattern matrices
-     */
-    cairo_pattern_get_matrix (abspat, &mat);
-    if (mat.xx != 1.0 || mat.yy != 1.0 || mat.xy != 0.0 || mat.yx != 0.0)
-	return DO_UNSUPPORTED;
-
-    if (!rpat->base.n_stops) {
+    if (rpat->base.n_stops == 0) {
 	CGContextSetRGBStrokeColor (surface->cgContext, 0., 0., 0., 0.);
 	CGContextSetRGBFillColor (surface->cgContext, 0., 0., 0., 0.);
 	return DO_SOLID;
     }
 
-    x0 = mat.x0;
-    y0 = mat.y0;
+    if (abspat->extend == CAIRO_EXTEND_REPEAT ||
+	abspat->extend == CAIRO_EXTEND_REFLECT)
+    {
+	/* I started trying to map these to Quartz, but it's much harder
+	 * then the linear case (I think it would involve doing multiple
+	 * Radial shadings).  So, instead, let's just render an image
+	 * for pixman to draw the shading into, and use that.
+	 */
+	return _cairo_quartz_setup_fallback_source (surface, (cairo_pattern_t*) rpat);
+    }
+
+    cairo_pattern_get_matrix (abspat, &mat);
+    cairo_matrix_invert (&mat);
+    _cairo_quartz_cairo_matrix_to_quartz (&mat, &surface->sourceTransform);
+
     rgb = CGColorSpaceCreateDeviceRGB();
 
-    start = CGPointMake (_cairo_fixed_to_double (rpat->c1.x) - x0,
-			 _cairo_fixed_to_double (rpat->c1.y) - y0);
-    end = CGPointMake (_cairo_fixed_to_double (rpat->c2.x) - x0,
-		       _cairo_fixed_to_double (rpat->c2.y) - y0);
-
-    cairo_pattern_reference (abspat);
+    start = CGPointMake (_cairo_fixed_to_double (rpat->c1.x),
+			 _cairo_fixed_to_double (rpat->c1.y));
+    end = CGPointMake (_cairo_fixed_to_double (rpat->c2.x),
+		       _cairo_fixed_to_double (rpat->c2.y));
+
+    // ref will be released by the CGShading's destructor
+    cairo_pattern_reference ((cairo_pattern_t*) rpat);
+
     gradFunc = CreateGradientFunction ((cairo_gradient_pattern_t*) rpat);
+
     surface->sourceShading = CGShadingCreateRadial (rgb,
 						    start,
 						    _cairo_fixed_to_double (rpat->r1),
 						    end,
 						    _cairo_fixed_to_double (rpat->r2),
 						    gradFunc,
 						    extend, extend);
+
     CGColorSpaceRelease(rgb);
     CGFunctionRelease(gradFunc);
 
     return DO_SHADING;
 }
 
 static cairo_quartz_action_t
 _cairo_quartz_setup_source (cairo_quartz_surface_t *surface,
@@ -800,17 +1105,17 @@ static cairo_quartz_action_t
 
 	img = _cairo_surface_to_cgimage ((cairo_surface_t *) surface, pat_surf);
 	if (!img)
 	    return DO_UNSUPPORTED;
 
 	surface->sourceImage = img;
 
 	cairo_matrix_invert(&m);
-	_cairo_quartz_cairo_matrix_to_quartz (&m, &surface->sourceImageTransform);
+	_cairo_quartz_cairo_matrix_to_quartz (&m, &surface->sourceTransform);
 
 	status = _cairo_surface_get_extents (pat_surf, &extents);
 	if (status)
 	    return DO_UNSUPPORTED;
 
 	if (source->extend == CAIRO_EXTEND_NONE) {
 	    surface->sourceImageRect = CGRectMake (0, 0, extents.width, extents.height);
 	    return DO_IMAGE;
@@ -819,17 +1124,17 @@ static cairo_quartz_action_t
 	/* Quartz seems to tile images at pixel-aligned regions only -- this
 	 * leads to seams if the image doesn't end up scaling to fill the
 	 * space exactly.  The CGPattern tiling approach doesn't have this
 	 * problem.  Check if we're going to fill up the space (within some
 	 * epsilon), and if not, fall back to the CGPattern type.
 	 */
 
 	xform = CGAffineTransformConcat (CGContextGetCTM (surface->cgContext),
-					 surface->sourceImageTransform);
+					 surface->sourceTransform);
 
 	srcRect = CGRectMake (0, 0, extents.width, extents.height);
 	srcRect = CGRectApplyAffineTransform (srcRect, xform);
 
 	fw = _cairo_fixed_from_double (srcRect.size.width);
 	fh = _cairo_fixed_from_double (srcRect.size.height);
 
 	if ((fw & CAIRO_FIXED_FRAC_MASK) <= CAIRO_FIXED_EPSILON &&
@@ -1243,21 +1548,22 @@ static cairo_int_status_t
     action = _cairo_quartz_setup_source (surface, source);
 
     if (action == DO_SOLID || action == DO_PATTERN) {
 	CGContextFillRect (surface->cgContext, CGRectMake(surface->extents.x,
 							  surface->extents.y,
 							  surface->extents.width,
 							  surface->extents.height));
     } else if (action == DO_SHADING) {
+	CGContextConcatCTM (surface->cgContext, surface->sourceTransform);
 	CGContextDrawShading (surface->cgContext, surface->sourceShading);
     } else if (action == DO_IMAGE || action == DO_TILED_IMAGE) {
 	CGContextSaveGState (surface->cgContext);
 
-	CGContextConcatCTM (surface->cgContext, surface->sourceImageTransform);
+	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);
 	CGContextRestoreGState (surface->cgContext);
@@ -1280,16 +1586,17 @@ static cairo_int_status_t
 			     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;
     cairo_box_t box;
+    CGPathRef path_for_unbounded = NULL;
 
     ND((stderr, "%p _cairo_quartz_surface_fill op %d source->type %d\n", surface, op, source->type));
 
     if (IS_EMPTY(surface))
 	return CAIRO_STATUS_SUCCESS;
 
     if (op == CAIRO_OPERATOR_DEST)
 	return CAIRO_STATUS_SUCCESS;
@@ -1314,88 +1621,104 @@ static cairo_int_status_t
     CGContextBeginPath (surface->cgContext);
 
     stroke.cgContext = surface->cgContext;
     stroke.ctm_inverse = NULL;
     rv = _cairo_quartz_cairo_path_to_quartz_context (path, &stroke);
     if (rv)
         goto BAIL;
 
+    if (!_cairo_operator_bounded_by_mask(op) && CGContextCopyPathPtr)
+	path_for_unbounded = CGContextCopyPathPtr (surface->cgContext);
+
     if (action == DO_SOLID || action == DO_PATTERN) {
 	if (fill_rule == CAIRO_FILL_RULE_WINDING)
 	    CGContextFillPath (surface->cgContext);
 	else
 	    CGContextEOFillPath (surface->cgContext);
     } else if (action == DO_SHADING) {
 
 	// we have to clip and then paint the shading; we can't fill
 	// with the shading
 	if (fill_rule == CAIRO_FILL_RULE_WINDING)
 	    CGContextClip (surface->cgContext);
 	else
 	    CGContextEOClip (surface->cgContext);
 
+	CGContextConcatCTM (surface->cgContext, surface->sourceTransform);
 	CGContextDrawShading (surface->cgContext, surface->sourceShading);
     } else if (action == DO_IMAGE || action == DO_TILED_IMAGE) {
 	if (fill_rule == CAIRO_FILL_RULE_WINDING)
 	    CGContextClip (surface->cgContext);
 	else
 	    CGContextEOClip (surface->cgContext);
 
-	CGContextConcatCTM (surface->cgContext, surface->sourceImageTransform);
+	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_NOTHING) {
 	rv = CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
   BAIL:
     _cairo_quartz_teardown_source (surface, source);
 
     CGContextRestoreGState (surface->cgContext);
 
+    if (path_for_unbounded) {
+	unbounded_op_data_t ub;
+	ub.op = UNBOUNDED_STROKE_FILL;
+	ub.u.stroke_fill.cgPath = path_for_unbounded;
+	ub.u.stroke_fill.fill_rule = fill_rule;
+
+	_cairo_quartz_fixup_unbounded_operation (surface, &ub, antialias);
+	CGPathRelease (path_for_unbounded);
+    }
+
     ND((stderr, "-- fill\n"));
     return rv;
 }
 
 static cairo_int_status_t
 _cairo_quartz_surface_stroke (void *abstract_surface,
-			       cairo_operator_t op,
-			       cairo_pattern_t *source,
-			       cairo_path_fixed_t *path,
-			       cairo_stroke_style_t *style,
-			       cairo_matrix_t *ctm,
-			       cairo_matrix_t *ctm_inverse,
-			       double tolerance,
-			       cairo_antialias_t antialias)
+			      cairo_operator_t op,
+			      cairo_pattern_t *source,
+			      cairo_path_fixed_t *path,
+			      cairo_stroke_style_t *style,
+			      cairo_matrix_t *ctm,
+			      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;
+    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)
 	return CAIRO_STATUS_SUCCESS;
 
     CGContextSaveGState (surface->cgContext);
 
-    // Turning antialiasing off causes misrendering with
-    // single-pixel lines (e.g. 20,10.5 -> 21,10.5 end up being rendered as 2 pixels)
-    //CGContextSetShouldAntialias (surface->cgContext, (antialias != CAIRO_ANTIALIAS_NONE));
+    // 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);
     _cairo_quartz_cairo_matrix_to_quartz (ctm, &strokeTransform);
     CGContextConcatCTM (surface->cgContext, strokeTransform);
 
     if (style->dash && style->num_dashes) {
@@ -1427,71 +1750,106 @@ static cairo_int_status_t
     CGContextBeginPath (surface->cgContext);
 
     stroke.cgContext = surface->cgContext;
     stroke.ctm_inverse = ctm_inverse;
     rv = _cairo_quartz_cairo_path_to_quartz_context (path, &stroke);
     if (rv)
 	goto BAIL;
 
+    if (!_cairo_operator_bounded_by_mask (op) && CGContextCopyPathPtr)
+	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);
 
-	CGContextConcatCTM (surface->cgContext, surface->sourceImageTransform);
+	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);
 
+	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);
 
     CGContextRestoreGState (surface->cgContext);
 
+    if (path_for_unbounded) {
+	unbounded_op_data_t ub;
+
+	CGContextBeginPath (surface->cgContext);
+
+	/* recreate the stroke state, but without the CTM, as it's been already baked
+	 * into the path.
+	 */
+	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);
+
+	CGContextAddPath (surface->cgContext, path_for_unbounded);
+	CGPathRelease (path_for_unbounded);
+
+	CGContextReplacePathWithStrokedPath (surface->cgContext);
+	path_for_unbounded = CGContextCopyPathPtr (surface->cgContext);
+
+	ub.op = UNBOUNDED_STROKE_FILL;
+	ub.u.stroke_fill.cgPath = path_for_unbounded;
+	ub.u.stroke_fill.fill_rule = CAIRO_FILL_RULE_WINDING;
+
+	_cairo_quartz_fixup_unbounded_operation (surface, &ub, antialias);
+
+	CGPathRelease (path_for_unbounded);
+    }
+
     ND((stderr, "-- stroke\n"));
     return rv;
 }
 
 #if CAIRO_HAS_ATSUI_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)
+				   cairo_operator_t op,
+				   cairo_pattern_t *source,
+				   cairo_glyph_t *glyphs,
+				   int num_glyphs,
+				   cairo_scaled_font_t *scaled_font)
 {
-    CGAffineTransform cairoTextTransform, textTransform, ctm;
-    // XXXtodo/perf: stack storage for glyphs/sizes
+    CGAffineTransform textTransform, ctm;
 #define STATIC_BUF_SIZE 64
     CGGlyph glyphs_static[STATIC_BUF_SIZE];
     CGSize cg_advances_static[STATIC_BUF_SIZE];
     CGGlyph *cg_glyphs = &glyphs_static[0];
     CGSize *cg_advances = &cg_advances_static[0];
 
     cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
     cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
     cairo_quartz_action_t action;
     float xprev, yprev;
     int i;
-    CGFontRef cgfref;
+    CGFontRef cgfref = NULL;
+
+    cairo_bool_t isClipping = FALSE;
+    cairo_bool_t didForceFontSmoothing = TRUE;
 
     if (IS_EMPTY(surface))
 	return CAIRO_STATUS_SUCCESS;
 
     if (num_glyphs <= 0)
 	return CAIRO_STATUS_SUCCESS;
 
     if (op == CAIRO_OPERATOR_DEST)
@@ -1502,122 +1860,175 @@ static cairo_int_status_t
 
     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) {
 	CGContextSetTextDrawingMode (surface->cgContext, kCGTextClip);
+	isClipping = TRUE;
     } else {
 	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);
     CGContextSetFont (surface->cgContext, cgfref);
-
-    /* So this should include the size; I don't know if I need to extract the
-     * size from this and call CGContextSetFontSize.. will I get crappy hinting
-     * with this 1.0 size business?  Or will CG just multiply that size into the
-     * text matrix?
-     */
-    //ND((stderr, "show_glyphs: glyph 0 at: %f, %f\n", glyphs[0].x, glyphs[0].y));
-    cairoTextTransform = CGAffineTransformMake (scaled_font->font_matrix.xx,
-						scaled_font->font_matrix.yx,
-						scaled_font->font_matrix.xy,
-						scaled_font->font_matrix.yy,
-						0., 0.);
-
-    textTransform = CGAffineTransformMakeTranslation (glyphs[0].x, glyphs[0].y);
-    textTransform = CGAffineTransformScale (textTransform, 1.0, -1.0);
-    textTransform = CGAffineTransformConcat (cairoTextTransform, textTransform);
-
-    ctm = CGAffineTransformMake (scaled_font->ctm.xx,
-				 -scaled_font->ctm.yx,
-				 -scaled_font->ctm.xy,
-				 scaled_font->ctm.yy,
-				 0., 0.);
-    textTransform = CGAffineTransformConcat (ctm, textTransform);
-
-    CGContextSetTextMatrix (surface->cgContext, textTransform);
     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;
+	}
+    }
+
     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;
 	}
 
 	cg_advances = (CGSize*) _cairo_malloc_ab (num_glyphs, sizeof(CGSize));
 	if (cg_advances == NULL) {
 	    rv = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto BAIL;
 	}
     }
 
+    textTransform = CGAffineTransformMake (scaled_font->font_matrix.xx,
+					   scaled_font->font_matrix.yx,
+					   scaled_font->font_matrix.xy,
+					   scaled_font->font_matrix.yy,
+					   0., 0.);
+    textTransform = CGAffineTransformScale (textTransform, 1.0, -1.0);
+    textTransform = CGAffineTransformConcat (CGAffineTransformMake(scaled_font->ctm.xx,
+								   -scaled_font->ctm.yx,
+								   -scaled_font->ctm.xy,
+								   scaled_font->ctm.yy,
+								   0., 0.),
+					     textTransform);
+
+    CGContextSetTextMatrix (surface->cgContext, textTransform);
+
+    /* Convert our glyph positions to glyph advances.  We need n-1 advances,
+     * since the advance at index 0 is applied after glyph 0. */
     xprev = glyphs[0].x;
     yprev = glyphs[0].y;
 
     cg_glyphs[0] = glyphs[0].index;
-    cg_advances[0].width = 0;
-    cg_advances[0].height = 0;
 
     for (i = 1; i < num_glyphs; i++) {
 	float xf = glyphs[i].x;
 	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. */
+	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));
     }
 #endif
 
+    /* Translate to the first glyph's position before drawing */
+    ctm = CGContextGetCTM (surface->cgContext);
+    CGContextTranslateCTM (surface->cgContext, glyphs[0].x, glyphs[0].y);
+
     CGContextShowGlyphsWithAdvances (surface->cgContext,
 				     cg_glyphs,
 				     cg_advances,
 				     num_glyphs);
 
+    CGContextSetCTM (surface->cgContext, ctm);
+
     if (action == DO_IMAGE || action == DO_TILED_IMAGE) {
-	CGContextConcatCTM (surface->cgContext, surface->sourceImageTransform);
+	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) {
+	CGContextConcatCTM (surface->cgContext, surface->sourceTransform);
 	CGContextDrawShading (surface->cgContext, surface->sourceShading);
     }
 
 BAIL:
+    _cairo_quartz_teardown_source (surface, source);
+
+    if (didForceFontSmoothing)
+	CGContextSetAllowsFontSmoothingPtr (surface->cgContext, FALSE);
+
+    CGContextRestoreGState (surface->cgContext);
+
+    if (rv == CAIRO_STATUS_SUCCESS &&
+	cgfref &&
+	!_cairo_operator_bounded_by_mask (op))
+    {
+	unbounded_op_data_t ub;
+	ub.op = UNBOUNDED_SHOW_GLYPHS;
+
+	ub.u.show_glyphs.isClipping = isClipping;
+	ub.u.show_glyphs.cg_glyphs = cg_glyphs;
+	ub.u.show_glyphs.cg_advances = cg_advances;
+	ub.u.show_glyphs.nglyphs = num_glyphs;
+	ub.u.show_glyphs.textTransform = textTransform;
+	ub.u.show_glyphs.font = cgfref;
+	ub.u.show_glyphs.origin = CGPointMake (glyphs[0].x, glyphs[0].y);
+
+	_cairo_quartz_fixup_unbounded_operation (surface, &ub, scaled_font->options.antialias);
+    }
+
+
     if (cg_advances != &cg_advances_static[0]) {
 	free (cg_advances);
     }
 
     if (cg_glyphs != &glyphs_static[0]) {
 	free (cg_glyphs);
     }
 
-    _cairo_quartz_teardown_source (surface, source);
-
-    CGContextRestoreGState (surface->cgContext);
-
     return rv;
 }
 #endif /* CAIRO_HAS_ATSUI_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,
@@ -1659,16 +2070,25 @@ static cairo_int_status_t
 
     CGContextClipToMaskPtr (surface->cgContext, rect, img);
 
     CGContextSetCTM (surface->cgContext, ctm);
 
     status = _cairo_quartz_surface_paint (surface, op, source);
 
     CGContextRestoreGState (surface->cgContext);
+
+    if (!_cairo_operator_bounded_by_mask (op)) {
+	unbounded_op_data_t ub;
+	ub.op = UNBOUNDED_MASK;
+	ub.u.mask.mask = img;
+	ub.u.mask.maskTransform = CGAffineTransformInvert(mask_matrix);
+	_cairo_quartz_fixup_unbounded_operation (surface, &ub, CAIRO_ANTIALIAS_NONE);
+    }
+
     CGImageRelease (img);
   BAIL:
     return status;
 }
 
 /* This is somewhat less than ideal, but it gets the job done;
  * it would be better to avoid calling back into cairo.  This
  * creates a temporary surface to use as the mask.
@@ -1785,16 +2205,18 @@ static cairo_int_status_t
 	 */
 	CGContextRestoreGState (surface->cgContext);
 	CGContextSaveGState (surface->cgContext);
     } else {
 	CGContextBeginPath (surface->cgContext);
 	stroke.cgContext = surface->cgContext;
 	stroke.ctm_inverse = NULL;
 
+	CGContextSetShouldAntialias (surface->cgContext, (antialias != CAIRO_ANTIALIAS_NONE));
+
 	/* path must not be empty. */
 	CGContextMoveToPoint (surface->cgContext, 0, 0);
 	status = _cairo_quartz_cairo_path_to_quartz_context (path, &stroke);
 	if (status)
 	    return status;
 
 	if (fill_rule == CAIRO_FILL_RULE_WINDING)
 	    CGContextClip (surface->cgContext);
@@ -1976,26 +2398,33 @@ cairo_quartz_surface_create (cairo_forma
     if (!_cairo_quartz_verify_surface_size(width, height))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
     if (width == 0 || height == 0) {
 	return (cairo_surface_t*) _cairo_quartz_surface_create_internal (NULL, _cairo_content_from_format (format),
 									 width, height);
     }
 
-    if (format == CAIRO_FORMAT_ARGB32) {
+    if (format == CAIRO_FORMAT_ARGB32 ||
+	format == CAIRO_FORMAT_RGB24)
+    {
 	cgColorspace = CGColorSpaceCreateDeviceRGB();
-	stride = width * 4;
-	bitinfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
+	bitinfo = kCGBitmapByteOrder32Host;
+	if (format == CAIRO_FORMAT_ARGB32)
+	    bitinfo |= kCGImageAlphaPremultipliedFirst;
+	else
+	    bitinfo |= kCGImageAlphaNoneSkipFirst;
 	bitsPerComponent = 8;
-    } else if (format == CAIRO_FORMAT_RGB24) {
-	cgColorspace = CGColorSpaceCreateDeviceRGB();
+
+	/* The Apple docs say that for best performance, the stride and the data
+	 * pointer should be 16-byte aligned.  malloc already aligns to 16-bytes,
+	 * so we don't have to anything special on allocation.
+	 */
 	stride = width * 4;
-	bitinfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
-	bitsPerComponent = 8;
+	stride += (16 - (stride & 15)) & 15;
     } else if (format == CAIRO_FORMAT_A8) {
 	cgColorspace = CGColorSpaceCreateDeviceGray();
 	if (width % 4 == 0)
 	    stride = width;
 	else
 	    stride = (width & ~3) + 4;
 	bitinfo = kCGImageAlphaNone;
 	bitsPerComponent = 8;
@@ -2118,40 +2547,36 @@ void ExportCGImageToPNGFile(CGImageRef i
 	    // remember to close the component
 	    CloseComponent(grex);
 	}
 
 	// remember to dispose of the data reference handle
 	DisposeHandle(dataRef);
     }
 }
-#endif
 
 void
 quartz_image_to_png (CGImageRef imgref, char *dest)
 {
-#if 0
     static int sctr = 0;
     char sptr[] = "/Users/vladimir/Desktop/barXXXXX.png";
 
     if (dest == NULL) {
 	fprintf (stderr, "** Writing %p to bar%d\n", imgref, sctr);
 	sprintf (sptr, "/Users/vladimir/Desktop/bar%d.png", sctr);
 	sctr++;
 	dest = sptr;
     }
 
     ExportCGImageToPNGFile(imgref, dest);
-#endif
 }
 
 void
 quartz_surface_to_png (cairo_quartz_surface_t *nq, char *dest)
 {
-#if 0
     static int sctr = 0;
     char sptr[] = "/Users/vladimir/Desktop/fooXXXXX.png";
 
     if (nq->base.type != CAIRO_SURFACE_TYPE_QUARTZ) {
 	fprintf (stderr, "** quartz_surface_to_png: surface %p isn't quartz!\n", nq);
 	return;
     }
 
@@ -2166,10 +2591,11 @@ quartz_surface_to_png (cairo_quartz_surf
     if (imgref == NULL) {
 	fprintf (stderr, "quartz surface at %p is not a bitmap context!\n", nq);
 	return;
     }
 
     ExportCGImageToPNGFile(imgref, dest);
 
     CGImageRelease(imgref);
-#endif
 }
+
+#endif /* QUARTZ_DEBUG */
--- a/gfx/cairo/cairo/src/cairo-quartz.h
+++ b/gfx/cairo/cairo/src/cairo-quartz.h
@@ -52,21 +52,15 @@ cairo_quartz_surface_create (cairo_forma
 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);
 
-cairo_public cairo_surface_t *
-cairo_quartz_image_surface_create (cairo_surface_t *image_surface);
-
-cairo_public cairo_surface_t *
-cairo_quartz_image_surface_get_image (cairo_surface_t *surface);
-
 CAIRO_END_DECLS
 
 #else  /* CAIRO_HAS_QUARTZ_SURFACE */
 # 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-scaled-font-subsets.c
+++ b/gfx/cairo/cairo/src/cairo-scaled-font-subsets.c
@@ -35,16 +35,17 @@
  *
  * Contributor(s):
  *	Carl D. Worth <cworth@cworth.org>
  *	Kristian Høgsberg <krh@redhat.com>
  *	Keith Packard <keithp@keithp.com>
  *	Adrian Johnson <ajohnson@redneon.com>
  */
 
+#define _BSD_SOURCE /* for snprintf(), strdup() */
 #include "cairoint.h"
 #include "cairo-scaled-font-subsets-private.h"
 
 #define MAX_GLYPHS_PER_SIMPLE_FONT 256
 #define MAX_GLYPHS_PER_COMPOSITE_FONT 65536
 
 typedef enum {
     CAIRO_SUBSETS_SCALED,
--- a/gfx/cairo/cairo/src/cairo-svg-surface.c
+++ b/gfx/cairo/cairo/src/cairo-svg-surface.c
@@ -30,20 +30,21 @@
  *
  * The Original Code is the cairo graphics library.
  *
  * The Initial Developer of the Original Code is University of Southern
  * California.
  *
  * Contributor(s):
  *	Kristian Høgsberg <krh@redhat.com>
- * 	Emmanuel Pacaud <emmanuel.pacaud@free.fr>
+ *	Emmanuel Pacaud <emmanuel.pacaud@free.fr>
  *	Carl Worth <cworth@cworth.org>
  */
 
+#define _BSD_SOURCE /* for snprintf() */
 #include "cairoint.h"
 #include "cairo-svg.h"
 #include "cairo-svg-surface-private.h"
 #include "cairo-path-fixed-private.h"
 #include "cairo-meta-surface-private.h"
 #include "cairo-paginated-private.h"
 #include "cairo-scaled-font-subsets-private.h"
 #include "cairo-output-stream-private.h"
--- a/gfx/cairo/cairo/src/cairo-truetype-subset.c
+++ b/gfx/cairo/cairo/src/cairo-truetype-subset.c
@@ -29,16 +29,17 @@
  *
  * The Initial Developer of the Original Code is Red Hat, Inc.
  *
  * Contributor(s):
  *	Kristian Høgsberg <krh@redhat.com>
  *	Adrian Johnson <ajohnson@redneon.com>
  */
 
+#define _BSD_SOURCE /* for snprintf(), strdup() */
 #include "cairoint.h"
 
 #include "cairo-scaled-font-subsets-private.h"
 #include "cairo-truetype-subset-private.h"
 
 
 typedef struct subset_glyph subset_glyph_t;
 struct subset_glyph {
@@ -219,17 +220,17 @@ static cairo_status_t
      * name table. If the mac/roman font name is not found a
      * CairoFont-x-y name is created.
      */
     font->base.base_font = NULL;
     for (i = 0; i < be16_to_cpu(name->num_records); i++) {
         record = &(name->records[i]);
         if ((be16_to_cpu (record->platform) == 1) &&
             (be16_to_cpu (record->encoding) == 0) &&
-            (be16_to_cpu (record->name) == 4)) { 
+            (be16_to_cpu (record->name) == 4)) {
             font->base.base_font = malloc (be16_to_cpu(record->length) + 1);
             if (font->base.base_font) {
                 strncpy(font->base.base_font,
                         ((char*)name) + be16_to_cpu (name->strings_offset) + be16_to_cpu (record->offset),
                         be16_to_cpu (record->length));
                 font->base.base_font[be16_to_cpu (record->length)] = 0;
             }
             break;
@@ -286,17 +287,17 @@ static cairo_status_t
     free (font->glyphs);
  fail1:
     _cairo_array_fini (&font->output);
     free (font);
  fail0:
     if (name)
 	free (name);
 
-    return _cairo_error (status);
+    return status;
 }
 
 static void
 cairo_truetype_font_destroy (cairo_truetype_font_t *font)
 {
     _cairo_array_fini (&font->string_offsets);
     free (font->base.widths);
     free (font->base.base_font);
@@ -1116,19 +1117,16 @@ cairo_status_t
     free (truetype_subset->data);
  fail3:
     free (truetype_subset->widths);
  fail2:
     free (truetype_subset->base_font);
  fail1:
     cairo_truetype_font_destroy (font);
 
-    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-	status = _cairo_error (status);
-
     return status;
 }
 
 void
 _cairo_truetype_subset_fini (cairo_truetype_subset_t *subset)
 {
     free (subset->base_font);
     free (subset->widths);
--- a/gfx/cairo/cairo/src/cairo-type1-fallback.c
+++ b/gfx/cairo/cairo/src/cairo-type1-fallback.c
@@ -28,16 +28,17 @@
  * The Original Code is the cairo graphics library.
  *
  * The Initial Developer of the Original Code is Red Hat, Inc.
  *
  * Contributor(s):
  *	Adrian Johnson <ajohnson@redneon.com>
  */
 
+#define _BSD_SOURCE /* for snprintf(), strdup() */
 #include "cairoint.h"
 #include "cairo-type1-private.h"
 #include "cairo-scaled-font-subsets-private.h"
 #include "cairo-path-fixed-private.h"
 #include "cairo-output-stream-private.h"
 
 typedef enum {
     CAIRO_CHARSTRING_TYPE1,
@@ -73,16 +74,17 @@ cairo_type1_font_create (cairo_scaled_fo
                          cairo_type1_font_t         **subset_return,
                          cairo_bool_t                 hex_encode)
 {
     cairo_type1_font_t *font;
     cairo_font_face_t *font_face;
     cairo_matrix_t font_matrix;
     cairo_matrix_t ctm;
     cairo_font_options_t font_options;
+    cairo_status_t status;
 
     font = calloc (1, sizeof (cairo_type1_font_t));
     if (font == NULL)
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     font->widths = calloc (scaled_font_subset->num_glyphs,
                            sizeof (int));
     if (font->widths == NULL) {
@@ -101,31 +103,32 @@ cairo_type1_font_create (cairo_scaled_fo
     _cairo_font_options_init_default (&font_options);
     cairo_font_options_set_hint_style (&font_options, CAIRO_HINT_STYLE_NONE);
     cairo_font_options_set_hint_metrics (&font_options, CAIRO_HINT_METRICS_OFF);
 
     font->type1_scaled_font = cairo_scaled_font_create (font_face,
 							&font_matrix,
 							&ctm,
 							&font_options);
-    if (font->type1_scaled_font->status)
+    status = font->type1_scaled_font->status;
+    if (status)
         goto fail;
 
     _cairo_array_init (&font->contents, sizeof (unsigned char));
     font->output = NULL;
 
     *subset_return = font;
 
     return CAIRO_STATUS_SUCCESS;
 
 fail:
     free (font->widths);
     free (font);
 
-    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    return status;
 }
 
 /* Charstring commands. If the high byte is 0 the command is encoded
  * with a single byte. */
 #define CHARSTRING_sbw        0x0c07
 #define CHARSTRING_rmoveto    0x0015
 #define CHARSTRING_rlineto    0x0005
 #define CHARSTRING_rcurveto   0x0008
@@ -339,19 +342,19 @@ create_notdef_charstring (cairo_array_t 
     status = _cairo_array_grow_by (data, 10);
     if (status)
         return status;
 
     if (type == CAIRO_CHARSTRING_TYPE1) {
         charstring_encode_integer (data, 0, type);
         charstring_encode_integer (data, 0, type);
 
-        /* The width and height is arbitrary. */
+        /* The width is arbitrary. */
         charstring_encode_integer (data, 500, type);
-        charstring_encode_integer (data, 500, type);
+        charstring_encode_integer (data, 0, type);
         charstring_encode_command (data, CHARSTRING_sbw);
     }
 
     charstring_encode_command (data, CHARSTRING_endchar);
 
     return CAIRO_STATUS_SUCCESS;
 }
 
@@ -396,18 +399,18 @@ cairo_type1_font_create_charstring (cair
 
     status = _cairo_array_grow_by (data, 30);
     if (status)
         return status;
 
     if (type == CAIRO_CHARSTRING_TYPE1) {
         charstring_encode_integer (data, (int) scaled_glyph->metrics.x_bearing, type);
         charstring_encode_integer (data, (int) scaled_glyph->metrics.y_bearing, type);
-        charstring_encode_integer (data, (int) scaled_glyph->metrics.width, type);
-        charstring_encode_integer (data, (int) scaled_glyph->metrics.height, type);
+        charstring_encode_integer (data, (int) scaled_glyph->metrics.x_advance, type);
+        charstring_encode_integer (data, (int) scaled_glyph->metrics.y_advance, type);
         charstring_encode_command (data, CHARSTRING_sbw);
 
         path_info.current_x = (int) scaled_glyph->metrics.x_bearing;
         path_info.current_y = (int) scaled_glyph->metrics.y_bearing;
     } else {
         charstring_encode_integer (data, (int) scaled_glyph->metrics.width, type);
 
         path_info.current_x = 0;
@@ -790,17 +793,17 @@ static cairo_status_t
  fail3:
     free (type1_subset->widths);
  fail2:
     free (type1_subset->base_font);
  fail1:
     /* status is already set, ignore further errors */
     cairo_type1_font_destroy (font);
 
-    return _cairo_error (status);
+    return status;
 }
 
 cairo_status_t
 _cairo_type1_fallback_init_binary (cairo_type1_subset_t	      *type1_subset,
                                    const char		      *name,
                                    cairo_scaled_font_subset_t *scaled_font_subset)
 {
     return _cairo_type1_fallback_init_internal (type1_subset,
@@ -881,17 +884,17 @@ cairo_status_t
 
     return cairo_type1_font_destroy (font);
 
 fail2:
     _cairo_array_fini (&charstring);
     _cairo_type2_charstrings_fini (type2_subset);
 fail1:
     cairo_type1_font_destroy (font);
-    return _cairo_error (status);
+    return status;
 }
 
 void
 _cairo_type2_charstrings_fini (cairo_type2_charstrings_t *type2_subset)
 {
     unsigned int i, num_charstrings;
     cairo_array_t *charstring;
 
--- a/gfx/cairo/cairo/src/cairo-type1-subset.c
+++ b/gfx/cairo/cairo/src/cairo-type1-subset.c
@@ -28,16 +28,17 @@
  * The Original Code is the cairo graphics library.
  *
  * The Initial Developer of the Original Code is Red Hat, Inc.
  *
  * Contributor(s):
  *	Kristian Høgsberg <krh@redhat.com>
  */
 
+#define _BSD_SOURCE /* for snprintf(), strdup() */
 #include "cairoint.h"
 #include "cairo-type1-private.h"
 #include "cairo-scaled-font-subsets-private.h"
 #include "cairo-output-stream-private.h"
 
 /* XXX: Eventually, we need to handle other font backends */
 #include "cairo-ft-private.h"
 
--- a/gfx/cairo/cairo/src/cairo-types-private.h
+++ b/gfx/cairo/cairo/src/cairo-types-private.h
@@ -308,9 +308,16 @@ typedef struct _cairo_format_masks {
 } cairo_format_masks_t;
 
 typedef enum {
     CAIRO_STOCK_WHITE,
     CAIRO_STOCK_BLACK,
     CAIRO_STOCK_TRANSPARENT
 } cairo_stock_t;
 
+typedef enum _cairo_image_transparency {
+    CAIRO_IMAGE_IS_OPAQUE,
+    CAIRO_IMAGE_HAS_BILEVEL_ALPHA,
+    CAIRO_IMAGE_HAS_ALPHA,
+    CAIRO_IMAGE_UNKNOWN
+} cairo_image_transparency_t;
+
 #endif /* CAIRO_TYPES_PRIVATE_H */
--- a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
+++ b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
@@ -1157,17 +1157,17 @@ static cairo_int_status_t
 	dash_array = calloc (sizeof (DWORD), style->num_dashes);
 	for (i = 0; i < style->num_dashes; i++) {
 	    dash_array[i] = (DWORD) (scale * style->dash[i]);
 	}
     } else {
 	pen_style |= PS_SOLID;
     }
 
-    SetMiterLimit (surface->dc, (FLOAT) (scale * style->miter_limit), NULL);
+    SetMiterLimit (surface->dc, (FLOAT) (style->miter_limit), NULL);
     if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
 	cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) source;
 
 
 	color = _cairo_win32_printing_surface_flatten_transparency (surface,
 								    &solid->color);
     } else {
 	/* Color not used as the pen will only be used by WidenPath() */
--- a/gfx/cairo/cairo/src/cairo-win32-surface.c
+++ b/gfx/cairo/cairo/src/cairo-win32-surface.c
@@ -381,19 +381,29 @@ static cairo_surface_t *
 					      int	     width,
 					      int	     height,
 					      cairo_bool_t   force_dib)
 {
     cairo_win32_surface_t *src = abstract_src;
     cairo_format_t format = _cairo_format_from_content (content);
     cairo_win32_surface_t *new_surf;
 
-    /* if the parent is a DIB or if we need alpha, then
-     * we have to create a dib */
-    if (force_dib || src->is_dib || (content & CAIRO_CONTENT_ALPHA)) {
+    /* We force a DIB always if:
+     * - we need alpha; or
+     * - the parent is a DIB; or
+     * - the parent is for printing (because we don't care about the bit depth at that point)
+     */
+    if (src->is_dib ||
+	(content & CAIRO_CONTENT_ALPHA) ||
+	src->base.backend->type == CAIRO_SURFACE_TYPE_WIN32_PRINTING)
+    {
+	force_dib = TRUE;
+    }
+
+    if (force_dib) {
 	new_surf = (cairo_win32_surface_t*)
 	    _cairo_win32_surface_create_for_dc (src->dc, format, width, height);
     } else {
 	/* otherwise, create a ddb */
 	HBITMAP ddb = CreateCompatibleBitmap (src->dc, width, height);
 	HDC ddb_dc = CreateCompatibleDC (src->dc);
 	HBITMAP saved_dc_bitmap;
 
@@ -1673,17 +1683,17 @@ cairo_int_status_t
 
 /**
  * cairo_win32_surface_create:
  * @hdc: the DC to create a surface for
  *
  * Creates a cairo surface that targets the given DC.  The DC will be
  * queried for its initial clip extents, and this will be used as the
  * size of the cairo surface.  The resulting surface will always be of
- * format CAIRO_FORMAT_RGB24; should you need another surface format,
+ * format %CAIRO_FORMAT_RGB24; should you need another surface format,
  * you will need to create one through
  * cairo_win32_surface_create_with_dib().
  *
  * Return value: the newly created surface
  **/
 cairo_surface_t *
 cairo_win32_surface_create (HDC hdc)
 {
--- a/gfx/cairo/cairo/src/cairo-xlib-display.c
+++ b/gfx/cairo/cairo/src/cairo-xlib-display.c
@@ -265,16 +265,17 @@ cairo_xlib_display_t *
      * on in our close_display hook are properly initialized before we
      * add our hook. For now, that means Render, so we call into its
      * QueryVersion function to ensure it gets initialized.
      */
     XRenderQueryVersion (dpy, &major_unused, &minor_unused);
 
     codes = XAddExtension (dpy);
     if (codes == NULL) {
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	free (display);
 	display = NULL;
 	goto UNLOCK;
     }
 
     XESetCloseDisplay (dpy, codes->extension, _cairo_xlib_close_display);
 
     _cairo_freelist_init (&display->wq_freelist, sizeof (cairo_xlib_job_t));
--- a/gfx/cairo/cairo/src/cairo-xlib-surface.c
+++ b/gfx/cairo/cairo/src/cairo-xlib-surface.c
@@ -461,16 +461,17 @@ static cairo_status_t
 		    cairo_image_surface_t  **image_out,
 		    cairo_rectangle_int_t   *image_rect)
 {
     cairo_image_surface_t *image;
     XImage *ximage;
     short x1, y1, x2, y2;
     cairo_format_masks_t masks;
     pixman_format_code_t pixman_format;
+    cairo_status_t status;
 
     x1 = 0;
     y1 = 0;
     x2 = surface->width;
     y2 = surface->height;
 
     if (interest_rect) {
 	cairo_rectangle_int_t rect;
@@ -601,30 +602,29 @@ static cairo_status_t
 
     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);
-    if (image->base.status)
-	goto FAIL;
+    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;
-
- FAIL:
-    XDestroyImage (ximage);
-    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 }
 
 static void
 _cairo_xlib_surface_ensure_src_picture (cairo_xlib_surface_t    *surface)
 {
     if (!surface->src_picture)
     {
 	XRenderPictureAttributes pa;
--- a/gfx/cairo/cairo/src/cairoint.h
+++ b/gfx/cairo/cairo/src/cairoint.h
@@ -710,16 +710,17 @@ struct _cairo_surface_backend {
 struct _cairo_image_surface {
     cairo_surface_t base;
 
     pixman_format_code_t pixman_format;
     cairo_format_t format;
     unsigned char *data;
     cairo_bool_t owns_data;
     cairo_bool_t has_clip;
+    cairo_image_transparency_t transparency;
 
     int width;
     int height;
     int stride;
     int depth;
 
     pixman_image_t *pixman_image;
 };
@@ -1905,16 +1906,19 @@ cairo_private void
 cairo_private cairo_int_status_t
 _cairo_image_surface_set_clip_region (void *abstract_surface,
 				      cairo_region_t *region);
 
 cairo_private cairo_image_surface_t *
 _cairo_image_surface_clone (cairo_image_surface_t	*surface,
 			    cairo_format_t		 format);
 
+cairo_private cairo_image_transparency_t
+_cairo_image_analyze_transparency (cairo_image_surface_t      *image);
+
 cairo_private cairo_bool_t
 _cairo_surface_is_image (const cairo_surface_t *surface);
 
 cairo_private cairo_bool_t
 _cairo_surface_is_meta (const cairo_surface_t *surface);
 
 /* cairo_pen.c */
 cairo_private cairo_status_t
@@ -2246,16 +2250,17 @@ slim_hidden_proto (cairo_font_options_se
 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_height);
 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);
 slim_hidden_proto (cairo_matrix_init_translate);
 slim_hidden_proto (cairo_matrix_invert);
--- a/gfx/cairo/libpixman/src/Makefile.in
+++ b/gfx/cairo/libpixman/src/Makefile.in
@@ -60,47 +60,57 @@ MODULE_OPTIMIZE_FLAGS = -xO5
 endif
 ifeq ($(OS_ARCH),WINNT)
 # FIXME: bug 413019
 OS_COMPILE_CFLAGS += -GL-
 MODULE_OPTIMIZE_FLAGS = -O2
 endif
 endif
 
+# Build MMX code either with VC or with gcc-on-x86
+ifdef _MSC_VER
+USE_MMX=1
+MMX_CFLAGS=
+endif
+
+ifdef GNU_CC
+ifeq (86,$(findstring 86,$(OS_TEST)))
+USE_MMX=1
+MMX_CFLAGS=-mmmx -msse -Winline --param inline-unit-growth=10000 --param large-function-growth=10000
+endif
+endif
+
+
 CSRCS	= \
 	pixman-compose.c \
 	pixman-compose-accessors.c \
 	pixman-compute-region.c \
 	pixman-edge.c \
 	pixman-edge-accessors.c \
 	pixman-image.c \
 	pixman-pict.c \
 	pixman-region.c \
 	pixman-trap.c \
 	pixman-utils.c \
 	$(NULL)
 
-ifdef MOZ_X11
-#CSRCS   += pixman-mmx.c
-#DEFINES += -DUSE_MMX
-endif
-
-ifdef _MSC_VER
-#CSRCS   += pixman-mmx.c
-#DEFINES += -DUSE_MMX
+ifdef USE_MMX
+CSRCS += pixman-mmx.c
+DEFINES += -DUSE_MMX
 endif
 
 EXPORTS		= pixman.h pixman-remap.h
 
 LOCAL_INCLUDES	+= -I$(srcdir) -I$(srcdir)/../../cairo/src
 
 FORCE_STATIC_LIB = 1
 # This library is used by other shared libs in a static build
 FORCE_USE_PIC = 1
 
 include $(topsrcdir)/config/rules.mk
 
 CFLAGS += -DPACKAGE="mozpixman" -D_USE_MATH_DEFINES
 
-ifdef MOZ_X11
-#CFLAGS  += -mmmx -msse -Winline --param inline-unit-growth=10000 --param large-function-growth=10000
-endif
-
+# special rule for pixman-mmx to get the right cflags
+pixman-mmx.$(OBJ_SUFFIX): pixman-mmx.c Makefile Makefile.in
+	$(REPORT_BUILD)
+	@$(MAKE_DEPS_AUTO_CC)
+	$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(MMX_CFLAGS) $(_VPATH_SRCS)
--- a/gfx/cairo/libpixman/src/pixman-compose.c
+++ b/gfx/cairo/libpixman/src/pixman-compose.c
@@ -4077,17 +4077,17 @@ fbFetchTransformed_Bilinear_General(bits
         v.vector[1] += unit.vector[1];
         v.vector[2] += unit.vector[2];
     }
 }
 
 static void
 fbFetchTransformed_Convolution(bits_image_t * pict, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits, pixman_bool_t affine, pixman_vector_t v, pixman_vector_t unit)
 {
-    pixman_box16_t *box = NULL;
+    pixman_box16_t dummy;
     fetchPixelProc fetch;
     int i;
 
     pixman_fixed_t *params = pict->common.filter_params;
     int32_t cwidth = pixman_fixed_to_int(params[0]);
     int32_t cheight = pixman_fixed_to_int(params[1]);
     int xoff = (params[0] - pixman_fixed_1) >> 1;
     int yoff = (params[1] - pixman_fixed_1) >> 1;
@@ -4139,17 +4139,17 @@ fbFetchTransformed_Convolution(bits_imag
                                     tx = MOD (x, pict->width);
                                     break;
                                 case PIXMAN_REPEAT_PAD:
                                     tx = CLIP (x, 0, pict->width-1);
                                     break;
                                 default:
                                     tx = x;
                             }
-                            if (pixman_region_contains_point (pict->common.src_clip, tx, ty, box)) {
+                            if (pixman_region_contains_point (pict->common.src_clip, tx, ty, &dummy)) {
                                 uint32_t c = fetch(pict, tx, ty);
 
                                 srtot += Red(c) * *p;
                                 sgtot += Green(c) * *p;
                                 sbtot += Blue(c) * *p;
                                 satot += Alpha(c) * *p;
                             }
                         }
@@ -4175,33 +4175,46 @@ fbFetchTransformed_Convolution(bits_imag
         }
         v.vector[0] += unit.vector[0];
         v.vector[1] += unit.vector[1];
         v.vector[2] += unit.vector[2];
     }
 }
 
 static void
+adjust (pixman_vector_t *v, pixman_vector_t *u, pixman_fixed_t adjustment)
+{
+    int delta_v = (adjustment * v->vector[2]) >> 16;
+    int delta_u = (adjustment * u->vector[2]) >> 16;
+    
+    v->vector[0] += delta_v;
+    v->vector[1] += delta_v;
+    
+    u->vector[0] += delta_u;
+    u->vector[1] += delta_u;
+}
+
+static void
 fbFetchTransformed(bits_image_t * pict, int x, int y, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
 {
     uint32_t     *bits;
     int32_t    stride;
     pixman_vector_t v;
     pixman_vector_t unit;
     pixman_bool_t affine = TRUE;
 
     bits = pict->bits;
     stride = pict->rowstride;
 
     /* reference point is the center of the pixel */
     v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1 / 2;
     v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1 / 2;
     v.vector[2] = pixman_fixed_1;
 
-    /* when using convolution filters one might get here without a transform */
+    /* when using convolution filters or PIXMAN_REPEAT_PAD one might get here without a transform */
     if (pict->common.transform)
     {
         if (!pixman_transform_point_3d (pict->common.transform, &v))
         {
             fbFinishAccess (pict->pDrawable);
             return;
         }
         unit.vector[0] = pict->common.transform->matrix[0][0];
@@ -4211,18 +4224,24 @@ fbFetchTransformed(bits_image_t * pict, 
     }
     else
     {
         unit.vector[0] = pixman_fixed_1;
         unit.vector[1] = 0;
         unit.vector[2] = 0;
     }
 
+    /* This allows filtering code to pretend that pixels are located at integer coordinates */
+    adjust (&v, &unit, -(pixman_fixed_1 / 2));
+    
     if (pict->common.filter == PIXMAN_FILTER_NEAREST || pict->common.filter == PIXMAN_FILTER_FAST)
     {
+	/* Round down to closest integer, ensuring that 0.5 rounds to 0, not 1 */
+	adjust (&v, &unit, pixman_fixed_1 / 2 - pixman_fixed_e);
+	
         if (pict->common.repeat == PIXMAN_REPEAT_NORMAL)
         {
             fbFetchTransformed_Nearest_Normal(pict, width, buffer, mask, maskBits, affine, v, unit);
 
         }
         else if (pict->common.repeat == PIXMAN_REPEAT_PAD)
         {
             fbFetchTransformed_Nearest_Pad(pict, width, buffer, mask, maskBits, affine, v, unit);
@@ -4230,37 +4249,34 @@ fbFetchTransformed(bits_image_t * pict, 
         else
         {
             fbFetchTransformed_Nearest_General(pict, width, buffer, mask, maskBits, affine, v, unit);
         }
     } else if (pict->common.filter == PIXMAN_FILTER_BILINEAR	||
 	       pict->common.filter == PIXMAN_FILTER_GOOD	||
 	       pict->common.filter == PIXMAN_FILTER_BEST)
     {
-        /* adjust vector for maximum contribution at 0.5, 0.5 of each texel. */
-        v.vector[0] -= v.vector[2] / 2;
-        v.vector[1] -= v.vector[2] / 2;
-        unit.vector[0] -= unit.vector[2] / 2;
-        unit.vector[1] -= unit.vector[2] / 2;
-
         if (pict->common.repeat == PIXMAN_REPEAT_NORMAL)
         {
             fbFetchTransformed_Bilinear_Normal(pict, width, buffer, mask, maskBits, affine, v, unit);
         }
         else if (pict->common.repeat == PIXMAN_REPEAT_PAD)
         {
             fbFetchTransformed_Bilinear_Pad(pict, width, buffer, mask, maskBits, affine, v, unit);
         }
         else
         {
             fbFetchTransformed_Bilinear_General(pict, width, buffer, mask, maskBits, affine, v, unit);
         }
     }
     else if (pict->common.filter == PIXMAN_FILTER_CONVOLUTION)
     {
+	/* Round to closest integer, ensuring that 0.5 rounds to 0, not 1 */
+	adjust (&v, &unit, pixman_fixed_1 / 2 - pixman_fixed_e);
+	
         fbFetchTransformed_Convolution(pict, width, buffer, mask, maskBits, affine, v, unit);
     }
 
     fbFinishAccess (pict->pDrawable);
 }
 
 
 static void
@@ -4393,17 +4409,18 @@ PIXMAN_COMPOSITE_RECT_GENERAL (const FbC
 	}
 	else if ((bits->common.repeat == PIXMAN_REPEAT_NORMAL || bits->common.repeat == PIXMAN_REPEAT_PAD) &&
 		 bits->width == 1 &&
 		 bits->height == 1)
 	{
 	    fetchSrc = (scanFetchProc)fbFetchSolid;
 	    srcClass = SOURCE_IMAGE_CLASS_HORIZONTAL;
 	}
-	else if (!bits->common.transform && bits->common.filter != PIXMAN_FILTER_CONVOLUTION)
+	else if (!bits->common.transform && bits->common.filter != PIXMAN_FILTER_CONVOLUTION
+                && bits->common.repeat != PIXMAN_REPEAT_PAD)
 	{
 	    fetchSrc = (scanFetchProc)fbFetch;
 	}
 	else
 	{
 	    fetchSrc = (scanFetchProc)fbFetchTransformed;
 	}
     }
@@ -4430,17 +4447,18 @@ PIXMAN_COMPOSITE_RECT_GENERAL (const FbC
 		fetchMask = (scanFetchProc)fbFetchExternalAlpha;
 	    }
 	    else if ((bits->common.repeat == PIXMAN_REPEAT_NORMAL || bits->common.repeat == PIXMAN_REPEAT_PAD) &&
 		     bits->width == 1 && bits->height == 1)
 	    {
 		fetchMask = (scanFetchProc)fbFetchSolid;
 		maskClass = SOURCE_IMAGE_CLASS_HORIZONTAL;
 	    }
-	    else if (!bits->common.transform && bits->common.filter != PIXMAN_FILTER_CONVOLUTION)
+	    else if (!bits->common.transform && bits->common.filter != PIXMAN_FILTER_CONVOLUTION
+                    && bits->common.repeat != PIXMAN_REPEAT_PAD)
 		fetchMask = (scanFetchProc)fbFetch;
 	    else
 		fetchMask = (scanFetchProc)fbFetchTransformed;
 	}
     }
 
     if (data->dest->common.alpha_map)
     {
--- a/gfx/cairo/libpixman/src/pixman-mmx.c
+++ b/gfx/cairo/libpixman/src/pixman-mmx.c
@@ -151,16 +151,46 @@ static const MMXData c =
 #ifdef __GNUC__
 #define MC(x) ((__m64) c.mmx_##x)
 #endif
 #ifdef _MSC_VER
 #define MC(x) c.mmx_##x
 #endif
 
 static inline __m64
+M64 (ullong x)
+{
+#ifdef __GNUC__
+    return (__m64)x;
+#endif
+
+#ifdef _MSC_VER
+    __m64 res;
+    
+    res.m64_u64 = x;
+    return res;
+#endif
+}
+
+static inline ullong
+ULLONG (__m64 x)
+{
+#ifdef __GNUC__
+    return (ullong)x;
+#endif
+
+#ifdef _MSC_VER
+    ullong res;
+
+    res = x.m64_u64;
+    return res;
+#endif
+}
+
+static inline __m64
 shift (__m64 v, int s)
 {
     if (s > 0)
 	return _mm_slli_si64 (v, s);
     else if (s < 0)
 	return _mm_srli_si64 (v, -s);
     else
 	return v;
@@ -1035,19 +1065,19 @@ fbCompositeSolid_nx0565mmx (pixman_op_t 
 	dstLine += dstStride;
 	w = width;
 
 	CHECKPOINT();
 
 	while (w && (unsigned long)dst & 7)
 	{
 	    ullong d = *dst;
-	    __m64 vdest = expand565 ((__m64)d, 0);
+	    __m64 vdest = expand565 (M64(d), 0);
 	    vdest = pack565(over(vsrc, vsrca, vdest), vdest, 0);
-	    *dst = (ullong)vdest;
+	    *dst = ULLONG(vdest);
 
 	    w--;
 	    dst++;
 	}
 
 	while (w >= 4)
 	{
 	    __m64 vdest;
@@ -1065,19 +1095,19 @@ fbCompositeSolid_nx0565mmx (pixman_op_t 
 	    w -= 4;
 	}
 
 	CHECKPOINT();
 
 	while (w)
 	{
 	    ullong d = *dst;
-	    __m64 vdest = expand565 ((__m64)d, 0);
+	    __m64 vdest = expand565 (M64(d), 0);
 	    vdest = pack565(over(vsrc, vsrca, vdest), vdest, 0);
-	    *dst = (ullong)vdest;
+	    *dst = ULLONG(vdest);
 
 	    w--;
 	    dst++;
 	}
     }
 
     _mm_empty();
 }
@@ -1493,21 +1523,21 @@ fbCompositeSrc_8888x0565mmx (pixman_op_t
 	w = width;
 
 	CHECKPOINT();
 
 	while (w && (unsigned long)dst & 7)
 	{
 	    __m64 vsrc = load8888 (*src);
 	    ullong d = *dst;
-	    __m64 vdest = expand565 ((__m64)d, 0);
+	    __m64 vdest = expand565 (M64(d), 0);
 
 	    vdest = pack565(over(vsrc, expand_alpha(vsrc), vdest), vdest, 0);
 
-	    *dst = (ullong)vdest;
+	    *dst = ULLONG(vdest);
 
 	    w--;
 	    dst++;
 	    src++;
 	}
 
 	CHECKPOINT();
 
@@ -1536,21 +1566,21 @@ fbCompositeSrc_8888x0565mmx (pixman_op_t
 	}
 
 	CHECKPOINT();
 
 	while (w)
 	{
 	    __m64 vsrc = load8888 (*src);
 	    ullong d = *dst;
-	    __m64 vdest = expand565 ((__m64)d, 0);
+	    __m64 vdest = expand565 (M64(d), 0);
 
 	    vdest = pack565(over(vsrc, expand_alpha(vsrc), vdest), vdest, 0);
 
-	    *dst = (ullong)vdest;
+	    *dst = ULLONG(vdest);
 
 	    w--;
 	    dst++;
 	    src++;
 	}
     }
 
     _mm_empty();
@@ -1605,17 +1635,17 @@ fbCompositeSolidMask_nx8x8888mmx (pixman
 	CHECKPOINT();
 
 	while (w && (unsigned long)dst & 7)
 	{
 	    ullong m = *mask;
 
 	    if (m)
 	    {
-		__m64 vdest = in_over(vsrc, vsrca, expand_alpha_rev ((__m64)m), load8888(*dst));
+		__m64 vdest = in_over(vsrc, vsrca, expand_alpha_rev (M64(m)), load8888(*dst));
 		*dst = store8888(vdest);
 	    }
 
 	    w--;
 	    mask++;
 	    dst++;
 	}
 
@@ -1633,18 +1663,18 @@ fbCompositeSolidMask_nx8x8888mmx (pixman
 	    }
 	    else if (m0 | m1)
 	    {
 		__m64 vdest;
 		__m64 dest0, dest1;
 
 		vdest = *(__m64 *)dst;
 
-		dest0 = in_over(vsrc, vsrca, expand_alpha_rev ((__m64)m0), expand8888(vdest, 0));
-		dest1 = in_over(vsrc, vsrca, expand_alpha_rev ((__m64)m1), expand8888(vdest, 1));
+		dest0 = in_over(vsrc, vsrca, expand_alpha_rev (M64(m0)), expand8888(vdest, 0));
+		dest1 = in_over(vsrc, vsrca, expand_alpha_rev (M64(m1)), expand8888(vdest, 1));
 
 		*(__m64 *)dst = pack8888(dest0, dest1);
 	    }
 
 	    mask += 2;
 	    dst += 2;
 	    w -= 2;
 	}
@@ -1653,17 +1683,17 @@ fbCompositeSolidMask_nx8x8888mmx (pixman
 
 	while (w)
 	{
 	    ullong m = *mask;
 
 	    if (m)
 	    {
 		__m64 vdest = load8888(*dst);
-		vdest = in_over(vsrc, vsrca, expand_alpha_rev ((__m64)m), vdest);
+		vdest = in_over(vsrc, vsrca, expand_alpha_rev (M64(m)), vdest);
 		*dst = store8888(vdest);
 	    }
 
 	    w--;
 	    mask++;
 	    dst++;
 	}
     }
@@ -1706,17 +1736,17 @@ pixman_fill_mmx (uint32_t *bits,
     {
 	stride = stride * (int) sizeof (uint32_t) / 4;
 	byte_line = (uint8_t *)(((uint32_t *)bits) + stride * y + x);
 	byte_width = 4 * width;
 	stride *= 4;
     }
 
     fill = ((ullong)xor << 32) | xor;
-    vfill = (__m64)fill;
+    vfill = M64(fill);
 
 #ifdef __GNUC__
     __asm__ (
 	"movq		%7,	%0\n"
 	"movq		%7,	%1\n"
 	"movq		%7,	%2\n"
 	"movq		%7,	%3\n"
 	"movq		%7,	%4\n"
@@ -1852,17 +1882,17 @@ fbCompositeSolidMaskSrc_nx8x8888mmx (pix
 	CHECKPOINT();
 
 	while (w && (unsigned long)dst & 7)
 	{
 	    ullong m = *mask;
 
 	    if (m)
 	    {
-		__m64 vdest = in(vsrc, expand_alpha_rev ((__m64)m));
+		__m64 vdest = in(vsrc, expand_alpha_rev (M64(m)));
 		*dst = store8888(vdest);
 	    }
 	    else
 	    {
 		*dst = 0;
 	    }
 
 	    w--;
@@ -1884,18 +1914,18 @@ fbCompositeSolidMaskSrc_nx8x8888mmx (pix
 	    }
 	    else if (m0 | m1)
 	    {
 		__m64 vdest;
 		__m64 dest0, dest1;
 
 		vdest = *(__m64 *)dst;
 
-		dest0 = in(vsrc, expand_alpha_rev ((__m64)m0));
-		dest1 = in(vsrc, expand_alpha_rev ((__m64)m1));
+		dest0 = in(vsrc, expand_alpha_rev (M64(m0)));
+		dest1 = in(vsrc, expand_alpha_rev (M64(m1)));
 
 		*(__m64 *)dst = pack8888(dest0, dest1);
 	    }
 	    else
 	    {
 		*(ullong *)dst = 0;
 	    }
 
@@ -1908,17 +1938,17 @@ fbCompositeSolidMaskSrc_nx8x8888mmx (pix
 
 	while (w)
 	{
 	    ullong m = *mask;
 
 	    if (m)
 	    {
 		__m64 vdest = load8888(*dst);
-		vdest = in(vsrc, expand_alpha_rev ((__m64)m));
+		vdest = in(vsrc, expand_alpha_rev (M64(m)));
 		*dst = store8888(vdest);
 	    }
 	    else
 	    {
 		*dst = 0;
 	    }
 
 	    w--;
@@ -1944,34 +1974,35 @@ fbCompositeSolidMask_nx8x0565mmx (pixman
 				  uint16_t     width,
 				  uint16_t     height)
 {
     uint32_t	src, srca;
     uint16_t	*dstLine, *dst;
     uint8_t	*maskLine, *mask;
     int	dstStride, maskStride;
     uint16_t	w;
-    __m64	vsrc, vsrca;
+    __m64	vsrc, vsrca, tmp;
     unsigned long long srcsrcsrcsrc, src16;
 
     CHECKPOINT();
 
     fbComposeGetSolid(pSrc, src, pDst->bits.format);
 
     srca = src >> 24;
     if (srca == 0)
 	return;
 
     fbComposeGetStart (pDst, xDst, yDst, uint16_t, dstStride, dstLine, 1);
     fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
 
     vsrc = load8888 (src);
     vsrca = expand_alpha (vsrc);
 
-    src16 = (ullong)pack565(vsrc, _mm_setzero_si64(), 0);
+    tmp = pack565(vsrc, _mm_setzero_si64(), 0);
+    src16 = ULLONG(tmp);
 
     srcsrcsrcsrc = (ullong)src16 << 48 | (ullong)src16 << 32 |
 	(ullong)src16 << 16 | (ullong)src16;
 
     while (height--)
     {
 	dst = dstLine;
 	dstLine += dstStride;
@@ -1983,19 +2014,20 @@ fbCompositeSolidMask_nx8x0565mmx (pixman
 
 	while (w && (unsigned long)dst & 7)
 	{
 	    ullong m = *mask;
 
 	    if (m)
 	    {
 		ullong d = *dst;
-		__m64 vd = (__m64)d;
-		__m64 vdest = in_over(vsrc, vsrca, expand_alpha_rev ((__m64)m), expand565(vd, 0));
-		*dst = (ullong)pack565(vdest, _mm_setzero_si64(), 0);
+		__m64 vd = M64(d);
+		__m64 vdest = in_over(vsrc, vsrca, expand_alpha_rev (M64 (m)), expand565(vd, 0));
+		vd = pack565(vdest, _mm_setzero_si64(), 0);
+		*dst = ULLONG(vd);
 	    }
 
 	    w--;
 	    mask++;
 	    dst++;
 	}
 
 	CHECKPOINT();
@@ -2014,23 +2046,23 @@ fbCompositeSolidMask_nx8x0565mmx (pixman
 	    }
 	    else if (m0 | m1 | m2 | m3)
 	    {
 		__m64 vdest;
 		__m64 vm0, vm1, vm2, vm3;
 
 		vdest = *(__m64 *)dst;
 
-		vm0 = (__m64)m0;
+		vm0 = M64(m0);
 		vdest = pack565(in_over(vsrc, vsrca, expand_alpha_rev(vm0), expand565(vdest, 0)), vdest, 0);
-		vm1 = (__m64)m1;
+		vm1 = M64(m1);
 		vdest = pack565(in_over(vsrc, vsrca, expand_alpha_rev(vm1), expand565(vdest, 1)), vdest, 1);
-		vm2 = (__m64)m2;
+		vm2 = M64(m2);
 		vdest = pack565(in_over(vsrc, vsrca, expand_alpha_rev(vm2), expand565(vdest, 2)), vdest, 2);
-		vm3 = (__m64)m3;
+		vm3 = M64(m3);
 		vdest = pack565(in_over(vsrc, vsrca, expand_alpha_rev(vm3), expand565(vdest, 3)), vdest, 3);
 
 		*(__m64 *)dst = vdest;
 	    }
 
 	    w -= 4;
 	    mask += 4;
 	    dst += 4;
@@ -2040,19 +2072,20 @@ fbCompositeSolidMask_nx8x0565mmx (pixman
 
 	while (w)
 	{
 	    ullong m = *mask;
 
 	    if (m)
 	    {
 		ullong d = *dst;
-		__m64 vd = (__m64)d;
-		__m64 vdest = in_over(vsrc, vsrca, expand_alpha_rev ((__m64)m), expand565(vd, 0));
-		*dst = (ullong)pack565(vdest, _mm_setzero_si64(), 0);
+		__m64 vd = M64(d);
+		__m64 vdest = in_over(vsrc, vsrca, expand_alpha_rev (M64(m)), expand565(vd, 0));
+		vd = pack565(vdest, _mm_setzero_si64(), 0);
+		*dst = ULLONG(vd);
 	    }
 
 	    w--;
 	    mask++;
 	    dst++;
 	}
     }
 
@@ -2097,21 +2130,21 @@ fbCompositeSrc_8888RevNPx0565mmx (pixman
 	w = width;
 
 	CHECKPOINT();
 
 	while (w && (unsigned long)dst & 7)
 	{
 	    __m64 vsrc = load8888 (*src);
 	    ullong d = *dst;
-	    __m64 vdest = expand565 ((__m64)d, 0);
+	    __m64 vdest = expand565 (M64(d), 0);
 
 	    vdest = pack565(over_rev_non_pre(vsrc, vdest), vdest, 0);
 
-	    *dst = (ullong)vdest;
+	    *dst = ULLONG(vdest);
 
 	    w--;
 	    dst++;
 	    src++;
 	}
 
 	CHECKPOINT();
 
@@ -2158,21 +2191,21 @@ fbCompositeSrc_8888RevNPx0565mmx (pixman
 	}
 
 	CHECKPOINT();
 
 	while (w)
 	{
 	    __m64 vsrc = load8888 (*src);
 	    ullong d = *dst;
-	    __m64 vdest = expand565 ((__m64)d, 0);
+	    __m64 vdest = expand565 (M64(d), 0);
 
 	    vdest = pack565(over_rev_non_pre(vsrc, vdest), vdest, 0);
 
-	    *dst = (ullong)vdest;
+	    *dst = ULLONG(vdest);
 
 	    w--;
 	    dst++;
 	    src++;
 	}
     }
 
     _mm_empty();
@@ -2321,19 +2354,19 @@ fbCompositeSolidMask_nx8888x0565Cmmx (pi
 
 	while (twidth && ((unsigned long)q & 7))
 	{
 	    uint32_t m = *(uint32_t *)p;
 
 	    if (m)
 	    {
 		ullong d = *q;
-		__m64 vdest = expand565 ((__m64)d, 0);
+		__m64 vdest = expand565 (M64(d), 0);
 		vdest = pack565 (in_over (vsrc, vsrca, load8888 (m), vdest), vdest, 0);
-		*q = (ullong)vdest;
+		*q = ULLONG(vdest);
 	    }
 
 	    twidth--;
 	    p++;
 	    q++;
 	}
 
 	while (twidth >= 4)
@@ -2364,19 +2397,19 @@ fbCompositeSolidMask_nx8888x0565Cmmx (pi
 	while (twidth)
 	{
 	    uint32_t m;
 
 	    m = *(uint32_t *)p;
 	    if (m)
 	    {
 		ullong d = *q;
-		__m64 vdest = expand565((__m64)d, 0);
+		__m64 vdest = expand565(M64(d), 0);
 		vdest = pack565 (in_over(vsrc, vsrca, load8888(m), vdest), vdest, 0);
-		*q = (ullong)vdest;
+		*q = ULLONG(vdest);
 	    }
 
 	    twidth--;
 	    p++;
 	    q++;
 	}
 
 	maskLine += maskStride;
@@ -2693,16 +2726,17 @@ fbCompositeSrcAdd_8888x8888mmx (pixman_o
 				int16_t      ySrc,
 				int16_t      xMask,
 				int16_t      yMask,
 				int16_t      xDst,
 				int16_t      yDst,
 				uint16_t     width,
 				uint16_t     height)
 {
+    __m64 dst64;
     uint32_t	*dstLine, *dst;
     uint32_t	*srcLine, *src;
     int	dstStride, srcStride;
     uint16_t	w;
 
     CHECKPOINT();
 
     fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
@@ -2722,17 +2756,18 @@ fbCompositeSrcAdd_8888x8888mmx (pixman_o
 						 _mm_cvtsi32_si64(*dst)));
 	    dst++;
 	    src++;
 	    w--;
 	}
 
 	while (w >= 2)
 	{
-	    *(ullong*)dst = (ullong) _mm_adds_pu8(*(__m64*)src, *(__m64*)dst);
+	    dst64 = _mm_adds_pu8(*(__m64*)src, *(__m64*)dst);
+	    *(ullong*)dst = ULLONG(dst64);
 	    dst += 2;
 	    src += 2;
 	    w -= 2;
 	}
 
 	if (w)
 	{
 	    *dst = _mm_cvtsi64_si32(_mm_adds_pu8(_mm_cvtsi32_si64(*src),
@@ -2948,17 +2983,17 @@ fbCompositeOver_x888x8x8888mmx (pixman_o
 	    {
 		__m64 s = load8888 (*src | 0xff000000);
 
 		if (m == 0xff)
 		    *dst = store8888 (s);
 		else
 		{
 		    __m64 sa = expand_alpha (s);
-		    __m64 vm = expand_alpha_rev ((__m64)m);
+		    __m64 vm = expand_alpha_rev (M64(m));
 		    __m64 vdest = in_over(s, sa, vm, load8888 (*dst));
 
 		    *dst = store8888 (vdest);
 		}
 	    }
 
 	    mask++;
 	    dst++;
--- a/gfx/cairo/libpixman/src/pixman-pict.c
+++ b/gfx/cairo/libpixman/src/pixman-pict.c
@@ -1,8 +1,9 @@
+/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
 /*
  * Copyright © 2000 SuSE, Inc.
  * Copyright © 2007 Red Hat, Inc.
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
  * the above copyright notice appear in all copies and that both that
  * copyright notice and this permission notice appear in supporting
@@ -1683,17 +1684,18 @@ pixman_image_composite (pixman_op_t     
 	    pMask->bits.height == 1)
 	    maskTransform = FALSE;
     }
 
     if ((pSrc->type == BITS || can_get_solid (pSrc)) && (!pMask || pMask->type == BITS)
         && !srcTransform && !maskTransform
         && !maskAlphaMap && !srcAlphaMap && !dstAlphaMap
         && (pSrc->common.filter != PIXMAN_FILTER_CONVOLUTION)
-        && (!pMask || pMask->common.filter != PIXMAN_FILTER_CONVOLUTION)
+        && (pSrc->common.repeat != PIXMAN_REPEAT_PAD)
+        && (!pMask || (pMask->common.filter != PIXMAN_FILTER_CONVOLUTION && pMask->common.repeat != PIXMAN_REPEAT_PAD))
 	&& !pSrc->common.read_func && !pSrc->common.write_func
 	&& !(pMask && pMask->common.read_func) && !(pMask && pMask->common.write_func)
 	&& !pDst->common.read_func && !pDst->common.write_func)
     {
 	const FastPathInfo *info;
 	pixman_bool_t pixbuf;
 
 	pixbuf =
@@ -1763,17 +1765,17 @@ pixman_image_composite (pixman_op_t     
 	    maskRepeat = FALSE;
 	}
 
 	/* if we are transforming, repeats are handled in fbFetchTransformed */
 	if (srcTransform)
 	    srcRepeat = FALSE;
 
 	if (maskTransform)
-	    maskTransform = FALSE;
+	    maskRepeat = FALSE;
     }
 
     pixman_walk_composite_region (op, pSrc, pMask, pDst, xSrc, ySrc,
 				  xMask, yMask, xDst, yDst, width, height,
 				  srcRepeat, maskRepeat, func);
 }
 
 
deleted file mode 100644
--- a/gfx/cairo/pixman-fbFetchTransformed-backout.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-diff -NrpU12 mozilla-trunk.c81ad22ccb3f/gfx/cairo/libpixman/src/pixman-compose.c mozilla-trunk/gfx/cairo/libpixman/src/pixman-compose.c
---- mozilla-trunk.c81ad22ccb3f/gfx/cairo/libpixman/src/pixman-compose.c	2008-03-07 16:22:34.000000000 +1300
-+++ mozilla-trunk/gfx/cairo/libpixman/src/pixman-compose.c	2008-03-07 16:22:35.000000000 +1300
-@@ -4183,26 +4183,26 @@ static void
- fbFetchTransformed(bits_image_t * pict, int x, int y, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
- {
-     uint32_t     *bits;
-     int32_t    stride;
-     pixman_vector_t v;
-     pixman_vector_t unit;
-     pixman_bool_t affine = TRUE;
- 
-     bits = pict->bits;
-     stride = pict->rowstride;
- 
-     /* reference point is the center of the pixel */
--    v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1 / 2 - 1;
--    v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1 / 2 - 1;
-+    v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1 / 2;
-+    v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1 / 2;
-     v.vector[2] = pixman_fixed_1;
- 
-     /* when using convolution filters one might get here without a transform */
-     if (pict->common.transform)
-     {
-         if (!pixman_transform_point_3d (pict->common.transform, &v))
-         {
-             fbFinishAccess (pict->pDrawable);
-             return;
-         }
-         unit.vector[0] = pict->common.transform->matrix[0][0];
-         unit.vector[1] = pict->common.transform->matrix[1][0];
--- a/gfx/thebes/src/gfxQuartzImageSurface.cpp
+++ b/gfx/thebes/src/gfxQuartzImageSurface.cpp
@@ -33,16 +33,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "gfxQuartzImageSurface.h"
 
 #include "cairo-quartz.h"
+#include "cairo-quartz-image.h"
 
 gfxQuartzImageSurface::gfxQuartzImageSurface(gfxImageSurface *imageSurface)
 {
     if (imageSurface->CairoStatus() || imageSurface->CairoSurface() == NULL)
         return;
 
     cairo_surface_t *surf = cairo_quartz_image_surface_create (imageSurface->CairoSurface());
     Init (surf);