Bug 562746. Update cairo to 1.10.
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Thu, 10 Mar 2011 14:52:15 -0500
changeset 70435 acb4e51fa8a6c6d4d6f13a6fee31f88c293387e7
parent 70434 db4b1f3096eac669b5c8c2ef9e8d911b993363b0
child 70436 4e79d99681f0c3cc45df5362decb359ae0a894c1
push id209
push userbzbarsky@mozilla.com
push dateTue, 05 Jul 2011 17:42:16 +0000
treeherdermozilla-aurora@cc6e30cce8af [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs562746
milestone7.0a1
Bug 562746. Update cairo to 1.10. A lot of changes from upstream here that will hopefully be smoothed out a bit soon.
configure.in
gfx/cairo/cairo/src/Makefile.in
gfx/cairo/cairo/src/cairo-analysis-surface-private.h
gfx/cairo/cairo/src/cairo-analysis-surface.c
gfx/cairo/cairo/src/cairo-arc-private.h
gfx/cairo/cairo/src/cairo-arc.c
gfx/cairo/cairo/src/cairo-array.c
gfx/cairo/cairo/src/cairo-atomic-private.h
gfx/cairo/cairo/src/cairo-atomic.c
gfx/cairo/cairo/src/cairo-base64-stream.c
gfx/cairo/cairo/src/cairo-base85-stream.c
gfx/cairo/cairo/src/cairo-bentley-ottmann-rectangular.c
gfx/cairo/cairo/src/cairo-bentley-ottmann-rectilinear.c
gfx/cairo/cairo/src/cairo-bentley-ottmann.c
gfx/cairo/cairo/src/cairo-beos.h
gfx/cairo/cairo/src/cairo-botor-scan-converter.c
gfx/cairo/cairo/src/cairo-boxes-private.h
gfx/cairo/cairo/src/cairo-boxes.c
gfx/cairo/cairo/src/cairo-cache-private.h
gfx/cairo/cairo/src/cairo-cache.c
gfx/cairo/cairo/src/cairo-cff-subset.c
gfx/cairo/cairo/src/cairo-clip-private.h
gfx/cairo/cairo/src/cairo-clip.c
gfx/cairo/cairo/src/cairo-color.c
gfx/cairo/cairo/src/cairo-combsort-private.h
gfx/cairo/cairo/src/cairo-compiler-private.h
gfx/cairo/cairo/src/cairo-composite-rectangles-private.h
gfx/cairo/cairo/src/cairo-composite-rectangles.c
gfx/cairo/cairo/src/cairo-d2d-private.h
gfx/cairo/cairo/src/cairo-d2d-surface.cpp
gfx/cairo/cairo/src/cairo-debug.c
gfx/cairo/cairo/src/cairo-deflate-stream.c
gfx/cairo/cairo/src/cairo-deprecated.h
gfx/cairo/cairo/src/cairo-device-private.h
gfx/cairo/cairo/src/cairo-device.c
gfx/cairo/cairo/src/cairo-directfb-surface.c
gfx/cairo/cairo/src/cairo-directfb.h
gfx/cairo/cairo/src/cairo-drm.h
gfx/cairo/cairo/src/cairo-dwrite-font.cpp
gfx/cairo/cairo/src/cairo-error-private.h
gfx/cairo/cairo/src/cairo-features.h.in
gfx/cairo/cairo/src/cairo-fixed-private.h
gfx/cairo/cairo/src/cairo-fixed-type-private.h
gfx/cairo/cairo/src/cairo-fixed.c
gfx/cairo/cairo/src/cairo-font-face-twin.c
gfx/cairo/cairo/src/cairo-font-face.c
gfx/cairo/cairo/src/cairo-font-options.c
gfx/cairo/cairo/src/cairo-fontconfig-private.h
gfx/cairo/cairo/src/cairo-freed-pool-private.h
gfx/cairo/cairo/src/cairo-freed-pool.c
gfx/cairo/cairo/src/cairo-freelist-private.h
gfx/cairo/cairo/src/cairo-freelist-type-private.h
gfx/cairo/cairo/src/cairo-freelist.c
gfx/cairo/cairo/src/cairo-ft-font.c
gfx/cairo/cairo/src/cairo-ft-private.h
gfx/cairo/cairo/src/cairo-ft.h
gfx/cairo/cairo/src/cairo-gl-glyphs.c
gfx/cairo/cairo/src/cairo-gl-private.h
gfx/cairo/cairo/src/cairo-gl-shaders.c
gfx/cairo/cairo/src/cairo-gl-surface.c
gfx/cairo/cairo/src/cairo-gl.h
gfx/cairo/cairo/src/cairo-glx-context.c
gfx/cairo/cairo/src/cairo-gstate-private.h
gfx/cairo/cairo/src/cairo-gstate.c
gfx/cairo/cairo/src/cairo-hash-private.h
gfx/cairo/cairo/src/cairo-hash.c
gfx/cairo/cairo/src/cairo-hull.c
gfx/cairo/cairo/src/cairo-image-info-private.h
gfx/cairo/cairo/src/cairo-image-info.c
gfx/cairo/cairo/src/cairo-image-surface.c
gfx/cairo/cairo/src/cairo-list-private.h
gfx/cairo/cairo/src/cairo-lzw.c
gfx/cairo/cairo/src/cairo-malloc-private.h
gfx/cairo/cairo/src/cairo-matrix.c
gfx/cairo/cairo/src/cairo-misc.c
gfx/cairo/cairo/src/cairo-mutex-impl-private.h
gfx/cairo/cairo/src/cairo-mutex-list-private.h
gfx/cairo/cairo/src/cairo-mutex-private.h
gfx/cairo/cairo/src/cairo-mutex-type-private.h
gfx/cairo/cairo/src/cairo-mutex.c
gfx/cairo/cairo/src/cairo-observer.c
gfx/cairo/cairo/src/cairo-os2-private.h
gfx/cairo/cairo/src/cairo-os2-surface.c
gfx/cairo/cairo/src/cairo-os2.h
gfx/cairo/cairo/src/cairo-output-stream-private.h
gfx/cairo/cairo/src/cairo-output-stream.c
gfx/cairo/cairo/src/cairo-paginated-private.h
gfx/cairo/cairo/src/cairo-paginated-surface-private.h
gfx/cairo/cairo/src/cairo-paginated-surface.c
gfx/cairo/cairo/src/cairo-path-bounds.c
gfx/cairo/cairo/src/cairo-path-fill.c
gfx/cairo/cairo/src/cairo-path-fixed-private.h
gfx/cairo/cairo/src/cairo-path-fixed.c
gfx/cairo/cairo/src/cairo-path-in-fill.c
gfx/cairo/cairo/src/cairo-path-private.h
gfx/cairo/cairo/src/cairo-path-stroke.c
gfx/cairo/cairo/src/cairo-path.c
gfx/cairo/cairo/src/cairo-pattern.c
gfx/cairo/cairo/src/cairo-pdf-operators-private.h
gfx/cairo/cairo/src/cairo-pdf-operators.c
gfx/cairo/cairo/src/cairo-pdf-surface-private.h
gfx/cairo/cairo/src/cairo-pdf-surface.c
gfx/cairo/cairo/src/cairo-pdf.h
gfx/cairo/cairo/src/cairo-pen.c
gfx/cairo/cairo/src/cairo-png.c
gfx/cairo/cairo/src/cairo-polygon.c
gfx/cairo/cairo/src/cairo-private.h
gfx/cairo/cairo/src/cairo-ps-surface-private.h
gfx/cairo/cairo/src/cairo-ps-surface.c
gfx/cairo/cairo/src/cairo-ps.h
gfx/cairo/cairo/src/cairo-qt-surface.cpp
gfx/cairo/cairo/src/cairo-qt.h
gfx/cairo/cairo/src/cairo-quartz-font.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-recording-surface-private.h
gfx/cairo/cairo/src/cairo-recording-surface.c
gfx/cairo/cairo/src/cairo-rectangle.c
gfx/cairo/cairo/src/cairo-rectangular-scan-converter.c
gfx/cairo/cairo/src/cairo-reference-count-private.h
gfx/cairo/cairo/src/cairo-region-private.h
gfx/cairo/cairo/src/cairo-region.c
gfx/cairo/cairo/src/cairo-rtree-private.h
gfx/cairo/cairo/src/cairo-rtree.c
gfx/cairo/cairo/src/cairo-scaled-font-private.h
gfx/cairo/cairo/src/cairo-scaled-font-subsets-private.h
gfx/cairo/cairo/src/cairo-scaled-font-subsets.c
gfx/cairo/cairo/src/cairo-scaled-font.c
gfx/cairo/cairo/src/cairo-script-surface.c
gfx/cairo/cairo/src/cairo-script.h
gfx/cairo/cairo/src/cairo-skia.h
gfx/cairo/cairo/src/cairo-slope-private.h
gfx/cairo/cairo/src/cairo-slope.c
gfx/cairo/cairo/src/cairo-spans-private.h
gfx/cairo/cairo/src/cairo-spans.c
gfx/cairo/cairo/src/cairo-spline.c
gfx/cairo/cairo/src/cairo-stroke-style.c
gfx/cairo/cairo/src/cairo-supported-features.h
gfx/cairo/cairo/src/cairo-surface-clipper-private.h
gfx/cairo/cairo/src/cairo-surface-clipper.c
gfx/cairo/cairo/src/cairo-surface-fallback-private.h
gfx/cairo/cairo/src/cairo-surface-fallback.c
gfx/cairo/cairo/src/cairo-surface-offset-private.h
gfx/cairo/cairo/src/cairo-surface-offset.c
gfx/cairo/cairo/src/cairo-surface-private.h
gfx/cairo/cairo/src/cairo-surface-snapshot-private.h
gfx/cairo/cairo/src/cairo-surface-snapshot.c
gfx/cairo/cairo/src/cairo-surface-subsurface-private.h
gfx/cairo/cairo/src/cairo-surface-subsurface.c
gfx/cairo/cairo/src/cairo-surface-wrapper-private.h
gfx/cairo/cairo/src/cairo-surface-wrapper.c
gfx/cairo/cairo/src/cairo-surface.c
gfx/cairo/cairo/src/cairo-svg-surface-private.h
gfx/cairo/cairo/src/cairo-svg-surface.c
gfx/cairo/cairo/src/cairo-svg.h
gfx/cairo/cairo/src/cairo-system.c
gfx/cairo/cairo/src/cairo-tee-surface-private.h
gfx/cairo/cairo/src/cairo-tee-surface.c
gfx/cairo/cairo/src/cairo-tee.h
gfx/cairo/cairo/src/cairo-tor-scan-converter.c
gfx/cairo/cairo/src/cairo-toy-font-face.c
gfx/cairo/cairo/src/cairo-traps.c
gfx/cairo/cairo/src/cairo-truetype-subset-private.h
gfx/cairo/cairo/src/cairo-truetype-subset.c
gfx/cairo/cairo/src/cairo-type1-fallback.c
gfx/cairo/cairo/src/cairo-type1-private.h
gfx/cairo/cairo/src/cairo-type1-subset.c
gfx/cairo/cairo/src/cairo-type3-glyph-surface-private.h
gfx/cairo/cairo/src/cairo-type3-glyph-surface.c
gfx/cairo/cairo/src/cairo-types-private.h
gfx/cairo/cairo/src/cairo-unicode.c
gfx/cairo/cairo/src/cairo-user-font-private.h
gfx/cairo/cairo/src/cairo-user-font.c
gfx/cairo/cairo/src/cairo-version.c
gfx/cairo/cairo/src/cairo-vg-surface.c
gfx/cairo/cairo/src/cairo-vg.h
gfx/cairo/cairo/src/cairo-wideint-private.h
gfx/cairo/cairo/src/cairo-wideint-type-private.h
gfx/cairo/cairo/src/cairo-wideint.c
gfx/cairo/cairo/src/cairo-win32-font.c
gfx/cairo/cairo/src/cairo-win32-printing-surface.c
gfx/cairo/cairo/src/cairo-win32-private.h
gfx/cairo/cairo/src/cairo-win32-surface.c
gfx/cairo/cairo/src/cairo-win32.h
gfx/cairo/cairo/src/cairo-xcb-surface.c
gfx/cairo/cairo/src/cairo-xcb.h
gfx/cairo/cairo/src/cairo-xlib-display.c
gfx/cairo/cairo/src/cairo-xlib-private.h
gfx/cairo/cairo/src/cairo-xlib-screen.c
gfx/cairo/cairo/src/cairo-xlib-surface-private.h
gfx/cairo/cairo/src/cairo-xlib-surface.c
gfx/cairo/cairo/src/cairo-xlib-visual.c
gfx/cairo/cairo/src/cairo-xlib-xrender-private.h
gfx/cairo/cairo/src/cairo-xlib-xrender.h
gfx/cairo/cairo/src/cairo-xlib.h
gfx/cairo/cairo/src/cairo-xml-surface.c
gfx/cairo/cairo/src/cairo-xml.h
gfx/cairo/cairo/src/cairo.c
gfx/cairo/cairo/src/cairo.h
gfx/cairo/cairo/src/cairoint.h
gfx/cairo/cairo/src/test-fallback-surface.c
gfx/cairo/cairo/src/test-fallback-surface.h
gfx/cairo/cairo/src/test-paginated-surface.c
gfx/cairo/cairo/src/test-paginated-surface.h
gfx/thebes/gfxASurface.cpp
gfx/thebes/gfxASurface.h
gfx/thebes/gfxQPainterSurface.cpp
gfx/thebes/gfxTeeSurface.cpp
layout/reftests/border-radius/reftest.list
layout/reftests/counters/reftest.list
layout/reftests/generated-content/reftest.list
--- a/configure.in
+++ b/configure.in
@@ -8383,16 +8383,17 @@ MOZ_CHECK_HEADERS(stdint.h inttypes.h sy
 if test "$MOZ_TREE_CAIRO"; then
     AC_DEFINE(MOZ_TREE_CAIRO)
 
     # For now we assume that we will have a uint64_t available through
     # one of the above headers or mozstdint.h.
     AC_DEFINE(HAVE_UINT64_T)
 
     # Define macros for cairo-features.h
+    TEE_SURFACE_FEATURE="#define CAIRO_HAS_TEE_SURFACE 1"
     if test "$MOZ_X11"; then
         XLIB_SURFACE_FEATURE="#define CAIRO_HAS_XLIB_SURFACE 1"
         XLIB_XRENDER_SURFACE_FEATURE="#define CAIRO_HAS_XLIB_XRENDER_SURFACE 1"
         PS_SURFACE_FEATURE="#define CAIRO_HAS_PS_SURFACE 1"
         FT_FONT_FEATURE="#define CAIRO_HAS_FT_FONT 1"
         MOZ_ENABLE_CAIRO_FT=1
         CAIRO_FT_CFLAGS="$FT2_CFLAGS"
     fi
@@ -8465,16 +8466,17 @@ if test "$MOZ_TREE_CAIRO"; then
     AC_SUBST(FT_FONT_FEATURE)
     AC_SUBST(FC_FONT_FEATURE)
     AC_SUBST(WIN32_FONT_FEATURE)
     AC_SUBST(WIN32_DWRITE_FONT_FEATURE)
     AC_SUBST(WIN32_D2D_SURFACE_FEATURE)
     AC_SUBST(QUARTZ_FONT_FEATURE)
     AC_SUBST(PNG_FUNCTIONS_FEATURE)
     AC_SUBST(QT_SURFACE_FEATURE)
+    AC_SUBST(TEE_SURFACE_FEATURE)
 
     MOZ_CAIRO_LIBS='$(call EXPAND_LIBNAME_PATH,mozcairo,$(DEPTH)/gfx/cairo/cairo/src)'" $CAIRO_FT_LIBS"
 
     if test "$MOZ_TREE_PIXMAN"; then
         AC_DEFINE(MOZ_TREE_PIXMAN)
         MOZ_CAIRO_LIBS="$MOZ_CAIRO_LIBS"' $(call EXPAND_LIBNAME_PATH,mozlibpixman,$(DEPTH)/gfx/cairo/libpixman/src)'
     else
         PKG_CHECK_MODULES(PIXMAN, pixman-1 >= 0.19.2)
--- a/gfx/cairo/cairo/src/Makefile.in
+++ b/gfx/cairo/cairo/src/Makefile.in
@@ -65,77 +65,87 @@ endif
 
 
 CSRCS   = \
         cairo.c \
         cairo-analysis-surface.c \
         cairo-arc.c \
         cairo-array.c \
 	cairo-atomic.c \
+        cairo-base64-stream.c \
         cairo-bentley-ottmann.c \
 	cairo-bentley-ottmann-rectilinear.c \
 	cairo-bentley-ottmann-rectangular.c \
-        cairo-base64-stream.c \
+	cairo-botor-scan-converter.c \
+	cairo-boxes.c \
 	cairo-cache.c \
         cairo-clip.c \
         cairo-color.c \
+	cairo-composite-rectangles.c \
         cairo-debug.c \
         cairo-deflate-stream.c \
+	cairo-device.c \
         cairo-fixed.c \
 	cairo-font-face.c \
 	cairo-font-face-twin.c \
 	cairo-font-face-twin-data.c \
         cairo-font-options.c \
+	cairo-freed-pool.c \
         cairo-freelist.c \
         cairo-gstate.c \
         cairo-hash.c \
         cairo-hull.c \
 	cairo-image-info.c \
         cairo-image-surface.c \
         cairo-lzw.c \
         cairo-matrix.c \
 	cairo-misc.c \
 	cairo-mutex.c \
+	cairo-observer.c \
         cairo-output-stream.c \
         cairo-paginated-surface.c \
         cairo-path.c \
         cairo-path-bounds.c \
         cairo-path-fill.c \
         cairo-path-fixed.c \
         cairo-path-in-fill.c \
         cairo-path-stroke.c \
         cairo-pattern.c \
         cairo-pen.c \
         cairo-polygon.c \
 	cairo-recording-surface.c \
         cairo-rectangle.c \
+	cairo-rectangular-scan-converter.c \
         cairo-region.c \
         cairo-scaled-font.c \
         cairo-scaled-font-subsets.c \
         cairo-slope.c \
         cairo-spans.c \
         cairo-spline.c \
         cairo-stroke-style.c \
         cairo-surface.c \
 	cairo-surface-clipper.c \
         cairo-surface-fallback.c \
+	cairo-surface-offset.c \
+	cairo-surface-snapshot.c \
+	cairo-surface-subsurface.c \
 	cairo-surface-wrapper.c \
 	cairo-tee-surface.c \
         cairo-tor-scan-converter.c \
         cairo-toy-font-face.c \
         cairo-traps.c \
         cairo-unicode.c \
 	cairo-user-font.c \
 	cairo-version.c \
         cairo-wideint.c \
         $(NULL)
 
 EXPORTS_NAMESPACES = cairo
 
-EXPORTS_cairo = cairo.h cairo-version.h cairo-features.h cairo-platform.h cairo-deprecated.h cairo-rename.h
+EXPORTS_cairo = cairo.h cairo-version.h cairo-features.h cairo-platform.h cairo-deprecated.h cairo-rename.h cairo-tee.h
 
 # cairo-type1-subset.c should be here, but it's only supported on freetype platforms
 
 PSPDF_BASE_CSRCS = \
 	cairo-base85-stream.c \
 	cairo-type1-fallback.c \
 	cairo-type3-glyph-surface.c \
 	cairo-truetype-subset.c \
@@ -148,16 +158,17 @@ PDF_CSRCS = \
 	$(NULL)
 
 PS_CSRCS = cairo-ps-surface.c
 
 PDF_EXPORTS = cairo-pdf.h
 PS_EXPORTS = cairo-ps.h
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
+DEFINES += -DDISABLE_SOME_FLOATING_POINT
 CSRCS	+=	cairo-win32-surface.c
 
 ifndef WINCE
 ifdef MOZ_ENABLE_DWRITE_FONT
 CPPSRCS +=	cairo-dwrite-font.cpp
 endif
 ifdef MOZ_ENABLE_D2D_SURFACE
 CPPSRCS +=	cairo-d2d-surface.cpp
@@ -264,8 +275,9 @@ ifndef MOZ_TREE_PIXMAN
 CFLAGS += $(MOZ_CAIRO_CFLAGS)
 CXXFLAGS += $(MOZ_CAIRO_CFLAGS)
 else
 DEFINES += -DMOZ_TREE_PIXMAN
 endif
 
 cairo-features.h: $(srcdir)/cairo-features.h.in $(GLOBAL_DEPS)
 	$(PERL) $(AUTOCONF_TOOLS)/make-makefile -t $(topsrcdir) -d $(DEPTH) ./$@
+	cat cairo-dwrite-font.i | gzip | python -c "import base64,sys; base64.encode(sys.stdin,sys.stdout)"
--- a/gfx/cairo/cairo/src/cairo-analysis-surface-private.h
+++ b/gfx/cairo/cairo/src/cairo-analysis-surface-private.h
@@ -6,17 +6,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
@@ -32,16 +32,18 @@
  *      Keith Packard <keithp@keithp.com>
  */
 
 #ifndef CAIRO_ANALYSIS_SURFACE_H
 #define CAIRO_ANALYSIS_SURFACE_H
 
 #include "cairoint.h"
 
+CAIRO_BEGIN_DECLS
+
 cairo_private cairo_surface_t *
 _cairo_analysis_surface_create (cairo_surface_t		*target);
 
 cairo_private void
 _cairo_analysis_surface_set_ctm (cairo_surface_t *surface,
 				 const cairo_matrix_t  *ctm);
 
 cairo_private void
@@ -66,9 +68,11 @@ cairo_private void
 
 cairo_private cairo_int_status_t
 _cairo_analysis_surface_merge_status (cairo_int_status_t status_a,
 				      cairo_int_status_t status_b);
 
 cairo_private cairo_surface_t *
 _cairo_null_surface_create (cairo_content_t content);
 
+CAIRO_END_DECLS
+
 #endif /* CAIRO_ANALYSIS_SURFACE_H */
--- a/gfx/cairo/cairo/src/cairo-analysis-surface.c
+++ b/gfx/cairo/cairo/src/cairo-analysis-surface.c
@@ -7,17 +7,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
@@ -32,18 +32,20 @@
  * Contributor(s):
  *      Keith Packard <keithp@keithp.com>
  *      Adrian Johnson <ajohnson@redneon.com>
  */
 
 #include "cairoint.h"
 
 #include "cairo-analysis-surface-private.h"
+#include "cairo-error-private.h"
 #include "cairo-paginated-private.h"
 #include "cairo-recording-surface-private.h"
+#include "cairo-surface-subsurface-private.h"
 #include "cairo-region-private.h"
 
 typedef struct {
     cairo_surface_t base;
 
     cairo_surface_t *target;
 
     cairo_bool_t first_op;
@@ -94,33 +96,39 @@ cairo_int_status_t
 static cairo_int_status_t
 _analyze_recording_surface_pattern (cairo_analysis_surface_t *surface,
 				    const cairo_pattern_t    *pattern)
 {
     const cairo_surface_pattern_t *surface_pattern;
     cairo_bool_t old_has_ctm;
     cairo_matrix_t old_ctm, p2d;
     cairo_status_t status;
+    cairo_surface_t *source;
 
     assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
     surface_pattern = (const cairo_surface_pattern_t *) pattern;
-    assert (_cairo_surface_is_recording (surface_pattern->surface));
+    assert (surface_pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING);
 
     old_ctm = surface->ctm;
     old_has_ctm = surface->has_ctm;
 
     p2d = pattern->matrix;
     status = cairo_matrix_invert (&p2d);
     assert (status == CAIRO_STATUS_SUCCESS);
 
     cairo_matrix_multiply (&surface->ctm, &p2d, &surface->ctm);
     surface->has_ctm = ! _cairo_matrix_is_identity (&surface->ctm);
 
-    status = _cairo_recording_surface_replay_and_create_regions (surface_pattern->surface,
-							    &surface->base);
+    source = surface_pattern->surface;
+    if (source->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
+	cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) source;
+	source = sub->target;
+    }
+
+    status = _cairo_recording_surface_replay_and_create_regions (source, &surface->base);
 
     surface->ctm = old_ctm;
     surface->has_ctm = old_has_ctm;
 
     return status;
 }
 
 static cairo_int_status_t
@@ -391,19 +399,19 @@ static cairo_int_status_t
     return _add_operation (surface, &extents, backend_status);
 }
 
 static cairo_int_status_t
 _cairo_analysis_surface_stroke (void			*abstract_surface,
 				cairo_operator_t	 op,
 				const cairo_pattern_t	*source,
 				cairo_path_fixed_t	*path,
-				cairo_stroke_style_t	*style,
-				cairo_matrix_t		*ctm,
-				cairo_matrix_t		*ctm_inverse,
+				const cairo_stroke_style_t	*style,
+				const cairo_matrix_t		*ctm,
+				const cairo_matrix_t		*ctm_inverse,
 				double			 tolerance,
 				cairo_antialias_t	 antialias,
 				cairo_clip_t		*clip)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
     cairo_status_t	     backend_status;
     cairo_rectangle_int_t    extents;
     cairo_bool_t             is_empty;
@@ -711,17 +719,19 @@ cairo_surface_t *
 	return _cairo_surface_create_in_error (status);
 
     surface = malloc (sizeof (cairo_analysis_surface_t));
     if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
     /* I believe the content type here is truly arbitrary. I'm quite
      * sure nothing will ever use this value. */
-    _cairo_surface_init (&surface->base, &cairo_analysis_surface_backend,
+    _cairo_surface_init (&surface->base,
+			 &cairo_analysis_surface_backend,
+			 NULL, /* device */
 			 CAIRO_CONTENT_COLOR_ALPHA);
 
     cairo_matrix_init_identity (&surface->ctm);
     surface->has_ctm = FALSE;
 
     surface->target = cairo_surface_reference (target);
     surface->first_op  = TRUE;
     surface->has_supported = FALSE;
@@ -826,19 +836,19 @@ typedef cairo_int_status_t
 				 const cairo_pattern_t	*mask,
 				 cairo_clip_t		*clip);
 
 typedef cairo_int_status_t
 (*_stroke_func)			(void			*surface,
 			         cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
 				 cairo_path_fixed_t	*path,
-				 cairo_stroke_style_t	*style,
-				 cairo_matrix_t		*ctm,
-				 cairo_matrix_t		*ctm_inverse,
+				 const cairo_stroke_style_t	*style,
+				 const cairo_matrix_t		*ctm,
+				 const cairo_matrix_t		*ctm_inverse,
 				 double			 tolerance,
 				 cairo_antialias_t	 antialias,
 				 cairo_clip_t		*clip);
 
 typedef cairo_int_status_t
 (*_fill_func)			(void			*surface,
 			         cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
@@ -901,12 +911,15 @@ cairo_surface_t *
 {
     cairo_surface_t *surface;
 
     surface = malloc (sizeof (cairo_surface_t));
     if (unlikely (surface == NULL)) {
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
     }
 
-    _cairo_surface_init (surface, &cairo_null_surface_backend, content);
+    _cairo_surface_init (surface,
+			 &cairo_null_surface_backend,
+			 NULL, /* device */
+			 content);
 
     return surface;
 }
--- a/gfx/cairo/cairo/src/cairo-arc-private.h
+++ b/gfx/cairo/cairo/src/cairo-arc-private.h
@@ -7,17 +7,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
--- a/gfx/cairo/cairo/src/cairo-arc.c
+++ b/gfx/cairo/cairo/src/cairo-arc.c
@@ -7,17 +7,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
--- a/gfx/cairo/cairo/src/cairo-array.c
+++ b/gfx/cairo/cairo/src/cairo-array.c
@@ -7,17 +7,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
@@ -31,16 +31,17 @@
  * California.
  *
  * Contributor(s):
  *	Kristian Høgsberg <krh@redhat.com>
  *	Carl Worth <cworth@cworth.org>
  */
 
 #include "cairoint.h"
+#include "cairo-error-private.h"
 
 /**
  * _cairo_array_init:
  *
  * Initialize a new #cairo_array_t object to store objects each of size
  * @element_size.
  *
  * The #cairo_array_t object provides grow-by-doubling storage. It
@@ -255,17 +256,17 @@ cairo_status_t
 		     const void		*element)
 {
     assert (! array->is_snapshot);
 
     return _cairo_array_append_multiple (array, element, 1);
 }
 
 /**
- * _cairo_array_append:
+ * _cairo_array_append_multiple:
  * @array: a #cairo_array_t
  *
  * Append one or more items onto the array by growing the array by
  * @num_elements, then copying @num_elements * element_size bytes from
  * @elements into the array.
  *
  * Return value: %CAIRO_STATUS_SUCCESS if successful or
  * %CAIRO_STATUS_NO_MEMORY if insufficient memory is available for the
--- a/gfx/cairo/cairo/src/cairo-atomic-private.h
+++ b/gfx/cairo/cairo/src/cairo-atomic-private.h
@@ -1,23 +1,24 @@
 /* cairo - a vector graphics library with display and print output
  *
  * Copyright © 2007 Chris Wilson
+ * Copyright © 2010 Andrea Canciani
  *
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
@@ -27,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):
  *	Chris Wilson <chris@chris-wilson.co.uk>
+ *	Andrea Canciani <ranma42@gmail.com>
  */
 
 #ifndef CAIRO_ATOMIC_PRIVATE_H
 #define CAIRO_ATOMIC_PRIVATE_H
 
 # include "cairo-compiler-private.h"
 
 #if HAVE_CONFIG_H
@@ -52,101 +54,204 @@
 CAIRO_BEGIN_DECLS
 
 #if HAVE_INTEL_ATOMIC_PRIMITIVES
 
 #define HAS_ATOMIC_OPS 1
 
 typedef int cairo_atomic_int_t;
 
+#ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER
+static cairo_always_inline cairo_atomic_int_t
+_cairo_atomic_int_get (cairo_atomic_int_t *x)
+{
+    __sync_synchronize ();
+    return *x;
+}
+
+static cairo_always_inline void *
+_cairo_atomic_ptr_get (void **x)
+{
+    __sync_synchronize ();
+    return *x;
+}
+#else
 # define _cairo_atomic_int_get(x) (*x)
-# define _cairo_atomic_int_set(x, value) ((*x) = value)
+# define _cairo_atomic_ptr_get(x) (*x)
+#endif
 
 # define _cairo_atomic_int_inc(x) ((void) __sync_fetch_and_add(x, 1))
 # define _cairo_atomic_int_dec_and_test(x) (__sync_fetch_and_add(x, -1) == 1)
-# define _cairo_atomic_int_cmpxchg(x, oldv, newv) __sync_val_compare_and_swap (x, oldv, newv)
+# define _cairo_atomic_int_cmpxchg(x, oldv, newv) __sync_bool_compare_and_swap (x, oldv, newv)
+# define _cairo_atomic_int_cmpxchg_return_old(x, oldv, newv) __sync_val_compare_and_swap (x, oldv, newv)
 
 #if SIZEOF_VOID_P==SIZEOF_INT
 typedef int cairo_atomic_intptr_t;
 #elif SIZEOF_VOID_P==SIZEOF_LONG
 typedef long cairo_atomic_intptr_t;
 #elif SIZEOF_VOID_P==SIZEOF_LONG_LONG
 typedef long long cairo_atomic_intptr_t;
 #else
 #error No matching integer pointer type
 #endif
 
 # define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
-    (void*)__sync_val_compare_and_swap ((cairo_atomic_intptr_t*)x, (cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv)
+    __sync_bool_compare_and_swap ((cairo_atomic_intptr_t*)x, (cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv)
+
+# define _cairo_atomic_ptr_cmpxchg_return_old(x, oldv, newv) \
+    _cairo_atomic_intptr_to_voidptr (__sync_val_compare_and_swap ((cairo_atomic_intptr_t*)x, (cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv))
 
 #endif
 
 #if HAVE_LIB_ATOMIC_OPS
 #include <atomic_ops.h>
 
 #define HAS_ATOMIC_OPS 1
 
 typedef  AO_t cairo_atomic_int_t;
 
 # define _cairo_atomic_int_get(x) (AO_load_full (x))
-# define _cairo_atomic_int_set(x, value) (AO_store_full (x))
 
 # define _cairo_atomic_int_inc(x) ((void) AO_fetch_and_add1_full(x))
 # define _cairo_atomic_int_dec_and_test(x) (AO_fetch_and_sub1_full(x) == 1)
-# define _cairo_atomic_int_cmpxchg(x, oldv, newv) ((cairo_atomic_int_t) AO_compare_and_swap_full(x, oldv, newv) ? oldv : *x)
+# define _cairo_atomic_int_cmpxchg(x, oldv, newv) AO_compare_and_swap_full(x, oldv, newv)
 
 #if SIZEOF_VOID_P==SIZEOF_INT
 typedef unsigned int cairo_atomic_intptr_t;
 #elif SIZEOF_VOID_P==SIZEOF_LONG
 typedef unsigned long cairo_atomic_intptr_t;
 #elif SIZEOF_VOID_P==SIZEOF_LONG_LONG
 typedef unsigned long long cairo_atomic_intptr_t;
 #else
 #error No matching integer pointer type
 #endif
 
+# define _cairo_atomic_ptr_get(x) _cairo_atomic_intptr_to_voidptr (AO_load_full (x))
 # define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
-    (void*) (cairo_atomic_intptr_t) _cairo_atomic_int_cmpxchg ((cairo_atomic_intptr_t*)(x), (cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv)
+    _cairo_atomic_int_cmpxchg ((cairo_atomic_intptr_t*)(x), (cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv)
 
 #endif
 
+#if HAVE_OS_ATOMIC_OPS
+#include <libkern/OSAtomic.h>
+
+#define HAS_ATOMIC_OPS 1
+
+typedef int32_t cairo_atomic_int_t;
+
+# define _cairo_atomic_int_get(x) (OSMemoryBarrier(), *(x))
+
+# define _cairo_atomic_int_inc(x) ((void) OSAtomicIncrement32Barrier (x))
+# define _cairo_atomic_int_dec_and_test(x) (OSAtomicDecrement32Barrier (x) == 0)
+# define _cairo_atomic_int_cmpxchg(x, oldv, newv) OSAtomicCompareAndSwap32Barrier(oldv, newv, x)
+
+#if SIZEOF_VOID_P==4
+typedef int32_t cairo_atomic_intptr_t;
+# define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
+    OSAtomicCompareAndSwap32Barrier((cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv, (cairo_atomic_intptr_t *)x)
+
+#elif SIZEOF_VOID_P==8
+typedef int64_t cairo_atomic_intptr_t;
+# define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
+    OSAtomicCompareAndSwap64Barrier((cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv, (cairo_atomic_intptr_t *)x)
+
+#else
+#error No matching integer pointer type
+#endif
+
+# define _cairo_atomic_ptr_get(x) (OSMemoryBarrier(), *(x))
+
+#endif
 
 #ifndef HAS_ATOMIC_OPS
 
-typedef int cairo_atomic_int_t;
+#if SIZEOF_VOID_P==SIZEOF_INT
+typedef unsigned int cairo_atomic_intptr_t;
+#elif SIZEOF_VOID_P==SIZEOF_LONG
+typedef unsigned long cairo_atomic_intptr_t;
+#elif SIZEOF_VOID_P==SIZEOF_LONG_LONG
+typedef unsigned long long cairo_atomic_intptr_t;
+#else
+#error No matching integer pointer type
+#endif
+
+typedef cairo_atomic_intptr_t cairo_atomic_int_t;
 
 cairo_private void
-_cairo_atomic_int_inc (int *x);
+_cairo_atomic_int_inc (cairo_atomic_int_t *x);
 
 cairo_private cairo_bool_t
-_cairo_atomic_int_dec_and_test (int *x);
+_cairo_atomic_int_dec_and_test (cairo_atomic_int_t *x);
 
-cairo_private int
-_cairo_atomic_int_cmpxchg (int *x, int oldv, int newv);
+cairo_private cairo_atomic_int_t
+_cairo_atomic_int_cmpxchg_return_old_impl (cairo_atomic_int_t *x, cairo_atomic_int_t oldv, cairo_atomic_int_t newv);
 
 cairo_private void *
-_cairo_atomic_ptr_cmpxchg (void **x, void *oldv, void *newv);
+_cairo_atomic_ptr_cmpxchg_return_old_impl (void **x, void *oldv, void *newv);
+
+#define _cairo_atomic_int_cmpxchg_return_old(x, oldv, newv) _cairo_atomic_int_cmpxchg_return_old_impl (x, oldv, newv)
+#define _cairo_atomic_ptr_cmpxchg_return_old(x, oldv, newv) _cairo_atomic_ptr_cmpxchg_return_old_impl (x, oldv, newv)
 
 #ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER
-
-# include "cairo-compiler-private.h"
-
-cairo_private int
-_cairo_atomic_int_get (int *x);
-
-cairo_private void
-_cairo_atomic_int_set (int *x, int value);
+cairo_private cairo_atomic_int_t
+_cairo_atomic_int_get (cairo_atomic_int_t *x);
+# define _cairo_atomic_ptr_get(x) (void *) _cairo_atomic_int_get((cairo_atomic_int_t *) x)
+#else
+# define _cairo_atomic_int_get(x) (*x)
+# define _cairo_atomic_ptr_get(x) (*x)
+#endif
 
 #else
 
-# define _cairo_atomic_int_get(x) (*x)
-# define _cairo_atomic_int_set(x, value) ((*x) = value)
+/* Workaround GCC complaining about casts */
+static cairo_always_inline void *
+_cairo_atomic_intptr_to_voidptr (cairo_atomic_intptr_t x)
+{
+  return (void *) x;
+}
+
+static cairo_always_inline cairo_atomic_int_t
+_cairo_atomic_int_cmpxchg_return_old_fallback(cairo_atomic_int_t *x, cairo_atomic_int_t oldv, cairo_atomic_int_t newv)
+{
+    cairo_atomic_int_t curr;
 
+    do {
+        curr = _cairo_atomic_int_get (x);
+    } while (curr == oldv && !_cairo_atomic_int_cmpxchg (x, oldv, newv));
+
+    return curr;
+}
+
+static cairo_always_inline void *
+_cairo_atomic_ptr_cmpxchg_return_old_fallback(void **x, void *oldv, void *newv)
+{
+    void *curr;
+
+    do {
+        curr = _cairo_atomic_ptr_get (x);
+    } while (curr == oldv && !_cairo_atomic_ptr_cmpxchg (x, oldv, newv));
+
+    return curr;
+}
 #endif
 
+#ifndef _cairo_atomic_int_cmpxchg_return_old
+#define _cairo_atomic_int_cmpxchg_return_old(x, oldv, newv) _cairo_atomic_int_cmpxchg_return_old_fallback (x, oldv, newv)
+#endif
+
+#ifndef _cairo_atomic_ptr_cmpxchg_return_old
+#define _cairo_atomic_ptr_cmpxchg_return_old(x, oldv, newv) _cairo_atomic_ptr_cmpxchg_return_old_fallback (x, oldv, newv)
+#endif
+
+#ifndef _cairo_atomic_int_cmpxchg
+#define _cairo_atomic_int_cmpxchg(x, oldv, newv) (_cairo_atomic_int_cmpxchg_return_old (x, oldv, newv) == oldv)
+#endif
+
+#ifndef _cairo_atomic_ptr_cmpxchg
+#define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) (_cairo_atomic_ptr_cmpxchg_return_old (x, oldv, newv) == oldv)
 #endif
 
 #define _cairo_atomic_uint_get(x) _cairo_atomic_int_get(x)
 #define _cairo_atomic_uint_cmpxchg(x, oldv, newv) \
     _cairo_atomic_int_cmpxchg((cairo_atomic_int_t *)x, oldv, newv)
 
 #define _cairo_status_set_error(status, err) do { \
     /* hide compiler warnings about cairo_status_t != int (gcc treats its as \
--- a/gfx/cairo/cairo/src/cairo-atomic.c
+++ b/gfx/cairo/cairo/src/cairo-atomic.c
@@ -7,17 +7,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
@@ -37,77 +37,70 @@
 #include "cairo-mutex-private.h"
 
 #ifdef HAS_ATOMIC_OPS
 COMPILE_TIME_ASSERT(sizeof(void*) == sizeof(int) ||
 		    sizeof(void*) == sizeof(long) ||
 		    sizeof(void*) == sizeof(long long));
 #else
 void
-_cairo_atomic_int_inc (int *x)
+_cairo_atomic_int_inc (cairo_atomic_intptr_t *x)
 {
     CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
     *x += 1;
     CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
 }
 
 cairo_bool_t
-_cairo_atomic_int_dec_and_test (int *x)
+_cairo_atomic_int_dec_and_test (cairo_atomic_intptr_t *x)
 {
     cairo_bool_t ret;
 
     CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
     ret = --*x == 0;
     CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
 
     return ret;
 }
 
-int
-_cairo_atomic_int_cmpxchg (int *x, int oldv, int newv)
+cairo_atomic_intptr_t
+_cairo_atomic_int_cmpxchg_return_old_impl (cairo_atomic_intptr_t *x, cairo_atomic_intptr_t oldv, cairo_atomic_intptr_t newv)
 {
-    int ret;
+    cairo_atomic_intptr_t ret;
 
     CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
     ret = *x;
     if (ret == oldv)
 	*x = newv;
     CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
 
     return ret;
 }
 
 void *
-_cairo_atomic_ptr_cmpxchg (void **x, void *oldv, void *newv)
+_cairo_atomic_ptr_cmpxchg_return_old_impl (void **x, void *oldv, void *newv)
 {
     void *ret;
 
     CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
     ret = *x;
     if (ret == oldv)
 	*x = newv;
     CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
 
     return ret;
 }
-#endif
 
 #ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER
-int
-_cairo_atomic_int_get (int *x)
+cairo_atomic_intptr_t
+_cairo_atomic_int_get (cairo_atomic_intptr_t *x)
 {
-    int ret;
+    cairo_atomic_intptr_t ret;
 
     CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
     ret = *x;
     CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
 
     return ret;
 }
+#endif
 
-void
-_cairo_atomic_int_set (int *x, int value)
-{
-    CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
-    *x = value;
-    CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
-}
 #endif
--- a/gfx/cairo/cairo/src/cairo-base64-stream.c
+++ b/gfx/cairo/cairo/src/cairo-base64-stream.c
@@ -9,17 +9,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
@@ -32,16 +32,17 @@
  * The Initial Developer of the Original Code is Red Hat, Inc.
  *
  * Author(s):
  *	Kristian Høgsberg <krh@redhat.com>
  *	Chris Wilson <chris@chris-wilson.co.uk>
  */
 
 #include "cairoint.h"
+#include "cairo-error-private.h"
 #include "cairo-output-stream-private.h"
 
 typedef struct _cairo_base64_stream {
     cairo_output_stream_t base;
     cairo_output_stream_t *output;
     unsigned int in_mem;
     unsigned int trailing;
     unsigned char src[3];
--- a/gfx/cairo/cairo/src/cairo-base85-stream.c
+++ b/gfx/cairo/cairo/src/cairo-base85-stream.c
@@ -8,17 +8,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
@@ -30,16 +30,17 @@
  *
  * The Initial Developer of the Original Code is Red Hat, Inc.
  *
  * Author(s):
  *	Kristian Høgsberg <krh@redhat.com>
  */
 
 #include "cairoint.h"
+#include "cairo-error-private.h"
 #include "cairo-output-stream-private.h"
 
 typedef struct _cairo_base85_stream {
     cairo_output_stream_t base;
     cairo_output_stream_t *output;
     unsigned char four_tuple[4];
     int pending;
 } cairo_base85_stream_t;
--- a/gfx/cairo/cairo/src/cairo-bentley-ottmann-rectangular.c
+++ b/gfx/cairo/cairo/src/cairo-bentley-ottmann-rectangular.c
@@ -8,17 +8,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
@@ -33,62 +33,66 @@
  * Contributor(s):
  *	Carl D. Worth <cworth@cworth.org>
  *	Chris Wilson <chris@chris-wilson.co.uk>
  */
 
 /* Provide definitions for standalone compilation */
 #include "cairoint.h"
 
+#include "cairo-boxes-private.h"
+#include "cairo-error-private.h"
 #include "cairo-combsort-private.h"
 #include "cairo-list-private.h"
 
-typedef struct _cairo_bo_rectangle cairo_bo_rectangle_t;
-typedef struct _cairo_bo_edge cairo_bo_edge_t;
+#include <setjmp.h>
+
+typedef struct _rectangle rectangle_t;
+typedef struct _edge edge_t;
 
-/* A deferred trapezoid of an edge */
-typedef struct _cairo_bo_trap {
-    cairo_bo_edge_t *right;
-    int32_t top;
-} cairo_bo_trap_t;
-
-struct _cairo_bo_edge {
-    int x;
+struct _edge {
+    edge_t *next, *prev;
+    edge_t *right;
+    cairo_fixed_t x, top;
     int dir;
-    cairo_bo_trap_t deferred_trap;
-    cairo_list_t link;
 };
 
-struct _cairo_bo_rectangle {
-    cairo_bo_edge_t left, right;
-    int top, bottom;
+struct _rectangle {
+    edge_t left, right;
+    int32_t top, bottom;
 };
 
+#define UNROLL3(x) x x x
+
 /* the parent is always given by index/2 */
 #define PQ_PARENT_INDEX(i) ((i) >> 1)
 #define PQ_FIRST_ENTRY 1
 
 /* left and right children are index * 2 and (index * 2) +1 respectively */
 #define PQ_LEFT_CHILD_INDEX(i) ((i) << 1)
 
 typedef struct _pqueue {
     int size, max_size;
 
-    cairo_bo_rectangle_t **elements;
-    cairo_bo_rectangle_t *elements_embedded[1024];
+    rectangle_t **elements;
+    rectangle_t *elements_embedded[1024];
 } pqueue_t;
 
-typedef struct _cairo_bo_sweep_line {
-    cairo_bo_rectangle_t **rectangles;
-    pqueue_t stop;
-    cairo_list_t sweep;
-    cairo_list_t *current_left, *current_right;
+typedef struct _sweep_line {
+    rectangle_t **rectangles;
+    pqueue_t pq;
+    edge_t head, tail;
+    edge_t *insert_left, *insert_right;
     int32_t current_y;
     int32_t last_y;
-} cairo_bo_sweep_line_t;
+
+    cairo_fill_rule_t fill_rule;
+
+    jmp_buf unwind;
+} sweep_line_t;
 
 #define DEBUG_TRAPS 0
 
 #if DEBUG_TRAPS
 static void
 dump_traps (cairo_traps_t *traps, const char *filename)
 {
     FILE *file;
@@ -116,588 +120,568 @@ dump_traps (cairo_traps_t *traps, const 
 	fclose (file);
     }
 }
 #else
 #define dump_traps(traps, filename)
 #endif
 
 static inline int
-cairo_bo_rectangle_compare_start (const cairo_bo_rectangle_t *a,
-				  const cairo_bo_rectangle_t *b)
+rectangle_compare_start (const rectangle_t *a,
+			 const rectangle_t *b)
 {
     return a->top - b->top;
 }
 
 static inline int
-_cairo_bo_rectangle_compare_stop (const cairo_bo_rectangle_t *a,
-				  const cairo_bo_rectangle_t *b)
+rectangle_compare_stop (const rectangle_t *a,
+			 const rectangle_t *b)
 {
     return a->bottom - b->bottom;
 }
 
 static inline void
-_pqueue_init (pqueue_t *pq)
+pqueue_init (pqueue_t *pq)
 {
     pq->max_size = ARRAY_LENGTH (pq->elements_embedded);
     pq->size = 0;
 
     pq->elements = pq->elements_embedded;
     pq->elements[PQ_FIRST_ENTRY] = NULL;
 }
 
 static inline void
-_pqueue_fini (pqueue_t *pq)
+pqueue_fini (pqueue_t *pq)
 {
     if (pq->elements != pq->elements_embedded)
 	free (pq->elements);
 }
 
-static cairo_status_t
-_pqueue_grow (pqueue_t *pq)
+static cairo_bool_t
+pqueue_grow (pqueue_t *pq)
 {
-    cairo_bo_rectangle_t **new_elements;
+    rectangle_t **new_elements;
     pq->max_size *= 2;
 
     if (pq->elements == pq->elements_embedded) {
 	new_elements = _cairo_malloc_ab (pq->max_size,
-					 sizeof (cairo_bo_rectangle_t *));
+					 sizeof (rectangle_t *));
 	if (unlikely (new_elements == NULL))
-	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    return FALSE;
 
 	memcpy (new_elements, pq->elements_embedded,
 		sizeof (pq->elements_embedded));
     } else {
 	new_elements = _cairo_realloc_ab (pq->elements,
 					  pq->max_size,
-					  sizeof (cairo_bo_rectangle_t *));
+					  sizeof (rectangle_t *));
 	if (unlikely (new_elements == NULL))
-	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    return FALSE;
     }
 
     pq->elements = new_elements;
-    return CAIRO_STATUS_SUCCESS;
+    return TRUE;
 }
 
-static inline cairo_status_t
-_pqueue_push (pqueue_t *pq, cairo_bo_rectangle_t *rectangle)
+static inline void
+pqueue_push (sweep_line_t *sweep, rectangle_t *rectangle)
 {
-    cairo_bo_rectangle_t **elements;
+    rectangle_t **elements;
     int i, parent;
 
-    if (unlikely (pq->size + 1 == pq->max_size)) {
-	cairo_status_t status;
-
-	status = _pqueue_grow (pq);
-	if (unlikely (status))
-	    return status;
+    if (unlikely (sweep->pq.size + 1 == sweep->pq.max_size)) {
+	if (unlikely (! pqueue_grow (&sweep->pq))) {
+	    longjmp (sweep->unwind,
+		     _cairo_error (CAIRO_STATUS_NO_MEMORY));
+	}
     }
 
-    elements = pq->elements;
-
-    for (i = ++pq->size;
+    elements = sweep->pq.elements;
+    for (i = ++sweep->pq.size;
 	 i != PQ_FIRST_ENTRY &&
-	 _cairo_bo_rectangle_compare_stop (rectangle,
-					   elements[parent = PQ_PARENT_INDEX (i)]) < 0;
+	 rectangle_compare_stop (rectangle,
+				 elements[parent = PQ_PARENT_INDEX (i)]) < 0;
 	 i = parent)
     {
 	elements[i] = elements[parent];
     }
 
     elements[i] = rectangle;
-
-    return CAIRO_STATUS_SUCCESS;
 }
 
 static inline void
-_pqueue_pop (pqueue_t *pq)
+pqueue_pop (pqueue_t *pq)
 {
-    cairo_bo_rectangle_t **elements = pq->elements;
-    cairo_bo_rectangle_t *tail;
+    rectangle_t **elements = pq->elements;
+    rectangle_t *tail;
     int child, i;
 
     tail = elements[pq->size--];
     if (pq->size == 0) {
 	elements[PQ_FIRST_ENTRY] = NULL;
 	return;
     }
 
     for (i = PQ_FIRST_ENTRY;
 	 (child = PQ_LEFT_CHILD_INDEX (i)) <= pq->size;
 	 i = child)
     {
 	if (child != pq->size &&
-	    _cairo_bo_rectangle_compare_stop (elements[child+1],
-					      elements[child]) < 0)
+	    rectangle_compare_stop (elements[child+1],
+				    elements[child]) < 0)
 	{
 	    child++;
 	}
 
-	if (_cairo_bo_rectangle_compare_stop (elements[child], tail) >= 0)
+	if (rectangle_compare_stop (elements[child], tail) >= 0)
 	    break;
 
 	elements[i] = elements[child];
     }
     elements[i] = tail;
 }
 
-static inline cairo_bo_rectangle_t *
-_cairo_bo_rectangle_pop_start (cairo_bo_sweep_line_t *sweep_line)
+static inline rectangle_t *
+rectangle_pop_start (sweep_line_t *sweep_line)
 {
     return *sweep_line->rectangles++;
 }
 
-static inline cairo_bo_rectangle_t *
-_cairo_bo_rectangle_peek_stop (cairo_bo_sweep_line_t *sweep_line)
+static inline rectangle_t *
+rectangle_peek_stop (sweep_line_t *sweep_line)
 {
-    return sweep_line->stop.elements[PQ_FIRST_ENTRY];
+    return sweep_line->pq.elements[PQ_FIRST_ENTRY];
 }
 
-CAIRO_COMBSORT_DECLARE (_cairo_bo_rectangle_sort,
-			cairo_bo_rectangle_t *,
-			cairo_bo_rectangle_compare_start)
+CAIRO_COMBSORT_DECLARE (_rectangle_sort,
+			rectangle_t *,
+			rectangle_compare_start)
 
 static void
-_cairo_bo_sweep_line_init (cairo_bo_sweep_line_t *sweep_line,
-			   cairo_bo_rectangle_t	**rectangles,
-			   int			  num_rectangles)
+sweep_line_init (sweep_line_t	 *sweep_line,
+		 rectangle_t	**rectangles,
+		 int		  num_rectangles,
+		 cairo_fill_rule_t fill_rule)
 {
-    _cairo_bo_rectangle_sort (rectangles, num_rectangles);
+    _rectangle_sort (rectangles, num_rectangles);
     rectangles[num_rectangles] = NULL;
     sweep_line->rectangles = rectangles;
 
-    cairo_list_init (&sweep_line->sweep);
-    sweep_line->current_left = &sweep_line->sweep;
-    sweep_line->current_right = &sweep_line->sweep;
+    sweep_line->head.x = INT32_MIN;
+    sweep_line->head.right = NULL;
+    sweep_line->head.dir = 0;
+    sweep_line->head.next = &sweep_line->tail;
+    sweep_line->tail.x = INT32_MAX;
+    sweep_line->tail.right = NULL;
+    sweep_line->tail.dir = 0;
+    sweep_line->tail.prev = &sweep_line->head;
+
+    sweep_line->insert_left = &sweep_line->tail;
+    sweep_line->insert_right = &sweep_line->tail;
+
     sweep_line->current_y = INT32_MIN;
     sweep_line->last_y = INT32_MIN;
 
-    _pqueue_init (&sweep_line->stop);
+    sweep_line->fill_rule = fill_rule;
+
+    pqueue_init (&sweep_line->pq);
 }
 
 static void
-_cairo_bo_sweep_line_fini (cairo_bo_sweep_line_t *sweep_line)
+sweep_line_fini (sweep_line_t *sweep_line)
 {
-    _pqueue_fini (&sweep_line->stop);
-}
-
-static inline cairo_bo_edge_t *
-link_to_edge (cairo_list_t *elt)
-{
-    return cairo_container_of (elt, cairo_bo_edge_t, link);
+    pqueue_fini (&sweep_line->pq);
 }
 
-static cairo_status_t
-_cairo_bo_edge_end_trap (cairo_bo_edge_t	*left,
-			 int32_t		 bot,
-			 cairo_traps_t	        *traps)
+static void
+edge_end_box (sweep_line_t *sweep_line,
+	      edge_t	*left,
+	      int32_t		 bot,
+	      cairo_bool_t	 do_traps,
+	      void	        *container)
 {
-    cairo_bo_trap_t *trap = &left->deferred_trap;
+    cairo_status_t status = CAIRO_STATUS_SUCCESS;
 
     /* Only emit (trivial) non-degenerate trapezoids with positive height. */
-    if (likely (trap->top < bot)) {
-	cairo_line_t _left = {
-	    { left->x, trap->top },
-	    { left->x, bot },
-	}, _right = {
-	    { trap->right->x, trap->top },
-	    { trap->right->x, bot },
-	};
-	_cairo_traps_add_trap (traps, trap->top, bot, &_left, &_right);
+    if (likely (left->top < bot)) {
+	if (do_traps) {
+	    cairo_line_t _left = {
+		{ left->x, left->top },
+		{ left->x, bot },
+	    }, _right = {
+		{ left->right->x, left->top },
+		{ left->right->x, bot },
+	    };
+	    _cairo_traps_add_trap (container, left->top, bot, &_left, &_right);
+	    status = _cairo_traps_status ((cairo_traps_t *) container);
+	} else {
+	    cairo_box_t box;
+
+	    box.p1.x = left->x;
+	    box.p1.y = left->top;
+	    box.p2.x = left->right->x;
+	    box.p2.y = bot;
+
+	    status = _cairo_boxes_add (container, &box);
+	}
     }
+    if (unlikely (status))
+	longjmp (sweep_line->unwind, status);
 
-    trap->right = NULL;
-
-    return _cairo_traps_status (traps);
+    left->right = NULL;
 }
 
 /* Start a new trapezoid at the given top y coordinate, whose edges
  * are `edge' and `edge->next'. If `edge' already has a trapezoid,
  * then either add it to the traps in `traps', if the trapezoid's
  * right edge differs from `edge->next', or do nothing if the new
  * trapezoid would be a continuation of the existing one. */
-static inline cairo_status_t
-_cairo_bo_edge_start_or_continue_trap (cairo_bo_edge_t	    *left,
-				       cairo_bo_edge_t	    *right,
-				       int		     top,
-				       cairo_traps_t	    *traps)
+static inline void
+edge_start_or_continue_box (sweep_line_t *sweep_line,
+			    edge_t	*left,
+			    edge_t	*right,
+			    int		 top,
+			    cairo_bool_t	 do_traps,
+			    void		*container)
 {
-    cairo_status_t status;
+    if (left->right == right)
+	return;
 
-    if (left->deferred_trap.right == right)
-	return CAIRO_STATUS_SUCCESS;
-
-    if (left->deferred_trap.right != NULL) {
-	if (right != NULL && left->deferred_trap.right->x == right->x) {
+    if (left->right != NULL) {
+	if (right != NULL && left->right->x == right->x) {
 	    /* continuation on right, so just swap edges */
-	    left->deferred_trap.right = right;
-	    return CAIRO_STATUS_SUCCESS;
+	    left->right = right;
+	    return;
 	}
 
-	status = _cairo_bo_edge_end_trap (left, top, traps);
-	if (unlikely (status))
-	    return status;
+	edge_end_box (sweep_line,
+		      left, top, do_traps, container);
     }
 
     if (right != NULL && left->x != right->x) {
-	left->deferred_trap.top = top;
-	left->deferred_trap.right = right;
+	left->top = top;
+	left->right = right;
     }
-
-    return CAIRO_STATUS_SUCCESS;
 }
 
-static inline cairo_status_t
-_active_edges_to_traps (cairo_bo_sweep_line_t	*sweep,
-			cairo_fill_rule_t	 fill_rule,
-			cairo_traps_t	        *traps)
+static inline void
+active_edges_to_traps (sweep_line_t	*sweep,
+		       cairo_bool_t	 do_traps,
+		       void		*container)
 {
     int top = sweep->current_y;
-    cairo_list_t *pos = &sweep->sweep;
-    cairo_status_t status;
+    edge_t *pos;
 
     if (sweep->last_y == sweep->current_y)
-	return CAIRO_STATUS_SUCCESS;
+	return;
 
-    if (fill_rule == CAIRO_FILL_RULE_WINDING) {
-	do {
-	    cairo_bo_edge_t *left, *right;
-	    int in_out;
+    pos = sweep->head.next;
+    if (pos == &sweep->tail)
+	return;
 
-	    pos = pos->next;
-	    if (pos == &sweep->sweep)
-		break;
+    if (sweep->fill_rule == CAIRO_FILL_RULE_WINDING) {
+	do {
+	    edge_t *left, *right;
+	    int winding;
 
-	    left = link_to_edge (pos);
-	    in_out = left->dir;
+	    left = pos;
+	    winding = left->dir;
+
+	    right = left->next;
 
 	    /* Check if there is a co-linear edge with an existing trap */
-	    if (left->deferred_trap.right == NULL) {
-		right = link_to_edge (pos->next);
+	    if (left->right == NULL) {
 		while (unlikely (right->x == left->x)) {
-		    if (right->deferred_trap.right != NULL) {
+		    winding += right->dir;
+		    if (right->right != NULL) {
 			/* continuation on left */
-			left->deferred_trap = right->deferred_trap;
-			right->deferred_trap.right = NULL;
+			left->top = right->top;
+			left->right = right->right;
+			right->right = NULL;
+			winding -= right->dir;
 			break;
 		    }
 
-		    if (right->link.next == &sweep->sweep)
-			break;
-		    right = link_to_edge (right->link.next);
+		    right = right->next;
+		}
+
+		if (winding == 0) {
+		    pos = right;
+		    continue;
 		}
 	    }
 
 	    /* Greedily search for the closing edge, so that we generate the
 	     * maximal span width with the minimal number of trapezoids.
 	     */
 
-	    right = link_to_edge (left->link.next);
 	    do {
 		/* End all subsumed traps */
-		if (right->deferred_trap.right != NULL) {
-		    status = _cairo_bo_edge_end_trap (right, top, traps);
-		    if (unlikely (status))
-			return status;
+		if (unlikely (right->right != NULL)) {
+		    edge_end_box (sweep,
+				  right, top, do_traps, container);
 		}
 
-		in_out += right->dir;
-		if (in_out == 0) {
+		winding += right->dir;
+		if (winding == 0) {
 		    /* skip co-linear edges */
-		    if (likely (right->link.next == &sweep->sweep ||
-				right->x != link_to_edge (right->link.next)->x))
-		    {
+		    if (likely (right->x != right->next->x))
 			break;
-		    }
 		}
 
-		right = link_to_edge (right->link.next);
+		right = right->next;
 	    } while (TRUE);
 
-	    status = _cairo_bo_edge_start_or_continue_trap (left, right,
-							    top, traps);
-	    if (unlikely (status))
-		return status;
-
-	    pos = &right->link;
-	} while (TRUE);
-    } else {
-	cairo_bo_edge_t *left, *right;
-	do {
-	    int in_out = 0;
+	    edge_start_or_continue_box (sweep,
+					left, right, top,
+					do_traps, container);
 
-	    pos = pos->next;
-	    if (pos == &sweep->sweep)
-		break;
-
-	    left = link_to_edge (pos);
+	    pos = right->next;
+	} while (pos != &sweep->tail);
+    } else {
+	do {
+	    edge_t *right = pos->next;
+	    int count = 0;
 
-	    pos = pos->next;
 	    do {
-		right = link_to_edge (pos);
-		if (right->deferred_trap.right != NULL) {
-		    status = _cairo_bo_edge_end_trap (right, top, traps);
-		    if (unlikely (status))
-			return status;
+		/* End all subsumed traps */
+		if (unlikely (right->right != NULL)) {
+		    edge_end_box (sweep,
+				  right, top, do_traps, container);
 		}
 
-		if ((in_out++ & 1) == 0) {
-		    cairo_list_t *next;
-		    cairo_bool_t skip = FALSE;
-
+		if (++count & 1) {
 		    /* skip co-linear edges */
-		    next = pos->next;
-		    if (next != &sweep->sweep)
-			skip = right->x == link_to_edge (next)->x;
-
-		    if (! skip)
+		    if (likely (right->x != right->next->x))
 			break;
 		}
-		pos = pos->next;
+
+		right = right->next;
 	    } while (TRUE);
 
-	    right = pos == &sweep->sweep ? NULL : link_to_edge (pos);
-	    status = _cairo_bo_edge_start_or_continue_trap (left, right,
-							    top, traps);
-	    if (unlikely (status))
-		return status;
-	} while (right != NULL);
+	    edge_start_or_continue_box (sweep,
+					pos, right, top,
+					do_traps, container);
+
+	    pos = right->next;
+	} while (pos != &sweep->tail);
     }
 
     sweep->last_y = sweep->current_y;
-    return CAIRO_STATUS_SUCCESS;
 }
 
-static inline cairo_status_t
-_cairo_bo_sweep_line_delete_edge (cairo_bo_sweep_line_t *sweep_line,
-	                          cairo_bo_edge_t *edge,
-				  cairo_traps_t *traps)
+static inline void
+sweep_line_delete_edge (sweep_line_t *sweep_line,
+			edge_t *edge,
+			cairo_bool_t do_traps,
+			void *container)
 {
-    if (edge->deferred_trap.right != NULL) {
-	cairo_bo_edge_t *next = link_to_edge (edge->link.next);
-	if (&next->link != &sweep_line->sweep && next->x == edge->x) {
-	    next->deferred_trap = edge->deferred_trap;
+    if (edge->right != NULL) {
+	edge_t *next = edge->next;
+	if (next->x == edge->x) {
+	    next->top = edge->top;
+	    next->right = edge->right;
 	} else {
-	    cairo_status_t status;
-
-	    status = _cairo_bo_edge_end_trap (edge,
-		                              sweep_line->current_y,
-					      traps);
-	    if (unlikely (status))
-		return status;
+	    edge_end_box (sweep_line,
+			  edge,
+			  sweep_line->current_y,
+			  do_traps, container);
 	}
     }
 
-    if (sweep_line->current_left == &edge->link)
-	sweep_line->current_left = edge->link.prev;
+    if (sweep_line->insert_left == edge)
+	sweep_line->insert_left = edge->next;
+    if (sweep_line->insert_right == edge)
+	sweep_line->insert_right = edge->next;
 
-    if (sweep_line->current_right == &edge->link)
-	sweep_line->current_right = edge->link.next;
-
-    cairo_list_del (&edge->link);
-
-    return CAIRO_STATUS_SUCCESS;
+    edge->prev->next = edge->next;
+    edge->next->prev = edge->prev;
 }
 
-static inline cairo_status_t
-_cairo_bo_sweep_line_delete (cairo_bo_sweep_line_t	*sweep_line,
-			     cairo_bo_rectangle_t	*rectangle,
-			     cairo_fill_rule_t		 fill_rule,
-			     cairo_traps_t		*traps)
+static inline cairo_bool_t
+sweep_line_delete (sweep_line_t	*sweep,
+		   rectangle_t	*rectangle,
+		   cairo_bool_t		 do_traps,
+		   void			*container)
 {
-    cairo_status_t status;
+    cairo_bool_t update;
 
-    if (rectangle->bottom != sweep_line->current_y) {
-	status = _active_edges_to_traps (sweep_line, fill_rule, traps);
-	if (unlikely (status))
-	    return status;
-
-	sweep_line->current_y = rectangle->bottom;
+    update = TRUE;
+    if (sweep->fill_rule == CAIRO_FILL_RULE_WINDING &&
+	rectangle->left.prev->dir == rectangle->left.dir)
+    {
+	update = rectangle->left.next != &rectangle->right;
     }
 
-    status = _cairo_bo_sweep_line_delete_edge (sweep_line,
-	                                       &rectangle->left,
-					       traps);
-    if (unlikely (status))
-	return status;
+    sweep_line_delete_edge (sweep,
+			    &rectangle->left,
+			    do_traps, container);
 
-    status = _cairo_bo_sweep_line_delete_edge (sweep_line,
-	                                       &rectangle->right,
-					       traps);
-    if (unlikely (status))
-	return status;
+    sweep_line_delete_edge (sweep,
+			    &rectangle->right,
+			    do_traps, container);
 
-    _pqueue_pop (&sweep_line->stop);
-    return CAIRO_STATUS_SUCCESS;
+    pqueue_pop (&sweep->pq);
+    return update;
 }
 
-static cairo_bool_t
-validate_sweep_line (cairo_bo_sweep_line_t *sweep_line)
-{
-    int32_t last_x = INT32_MIN;
-    cairo_bo_edge_t *edge;
-    cairo_list_foreach_entry (edge, cairo_bo_edge_t, &sweep_line->sweep, link) {
-	if (edge->x < last_x)
-	    return FALSE;
-	last_x = edge->x;
-    }
-    return TRUE;
-}
-static inline cairo_status_t
-_cairo_bo_sweep_line_insert (cairo_bo_sweep_line_t	*sweep_line,
-			     cairo_bo_rectangle_t	*rectangle,
-			     cairo_fill_rule_t		 fill_rule,
-			     cairo_traps_t		*traps)
+static inline void
+insert_edge (edge_t *edge, edge_t *pos)
 {
-    cairo_list_t *pos;
-    cairo_status_t status;
-
-    if (rectangle->top != sweep_line->current_y) {
-	cairo_bo_rectangle_t *stop;
+    if (pos->x != edge->x) {
+	if (pos->x > edge->x) {
+	    do {
+		UNROLL3({
+		    if (pos->prev->x <= edge->x)
+			break;
+		    pos = pos->prev;
+		})
+	    } while (TRUE);
+	} else {
+	    do {
+		UNROLL3({
+		    pos = pos->next;
+		    if (pos->x >= edge->x)
+			break;
+		})
+	    } while (TRUE);
+	}
+    }
 
-	stop = _cairo_bo_rectangle_peek_stop (sweep_line);
-	while (stop != NULL && stop->bottom < rectangle->top) {
-	    status = _cairo_bo_sweep_line_delete (sweep_line, stop,
-						  fill_rule, traps);
-	    if (unlikely (status))
-		return status;
+    pos->prev->next = edge;
+    edge->prev = pos->prev;
+    edge->next = pos;
+    pos->prev = edge;
+}
 
-	    stop = _cairo_bo_rectangle_peek_stop (sweep_line);
-	}
-
-	status = _active_edges_to_traps (sweep_line, fill_rule, traps);
-	if (unlikely (status))
-	    return status;
-
-	sweep_line->current_y = rectangle->top;
-    }
+static inline cairo_bool_t
+sweep_line_insert (sweep_line_t	*sweep,
+		   rectangle_t	*rectangle)
+{
+    edge_t *pos;
 
     /* right edge */
-    pos = sweep_line->current_right;
-    if (pos == &sweep_line->sweep)
-	pos = sweep_line->sweep.prev;
-    if (pos != &sweep_line->sweep) {
-	int cmp;
-
-	cmp = link_to_edge (pos)->x - rectangle->right.x;
-	if (cmp < 0) {
-	    while (pos->next != &sweep_line->sweep &&
-		   link_to_edge (pos->next)->x - rectangle->right.x < 0)
-	    {
-		pos = pos->next;
-	    }
-	} else if (cmp > 0) {
-	    do {
-		pos = pos->prev;
-	    } while (pos != &sweep_line->sweep &&
-		     link_to_edge (pos)->x - rectangle->right.x > 0);
-	}
-
-	cairo_list_add (&rectangle->right.link, pos);
-    } else {
-	cairo_list_add_tail (&rectangle->right.link, pos);
-    }
-    sweep_line->current_right = &rectangle->right.link;
-    assert (validate_sweep_line (sweep_line));
+    pos = sweep->insert_right;
+    insert_edge (&rectangle->right, pos);
+    sweep->insert_right = &rectangle->right;
 
     /* left edge */
-    pos = sweep_line->current_left;
-    if (pos == &sweep_line->sweep)
-	pos = sweep_line->sweep.next;
-    if (pos != &sweep_line->sweep) {
-	int cmp;
+    pos = sweep->insert_left;
+    if (pos->x > sweep->insert_right->x)
+	pos = sweep->insert_right->prev;
+    insert_edge (&rectangle->left, pos);
+    sweep->insert_left = &rectangle->left;
 
-	if (link_to_edge (pos)->x >= rectangle->right.x) {
-	    pos = rectangle->right.link.prev;
-	    if (pos == &sweep_line->sweep)
-		goto left_done;
-	}
+    pqueue_push (sweep, rectangle);
 
-	cmp = link_to_edge (pos)->x - rectangle->left.x;
-	if (cmp < 0) {
-	    while (pos->next != &sweep_line->sweep &&
-		   link_to_edge (pos->next)->x - rectangle->left.x < 0)
-	    {
-		pos = pos->next;
-	    }
-	} else if (cmp > 0) {
-	    do {
-		pos = pos->prev;
-	    } while (pos != &sweep_line->sweep &&
-		    link_to_edge (pos)->x - rectangle->left.x > 0);
-	}
+    if (sweep->fill_rule == CAIRO_FILL_RULE_WINDING &&
+	rectangle->left.prev->dir == rectangle->left.dir)
+    {
+	return rectangle->left.next != &rectangle->right;
     }
-  left_done:
-    cairo_list_add (&rectangle->left.link, pos);
-    sweep_line->current_left = &rectangle->left.link;
-    assert (validate_sweep_line (sweep_line));
 
-    return _pqueue_push (&sweep_line->stop, rectangle);
+    return TRUE;
 }
 
 static cairo_status_t
-_cairo_bentley_ottmann_tessellate_rectangular (cairo_bo_rectangle_t	**rectangles,
+_cairo_bentley_ottmann_tessellate_rectangular (rectangle_t	**rectangles,
 					       int			  num_rectangles,
 					       cairo_fill_rule_t	  fill_rule,
-					       cairo_traps_t		 *traps)
+					       cairo_bool_t		 do_traps,
+					       void			*container)
 {
-    cairo_bo_sweep_line_t sweep_line;
-    cairo_bo_rectangle_t *rectangle;
-    cairo_status_t status = CAIRO_STATUS_SUCCESS;
+    sweep_line_t sweep_line;
+    rectangle_t *rectangle;
+    cairo_status_t status;
+    cairo_bool_t update = FALSE;
+
+    sweep_line_init (&sweep_line, rectangles, num_rectangles, fill_rule);
+    if ((status = setjmp (sweep_line.unwind)))
+	goto unwind;
+
+    rectangle = rectangle_pop_start (&sweep_line);
+    do {
+	if (rectangle->top != sweep_line.current_y) {
+	    rectangle_t *stop;
+
+	    stop = rectangle_peek_stop (&sweep_line);
+	    while (stop != NULL && stop->bottom < rectangle->top) {
+		if (stop->bottom != sweep_line.current_y) {
+		    if (update) {
+			active_edges_to_traps (&sweep_line,
+					       do_traps, container);
+			update = FALSE;
+		    }
 
-    _cairo_bo_sweep_line_init (&sweep_line, rectangles, num_rectangles);
+		    sweep_line.current_y = stop->bottom;
+		}
+
+		update |= sweep_line_delete (&sweep_line, stop, do_traps, container);
+
+		stop = rectangle_peek_stop (&sweep_line);
+	    }
+
+	    if (update) {
+		active_edges_to_traps (&sweep_line, do_traps, container);
+		update = FALSE;
+	    }
 
-    while ((rectangle = _cairo_bo_rectangle_pop_start (&sweep_line)) != NULL) {
-	status = _cairo_bo_sweep_line_insert (&sweep_line, rectangle,
-					      fill_rule, traps);
-	if (unlikely (status))
-	    goto BAIL;
+	    sweep_line.current_y = rectangle->top;
+	}
+
+	update |= sweep_line_insert (&sweep_line, rectangle);
+    } while ((rectangle = rectangle_pop_start (&sweep_line)) != NULL);
+
+    while ((rectangle = rectangle_peek_stop (&sweep_line)) != NULL) {
+	if (rectangle->bottom != sweep_line.current_y) {
+	    if (update) {
+		active_edges_to_traps (&sweep_line, do_traps, container);
+		update = FALSE;
+	    }
+
+	    sweep_line.current_y = rectangle->bottom;
+	}
+
+	update |= sweep_line_delete (&sweep_line, rectangle, do_traps, container);
     }
 
-    while ((rectangle = _cairo_bo_rectangle_peek_stop (&sweep_line)) != NULL) {
-	status = _cairo_bo_sweep_line_delete (&sweep_line, rectangle,
-					      fill_rule, traps);
-	if (unlikely (status))
-	    goto BAIL;
-    }
-
-BAIL:
-    _cairo_bo_sweep_line_fini (&sweep_line);
+unwind:
+    sweep_line_fini (&sweep_line);
     return status;
 }
 
 cairo_status_t
 _cairo_bentley_ottmann_tessellate_rectangular_traps (cairo_traps_t *traps,
 						     cairo_fill_rule_t fill_rule)
 {
-    cairo_bo_rectangle_t stack_rectangles[CAIRO_STACK_ARRAY_LENGTH (cairo_bo_rectangle_t)];
-    cairo_bo_rectangle_t *rectangles;
-    cairo_bo_rectangle_t *stack_rectangles_ptrs[ARRAY_LENGTH (stack_rectangles) + 1];
-    cairo_bo_rectangle_t **rectangles_ptrs;
+    rectangle_t stack_rectangles[CAIRO_STACK_ARRAY_LENGTH (rectangle_t)];
+    rectangle_t *rectangles;
+    rectangle_t *stack_rectangles_ptrs[ARRAY_LENGTH (stack_rectangles) + 1];
+    rectangle_t **rectangles_ptrs;
     cairo_status_t status;
     int i;
 
-    if (unlikely (traps->num_traps == 0))
+    if (unlikely (traps->num_traps <= 1))
 	return CAIRO_STATUS_SUCCESS;
 
     assert (traps->is_rectangular);
 
     dump_traps (traps, "bo-rects-traps-in.txt");
 
     rectangles = stack_rectangles;
     rectangles_ptrs = stack_rectangles_ptrs;
     if (traps->num_traps > ARRAY_LENGTH (stack_rectangles)) {
 	rectangles = _cairo_malloc_ab_plus_c (traps->num_traps,
-					  sizeof (cairo_bo_rectangle_t) +
-					  sizeof (cairo_bo_rectangle_t *),
-					  sizeof (cairo_bo_rectangle_t *));
+					  sizeof (rectangle_t) +
+					  sizeof (rectangle_t *),
+					  sizeof (rectangle_t *));
 	if (unlikely (rectangles == NULL))
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
-	rectangles_ptrs = (cairo_bo_rectangle_t **) (rectangles + traps->num_traps);
+	rectangles_ptrs = (rectangle_t **) (rectangles + traps->num_traps);
     }
 
     for (i = 0; i < traps->num_traps; i++) {
 	if (traps->traps[i].left.p1.x < traps->traps[i].right.p1.x) {
 	    rectangles[i].left.x = traps->traps[i].left.p1.x;
 	    rectangles[i].left.dir = 1;
 
 	    rectangles[i].right.x = traps->traps[i].right.p1.x;
@@ -705,35 +689,99 @@ cairo_status_t
 	} else {
 	    rectangles[i].right.x = traps->traps[i].left.p1.x;
 	    rectangles[i].right.dir = 1;
 
 	    rectangles[i].left.x = traps->traps[i].right.p1.x;
 	    rectangles[i].left.dir = -1;
 	}
 
-	rectangles[i].left.deferred_trap.right = NULL;
-	cairo_list_init (&rectangles[i].left.link);
-
-	rectangles[i].right.deferred_trap.right = NULL;
-	cairo_list_init (&rectangles[i].right.link);
+	rectangles[i].left.right = NULL;
+	rectangles[i].right.right = NULL;
 
 	rectangles[i].top = traps->traps[i].top;
 	rectangles[i].bottom = traps->traps[i].bottom;
 
 	rectangles_ptrs[i] = &rectangles[i];
     }
 
     _cairo_traps_clear (traps);
     status = _cairo_bentley_ottmann_tessellate_rectangular (rectangles_ptrs, i,
 							    fill_rule,
-							    traps);
+							    TRUE, traps);
     traps->is_rectilinear = TRUE;
     traps->is_rectangular = TRUE;
 
     if (rectangles != stack_rectangles)
 	free (rectangles);
 
     dump_traps (traps, "bo-rects-traps-out.txt");
 
+    return status;
+}
+
+cairo_status_t
+_cairo_bentley_ottmann_tessellate_boxes (const cairo_boxes_t *in,
+					 cairo_fill_rule_t fill_rule,
+					 cairo_boxes_t *out)
+{
+    rectangle_t stack_rectangles[CAIRO_STACK_ARRAY_LENGTH (rectangle_t)];
+    rectangle_t *rectangles;
+    rectangle_t *stack_rectangles_ptrs[ARRAY_LENGTH (stack_rectangles) + 1];
+    rectangle_t **rectangles_ptrs;
+    const struct _cairo_boxes_chunk *chunk;
+    cairo_status_t status;
+    int i, j;
+
+    if (unlikely (in->num_boxes <= 1))
+	return CAIRO_STATUS_SUCCESS;
+
+    rectangles = stack_rectangles;
+    rectangles_ptrs = stack_rectangles_ptrs;
+    if (in->num_boxes > ARRAY_LENGTH (stack_rectangles)) {
+	rectangles = _cairo_malloc_ab_plus_c (in->num_boxes,
+					  sizeof (rectangle_t) +
+					  sizeof (rectangle_t *),
+					  sizeof (rectangle_t *));
+	if (unlikely (rectangles == NULL))
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+	rectangles_ptrs = (rectangle_t **) (rectangles + in->num_boxes);
+    }
+
+    j = 0;
+    for (chunk = &in->chunks; chunk != NULL; chunk = chunk->next) {
+	const cairo_box_t *box = chunk->base;
+	for (i = 0; i < chunk->count; i++) {
+	    if (box[i].p1.x < box[i].p2.x) {
+		rectangles[j].left.x = box[i].p1.x;
+		rectangles[j].left.dir = 1;
+
+		rectangles[j].right.x = box[i].p2.x;
+		rectangles[j].right.dir = -1;
+	    } else {
+		rectangles[j].right.x = box[i].p1.x;
+		rectangles[j].right.dir = 1;
+
+		rectangles[j].left.x = box[i].p2.x;
+		rectangles[j].left.dir = -1;
+	    }
+
+	    rectangles[j].left.right = NULL;
+	    rectangles[j].right.right = NULL;
+
+	    rectangles[j].top = box[i].p1.y;
+	    rectangles[j].bottom = box[i].p2.y;
+
+	    rectangles_ptrs[j] = &rectangles[j];
+	    j++;
+	}
+    }
+
+    _cairo_boxes_clear (out);
+    status = _cairo_bentley_ottmann_tessellate_rectangular (rectangles_ptrs, j,
+							    fill_rule,
+							    FALSE, out);
+    if (rectangles != stack_rectangles)
+	free (rectangles);
 
     return status;
 }
--- a/gfx/cairo/cairo/src/cairo-bentley-ottmann-rectilinear.c
+++ b/gfx/cairo/cairo/src/cairo-bentley-ottmann-rectilinear.c
@@ -8,17 +8,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
@@ -33,17 +33,19 @@
  * Contributor(s):
  *	Carl D. Worth <cworth@cworth.org>
  *	Chris Wilson <chris@chris-wilson.co.uk>
  */
 
 /* Provide definitions for standalone compilation */
 #include "cairoint.h"
 
+#include "cairo-boxes-private.h"
 #include "cairo-combsort-private.h"
+#include "cairo-error-private.h"
 
 typedef struct _cairo_bo_edge cairo_bo_edge_t;
 typedef struct _cairo_bo_trap cairo_bo_trap_t;
 
 /* A deferred trapezoid of an edge */
 struct _cairo_bo_trap {
     cairo_bo_edge_t *right;
     int32_t top;
@@ -210,74 +212,89 @@ static inline cairo_bool_t
 edges_collinear (const cairo_bo_edge_t *a, const cairo_bo_edge_t *b)
 {
     return a->edge.line.p1.x == b->edge.line.p1.x;
 }
 
 static cairo_status_t
 _cairo_bo_edge_end_trap (cairo_bo_edge_t	*left,
 			 int32_t		 bot,
-			 cairo_traps_t	        *traps)
+			 cairo_bool_t		 do_traps,
+			 void			*container)
 {
     cairo_bo_trap_t *trap = &left->deferred_trap;
+    cairo_status_t status = CAIRO_STATUS_SUCCESS;
 
     /* Only emit (trivial) non-degenerate trapezoids with positive height. */
     if (likely (trap->top < bot)) {
-	_cairo_traps_add_trap (traps,
-			       trap->top, bot,
-			       &left->edge.line, &trap->right->edge.line);
+	if (do_traps) {
+	    _cairo_traps_add_trap (container,
+				   trap->top, bot,
+				   &left->edge.line, &trap->right->edge.line);
+	    status =  _cairo_traps_status ((cairo_traps_t *) container);
+	} else {
+	    cairo_box_t box;
+
+	    box.p1.x = left->edge.line.p1.x;
+	    box.p1.y = trap->top;
+	    box.p2.x = trap->right->edge.line.p1.x;
+	    box.p2.y = bot;
+	    status = _cairo_boxes_add (container, &box);
+	}
     }
 
     trap->right = NULL;
 
-    return _cairo_traps_status (traps);
+    return status;
 }
 
 /* Start a new trapezoid at the given top y coordinate, whose edges
  * are `edge' and `edge->next'. If `edge' already has a trapezoid,
  * then either add it to the traps in `traps', if the trapezoid's
  * right edge differs from `edge->next', or do nothing if the new
  * trapezoid would be a continuation of the existing one. */
 static inline cairo_status_t
 _cairo_bo_edge_start_or_continue_trap (cairo_bo_edge_t	*left,
 				       cairo_bo_edge_t  *right,
 				       int               top,
-				       cairo_traps_t	*traps)
+				       cairo_bool_t	 do_traps,
+				       void		*container)
 {
     cairo_status_t status;
 
     if (left->deferred_trap.right == right)
 	return CAIRO_STATUS_SUCCESS;
 
     if (left->deferred_trap.right != NULL) {
 	if (right != NULL && edges_collinear (left->deferred_trap.right, right))
 	{
 	    /* continuation on right, so just swap edges */
 	    left->deferred_trap.right = right;
 	    return CAIRO_STATUS_SUCCESS;
 	}
 
-	status = _cairo_bo_edge_end_trap (left, top, traps);
+	status = _cairo_bo_edge_end_trap (left, top, do_traps, container);
 	if (unlikely (status))
 	    return status;
     }
 
     if (right != NULL && ! edges_collinear (left, right)) {
 	left->deferred_trap.top = top;
 	left->deferred_trap.right = right;
     }
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static inline cairo_status_t
 _active_edges_to_traps (cairo_bo_edge_t		*left,
 			int32_t			 top,
 			cairo_fill_rule_t	 fill_rule,
-			cairo_traps_t	        *traps)
+			cairo_bool_t		 do_traps,
+			void			*container)
 {
     cairo_bo_edge_t *right;
     cairo_status_t status;
 
     if (fill_rule == CAIRO_FILL_RULE_WINDING) {
 	while (left != NULL) {
 	    int in_out;
 
@@ -298,17 +315,17 @@ static inline cairo_status_t
 		    right->deferred_trap.right = NULL;
 		}
 	    }
 
 	    /* End all subsumed traps */
 	    right = left->next;
 	    while (right != NULL) {
 		if (right->deferred_trap.right != NULL) {
-		    status = _cairo_bo_edge_end_trap (right, top, traps);
+		    status = _cairo_bo_edge_end_trap (right, top, do_traps, container);
 		    if (unlikely (status))
 			return status;
 		}
 
 		in_out += right->edge.dir;
 		if (in_out == 0) {
 		    /* skip co-linear edges */
 		    if (right->next == NULL ||
@@ -316,33 +333,33 @@ static inline cairo_status_t
 		    {
 			break;
 		    }
 		}
 
 		right = right->next;
 	    }
 
-	    status = _cairo_bo_edge_start_or_continue_trap (left, right,
-							    top, traps);
+	    status = _cairo_bo_edge_start_or_continue_trap (left, right, top,
+							    do_traps, container);
 	    if (unlikely (status))
 		return status;
 
 	    left = right;
 	    if (left != NULL)
 		left = left->next;
 	}
     } else {
 	while (left != NULL) {
 	    int in_out = 0;
 
 	    right = left->next;
 	    while (right != NULL) {
 		if (right->deferred_trap.right != NULL) {
-		    status = _cairo_bo_edge_end_trap (right, top, traps);
+		    status = _cairo_bo_edge_end_trap (right, top, do_traps, container);
 		    if (unlikely (status))
 			return status;
 		}
 
 		if ((in_out++ & 1) == 0) {
 		    cairo_bo_edge_t *next;
 		    cairo_bool_t skip = FALSE;
 
@@ -353,47 +370,48 @@ static inline cairo_status_t
 
 		    if (! skip)
 			break;
 		}
 
 		right = right->next;
 	    }
 
-	    status = _cairo_bo_edge_start_or_continue_trap (left, right,
-							    top, traps);
+	    status = _cairo_bo_edge_start_or_continue_trap (left, right, top,
+							    do_traps, container);
 	    if (unlikely (status))
 		return status;
 
 	    left = right;
 	    if (left != NULL)
 		left = left->next;
 	}
     }
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
 _cairo_bentley_ottmann_tessellate_rectilinear (cairo_bo_event_t   **start_events,
 					       int			 num_events,
 					       cairo_fill_rule_t	 fill_rule,
-					       cairo_traps_t	*traps)
+					       cairo_bool_t		 do_traps,
+					       void			*container)
 {
     cairo_bo_sweep_line_t sweep_line;
     cairo_bo_event_t *event;
     cairo_status_t status;
 
     _cairo_bo_sweep_line_init (&sweep_line, start_events, num_events);
 
     while ((event = _cairo_bo_event_dequeue (&sweep_line))) {
 	if (event->point.y != sweep_line.current_y) {
 	    status = _active_edges_to_traps (sweep_line.head,
 					     sweep_line.current_y,
-					     fill_rule, traps);
+					     fill_rule, do_traps, container);
 	    if (unlikely (status))
 		return status;
 
 	    sweep_line.current_y = event->point.y;
 	}
 
 	switch (event->type) {
 	case CAIRO_BO_EVENT_TYPE_START:
@@ -401,17 +419,17 @@ static cairo_status_t
 	    break;
 
 	case CAIRO_BO_EVENT_TYPE_STOP:
 	    _cairo_bo_sweep_line_delete (&sweep_line, event->edge);
 
 	    if (event->edge->deferred_trap.right != NULL) {
 		status = _cairo_bo_edge_end_trap (event->edge,
 						  sweep_line.current_y,
-						  traps);
+						  do_traps, container);
 		if (unlikely (status))
 		    return status;
 	    }
 
 	    break;
 	}
     }
 
@@ -471,26 +489,93 @@ cairo_status_t
 	events[j].type = CAIRO_BO_EVENT_TYPE_STOP;
 	events[j].point.y = polygon->edges[i].bottom;
 	events[j].point.x = polygon->edges[i].line.p1.x;
 	events[j].edge = &edges[i];
 	j++;
     }
 
     status = _cairo_bentley_ottmann_tessellate_rectilinear (event_ptrs, j,
-							    fill_rule, traps);
+							    fill_rule,
+							    TRUE, traps);
     if (events != stack_events)
 	free (events);
 
     traps->is_rectilinear = TRUE;
 
     return status;
 }
 
 cairo_status_t
+_cairo_bentley_ottmann_tessellate_rectilinear_polygon_to_boxes (const cairo_polygon_t *polygon,
+								cairo_fill_rule_t	  fill_rule,
+								cairo_boxes_t *boxes)
+{
+    cairo_status_t status;
+    cairo_bo_event_t stack_events[CAIRO_STACK_ARRAY_LENGTH (cairo_bo_event_t)];
+    cairo_bo_event_t *events;
+    cairo_bo_event_t *stack_event_ptrs[ARRAY_LENGTH (stack_events) + 1];
+    cairo_bo_event_t **event_ptrs;
+    cairo_bo_edge_t stack_edges[ARRAY_LENGTH (stack_events)];
+    cairo_bo_edge_t *edges;
+    int num_events;
+    int i, j;
+
+    if (unlikely (polygon->num_edges == 0))
+	return CAIRO_STATUS_SUCCESS;
+
+    num_events = 2 * polygon->num_edges;
+
+    events = stack_events;
+    event_ptrs = stack_event_ptrs;
+    edges = stack_edges;
+    if (num_events > ARRAY_LENGTH (stack_events)) {
+	events = _cairo_malloc_ab_plus_c (num_events,
+					  sizeof (cairo_bo_event_t) +
+					  sizeof (cairo_bo_edge_t) +
+					  sizeof (cairo_bo_event_t *),
+					  sizeof (cairo_bo_event_t *));
+	if (unlikely (events == NULL))
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+	event_ptrs = (cairo_bo_event_t **) (events + num_events);
+	edges = (cairo_bo_edge_t *) (event_ptrs + num_events + 1);
+    }
+
+    for (i = j = 0; i < polygon->num_edges; i++) {
+	edges[i].edge = polygon->edges[i];
+	edges[i].deferred_trap.right = NULL;
+	edges[i].prev = NULL;
+	edges[i].next = NULL;
+
+	event_ptrs[j] = &events[j];
+	events[j].type = CAIRO_BO_EVENT_TYPE_START;
+	events[j].point.y = polygon->edges[i].top;
+	events[j].point.x = polygon->edges[i].line.p1.x;
+	events[j].edge = &edges[i];
+	j++;
+
+	event_ptrs[j] = &events[j];
+	events[j].type = CAIRO_BO_EVENT_TYPE_STOP;
+	events[j].point.y = polygon->edges[i].bottom;
+	events[j].point.x = polygon->edges[i].line.p1.x;
+	events[j].edge = &edges[i];
+	j++;
+    }
+
+    status = _cairo_bentley_ottmann_tessellate_rectilinear (event_ptrs, j,
+							    fill_rule,
+							    FALSE, boxes);
+    if (events != stack_events)
+	free (events);
+
+    return status;
+}
+
+cairo_status_t
 _cairo_bentley_ottmann_tessellate_rectilinear_traps (cairo_traps_t *traps,
 						     cairo_fill_rule_t fill_rule)
 {
     cairo_bo_event_t stack_events[CAIRO_STACK_ARRAY_LENGTH (cairo_bo_event_t)];
     cairo_bo_event_t *events;
     cairo_bo_event_t *stack_event_ptrs[ARRAY_LENGTH (stack_events) + 1];
     cairo_bo_event_t **event_ptrs;
     cairo_bo_edge_t stack_edges[ARRAY_LENGTH (stack_events)];
@@ -567,16 +652,16 @@ cairo_status_t
 	events[j].edge = &edges[k];
 	j++;
 	k++;
     }
 
     _cairo_traps_clear (traps);
     status = _cairo_bentley_ottmann_tessellate_rectilinear (event_ptrs, j,
 							    fill_rule,
-							    traps);
+							    TRUE, traps);
     traps->is_rectilinear = TRUE;
 
     if (events != stack_events)
 	free (events);
 
     return status;
 }
--- a/gfx/cairo/cairo/src/cairo-bentley-ottmann.c
+++ b/gfx/cairo/cairo/src/cairo-bentley-ottmann.c
@@ -8,17 +8,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
@@ -33,16 +33,17 @@
  * Contributor(s):
  *	Carl D. Worth <cworth@cworth.org>
  *	Chris Wilson <chris@chris-wilson.co.uk>
  */
 
 /* Provide definitions for standalone compilation */
 #include "cairoint.h"
 
+#include "cairo-error-private.h"
 #include "cairo-freelist-private.h"
 #include "cairo-combsort-private.h"
 
 #define DEBUG_PRINT_STATE 0
 #define DEBUG_EVENTS 0
 #define DEBUG_TRAPS 0
 
 typedef cairo_point_t cairo_bo_point32_t;
@@ -124,31 +125,35 @@ typedef struct _cairo_bo_sweep_line {
     cairo_bo_edge_t *current_edge;
 } cairo_bo_sweep_line_t;
 
 #if DEBUG_TRAPS
 static void
 dump_traps (cairo_traps_t *traps, const char *filename)
 {
     FILE *file;
+    cairo_box_t extents;
     int n;
 
     if (getenv ("CAIRO_DEBUG_TRAPS") == NULL)
 	return;
 
+#if 0
     if (traps->has_limits) {
 	printf ("%s: limits=(%d, %d, %d, %d)\n",
 		filename,
 		traps->limits.p1.x, traps->limits.p1.y,
 		traps->limits.p2.x, traps->limits.p2.y);
     }
+#endif
+    _cairo_traps_extents (traps, &extents);
     printf ("%s: extents=(%d, %d, %d, %d)\n",
 	    filename,
-	    traps->extents.p1.x, traps->extents.p1.y,
-	    traps->extents.p2.x, traps->extents.p2.y);
+	    extents.p1.x, extents.p1.y,
+	    extents.p2.x, extents.p2.y);
 
     file = fopen (filename, "a");
     if (file != NULL) {
 	for (n = 0; n < traps->num_traps; n++) {
 	    fprintf (file, "%d %d L:(%d, %d), (%d, %d) R:(%d, %d), (%d, %d)\n",
 		     traps->traps[n].top,
 		     traps->traps[n].bottom,
 		     traps->traps[n].left.p1.x,
--- a/gfx/cairo/cairo/src/cairo-beos.h
+++ b/gfx/cairo/cairo/src/cairo-beos.h
@@ -7,17 +7,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/cairo/src/cairo-botor-scan-converter.c
@@ -0,0 +1,2199 @@
+/*
+ * Copyright © 2004 Carl Worth
+ * Copyright © 2006 Red Hat, Inc.
+ * Copyright © 2007 David Turner
+ * Copyright © 2008 M Joonas Pihlaja
+ * Copyright © 2008 Chris Wilson
+ * Copyright © 2009 Intel 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Carl Worth
+ *
+ * Contributor(s):
+ *	Carl D. Worth <cworth@cworth.org>
+ *      M Joonas Pihlaja <jpihlaja@cc.helsinki.fi>
+ *	Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+/* Provide definitions for standalone compilation */
+#include "cairoint.h"
+
+#include "cairo-error-private.h"
+#include "cairo-list-private.h"
+#include "cairo-freelist-private.h"
+#include "cairo-combsort-private.h"
+
+#include <setjmp.h>
+
+#define STEP_X CAIRO_FIXED_ONE
+#define STEP_Y CAIRO_FIXED_ONE
+#define UNROLL3(x) x x x
+
+#define STEP_XY (2*STEP_X*STEP_Y) /* Unit area in the step. */
+#define AREA_TO_ALPHA(c)  (((c)*255 + STEP_XY/2) / STEP_XY)
+
+typedef struct _cairo_bo_intersect_ordinate {
+    int32_t ordinate;
+    enum { EXACT, INEXACT } exactness;
+} cairo_bo_intersect_ordinate_t;
+
+typedef struct _cairo_bo_intersect_point {
+    cairo_bo_intersect_ordinate_t x;
+    cairo_bo_intersect_ordinate_t y;
+} cairo_bo_intersect_point_t;
+
+struct quorem {
+    cairo_fixed_t quo;
+    cairo_fixed_t rem;
+};
+
+struct run {
+    struct run *next;
+    int sign;
+    cairo_fixed_t y;
+};
+
+typedef struct edge {
+    cairo_list_t link;
+
+    cairo_edge_t edge;
+
+    /* Current x coordinate and advancement.
+     * Initialised to the x coordinate of the top of the
+     * edge. The quotient is in cairo_fixed_t units and the
+     * remainder is mod dy in cairo_fixed_t units.
+     */
+    cairo_fixed_t dy;
+    struct quorem x;
+    struct quorem dxdy;
+    struct quorem dxdy_full;
+
+    cairo_bool_t vertical;
+    unsigned int flags;
+
+    int current_sign;
+    struct run *runs;
+} edge_t;
+
+enum {
+    START = 0x1,
+    STOP = 0x2,
+};
+
+/* the parent is always given by index/2 */
+#define PQ_PARENT_INDEX(i) ((i) >> 1)
+#define PQ_FIRST_ENTRY 1
+
+/* left and right children are index * 2 and (index * 2) +1 respectively */
+#define PQ_LEFT_CHILD_INDEX(i) ((i) << 1)
+
+typedef enum {
+    EVENT_TYPE_STOP,
+    EVENT_TYPE_INTERSECTION,
+    EVENT_TYPE_START
+} event_type_t;
+
+typedef struct _event {
+    cairo_fixed_t y;
+    event_type_t type;
+} event_t;
+
+typedef struct _start_event {
+    cairo_fixed_t y;
+    event_type_t type;
+    edge_t *edge;
+} start_event_t;
+
+typedef struct _queue_event {
+    cairo_fixed_t y;
+    event_type_t type;
+    edge_t *e1;
+    edge_t *e2;
+} queue_event_t;
+
+typedef struct _pqueue {
+    int size, max_size;
+
+    event_t **elements;
+    event_t *elements_embedded[1024];
+} pqueue_t;
+
+struct cell {
+    struct cell	*prev;
+    struct cell	*next;
+    int		 x;
+    int		 uncovered_area;
+    int		 covered_height;
+};
+
+typedef struct _sweep_line {
+    cairo_list_t active;
+    cairo_list_t stopped;
+    cairo_list_t *insert_cursor;
+    cairo_bool_t is_vertical;
+
+    cairo_fixed_t current_row;
+    cairo_fixed_t current_subrow;
+
+    struct coverage {
+	struct cell head;
+	struct cell tail;
+
+	struct cell *cursor;
+	int count;
+
+	cairo_freepool_t pool;
+    } coverage;
+
+    struct event_queue {
+	pqueue_t pq;
+	event_t **start_events;
+
+	cairo_freepool_t pool;
+    } queue;
+
+    cairo_freepool_t runs;
+
+    jmp_buf unwind;
+} sweep_line_t;
+
+cairo_always_inline static struct quorem
+floored_divrem (int a, int b)
+{
+    struct quorem qr;
+    qr.quo = a/b;
+    qr.rem = a%b;
+    if ((a^b)<0 && qr.rem) {
+	qr.quo--;
+	qr.rem += b;
+    }
+    return qr;
+}
+
+static struct quorem
+floored_muldivrem(int x, int a, int b)
+{
+    struct quorem qr;
+    long long xa = (long long)x*a;
+    qr.quo = xa/b;
+    qr.rem = xa%b;
+    if ((xa>=0) != (b>=0) && qr.rem) {
+	qr.quo--;
+	qr.rem += b;
+    }
+    return qr;
+}
+
+static cairo_fixed_t
+line_compute_intersection_x_for_y (const cairo_line_t *line,
+				   cairo_fixed_t y)
+{
+    cairo_fixed_t x, dy;
+
+    if (y == line->p1.y)
+	return line->p1.x;
+    if (y == line->p2.y)
+	return line->p2.x;
+
+    x = line->p1.x;
+    dy = line->p2.y - line->p1.y;
+    if (dy != 0) {
+	x += _cairo_fixed_mul_div_floor (y - line->p1.y,
+					 line->p2.x - line->p1.x,
+					 dy);
+    }
+
+    return x;
+}
+
+/*
+ * We need to compare the x-coordinates of a pair of lines for a particular y,
+ * without loss of precision.
+ *
+ * The x-coordinate along an edge for a given y is:
+ *   X = A_x + (Y - A_y) * A_dx / A_dy
+ *
+ * So the inequality we wish to test is:
+ *   A_x + (Y - A_y) * A_dx / A_dy ∘ B_x + (Y - B_y) * B_dx / B_dy,
+ * where ∘ is our inequality operator.
+ *
+ * By construction, we know that A_dy and B_dy (and (Y - A_y), (Y - B_y)) are
+ * all positive, so we can rearrange it thus without causing a sign change:
+ *   A_dy * B_dy * (A_x - B_x) ∘ (Y - B_y) * B_dx * A_dy
+ *                                 - (Y - A_y) * A_dx * B_dy
+ *
+ * Given the assumption that all the deltas fit within 32 bits, we can compute
+ * this comparison directly using 128 bit arithmetic. For certain, but common,
+ * input we can reduce this down to a single 32 bit compare by inspecting the
+ * deltas.
+ *
+ * (And put the burden of the work on developing fast 128 bit ops, which are
+ * required throughout the tessellator.)
+ *
+ * See the similar discussion for _slope_compare().
+ */
+static int
+edges_compare_x_for_y_general (const cairo_edge_t *a,
+			       const cairo_edge_t *b,
+			       int32_t y)
+{
+    /* XXX: We're assuming here that dx and dy will still fit in 32
+     * bits. That's not true in general as there could be overflow. We
+     * should prevent that before the tessellation algorithm
+     * begins.
+     */
+    int32_t dx;
+    int32_t adx, ady;
+    int32_t bdx, bdy;
+    enum {
+       HAVE_NONE    = 0x0,
+       HAVE_DX      = 0x1,
+       HAVE_ADX     = 0x2,
+       HAVE_DX_ADX  = HAVE_DX | HAVE_ADX,
+       HAVE_BDX     = 0x4,
+       HAVE_DX_BDX  = HAVE_DX | HAVE_BDX,
+       HAVE_ADX_BDX = HAVE_ADX | HAVE_BDX,
+       HAVE_ALL     = HAVE_DX | HAVE_ADX | HAVE_BDX
+    } have_dx_adx_bdx = HAVE_ALL;
+
+    /* don't bother solving for abscissa if the edges' bounding boxes
+     * can be used to order them. */
+    {
+           int32_t amin, amax;
+           int32_t bmin, bmax;
+           if (a->line.p1.x < a->line.p2.x) {
+                   amin = a->line.p1.x;
+                   amax = a->line.p2.x;
+           } else {
+                   amin = a->line.p2.x;
+                   amax = a->line.p1.x;
+           }
+           if (b->line.p1.x < b->line.p2.x) {
+                   bmin = b->line.p1.x;
+                   bmax = b->line.p2.x;
+           } else {
+                   bmin = b->line.p2.x;
+                   bmax = b->line.p1.x;
+           }
+           if (amax < bmin) return -1;
+           if (amin > bmax) return +1;
+    }
+
+    ady = a->line.p2.y - a->line.p1.y;
+    adx = a->line.p2.x - a->line.p1.x;
+    if (adx == 0)
+	have_dx_adx_bdx &= ~HAVE_ADX;
+
+    bdy = b->line.p2.y - b->line.p1.y;
+    bdx = b->line.p2.x - b->line.p1.x;
+    if (bdx == 0)
+	have_dx_adx_bdx &= ~HAVE_BDX;
+
+    dx = a->line.p1.x - b->line.p1.x;
+    if (dx == 0)
+	have_dx_adx_bdx &= ~HAVE_DX;
+
+#define L _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (ady, bdy), dx)
+#define A _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (adx, bdy), y - a->line.p1.y)
+#define B _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (bdx, ady), y - b->line.p1.y)
+    switch (have_dx_adx_bdx) {
+    default:
+    case HAVE_NONE:
+	return 0;
+    case HAVE_DX:
+	/* A_dy * B_dy * (A_x - B_x) ∘ 0 */
+	return dx; /* ady * bdy is positive definite */
+    case HAVE_ADX:
+	/* 0 ∘  - (Y - A_y) * A_dx * B_dy */
+	return adx; /* bdy * (y - a->top.y) is positive definite */
+    case HAVE_BDX:
+	/* 0 ∘ (Y - B_y) * B_dx * A_dy */
+	return -bdx; /* ady * (y - b->top.y) is positive definite */
+    case HAVE_ADX_BDX:
+	/*  0 ∘ (Y - B_y) * B_dx * A_dy - (Y - A_y) * A_dx * B_dy */
+	if ((adx ^ bdx) < 0) {
+	    return adx;
+	} else if (a->line.p1.y == b->line.p1.y) { /* common origin */
+	    cairo_int64_t adx_bdy, bdx_ady;
+
+	    /* ∴ A_dx * B_dy ∘ B_dx * A_dy */
+
+	    adx_bdy = _cairo_int32x32_64_mul (adx, bdy);
+	    bdx_ady = _cairo_int32x32_64_mul (bdx, ady);
+
+	    return _cairo_int64_cmp (adx_bdy, bdx_ady);
+	} else
+	    return _cairo_int128_cmp (A, B);
+    case HAVE_DX_ADX:
+	/* A_dy * (A_x - B_x) ∘ - (Y - A_y) * A_dx */
+	if ((-adx ^ dx) < 0) {
+	    return dx;
+	} else {
+	    cairo_int64_t ady_dx, dy_adx;
+
+	    ady_dx = _cairo_int32x32_64_mul (ady, dx);
+	    dy_adx = _cairo_int32x32_64_mul (a->line.p1.y - y, adx);
+
+	    return _cairo_int64_cmp (ady_dx, dy_adx);
+	}
+    case HAVE_DX_BDX:
+	/* B_dy * (A_x - B_x) ∘ (Y - B_y) * B_dx */
+	if ((bdx ^ dx) < 0) {
+	    return dx;
+	} else {
+	    cairo_int64_t bdy_dx, dy_bdx;
+
+	    bdy_dx = _cairo_int32x32_64_mul (bdy, dx);
+	    dy_bdx = _cairo_int32x32_64_mul (y - b->line.p1.y, bdx);
+
+	    return _cairo_int64_cmp (bdy_dx, dy_bdx);
+	}
+    case HAVE_ALL:
+	/* XXX try comparing (a->line.p2.x - b->line.p2.x) et al */
+	return _cairo_int128_cmp (L, _cairo_int128_sub (B, A));
+    }
+#undef B
+#undef A
+#undef L
+}
+
+/*
+ * We need to compare the x-coordinate of a line for a particular y wrt to a
+ * given x, without loss of precision.
+ *
+ * The x-coordinate along an edge for a given y is:
+ *   X = A_x + (Y - A_y) * A_dx / A_dy
+ *
+ * So the inequality we wish to test is:
+ *   A_x + (Y - A_y) * A_dx / A_dy ∘ X
+ * where ∘ is our inequality operator.
+ *
+ * By construction, we know that A_dy (and (Y - A_y)) are
+ * all positive, so we can rearrange it thus without causing a sign change:
+ *   (Y - A_y) * A_dx ∘ (X - A_x) * A_dy
+ *
+ * Given the assumption that all the deltas fit within 32 bits, we can compute
+ * this comparison directly using 64 bit arithmetic.
+ *
+ * See the similar discussion for _slope_compare() and
+ * edges_compare_x_for_y_general().
+ */
+static int
+edge_compare_for_y_against_x (const cairo_edge_t *a,
+			      int32_t y,
+			      int32_t x)
+{
+    int32_t adx, ady;
+    int32_t dx, dy;
+    cairo_int64_t L, R;
+
+    if (a->line.p1.x <= a->line.p2.x) {
+	if (x < a->line.p1.x)
+	    return 1;
+	if (x > a->line.p2.x)
+	    return -1;
+    } else {
+	if (x < a->line.p2.x)
+	    return 1;
+	if (x > a->line.p1.x)
+	    return -1;
+    }
+
+    adx = a->line.p2.x - a->line.p1.x;
+    dx = x - a->line.p1.x;
+
+    if (adx == 0)
+	return -dx;
+    if (dx == 0 || (adx ^ dx) < 0)
+	return adx;
+
+    dy = y - a->line.p1.y;
+    ady = a->line.p2.y - a->line.p1.y;
+
+    L = _cairo_int32x32_64_mul (dy, adx);
+    R = _cairo_int32x32_64_mul (dx, ady);
+
+    return _cairo_int64_cmp (L, R);
+}
+
+static int
+edges_compare_x_for_y (const cairo_edge_t *a,
+		       const cairo_edge_t *b,
+		       int32_t y)
+{
+    /* If the sweep-line is currently on an end-point of a line,
+     * then we know its precise x value (and considering that we often need to
+     * compare events at end-points, this happens frequently enough to warrant
+     * special casing).
+     */
+    enum {
+       HAVE_NEITHER = 0x0,
+       HAVE_AX      = 0x1,
+       HAVE_BX      = 0x2,
+       HAVE_BOTH    = HAVE_AX | HAVE_BX
+    } have_ax_bx = HAVE_BOTH;
+    int32_t ax, bx;
+
+    /* XXX given we have x and dx? */
+
+    if (y == a->line.p1.y)
+	ax = a->line.p1.x;
+    else if (y == a->line.p2.y)
+	ax = a->line.p2.x;
+    else
+	have_ax_bx &= ~HAVE_AX;
+
+    if (y == b->line.p1.y)
+	bx = b->line.p1.x;
+    else if (y == b->line.p2.y)
+	bx = b->line.p2.x;
+    else
+	have_ax_bx &= ~HAVE_BX;
+
+    switch (have_ax_bx) {
+    default:
+    case HAVE_NEITHER:
+	return edges_compare_x_for_y_general (a, b, y);
+    case HAVE_AX:
+	return -edge_compare_for_y_against_x (b, y, ax);
+    case HAVE_BX:
+	return edge_compare_for_y_against_x (a, y, bx);
+    case HAVE_BOTH:
+	return ax - bx;
+    }
+}
+
+static inline int
+slope_compare (const edge_t *a,
+	       const edge_t *b)
+{
+    cairo_int64_t L, R;
+    int cmp;
+
+    cmp = a->dxdy.quo - b->dxdy.quo;
+    if (cmp)
+	return cmp;
+
+    if (a->dxdy.rem == 0)
+	return -b->dxdy.rem;
+    if (b->dxdy.rem == 0)
+	return a->dxdy.rem;
+
+    L = _cairo_int32x32_64_mul (b->dy, a->dxdy.rem);
+    R = _cairo_int32x32_64_mul (a->dy, b->dxdy.rem);
+    return _cairo_int64_cmp (L, R);
+}
+
+static inline int
+line_equal (const cairo_line_t *a, const cairo_line_t *b)
+{
+    return a->p1.x == b->p1.x && a->p1.y == b->p1.y &&
+           a->p2.x == b->p2.x && a->p2.y == b->p2.y;
+}
+
+static inline int
+sweep_line_compare_edges (const edge_t	*a,
+			  const edge_t	*b,
+			  cairo_fixed_t y)
+{
+    int cmp;
+
+    if (line_equal (&a->edge.line, &b->edge.line))
+	return 0;
+
+    cmp = edges_compare_x_for_y (&a->edge, &b->edge, y);
+    if (cmp)
+	return cmp;
+
+    return slope_compare (a, b);
+}
+
+static inline cairo_int64_t
+det32_64 (int32_t a, int32_t b,
+	  int32_t c, int32_t d)
+{
+    /* det = a * d - b * c */
+    return _cairo_int64_sub (_cairo_int32x32_64_mul (a, d),
+			     _cairo_int32x32_64_mul (b, c));
+}
+
+static inline cairo_int128_t
+det64x32_128 (cairo_int64_t a, int32_t       b,
+	      cairo_int64_t c, int32_t       d)
+{
+    /* det = a * d - b * c */
+    return _cairo_int128_sub (_cairo_int64x32_128_mul (a, d),
+			      _cairo_int64x32_128_mul (c, b));
+}
+
+/* Compute the intersection of two lines as defined by two edges. The
+ * result is provided as a coordinate pair of 128-bit integers.
+ *
+ * Returns %CAIRO_BO_STATUS_INTERSECTION if there is an intersection or
+ * %CAIRO_BO_STATUS_PARALLEL if the two lines are exactly parallel.
+ */
+static cairo_bool_t
+intersect_lines (const edge_t *a, const edge_t *b,
+		 cairo_bo_intersect_point_t	*intersection)
+{
+    cairo_int64_t a_det, b_det;
+
+    /* XXX: We're assuming here that dx and dy will still fit in 32
+     * bits. That's not true in general as there could be overflow. We
+     * should prevent that before the tessellation algorithm begins.
+     * What we're doing to mitigate this is to perform clamping in
+     * cairo_bo_tessellate_polygon().
+     */
+    int32_t dx1 = a->edge.line.p1.x - a->edge.line.p2.x;
+    int32_t dy1 = a->edge.line.p1.y - a->edge.line.p2.y;
+
+    int32_t dx2 = b->edge.line.p1.x - b->edge.line.p2.x;
+    int32_t dy2 = b->edge.line.p1.y - b->edge.line.p2.y;
+
+    cairo_int64_t den_det;
+    cairo_int64_t R;
+    cairo_quorem64_t qr;
+
+    den_det = det32_64 (dx1, dy1, dx2, dy2);
+
+     /* Q: Can we determine that the lines do not intersect (within range)
+      * much more cheaply than computing the intersection point i.e. by
+      * avoiding the division?
+      *
+      *   X = ax + t * adx = bx + s * bdx;
+      *   Y = ay + t * ady = by + s * bdy;
+      *   ∴ t * (ady*bdx - bdy*adx) = bdx * (by - ay) + bdy * (ax - bx)
+      *   => t * L = R
+      *
+      * Therefore we can reject any intersection (under the criteria for
+      * valid intersection events) if:
+      *   L^R < 0 => t < 0, or
+      *   L<R => t > 1
+      *
+      * (where top/bottom must at least extend to the line endpoints).
+      *
+      * A similar substitution can be performed for s, yielding:
+      *   s * (ady*bdx - bdy*adx) = ady * (ax - bx) - adx * (ay - by)
+      */
+    R = det32_64 (dx2, dy2,
+		  b->edge.line.p1.x - a->edge.line.p1.x,
+		  b->edge.line.p1.y - a->edge.line.p1.y);
+    if (_cairo_int64_negative (den_det)) {
+	if (_cairo_int64_ge (den_det, R))
+	    return FALSE;
+    } else {
+	if (_cairo_int64_le (den_det, R))
+	    return FALSE;
+    }
+
+    R = det32_64 (dy1, dx1,
+		  a->edge.line.p1.y - b->edge.line.p1.y,
+		  a->edge.line.p1.x - b->edge.line.p1.x);
+    if (_cairo_int64_negative (den_det)) {
+	if (_cairo_int64_ge (den_det, R))
+	    return FALSE;
+    } else {
+	if (_cairo_int64_le (den_det, R))
+	    return FALSE;
+    }
+
+    /* We now know that the two lines should intersect within range. */
+
+    a_det = det32_64 (a->edge.line.p1.x, a->edge.line.p1.y,
+		      a->edge.line.p2.x, a->edge.line.p2.y);
+    b_det = det32_64 (b->edge.line.p1.x, b->edge.line.p1.y,
+		      b->edge.line.p2.x, b->edge.line.p2.y);
+
+    /* x = det (a_det, dx1, b_det, dx2) / den_det */
+    qr = _cairo_int_96by64_32x64_divrem (det64x32_128 (a_det, dx1,
+						       b_det, dx2),
+					 den_det);
+    if (_cairo_int64_eq (qr.rem, den_det))
+	return FALSE;
+#if 0
+    intersection->x.exactness = _cairo_int64_is_zero (qr.rem) ? EXACT : INEXACT;
+#else
+    intersection->x.exactness = EXACT;
+    if (! _cairo_int64_is_zero (qr.rem)) {
+	if (_cairo_int64_negative (den_det) ^ _cairo_int64_negative (qr.rem))
+	    qr.rem = _cairo_int64_negate (qr.rem);
+	qr.rem = _cairo_int64_mul (qr.rem, _cairo_int32_to_int64 (2));
+	if (_cairo_int64_ge (qr.rem, den_det)) {
+	    qr.quo = _cairo_int64_add (qr.quo,
+				       _cairo_int32_to_int64 (_cairo_int64_negative (qr.quo) ? -1 : 1));
+	} else
+	    intersection->x.exactness = INEXACT;
+    }
+#endif
+    intersection->x.ordinate = _cairo_int64_to_int32 (qr.quo);
+
+    /* y = det (a_det, dy1, b_det, dy2) / den_det */
+    qr = _cairo_int_96by64_32x64_divrem (det64x32_128 (a_det, dy1,
+						       b_det, dy2),
+					 den_det);
+    if (_cairo_int64_eq (qr.rem, den_det))
+	return FALSE;
+#if 0
+    intersection->y.exactness = _cairo_int64_is_zero (qr.rem) ? EXACT : INEXACT;
+#else
+    intersection->y.exactness = EXACT;
+    if (! _cairo_int64_is_zero (qr.rem)) {
+	/* compute ceiling away from zero */
+	qr.quo = _cairo_int64_add (qr.quo,
+				   _cairo_int32_to_int64 (_cairo_int64_negative (qr.quo) ? -1 : 1));
+	intersection->y.exactness = INEXACT;
+    }
+#endif
+    intersection->y.ordinate = _cairo_int64_to_int32 (qr.quo);
+
+    return TRUE;
+}
+
+static int
+bo_intersect_ordinate_32_compare (int32_t a, int32_t b, int exactness)
+{
+    int cmp;
+
+    /* First compare the quotient */
+    cmp = a - b;
+    if (cmp)
+	return cmp;
+
+    /* With quotient identical, if remainder is 0 then compare equal */
+    /* Otherwise, the non-zero remainder makes a > b */
+    return -(INEXACT == exactness);
+}
+
+/* Does the given edge contain the given point. The point must already
+ * be known to be contained within the line determined by the edge,
+ * (most likely the point results from an intersection of this edge
+ * with another).
+ *
+ * If we had exact arithmetic, then this function would simply be a
+ * matter of examining whether the y value of the point lies within
+ * the range of y values of the edge. But since intersection points
+ * are not exact due to being rounded to the nearest integer within
+ * the available precision, we must also examine the x value of the
+ * point.
+ *
+ * The definition of "contains" here is that the given intersection
+ * point will be seen by the sweep line after the start event for the
+ * given edge and before the stop event for the edge. See the comments
+ * in the implementation for more details.
+ */
+static cairo_bool_t
+bo_edge_contains_intersect_point (const edge_t			*edge,
+				  cairo_bo_intersect_point_t	*point)
+{
+    int cmp_top, cmp_bottom;
+
+    /* XXX: When running the actual algorithm, we don't actually need to
+     * compare against edge->top at all here, since any intersection above
+     * top is eliminated early via a slope comparison. We're leaving these
+     * here for now only for the sake of the quadratic-time intersection
+     * finder which needs them.
+     */
+
+    cmp_top = bo_intersect_ordinate_32_compare (point->y.ordinate,
+						edge->edge.top,
+						point->y.exactness);
+    if (cmp_top < 0)
+	return FALSE;
+
+    cmp_bottom = bo_intersect_ordinate_32_compare (point->y.ordinate,
+						   edge->edge.bottom,
+						   point->y.exactness);
+    if (cmp_bottom > 0)
+	return FALSE;
+
+    if (cmp_top > 0 && cmp_bottom < 0)
+	return TRUE;
+
+    /* At this stage, the point lies on the same y value as either
+     * edge->top or edge->bottom, so we have to examine the x value in
+     * order to properly determine containment. */
+
+    /* If the y value of the point is the same as the y value of the
+     * top of the edge, then the x value of the point must be greater
+     * to be considered as inside the edge. Similarly, if the y value
+     * of the point is the same as the y value of the bottom of the
+     * edge, then the x value of the point must be less to be
+     * considered as inside. */
+
+    if (cmp_top == 0) {
+	cairo_fixed_t top_x;
+
+	top_x = line_compute_intersection_x_for_y (&edge->edge.line,
+						   edge->edge.top);
+	return bo_intersect_ordinate_32_compare (top_x, point->x.ordinate, point->x.exactness) < 0;
+    } else { /* cmp_bottom == 0 */
+	cairo_fixed_t bot_x;
+
+	bot_x = line_compute_intersection_x_for_y (&edge->edge.line,
+						   edge->edge.bottom);
+	return bo_intersect_ordinate_32_compare (point->x.ordinate, bot_x, point->x.exactness) < 0;
+    }
+}
+
+static cairo_bool_t
+edge_intersect (const edge_t		*a,
+		const edge_t		*b,
+		cairo_point_t	*intersection)
+{
+    cairo_bo_intersect_point_t quorem;
+
+    if (! intersect_lines (a, b, &quorem))
+	return FALSE;
+
+    if (a->edge.top != a->edge.line.p1.y || a->edge.bottom != a->edge.line.p2.y) {
+	if (! bo_edge_contains_intersect_point (a, &quorem))
+	    return FALSE;
+    }
+
+    if (b->edge.top != b->edge.line.p1.y || b->edge.bottom != b->edge.line.p2.y) {
+	if (! bo_edge_contains_intersect_point (b, &quorem))
+	    return FALSE;
+    }
+
+    /* Now that we've correctly compared the intersection point and
+     * determined that it lies within the edge, then we know that we
+     * no longer need any more bits of storage for the intersection
+     * than we do for our edge coordinates. We also no longer need the
+     * remainder from the division. */
+    intersection->x = quorem.x.ordinate;
+    intersection->y = quorem.y.ordinate;
+
+    return TRUE;
+}
+
+static inline int
+event_compare (const event_t *a, const event_t *b)
+{
+    return a->y - b->y;
+}
+
+static void
+pqueue_init (pqueue_t *pq)
+{
+    pq->max_size = ARRAY_LENGTH (pq->elements_embedded);
+    pq->size = 0;
+
+    pq->elements = pq->elements_embedded;
+}
+
+static void
+pqueue_fini (pqueue_t *pq)
+{
+    if (pq->elements != pq->elements_embedded)
+	free (pq->elements);
+}
+
+static cairo_bool_t
+pqueue_grow (pqueue_t *pq)
+{
+    event_t **new_elements;
+    pq->max_size *= 2;
+
+    if (pq->elements == pq->elements_embedded) {
+	new_elements = _cairo_malloc_ab (pq->max_size,
+					 sizeof (event_t *));
+	if (unlikely (new_elements == NULL))
+	    return FALSE;
+
+	memcpy (new_elements, pq->elements_embedded,
+		sizeof (pq->elements_embedded));
+    } else {
+	new_elements = _cairo_realloc_ab (pq->elements,
+					  pq->max_size,
+					  sizeof (event_t *));
+	if (unlikely (new_elements == NULL))
+	    return FALSE;
+    }
+
+    pq->elements = new_elements;
+    return TRUE;
+}
+
+static inline void
+pqueue_push (sweep_line_t *sweep_line, event_t *event)
+{
+    event_t **elements;
+    int i, parent;
+
+    if (unlikely (sweep_line->queue.pq.size + 1 == sweep_line->queue.pq.max_size)) {
+	if (unlikely (! pqueue_grow (&sweep_line->queue.pq))) {
+	    longjmp (sweep_line->unwind,
+		     _cairo_error (CAIRO_STATUS_NO_MEMORY));
+	}
+    }
+
+    elements = sweep_line->queue.pq.elements;
+    for (i = ++sweep_line->queue.pq.size;
+	 i != PQ_FIRST_ENTRY &&
+	 event_compare (event,
+			elements[parent = PQ_PARENT_INDEX (i)]) < 0;
+	 i = parent)
+    {
+	elements[i] = elements[parent];
+    }
+
+    elements[i] = event;
+}
+
+static inline void
+pqueue_pop (pqueue_t *pq)
+{
+    event_t **elements = pq->elements;
+    event_t *tail;
+    int child, i;
+
+    tail = elements[pq->size--];
+    if (pq->size == 0) {
+	elements[PQ_FIRST_ENTRY] = NULL;
+	return;
+    }
+
+    for (i = PQ_FIRST_ENTRY;
+	 (child = PQ_LEFT_CHILD_INDEX (i)) <= pq->size;
+	 i = child)
+    {
+	if (child != pq->size &&
+	    event_compare (elements[child+1],
+			   elements[child]) < 0)
+	{
+	    child++;
+	}
+
+	if (event_compare (elements[child], tail) >= 0)
+	    break;
+
+	elements[i] = elements[child];
+    }
+    elements[i] = tail;
+}
+
+static inline void
+event_insert (sweep_line_t	*sweep_line,
+	      event_type_t	 type,
+	      edge_t		*e1,
+	      edge_t		*e2,
+	      cairo_fixed_t	 y)
+{
+    queue_event_t *event;
+
+    event = _cairo_freepool_alloc (&sweep_line->queue.pool);
+    if (unlikely (event == NULL)) {
+	longjmp (sweep_line->unwind,
+		 _cairo_error (CAIRO_STATUS_NO_MEMORY));
+    }
+
+    event->y = y;
+    event->type = type;
+    event->e1 = e1;
+    event->e2 = e2;
+
+    pqueue_push (sweep_line, (event_t *) event);
+}
+
+static void
+event_delete (sweep_line_t	*sweep_line,
+	      event_t		*event)
+{
+    _cairo_freepool_free (&sweep_line->queue.pool, event);
+}
+
+static inline event_t *
+event_next (sweep_line_t *sweep_line)
+{
+    event_t *event, *cmp;
+
+    event = sweep_line->queue.pq.elements[PQ_FIRST_ENTRY];
+    cmp = *sweep_line->queue.start_events;
+    if (event == NULL ||
+	(cmp != NULL && event_compare (cmp, event) < 0))
+    {
+	event = cmp;
+	sweep_line->queue.start_events++;
+    }
+    else
+    {
+	pqueue_pop (&sweep_line->queue.pq);
+    }
+
+    return event;
+}
+
+CAIRO_COMBSORT_DECLARE (start_event_sort, event_t *, event_compare)
+
+static inline void
+event_insert_stop (sweep_line_t	*sweep_line,
+		   edge_t	*edge)
+{
+    event_insert (sweep_line,
+		  EVENT_TYPE_STOP,
+		  edge, NULL,
+		  edge->edge.bottom);
+}
+
+static inline void
+event_insert_if_intersect_below_current_y (sweep_line_t	*sweep_line,
+					   edge_t	*left,
+					   edge_t	*right)
+{
+    cairo_point_t intersection;
+
+    /* start points intersect */
+    if (left->edge.line.p1.x == right->edge.line.p1.x &&
+	left->edge.line.p1.y == right->edge.line.p1.y)
+    {
+	return;
+    }
+
+    /* end points intersect, process DELETE events first */
+    if (left->edge.line.p2.x == right->edge.line.p2.x &&
+	left->edge.line.p2.y == right->edge.line.p2.y)
+    {
+	return;
+    }
+
+    if (slope_compare (left, right) <= 0)
+	return;
+
+    if (! edge_intersect (left, right, &intersection))
+	return;
+
+    event_insert (sweep_line,
+		  EVENT_TYPE_INTERSECTION,
+		  left, right,
+		  intersection.y);
+}
+
+static inline edge_t *
+link_to_edge (cairo_list_t *link)
+{
+    return (edge_t *) link;
+}
+
+static void
+sweep_line_insert (sweep_line_t	*sweep_line,
+		   edge_t	*edge)
+{
+    cairo_list_t *pos;
+    cairo_fixed_t y = sweep_line->current_subrow;
+
+    pos = sweep_line->insert_cursor;
+    if (pos == &sweep_line->active)
+	pos = sweep_line->active.next;
+    if (pos != &sweep_line->active) {
+	int cmp;
+
+	cmp = sweep_line_compare_edges (link_to_edge (pos),
+					edge,
+					y);
+	if (cmp < 0) {
+	    while (pos->next != &sweep_line->active &&
+		   sweep_line_compare_edges (link_to_edge (pos->next),
+					     edge,
+					     y) < 0)
+	    {
+		pos = pos->next;
+	    }
+	} else if (cmp > 0) {
+	    do {
+		pos = pos->prev;
+	    } while (pos != &sweep_line->active &&
+		     sweep_line_compare_edges (link_to_edge (pos),
+					       edge,
+					       y) > 0);
+	}
+    }
+    cairo_list_add (&edge->link, pos);
+    sweep_line->insert_cursor = &edge->link;
+}
+
+inline static void
+coverage_rewind (struct coverage *cells)
+{
+    cells->cursor = &cells->head;
+}
+
+static void
+coverage_init (struct coverage *cells)
+{
+    _cairo_freepool_init (&cells->pool,
+			  sizeof (struct cell));
+    cells->head.prev = NULL;
+    cells->head.next = &cells->tail;
+    cells->head.x = INT_MIN;
+    cells->tail.prev = &cells->head;
+    cells->tail.next = NULL;
+    cells->tail.x = INT_MAX;
+    cells->count = 0;
+    coverage_rewind (cells);
+}
+
+static void
+coverage_fini (struct coverage *cells)
+{
+    _cairo_freepool_fini (&cells->pool);
+}
+
+inline static void
+coverage_reset (struct coverage *cells)
+{
+    cells->head.next = &cells->tail;
+    cells->tail.prev = &cells->head;
+    cells->count = 0;
+    _cairo_freepool_reset (&cells->pool);
+    coverage_rewind (cells);
+}
+
+inline static struct cell *
+coverage_alloc (sweep_line_t *sweep_line,
+		struct cell *tail,
+		int x)
+{
+    struct cell *cell;
+
+    cell = _cairo_freepool_alloc (&sweep_line->coverage.pool);
+    if (unlikely (NULL == cell)) {
+	longjmp (sweep_line->unwind,
+		 _cairo_error (CAIRO_STATUS_NO_MEMORY));
+    }
+
+    tail->prev->next = cell;
+    cell->prev = tail->prev;
+    cell->next = tail;
+    tail->prev = cell;
+    cell->x = x;
+    cell->uncovered_area = 0;
+    cell->covered_height = 0;
+    sweep_line->coverage.count++;
+    return cell;
+}
+
+inline static struct cell *
+coverage_find (sweep_line_t *sweep_line, int x)
+{
+    struct cell *cell;
+
+    cell = sweep_line->coverage.cursor;
+    if (unlikely (cell->x > x)) {
+	do {
+	    if (cell->prev->x < x)
+		break;
+	    cell = cell->prev;
+	} while (TRUE);
+    } else {
+	if (cell->x == x)
+	    return cell;
+
+	do {
+	    UNROLL3({
+		    cell = cell->next;
+		    if (cell->x >= x)
+			break;
+		    });
+	} while (TRUE);
+    }
+
+    if (cell->x != x)
+	cell = coverage_alloc (sweep_line, cell, x);
+
+    return sweep_line->coverage.cursor = cell;
+}
+
+static void
+coverage_render_cells (sweep_line_t *sweep_line,
+		       cairo_fixed_t left, cairo_fixed_t right,
+		       cairo_fixed_t y1, cairo_fixed_t y2,
+		       int sign)
+{
+    int fx1, fx2;
+    int ix1, ix2;
+    int dx, dy;
+
+    /* Orient the edge left-to-right. */
+    dx = right - left;
+    if (dx >= 0) {
+	ix1 = _cairo_fixed_integer_part (left);
+	fx1 = _cairo_fixed_fractional_part (left);
+
+	ix2 = _cairo_fixed_integer_part (right);
+	fx2 = _cairo_fixed_fractional_part (right);
+
+	dy = y2 - y1;
+    } else {
+	ix1 = _cairo_fixed_integer_part (right);
+	fx1 = _cairo_fixed_fractional_part (right);
+
+	ix2 = _cairo_fixed_integer_part (left);
+	fx2 = _cairo_fixed_fractional_part (left);
+
+	dx = -dx;
+	sign = -sign;
+	dy = y1 - y2;
+	y1 = y2 - dy;
+	y2 = y1 + dy;
+    }
+
+    /* Add coverage for all pixels [ix1,ix2] on this row crossed
+     * by the edge. */
+    {
+	struct quorem y = floored_divrem ((STEP_X - fx1)*dy, dx);
+	struct cell *cell;
+
+	cell = sweep_line->coverage.cursor;
+	if (cell->x != ix1) {
+	    if (unlikely (cell->x > ix1)) {
+		do {
+		    if (cell->prev->x < ix1)
+			break;
+		    cell = cell->prev;
+		} while (TRUE);
+	    } else do {
+		UNROLL3({
+			if (cell->x >= ix1)
+			    break;
+			cell = cell->next;
+			});
+	    } while (TRUE);
+
+	    if (cell->x != ix1)
+		cell = coverage_alloc (sweep_line, cell, ix1);
+	}
+
+	cell->uncovered_area += sign * y.quo * (STEP_X + fx1);
+	cell->covered_height += sign * y.quo;
+	y.quo += y1;
+
+	cell = cell->next;
+	if (cell->x != ++ix1)
+	    cell = coverage_alloc (sweep_line, cell, ix1);
+	if (ix1 < ix2) {
+	    struct quorem dydx_full = floored_divrem (STEP_X*dy, dx);
+
+	    do {
+		cairo_fixed_t y_skip = dydx_full.quo;
+		y.rem += dydx_full.rem;
+		if (y.rem >= dx) {
+		    ++y_skip;
+		    y.rem -= dx;
+		}
+
+		y.quo += y_skip;
+
+		y_skip *= sign;
+		cell->covered_height += y_skip;
+		cell->uncovered_area += y_skip*STEP_X;
+
+		cell = cell->next;
+		if (cell->x != ++ix1)
+		    cell = coverage_alloc (sweep_line, cell, ix1);
+	    } while (ix1 != ix2);
+	}
+	cell->uncovered_area += sign*(y2 - y.quo)*fx2;
+	cell->covered_height += sign*(y2 - y.quo);
+	sweep_line->coverage.cursor = cell;
+    }
+}
+
+inline static void
+full_inc_edge (edge_t *edge)
+{
+    edge->x.quo += edge->dxdy_full.quo;
+    edge->x.rem += edge->dxdy_full.rem;
+    if (edge->x.rem >= 0) {
+	++edge->x.quo;
+	edge->x.rem -= edge->dy;
+    }
+}
+
+static void
+full_add_edge (sweep_line_t *sweep_line, edge_t *edge, int sign)
+{
+    struct cell *cell;
+    cairo_fixed_t x1, x2;
+    int ix1, ix2;
+    int frac;
+
+    edge->current_sign = sign;
+
+    ix1 = _cairo_fixed_integer_part (edge->x.quo);
+
+    if (edge->vertical) {
+	frac = _cairo_fixed_fractional_part (edge->x.quo);
+	cell = coverage_find (sweep_line, ix1);
+	cell->covered_height += sign * STEP_Y;
+	cell->uncovered_area += sign * 2 * frac * STEP_Y;
+	return;
+    }
+
+    x1 = edge->x.quo;
+    full_inc_edge (edge);
+    x2 = edge->x.quo;
+
+    ix2 = _cairo_fixed_integer_part (edge->x.quo);
+
+    /* Edge is entirely within a column? */
+    if (likely (ix1 == ix2)) {
+	frac = _cairo_fixed_fractional_part (x1) +
+	       _cairo_fixed_fractional_part (x2);
+	cell = coverage_find (sweep_line, ix1);
+	cell->covered_height += sign * STEP_Y;
+	cell->uncovered_area += sign * frac * STEP_Y;
+	return;
+    }
+
+    coverage_render_cells (sweep_line, x1, x2, 0, STEP_Y, sign);
+}
+
+static void
+full_nonzero (sweep_line_t *sweep_line)
+{
+    cairo_list_t *pos;
+
+    sweep_line->is_vertical = TRUE;
+    pos = sweep_line->active.next;
+    do {
+	edge_t *left = link_to_edge (pos), *right;
+	int winding = left->edge.dir;
+
+	sweep_line->is_vertical &= left->vertical;
+
+	pos = left->link.next;
+	do {
+	    if (unlikely (pos == &sweep_line->active)) {
+		full_add_edge (sweep_line, left, +1);
+		return;
+	    }
+
+	    right = link_to_edge (pos);
+	    pos = pos->next;
+	    sweep_line->is_vertical &= right->vertical;
+
+	    winding += right->edge.dir;
+	    if (0 == winding) {
+		if (pos == &sweep_line->active ||
+		    link_to_edge (pos)->x.quo != right->x.quo)
+		{
+		    break;
+		}
+	    }
+
+	    if (! right->vertical)
+		full_inc_edge (right);
+	} while (TRUE);
+
+	full_add_edge (sweep_line, left,  +1);
+	full_add_edge (sweep_line, right, -1);
+    } while (pos != &sweep_line->active);
+}
+
+static void
+full_evenodd (sweep_line_t *sweep_line)
+{
+    cairo_list_t *pos;
+
+    sweep_line->is_vertical = TRUE;
+    pos = sweep_line->active.next;
+    do {
+	edge_t *left = link_to_edge (pos), *right;
+	int winding = 0;
+
+	sweep_line->is_vertical &= left->vertical;
+
+	pos = left->link.next;
+	do {
+	    if (pos == &sweep_line->active) {
+		full_add_edge (sweep_line, left, +1);
+		return;
+	    }
+
+	    right = link_to_edge (pos);
+	    pos = pos->next;
+	    sweep_line->is_vertical &= right->vertical;
+
+	    if (++winding & 1) {
+		if (pos == &sweep_line->active ||
+		    link_to_edge (pos)->x.quo != right->x.quo)
+		{
+		    break;
+		}
+	    }
+
+	    if (! right->vertical)
+		full_inc_edge (right);
+	} while (TRUE);
+
+	full_add_edge (sweep_line, left,  +1);
+	full_add_edge (sweep_line, right, -1);
+    } while (pos != &sweep_line->active);
+}
+
+static void
+render_rows (cairo_botor_scan_converter_t *self,
+	     sweep_line_t *sweep_line,
+	     int y, int height,
+	     cairo_span_renderer_t *renderer)
+{
+    cairo_half_open_span_t spans_stack[CAIRO_STACK_ARRAY_LENGTH (cairo_half_open_span_t)];
+    cairo_half_open_span_t *spans = spans_stack;
+    struct cell *cell;
+    int prev_x, cover;
+    int num_spans;
+    cairo_status_t status;
+
+    if (unlikely (sweep_line->coverage.count == 0)) {
+	status = renderer->render_rows (renderer, y, height, NULL, 0);
+	if (unlikely (status))
+	    longjmp (sweep_line->unwind, status);
+	return;
+    }
+
+    /* Allocate enough spans for the row. */
+
+    num_spans = 2*sweep_line->coverage.count+2;
+    if (unlikely (num_spans > ARRAY_LENGTH (spans_stack))) {
+	spans = _cairo_malloc_ab (num_spans, sizeof (cairo_half_open_span_t));
+	if (unlikely (spans == NULL)) {
+	    longjmp (sweep_line->unwind,
+		     _cairo_error (CAIRO_STATUS_NO_MEMORY));
+	}
+    }
+
+    /* Form the spans from the coverage and areas. */
+    num_spans = 0;
+    prev_x = self->xmin;
+    cover = 0;
+    cell = sweep_line->coverage.head.next;
+    do {
+	int x = cell->x;
+	int area;
+
+	if (x > prev_x) {
+	    spans[num_spans].x = prev_x;
+	    spans[num_spans].coverage = AREA_TO_ALPHA (cover);
+	    ++num_spans;
+	}
+
+	cover += cell->covered_height*STEP_X*2;
+	area = cover - cell->uncovered_area;
+
+	spans[num_spans].x = x;
+	spans[num_spans].coverage = AREA_TO_ALPHA (area);
+	++num_spans;
+
+	prev_x = x + 1;
+    } while ((cell = cell->next) != &sweep_line->coverage.tail);
+
+    if (prev_x <= self->xmax) {
+	spans[num_spans].x = prev_x;
+	spans[num_spans].coverage = AREA_TO_ALPHA (cover);
+	++num_spans;
+    }
+
+    if (cover && prev_x < self->xmax) {
+	spans[num_spans].x = self->xmax;
+	spans[num_spans].coverage = 0;
+	++num_spans;
+    }
+
+    status = renderer->render_rows (renderer, y, height, spans, num_spans);
+
+    if (unlikely (spans != spans_stack))
+	free (spans);
+
+    coverage_reset (&sweep_line->coverage);
+
+    if (unlikely (status))
+	longjmp (sweep_line->unwind, status);
+}
+
+static void
+full_repeat (sweep_line_t *sweep)
+{
+    edge_t *edge;
+
+    cairo_list_foreach_entry (edge, edge_t, &sweep->active, link) {
+	if (edge->current_sign)
+	    full_add_edge (sweep, edge, edge->current_sign);
+	else if (! edge->vertical)
+	    full_inc_edge (edge);
+    }
+}
+
+static void
+full_reset (sweep_line_t *sweep)
+{
+    edge_t *edge;
+
+    cairo_list_foreach_entry (edge, edge_t, &sweep->active, link)
+	edge->current_sign = 0;
+}
+
+static void
+full_step (cairo_botor_scan_converter_t *self,
+	   sweep_line_t *sweep_line,
+	   cairo_fixed_t row,
+	   cairo_span_renderer_t *renderer)
+{
+    int top, bottom;
+
+    top = _cairo_fixed_integer_part (sweep_line->current_row);
+    bottom = _cairo_fixed_integer_part (row);
+    if (cairo_list_is_empty (&sweep_line->active)) {
+	cairo_status_t  status;
+
+	status = renderer->render_rows (renderer, top, bottom - top, NULL, 0);
+	if (unlikely (status))
+	    longjmp (sweep_line->unwind, status);
+
+	return;
+    }
+
+    if (self->fill_rule == CAIRO_FILL_RULE_WINDING)
+	full_nonzero (sweep_line);
+    else
+	full_evenodd (sweep_line);
+
+    if (sweep_line->is_vertical || bottom == top + 1) {
+	render_rows (self, sweep_line, top, bottom - top, renderer);
+	full_reset (sweep_line);
+	return;
+    }
+
+    render_rows (self, sweep_line, top++, 1, renderer);
+    do {
+	full_repeat (sweep_line);
+	render_rows (self, sweep_line, top, 1, renderer);
+    } while (++top != bottom);
+
+    full_reset (sweep_line);
+}
+
+cairo_always_inline static void
+sub_inc_edge (edge_t *edge,
+	      cairo_fixed_t height)
+{
+    if (height == 1) {
+	edge->x.quo += edge->dxdy.quo;
+	edge->x.rem += edge->dxdy.rem;
+	if (edge->x.rem >= 0) {
+	    ++edge->x.quo;
+	    edge->x.rem -= edge->dy;
+	}
+    } else {
+	edge->x.quo += height * edge->dxdy.quo;
+	edge->x.rem += height * edge->dxdy.rem;
+	if (edge->x.rem >= 0) {
+	    int carry = edge->x.rem / edge->dy + 1;
+	    edge->x.quo += carry;
+	    edge->x.rem -= carry * edge->dy;
+	}
+    }
+}
+
+static void
+sub_add_run (sweep_line_t *sweep_line, edge_t *edge, int y, int sign)
+{
+    struct run *run;
+
+    run = _cairo_freepool_alloc (&sweep_line->runs);
+    if (unlikely (run == NULL))
+	longjmp (sweep_line->unwind, _cairo_error (CAIRO_STATUS_NO_MEMORY));
+
+    run->y = y;
+    run->sign = sign;
+    run->next = edge->runs;
+    edge->runs = run;
+
+    edge->current_sign = sign;
+}
+
+inline static cairo_bool_t
+edges_coincident (edge_t *left, edge_t *right, cairo_fixed_t y)
+{
+    /* XXX is compare_x_for_y() worth executing during sub steps? */
+    return line_equal (&left->edge.line, &right->edge.line);
+    //edges_compare_x_for_y (&left->edge, &right->edge, y) >= 0;
+}
+
+static void
+sub_nonzero (sweep_line_t *sweep_line)
+{
+    cairo_fixed_t y = sweep_line->current_subrow;
+    cairo_fixed_t fy = _cairo_fixed_fractional_part (y);
+    cairo_list_t *pos;
+
+    pos = sweep_line->active.next;
+    do {
+	edge_t *left = link_to_edge (pos), *right;
+	int winding = left->edge.dir;
+
+	pos = left->link.next;
+	do {
+	    if (unlikely (pos == &sweep_line->active)) {
+		if (left->current_sign != +1)
+		    sub_add_run (sweep_line, left, fy, +1);
+		return;
+	    }
+
+	    right = link_to_edge (pos);
+	    pos = pos->next;
+
+	    winding += right->edge.dir;
+	    if (0 == winding) {
+		if (pos == &sweep_line->active ||
+		    ! edges_coincident (right, link_to_edge (pos), y))
+		{
+		    break;
+		}
+	    }
+
+	    if (right->current_sign)
+		sub_add_run (sweep_line, right, fy, 0);
+	} while (TRUE);
+
+	if (left->current_sign != +1)
+	    sub_add_run (sweep_line, left, fy, +1);
+	if (right->current_sign != -1)
+	    sub_add_run (sweep_line, right, fy, -1);
+    } while (pos != &sweep_line->active);
+}
+
+static void
+sub_evenodd (sweep_line_t *sweep_line)
+{
+    cairo_fixed_t y = sweep_line->current_subrow;
+    cairo_fixed_t fy = _cairo_fixed_fractional_part (y);
+    cairo_list_t *pos;
+
+    pos = sweep_line->active.next;
+    do {
+	edge_t *left = link_to_edge (pos), *right;
+	int winding = 0;
+
+	pos = left->link.next;
+	do {
+	    if (unlikely (pos == &sweep_line->active)) {
+		if (left->current_sign != +1)
+		    sub_add_run (sweep_line, left, fy, +1);
+		return;
+	    }
+
+	    right = link_to_edge (pos);
+	    pos = pos->next;
+
+	    if (++winding & 1) {
+		if (pos == &sweep_line->active ||
+		    ! edges_coincident (right, link_to_edge (pos), y))
+		{
+		    break;
+		}
+	    }
+
+	    if (right->current_sign)
+		sub_add_run (sweep_line, right, fy, 0);
+	} while (TRUE);
+
+	if (left->current_sign != +1)
+	    sub_add_run (sweep_line, left, fy, +1);
+	if (right->current_sign != -1)
+	    sub_add_run (sweep_line, right, fy, -1);
+    } while (pos != &sweep_line->active);
+}
+
+cairo_always_inline static void
+sub_step (cairo_botor_scan_converter_t *self,
+	  sweep_line_t *sweep_line)
+{
+    if (cairo_list_is_empty (&sweep_line->active))
+	return;
+
+    if (self->fill_rule == CAIRO_FILL_RULE_WINDING)
+	sub_nonzero (sweep_line);
+    else
+	sub_evenodd (sweep_line);
+}
+
+static void
+coverage_render_runs (sweep_line_t *sweep, edge_t *edge,
+		      cairo_fixed_t y1, cairo_fixed_t y2)
+{
+    struct run tail;
+    struct run *run = &tail;
+
+    tail.next = NULL;
+    tail.y = y2;
+
+    /* Order the runs top->bottom */
+    while (edge->runs) {
+	struct run *r;
+
+	r = edge->runs;
+	edge->runs = r->next;
+	r->next = run;
+	run = r;
+    }
+
+    if (run->y > y1)
+	sub_inc_edge (edge, run->y - y1);
+
+    do {
+	cairo_fixed_t x1, x2;
+
+	y1 = run->y;
+	y2 = run->next->y;
+
+	x1 = edge->x.quo;
+	if (y2 - y1 == STEP_Y)
+	    full_inc_edge (edge);
+	else
+	    sub_inc_edge (edge, y2 - y1);
+	x2 = edge->x.quo;
+
+	if (run->sign) {
+	    int ix1, ix2;
+
+	    ix1 = _cairo_fixed_integer_part (x1);
+	    ix2 = _cairo_fixed_integer_part (x2);
+
+	    /* Edge is entirely within a column? */
+	    if (likely (ix1 == ix2)) {
+		struct cell *cell;
+		int frac;
+
+		frac = _cairo_fixed_fractional_part (x1) +
+		       _cairo_fixed_fractional_part (x2);
+		cell = coverage_find (sweep, ix1);
+		cell->covered_height += run->sign * (y2 - y1);
+		cell->uncovered_area += run->sign * (y2 - y1) * frac;
+	    } else {
+		coverage_render_cells (sweep, x1, x2, y1, y2, run->sign);
+	    }
+	}
+
+	run = run->next;
+    } while (run->next != NULL);
+}
+
+static void
+coverage_render_vertical_runs (sweep_line_t *sweep, edge_t *edge, cairo_fixed_t y2)
+{
+    struct cell *cell;
+    struct run *run;
+    int height = 0;
+
+    for (run = edge->runs; run != NULL; run = run->next) {
+	if (run->sign)
+	    height += run->sign * (y2 - run->y);
+	y2 = run->y;
+    }
+
+    cell = coverage_find (sweep, _cairo_fixed_integer_part (edge->x.quo));
+    cell->covered_height += height;
+    cell->uncovered_area += 2 * _cairo_fixed_fractional_part (edge->x.quo) * height;
+}
+
+cairo_always_inline static void
+sub_emit (cairo_botor_scan_converter_t *self,
+	  sweep_line_t *sweep,
+	  cairo_span_renderer_t *renderer)
+{
+    edge_t *edge;
+
+    sub_step (self, sweep);
+
+    /* convert the runs into coverages */
+
+    cairo_list_foreach_entry (edge, edge_t, &sweep->active, link) {
+	if (edge->runs == NULL) {
+	    if (! edge->vertical) {
+		if (edge->flags & START) {
+		    sub_inc_edge (edge,
+				  STEP_Y - _cairo_fixed_fractional_part (edge->edge.top));
+		    edge->flags &= ~START;
+		} else
+		    full_inc_edge (edge);
+	    }
+	} else {
+	    if (edge->vertical) {
+		coverage_render_vertical_runs (sweep, edge, STEP_Y);
+	    } else {
+		int y1 = 0;
+		if (edge->flags & START) {
+		    y1 = _cairo_fixed_fractional_part (edge->edge.top);
+		    edge->flags &= ~START;
+		}
+		coverage_render_runs (sweep, edge, y1, STEP_Y);
+	    }
+	}
+	edge->current_sign = 0;
+	edge->runs = NULL;
+    }
+
+    cairo_list_foreach_entry (edge, edge_t, &sweep->stopped, link) {
+	int y2 = _cairo_fixed_fractional_part (edge->edge.bottom);
+	if (edge->vertical) {
+	    coverage_render_vertical_runs (sweep, edge, y2);
+	} else {
+	    int y1 = 0;
+	    if (edge->flags & START)
+		y1 = _cairo_fixed_fractional_part (edge->edge.top);
+	    coverage_render_runs (sweep, edge, y1, y2);
+	}
+    }
+    cairo_list_init (&sweep->stopped);
+
+    _cairo_freepool_reset (&sweep->runs);
+
+    render_rows (self, sweep,
+		 _cairo_fixed_integer_part (sweep->current_row), 1,
+		 renderer);
+}
+
+static void
+sweep_line_init (sweep_line_t	 *sweep_line,
+		 event_t	**start_events,
+		 int		  num_events)
+{
+    cairo_list_init (&sweep_line->active);
+    cairo_list_init (&sweep_line->stopped);
+    sweep_line->insert_cursor = &sweep_line->active;
+
+    sweep_line->current_row = INT32_MIN;
+    sweep_line->current_subrow = INT32_MIN;
+
+    coverage_init (&sweep_line->coverage);
+    _cairo_freepool_init (&sweep_line->runs, sizeof (struct run));
+
+    start_event_sort (start_events, num_events);
+    start_events[num_events] = NULL;
+
+    sweep_line->queue.start_events = start_events;
+
+    _cairo_freepool_init (&sweep_line->queue.pool,
+			  sizeof (queue_event_t));
+    pqueue_init (&sweep_line->queue.pq);
+    sweep_line->queue.pq.elements[PQ_FIRST_ENTRY] = NULL;
+}
+
+static void
+sweep_line_delete (sweep_line_t	*sweep_line,
+		   edge_t	*edge)
+{
+    if (sweep_line->insert_cursor == &edge->link)
+	sweep_line->insert_cursor = edge->link.prev;
+
+    cairo_list_del (&edge->link);
+    if (edge->runs)
+	cairo_list_add_tail (&edge->link, &sweep_line->stopped);
+    edge->flags |= STOP;
+}
+
+static void
+sweep_line_swap (sweep_line_t	*sweep_line,
+		 edge_t	*left,
+		 edge_t	*right)
+{
+    right->link.prev = left->link.prev;
+    left->link.next = right->link.next;
+    right->link.next = &left->link;
+    left->link.prev = &right->link;
+    left->link.next->prev = &left->link;
+    right->link.prev->next = &right->link;
+}
+
+static void
+sweep_line_fini (sweep_line_t *sweep_line)
+{
+    pqueue_fini (&sweep_line->queue.pq);
+    _cairo_freepool_fini (&sweep_line->queue.pool);
+    coverage_fini (&sweep_line->coverage);
+    _cairo_freepool_fini (&sweep_line->runs);
+}
+
+static cairo_status_t
+botor_generate (cairo_botor_scan_converter_t	 *self,
+		event_t				**start_events,
+		cairo_span_renderer_t		 *renderer)
+{
+    cairo_status_t status;
+    sweep_line_t sweep_line;
+    cairo_fixed_t ybot;
+    event_t *event;
+    cairo_list_t *left, *right;
+    edge_t *e1, *e2;
+    int bottom;
+
+    sweep_line_init (&sweep_line, start_events, self->num_edges);
+    if ((status = setjmp (sweep_line.unwind)))
+	goto unwind;
+
+    ybot = self->extents.p2.y;
+    sweep_line.current_subrow = self->extents.p1.y;
+    sweep_line.current_row = _cairo_fixed_floor (self->extents.p1.y);
+    event = *sweep_line.queue.start_events++;
+    do {
+	/* Can we process a full step in one go? */
+	if (event->y >= sweep_line.current_row + STEP_Y) {
+	    bottom = _cairo_fixed_floor (event->y);
+	    full_step (self, &sweep_line, bottom, renderer);
+	    sweep_line.current_row = bottom;
+	    sweep_line.current_subrow = bottom;
+	}
+
+	do {
+	    if (event->y > sweep_line.current_subrow) {
+		sub_step (self, &sweep_line);
+		sweep_line.current_subrow = event->y;
+	    }
+
+	    do {
+		/* Update the active list using Bentley-Ottmann */
+		switch (event->type) {
+		case EVENT_TYPE_START:
+		    e1 = ((start_event_t *) event)->edge;
+
+		    sweep_line_insert (&sweep_line, e1);
+		    event_insert_stop (&sweep_line, e1);
+
+		    left = e1->link.prev;
+		    right = e1->link.next;
+
+		    if (left != &sweep_line.active) {
+			event_insert_if_intersect_below_current_y (&sweep_line,
+								   link_to_edge (left), e1);
+		    }
+
+		    if (right != &sweep_line.active) {
+			event_insert_if_intersect_below_current_y (&sweep_line,
+								   e1, link_to_edge (right));
+		    }
+
+		    break;
+
+		case EVENT_TYPE_STOP:
+		    e1 = ((queue_event_t *) event)->e1;
+		    event_delete (&sweep_line, event);
+
+		    left = e1->link.prev;
+		    right = e1->link.next;
+
+		    sweep_line_delete (&sweep_line, e1);
+
+		    if (left != &sweep_line.active &&
+			right != &sweep_line.active)
+		    {
+			 event_insert_if_intersect_below_current_y (&sweep_line,
+								    link_to_edge (left),
+								    link_to_edge (right));
+		    }
+
+		    break;
+
+		case EVENT_TYPE_INTERSECTION:
+		    e1 = ((queue_event_t *) event)->e1;
+		    e2 = ((queue_event_t *) event)->e2;
+
+		    event_delete (&sweep_line, event);
+		    if (e1->flags & STOP)
+			break;
+		    if (e2->flags & STOP)
+			break;
+
+		    /* skip this intersection if its edges are not adjacent */
+		    if (&e2->link != e1->link.next)
+			break;
+
+		    left = e1->link.prev;
+		    right = e2->link.next;
+
+		    sweep_line_swap (&sweep_line, e1, e2);
+
+		    /* after the swap e2 is left of e1 */
+		    if (left != &sweep_line.active) {
+			event_insert_if_intersect_below_current_y (&sweep_line,
+								   link_to_edge (left), e2);
+		    }
+
+		    if (right != &sweep_line.active) {
+			event_insert_if_intersect_below_current_y (&sweep_line,
+								   e1, link_to_edge (right));
+		    }
+
+		    break;
+		}
+
+		event = event_next (&sweep_line);
+		if (event == NULL)
+		    goto end;
+	    } while (event->y == sweep_line.current_subrow);
+	} while (event->y < sweep_line.current_row + STEP_Y);
+
+	bottom = sweep_line.current_row + STEP_Y;
+	sub_emit (self, &sweep_line, renderer);
+	sweep_line.current_subrow = bottom;
+	sweep_line.current_row = sweep_line.current_subrow;
+    } while (TRUE);
+
+  end:
+    /* flush any partial spans */
+    if (sweep_line.current_subrow != sweep_line.current_row) {
+	sub_emit (self, &sweep_line, renderer);
+	sweep_line.current_row += STEP_Y;
+	sweep_line.current_subrow = sweep_line.current_row;
+    }
+    /* clear the rest */
+    if (sweep_line.current_subrow < ybot) {
+	bottom = _cairo_fixed_integer_part (sweep_line.current_row);
+	status = renderer->render_rows (renderer,
+					bottom, _cairo_fixed_integer_ceil (ybot) - bottom,
+					NULL, 0);
+    }
+
+ unwind:
+    sweep_line_fini (&sweep_line);
+
+    return status;
+}
+
+static cairo_status_t
+_cairo_botor_scan_converter_generate (void			*converter,
+				      cairo_span_renderer_t	*renderer)
+{
+    cairo_botor_scan_converter_t *self = converter;
+    start_event_t stack_events[CAIRO_STACK_ARRAY_LENGTH (start_event_t)];
+    start_event_t *events;
+    event_t *stack_event_ptrs[ARRAY_LENGTH (stack_events) + 1];
+    event_t **event_ptrs;
+    struct _cairo_botor_scan_converter_chunk *chunk;
+    cairo_status_t status;
+    int num_events;
+    int i, j;
+
+    num_events = self->num_edges;
+    if (unlikely (0 == num_events)) {
+	return renderer->render_rows (renderer,
+				      _cairo_fixed_integer_floor (self->extents.p1.y),
+				      _cairo_fixed_integer_ceil (self->extents.p2.y) -
+				      _cairo_fixed_integer_floor (self->extents.p1.y),
+				      NULL, 0);
+    }
+
+    events = stack_events;
+    event_ptrs = stack_event_ptrs;
+    if (unlikely (num_events >= ARRAY_LENGTH (stack_events))) {
+	events = _cairo_malloc_ab_plus_c (num_events,
+					  sizeof (start_event_t) + sizeof (event_t *),
+					  sizeof (event_t *));
+	if (unlikely (events == NULL))
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+	event_ptrs = (event_t **) (events + num_events);
+    }
+
+    j = 0;
+    for (chunk = &self->chunks; chunk != NULL; chunk = chunk->next) {
+	edge_t *edge;
+
+	edge = chunk->base;
+	for (i = 0; i < chunk->count; i++) {
+	    event_ptrs[j] = (event_t *) &events[j];
+
+	    events[j].y = edge->edge.top;
+	    events[j].type = EVENT_TYPE_START;
+	    events[j].edge = edge;
+
+	    edge++, j++;
+	}
+    }
+
+    status = botor_generate (self, event_ptrs, renderer);
+
+    if (events != stack_events)
+	free (events);
+
+    return status;
+}
+
+static edge_t *
+botor_allocate_edge (cairo_botor_scan_converter_t *self)
+{
+    struct _cairo_botor_scan_converter_chunk *chunk;
+
+    chunk = self->tail;
+    if (chunk->count == chunk->size) {
+	int size;
+
+	size = chunk->size * 2;
+	chunk->next = _cairo_malloc_ab_plus_c (size,
+					       sizeof (edge_t),
+					       sizeof (struct _cairo_botor_scan_converter_chunk));
+	if (unlikely (chunk->next == NULL))
+	    return NULL;
+
+	chunk = chunk->next;
+	chunk->next = NULL;
+	chunk->count = 0;
+	chunk->size = size;
+	chunk->base = chunk + 1;
+	self->tail = chunk;
+    }
+
+    return (edge_t *) chunk->base + chunk->count++;
+}
+
+static cairo_status_t
+botor_add_edge (cairo_botor_scan_converter_t *self,
+		const cairo_edge_t *edge)
+{
+    edge_t *e;
+    cairo_fixed_t dx, dy;
+
+    e = botor_allocate_edge (self);
+    if (unlikely (e == NULL))
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    cairo_list_init (&e->link);
+    e->edge = *edge;
+
+    dx = edge->line.p2.x - edge->line.p1.x;
+    dy = edge->line.p2.y - edge->line.p1.y;
+    e->dy = dy;
+
+    if (dx == 0) {
+	e->vertical = TRUE;
+	e->x.quo = edge->line.p1.x;
+	e->x.rem = 0;
+	e->dxdy.quo = 0;
+	e->dxdy.rem = 0;
+	e->dxdy_full.quo = 0;
+	e->dxdy_full.rem = 0;
+    } else {
+	e->vertical = FALSE;
+	e->dxdy = floored_divrem (dx, dy);
+	if (edge->top == edge->line.p1.y) {
+	    e->x.quo = edge->line.p1.x;
+	    e->x.rem = 0;
+	} else {
+	    e->x = floored_muldivrem (edge->top - edge->line.p1.y,
+				      dx, dy);
+	    e->x.quo += edge->line.p1.x;
+	}
+
+	if (_cairo_fixed_integer_part (edge->bottom) - _cairo_fixed_integer_part (edge->top) > 1) {
+	    e->dxdy_full = floored_muldivrem (STEP_Y, dx, dy);
+	} else {
+	    e->dxdy_full.quo = 0;
+	    e->dxdy_full.rem = 0;
+	}
+    }
+
+    e->x.rem = -e->dy;
+    e->current_sign = 0;
+    e->runs = NULL;
+    e->flags = START;
+
+    self->num_edges++;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_cairo_botor_scan_converter_add_edge (void		*converter,
+				      const cairo_point_t *p1,
+				      const cairo_point_t *p2,
+				      int top, int bottom,
+				      int dir)
+{
+    cairo_botor_scan_converter_t *self = converter;
+    cairo_edge_t edge;
+
+    edge.line.p1 = *p1;
+    edge.line.p2 = *p2;
+    edge.top = top;
+    edge.bottom = bottom;
+    edge.dir = dir;
+
+    return botor_add_edge (self, &edge);
+}
+
+static cairo_status_t
+_cairo_botor_scan_converter_add_polygon (void		*converter,
+					 const cairo_polygon_t *polygon)
+{
+    cairo_botor_scan_converter_t *self = converter;
+    cairo_status_t status;
+    int i;
+
+    for (i = 0; i < polygon->num_edges; i++) {
+	status = botor_add_edge (self, &polygon->edges[i]);
+	if (unlikely (status))
+	    return status;
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static void
+_cairo_botor_scan_converter_destroy (void *converter)
+{
+    cairo_botor_scan_converter_t *self = converter;
+    struct _cairo_botor_scan_converter_chunk *chunk, *next;
+
+    for (chunk = self->chunks.next; chunk != NULL; chunk = next) {
+	next = chunk->next;
+	free (chunk);
+    }
+}
+
+void
+_cairo_botor_scan_converter_init (cairo_botor_scan_converter_t *self,
+				  const cairo_box_t *extents,
+				  cairo_fill_rule_t fill_rule)
+{
+    self->base.destroy     = _cairo_botor_scan_converter_destroy;
+    self->base.add_edge    = _cairo_botor_scan_converter_add_edge;
+    self->base.add_polygon = _cairo_botor_scan_converter_add_polygon;
+    self->base.generate    = _cairo_botor_scan_converter_generate;
+
+    self->extents   = *extents;
+    self->fill_rule = fill_rule;
+
+    self->xmin = _cairo_fixed_integer_floor (extents->p1.x);
+    self->xmax = _cairo_fixed_integer_ceil (extents->p2.x);
+
+    self->chunks.base = self->buf;
+    self->chunks.next = NULL;
+    self->chunks.count = 0;
+    self->chunks.size = sizeof (self->buf) / sizeof (edge_t);
+    self->tail = &self->chunks;
+
+    self->num_edges = 0;
+}
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/cairo/src/cairo-boxes-private.h
@@ -0,0 +1,84 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2009 Intel 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * Contributor(s):
+ *	Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#ifndef CAIRO_BOXES_H
+#define CAIRO_BOXES_H
+
+#include "cairo-types-private.h"
+#include "cairo-compiler-private.h"
+
+struct _cairo_boxes_t {
+    cairo_status_t status;
+    cairo_box_t limit;
+    const cairo_box_t *limits;
+    int num_limits;
+    int num_boxes;
+    unsigned int is_pixel_aligned : 1;
+
+    struct _cairo_boxes_chunk {
+	struct _cairo_boxes_chunk *next;
+	cairo_box_t *base;
+	int count;
+	int size;
+    } chunks, *tail;
+    cairo_box_t boxes_embedded[32];
+};
+
+cairo_private void
+_cairo_boxes_init (cairo_boxes_t *boxes);
+
+cairo_private void
+_cairo_boxes_init_for_array (cairo_boxes_t *boxes,
+			     cairo_box_t *array,
+			     int num_boxes);
+
+cairo_private void
+_cairo_boxes_limit (cairo_boxes_t	*boxes,
+		    const cairo_box_t	*limits,
+		    int			 num_limits);
+
+cairo_private cairo_status_t
+_cairo_boxes_add (cairo_boxes_t *boxes,
+		  const cairo_box_t *box);
+
+cairo_private void
+_cairo_boxes_extents (const cairo_boxes_t *boxes,
+		      cairo_rectangle_int_t *extents);
+
+cairo_private void
+_cairo_boxes_clear (cairo_boxes_t *boxes);
+
+cairo_private void
+_cairo_boxes_fini (cairo_boxes_t *boxes);
+
+#endif /* CAIRO_BOXES_H */
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/cairo/src/cairo-boxes.c
@@ -0,0 +1,300 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2009 Intel 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * Contributor(s):
+ *	Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairoint.h"
+
+#include "cairo-boxes-private.h"
+#include "cairo-error-private.h"
+
+void
+_cairo_boxes_init (cairo_boxes_t *boxes)
+{
+    boxes->status = CAIRO_STATUS_SUCCESS;
+    boxes->num_limits = 0;
+    boxes->num_boxes = 0;
+
+    boxes->tail = &boxes->chunks;
+    boxes->chunks.next = NULL;
+    boxes->chunks.base = boxes->boxes_embedded;
+    boxes->chunks.size = ARRAY_LENGTH (boxes->boxes_embedded);
+    boxes->chunks.count = 0;
+
+    boxes->is_pixel_aligned = TRUE;
+}
+
+void
+_cairo_boxes_init_for_array (cairo_boxes_t *boxes,
+			     cairo_box_t *array,
+			     int num_boxes)
+{
+    int n;
+
+    boxes->status = CAIRO_STATUS_SUCCESS;
+    boxes->num_limits = 0;
+    boxes->num_boxes = num_boxes;
+
+    boxes->tail = &boxes->chunks;
+    boxes->chunks.next = NULL;
+    boxes->chunks.base = array;
+    boxes->chunks.size = num_boxes;
+    boxes->chunks.count = num_boxes;
+
+    for (n = 0; n < num_boxes; n++) {
+	if (! _cairo_fixed_is_integer (array[n].p1.x) ||
+	    ! _cairo_fixed_is_integer (array[n].p1.y) ||
+	    ! _cairo_fixed_is_integer (array[n].p2.x) ||
+	    ! _cairo_fixed_is_integer (array[n].p2.y))
+	{
+	    break;
+	}
+    }
+
+    boxes->is_pixel_aligned = n == num_boxes;
+}
+
+void
+_cairo_boxes_limit (cairo_boxes_t	*boxes,
+		    const cairo_box_t	*limits,
+		    int			 num_limits)
+{
+    int n;
+
+    boxes->limits = limits;
+    boxes->num_limits = num_limits;
+
+    if (boxes->num_limits) {
+	boxes->limit = limits[0];
+	for (n = 1; n < num_limits; n++) {
+	    if (limits[n].p1.x < boxes->limit.p1.x)
+		boxes->limit.p1.x = limits[n].p1.x;
+
+	    if (limits[n].p1.y < boxes->limit.p1.y)
+		boxes->limit.p1.y = limits[n].p1.y;
+
+	    if (limits[n].p2.x > boxes->limit.p2.x)
+		boxes->limit.p2.x = limits[n].p2.x;
+
+	    if (limits[n].p2.y > boxes->limit.p2.y)
+		boxes->limit.p2.y = limits[n].p2.y;
+	}
+    }
+}
+
+static void
+_cairo_boxes_add_internal (cairo_boxes_t *boxes,
+			   const cairo_box_t *box)
+{
+    struct _cairo_boxes_chunk *chunk;
+
+    if (unlikely (boxes->status))
+	return;
+
+    chunk = boxes->tail;
+    if (unlikely (chunk->count == chunk->size)) {
+	int size;
+
+	size = chunk->size * 2;
+	chunk->next = _cairo_malloc_ab_plus_c (size,
+					       sizeof (cairo_box_t),
+					       sizeof (struct _cairo_boxes_chunk));
+
+	if (unlikely (chunk->next == NULL)) {
+	    boxes->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    return;
+	}
+
+	chunk = chunk->next;
+	boxes->tail = chunk;
+
+	chunk->next = NULL;
+	chunk->count = 0;
+	chunk->size = size;
+	chunk->base = (cairo_box_t *) (chunk + 1);
+    }
+
+    chunk->base[chunk->count++] = *box;
+    boxes->num_boxes++;
+
+    if (boxes->is_pixel_aligned) {
+	boxes->is_pixel_aligned =
+	    _cairo_fixed_is_integer (box->p1.x) &&
+	    _cairo_fixed_is_integer (box->p1.y) &&
+	    _cairo_fixed_is_integer (box->p2.x) &&
+	    _cairo_fixed_is_integer (box->p2.y);
+    }
+}
+
+cairo_status_t
+_cairo_boxes_add (cairo_boxes_t *boxes,
+		  const cairo_box_t *box)
+{
+    if (box->p1.y == box->p2.y)
+	return CAIRO_STATUS_SUCCESS;
+
+    if (box->p1.x == box->p2.x)
+	return CAIRO_STATUS_SUCCESS;
+
+    if (boxes->num_limits) {
+	cairo_point_t p1, p2;
+	cairo_bool_t reversed = FALSE;
+	int n;
+
+	/* support counter-clockwise winding for rectangular tessellation */
+	if (box->p1.x < box->p2.x) {
+	    p1.x = box->p1.x;
+	    p2.x = box->p2.x;
+	} else {
+	    p2.x = box->p1.x;
+	    p1.x = box->p2.x;
+	    reversed = ! reversed;
+	}
+
+	if (p1.x >= boxes->limit.p2.x || p2.x <= boxes->limit.p1.x)
+	    return CAIRO_STATUS_SUCCESS;
+
+	if (box->p1.y < box->p2.y) {
+	    p1.y = box->p1.y;
+	    p2.y = box->p2.y;
+	} else {
+	    p2.y = box->p1.y;
+	    p1.y = box->p2.y;
+	    reversed = ! reversed;
+	}
+
+	if (p1.y >= boxes->limit.p2.y || p2.y <= boxes->limit.p1.y)
+	    return CAIRO_STATUS_SUCCESS;
+
+	for (n = 0; n < boxes->num_limits; n++) {
+	    const cairo_box_t *limits = &boxes->limits[n];
+	    cairo_box_t _box;
+	    cairo_point_t _p1, _p2;
+
+	    if (p1.x >= limits->p2.x || p2.x <= limits->p1.x)
+		continue;
+	    if (p1.y >= limits->p2.y || p2.y <= limits->p1.y)
+		continue;
+
+	    /* Otherwise, clip the box to the limits. */
+	    _p1 = p1;
+	    if (_p1.x < limits->p1.x)
+		_p1.x = limits->p1.x;
+	    if (_p1.y < limits->p1.y)
+		_p1.y = limits->p1.y;
+
+	    _p2 = p2;
+	    if (_p2.x > limits->p2.x)
+		_p2.x = limits->p2.x;
+	    if (_p2.y > limits->p2.y)
+		_p2.y = limits->p2.y;
+
+	    if (_p2.y <= _p1.y || _p2.x <= _p1.x)
+		continue;
+
+	    _box.p1.y = _p1.y;
+	    _box.p2.y = _p2.y;
+	    if (reversed) {
+		_box.p1.x = _p2.x;
+		_box.p2.x = _p1.x;
+	    } else {
+		_box.p1.x = _p1.x;
+		_box.p2.x = _p2.x;
+	    }
+
+	    _cairo_boxes_add_internal (boxes, &_box);
+	}
+    } else {
+	_cairo_boxes_add_internal (boxes, box);
+    }
+
+    return boxes->status;
+}
+
+void
+_cairo_boxes_extents (const cairo_boxes_t *boxes,
+		      cairo_rectangle_int_t *extents)
+{
+    const struct _cairo_boxes_chunk *chunk;
+    cairo_box_t box;
+    int i;
+
+    box.p1.y = box.p1.x = INT_MAX;
+    box.p2.y = box.p2.x = INT_MIN;
+
+    for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
+	const cairo_box_t *b = chunk->base;
+	for (i = 0; i < chunk->count; i++) {
+	    if (b[i].p1.x < box.p1.x)
+		box.p1.x = b[i].p1.x;
+
+	    if (b[i].p1.y < box.p1.y)
+		box.p1.y = b[i].p1.y;
+
+	    if (b[i].p2.x > box.p2.x)
+		box.p2.x = b[i].p2.x;
+
+	    if (b[i].p2.y > box.p2.y)
+		box.p2.y = b[i].p2.y;
+	}
+    }
+
+    _cairo_box_round_to_rectangle (&box, extents);
+}
+
+void
+_cairo_boxes_clear (cairo_boxes_t *boxes)
+{
+    struct _cairo_boxes_chunk *chunk, *next;
+
+    for (chunk = boxes->chunks.next; chunk != NULL; chunk = next) {
+	next = chunk->next;
+	free (chunk);
+    }
+
+    boxes->tail = &boxes->chunks;
+    boxes->chunks.next = 0;
+    boxes->chunks.count = 0;
+    boxes->num_boxes = 0;
+
+    boxes->is_pixel_aligned = TRUE;
+}
+
+void
+_cairo_boxes_fini (cairo_boxes_t *boxes)
+{
+    struct _cairo_boxes_chunk *chunk, *next;
+
+    for (chunk = boxes->chunks.next; chunk != NULL; chunk = next) {
+	next = chunk->next;
+	free (chunk);
+    }
+}
--- a/gfx/cairo/cairo/src/cairo-cache-private.h
+++ b/gfx/cairo/cairo/src/cairo-cache-private.h
@@ -8,17 +8,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
--- a/gfx/cairo/cairo/src/cairo-cache.c
+++ b/gfx/cairo/cairo/src/cairo-cache.c
@@ -8,17 +8,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
@@ -32,16 +32,17 @@
  *
  * Contributor(s):
  *      Keith Packard <keithp@keithp.com>
  *	Graydon Hoare <graydon@redhat.com>
  *	Carl Worth <cworth@cworth.org>
  */
 
 #include "cairoint.h"
+#include "cairo-error-private.h"
 
 static void
 _cairo_cache_shrink_to_accommodate (cairo_cache_t *cache,
 				    unsigned long  additional);
 
 static cairo_bool_t
 _cairo_cache_entry_is_non_zero (const void *entry)
 {
@@ -169,19 +170,17 @@ void
  * the cache until the cache is smaller than max_size. Also, the
  * automatic ejection of entries on _cairo_cache_insert() will resume.
  **/
 void
 _cairo_cache_thaw (cairo_cache_t *cache)
 {
     assert (cache->freeze_count > 0);
 
-    cache->freeze_count--;
-
-    if (cache->freeze_count == 0)
+    if (--cache->freeze_count == 0)
 	_cairo_cache_shrink_to_accommodate (cache, 0);
 }
 
 /**
  * _cairo_cache_lookup:
  * @cache: a cache
  * @key: the key of interest
  * @entry_return: pointer for return value
@@ -235,19 +234,16 @@ static cairo_bool_t
  * the cache is at least @additional bytes less than
  * cache->max_size. That is, make enough room to accommodate a new
  * entry of size @additional.
  **/
 static void
 _cairo_cache_shrink_to_accommodate (cairo_cache_t *cache,
 				    unsigned long  additional)
 {
-    if (cache->freeze_count)
-	return;
-
     while (cache->size + additional > cache->max_size) {
 	if (! _cairo_cache_remove_random (cache))
 	    return;
     }
 }
 
 /**
  * _cairo_cache_insert:
@@ -262,17 +258,18 @@ static void
  * %CAIRO_STATUS_NO_MEMORY if insufficient memory is available.
  **/
 cairo_status_t
 _cairo_cache_insert (cairo_cache_t	 *cache,
 		     cairo_cache_entry_t *entry)
 {
     cairo_status_t status;
 
-    _cairo_cache_shrink_to_accommodate (cache, entry->size);
+    if (entry->size && ! cache->freeze_count)
+	_cairo_cache_shrink_to_accommodate (cache, entry->size);
 
     status = _cairo_hash_table_insert (cache->hash_table,
 				       (cairo_hash_entry_t *) entry);
     if (unlikely (status))
 	return status;
 
     cache->size += entry->size;
 
--- a/gfx/cairo/cairo/src/cairo-cff-subset.c
+++ b/gfx/cairo/cairo/src/cairo-cff-subset.c
@@ -7,17 +7,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
@@ -36,16 +36,17 @@
 
 /*
  * Useful links:
  * http://www.adobe.com/devnet/font/pdfs/5176.CFF.pdf
  */
 
 #define _BSD_SOURCE /* for snprintf(), strdup() */
 #include "cairoint.h"
+#include "cairo-error-private.h"
 
 #if CAIRO_HAS_FONT_SUBSET
 
 #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
@@ -112,16 +113,17 @@ typedef struct _cairo_cff_font {
     cairo_hash_table_t  *top_dict;
     cairo_hash_table_t  *private_dict;
     cairo_array_t        strings_index;
     cairo_array_t        charstrings_index;
     cairo_array_t        global_sub_index;
     cairo_array_t        local_sub_index;
     int                  num_glyphs;
     cairo_bool_t         is_cid;
+    int  		 units_per_em;
 
     /* CID Font Data */
     int                 *fdselect;
     unsigned int         num_fontdicts;
     cairo_hash_table_t **fd_dict;
     cairo_hash_table_t **fd_private_dict;
     cairo_array_t       *fd_local_sub_index;
 
@@ -1767,16 +1769,19 @@ static cairo_int_status_t
 	goto fail2;
     }
     font->x_min = (int16_t) be16_to_cpu (head.x_min);
     font->y_min = (int16_t) be16_to_cpu (head.y_min);
     font->x_max = (int16_t) be16_to_cpu (head.x_max);
     font->y_max = (int16_t) be16_to_cpu (head.y_max);
     font->ascent = (int16_t) be16_to_cpu (hhea.ascender);
     font->descent = (int16_t) be16_to_cpu (hhea.descender);
+    font->units_per_em = (int16_t) be16_to_cpu (head.units_per_em);
+    if (font->units_per_em == 0)
+        font->units_per_em = 1000;
 
     font->font_name = NULL;
     status = _cairo_truetype_read_font_name (scaled_font_subset->scaled_font,
 					     &font->ps_name,
 					     &font->font_name);
     if (_cairo_status_is_error (status))
 	goto fail3;
 
@@ -1950,30 +1955,30 @@ cairo_status_t
 	if (cff_subset->font_name == NULL) {
 	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto fail2;
 	}
     } else {
 	cff_subset->font_name = NULL;
     }
 
-    cff_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
+    cff_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
     if (unlikely (cff_subset->widths == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail3;
     }
     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
-        cff_subset->widths[i] = font->widths[i];
+        cff_subset->widths[i] = (double)font->widths[i]/font->units_per_em;
 
-    cff_subset->x_min = font->x_min;
-    cff_subset->y_min = font->y_min;
-    cff_subset->x_max = font->x_max;
-    cff_subset->y_max = font->y_max;
-    cff_subset->ascent = font->ascent;
-    cff_subset->descent = font->descent;
+    cff_subset->x_min = (double)font->x_min/font->units_per_em;
+    cff_subset->y_min = (double)font->y_min/font->units_per_em;
+    cff_subset->x_max = (double)font->x_max/font->units_per_em;
+    cff_subset->y_max = (double)font->y_max/font->units_per_em;
+    cff_subset->ascent = (double)font->ascent/font->units_per_em;
+    cff_subset->descent = (double)font->descent/font->units_per_em;
 
     cff_subset->data = malloc (length);
     if (unlikely (cff_subset->data == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail4;
     }
 
     memcpy (cff_subset->data, data, length);
@@ -2207,31 +2212,31 @@ cairo_status_t
 
     cff_subset->font_name = NULL;
     cff_subset->ps_name = strdup (font->ps_name);
     if (unlikely (cff_subset->ps_name == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail2;
     }
 
-    cff_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs);
+    cff_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
     if (unlikely (cff_subset->widths == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail3;
     }
 
     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
-        cff_subset->widths[i] = type2_subset.widths[i];
+        cff_subset->widths[i] = (double)type2_subset.widths[i]/1000;
 
-    cff_subset->x_min = type2_subset.x_min;
-    cff_subset->y_min = type2_subset.y_min;
-    cff_subset->x_max = type2_subset.x_max;
-    cff_subset->y_max = type2_subset.y_max;
-    cff_subset->ascent = type2_subset.y_max;
-    cff_subset->descent = type2_subset.y_min;
+    cff_subset->x_min = (double)type2_subset.x_min/1000;
+    cff_subset->y_min = (double)type2_subset.y_min/1000;
+    cff_subset->x_max = (double)type2_subset.x_max/1000;
+    cff_subset->y_max = (double)type2_subset.y_max/1000;
+    cff_subset->ascent = (double)type2_subset.y_max/1000;
+    cff_subset->descent = (double)type2_subset.y_min/1000;
 
     cff_subset->data = malloc (length);
     if (unlikely (cff_subset->data == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail4;
     }
 
     memcpy (cff_subset->data, data, length);
--- a/gfx/cairo/cairo/src/cairo-clip-private.h
+++ b/gfx/cairo/cairo/src/cairo-clip-private.h
@@ -7,17 +7,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
@@ -71,31 +71,31 @@ struct _cairo_clip {
 
     cairo_bool_t all_clipped;
 
 };
 
 cairo_private void
 _cairo_clip_init (cairo_clip_t *clip);
 
-cairo_private cairo_status_t
-_cairo_clip_init_rectangle (cairo_clip_t *clip,
-			    const cairo_rectangle_int_t *rect);
-
 cairo_private_no_warn cairo_clip_t *
 _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other);
 
 cairo_private cairo_status_t
 _cairo_clip_init_copy_transformed (cairo_clip_t    *clip,
 				   cairo_clip_t    *other,
 				   const cairo_matrix_t *matrix);
 
 cairo_private void
 _cairo_clip_reset (cairo_clip_t *clip);
 
+cairo_private cairo_bool_t
+_cairo_clip_equal (const cairo_clip_t *clip_a,
+		   const cairo_clip_t *clip_b);
+
 #define _cairo_clip_fini(clip) _cairo_clip_reset (clip)
 
 cairo_private cairo_status_t
 _cairo_clip_rectangle (cairo_clip_t       *clip,
 		       const cairo_rectangle_int_t *rectangle);
 
 cairo_private cairo_status_t
 _cairo_clip_clip (cairo_clip_t       *clip,
@@ -107,31 +107,45 @@ cairo_private cairo_status_t
 cairo_private cairo_status_t
 _cairo_clip_apply_clip (cairo_clip_t *clip,
 			const cairo_clip_t *other);
 
 cairo_private const cairo_rectangle_int_t *
 _cairo_clip_get_extents (const cairo_clip_t *clip);
 
 cairo_private cairo_surface_t *
-_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *dst);
+_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *dst, int *tx, int *ty);
 
 cairo_private cairo_status_t
 _cairo_clip_combine_with_surface (cairo_clip_t *clip,
 				  cairo_surface_t *dst,
-				  const cairo_rectangle_int_t *extents);
+				  int dst_x, int dst_y);
 
 cairo_private cairo_int_status_t
 _cairo_clip_get_region (cairo_clip_t *clip,
 			cairo_region_t **region);
 
 cairo_private cairo_int_status_t
 _cairo_clip_get_boxes (cairo_clip_t *clip,
 		       cairo_box_t **boxes,
 		       int *count);
 
+cairo_private cairo_status_t
+_cairo_clip_to_boxes (cairo_clip_t **clip,
+		      cairo_composite_rectangles_t *extents,
+		      cairo_box_t **boxes,
+		      int *num_boxes);
+
+cairo_private cairo_bool_t
+_cairo_clip_contains_rectangle (cairo_clip_t *clip,
+				const cairo_rectangle_int_t *rect);
+
+cairo_private cairo_bool_t
+_cairo_clip_contains_extents (cairo_clip_t *clip,
+				const cairo_composite_rectangles_t *extents);
+
 cairo_private void
 _cairo_clip_drop_cache (cairo_clip_t  *clip);
 
 cairo_private cairo_rectangle_list_t*
 _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate);
 
 #endif /* CAIRO_CLIP_PRIVATE_H */
--- a/gfx/cairo/cairo/src/cairo-clip.c
+++ b/gfx/cairo/cairo/src/cairo-clip.c
@@ -10,17 +10,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
@@ -36,105 +36,26 @@
  * 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 "cairo-clip-private.h"
+#include "cairo-error-private.h"
+#include "cairo-freed-pool-private.h"
+#include "cairo-gstate-private.h"
 #include "cairo-path-fixed-private.h"
+#include "cairo-composite-rectangles-private.h"
 #include "cairo-region-private.h"
 
-/* Keep a stash of recently freed clip_paths, since we need to
- * reallocate them frequently.
- */
-#define MAX_FREED_POOL_SIZE 4
-typedef struct {
-    void *pool[MAX_FREED_POOL_SIZE];
-    int top;
-} freed_pool_t;
-
+#if HAS_FREED_POOL
 static freed_pool_t clip_path_pool;
-
-static void *
-_atomic_fetch (void **slot)
-{
-    return _cairo_atomic_ptr_cmpxchg (slot, *slot, NULL);
-}
-
-static cairo_bool_t
-_atomic_store (void **slot, void *ptr)
-{
-    return _cairo_atomic_ptr_cmpxchg (slot, NULL, ptr) == NULL;
-}
-
-static void *
-_freed_pool_get (freed_pool_t *pool)
-{
-    void *ptr;
-    int i;
-
-    i = pool->top - 1;
-    if (i < 0)
-	i = 0;
-
-    ptr = _atomic_fetch (&pool->pool[i]);
-    if (ptr != NULL) {
-	pool->top = i;
-	return ptr;
-    }
-
-    /* either empty or contended */
-    for (i = ARRAY_LENGTH (pool->pool); i--;) {
-	ptr = _atomic_fetch (&pool->pool[i]);
-	if (ptr != NULL) {
-	    pool->top = i;
-	    return ptr;
-	}
-    }
-
-    /* empty */
-    pool->top = 0;
-    return NULL;
-}
-
-static void
-_freed_pool_put (freed_pool_t *pool, void *ptr)
-{
-    int i = pool->top;
-
-    if (_atomic_store (&pool->pool[i], ptr)) {
-	pool->top = i + 1;
-	return;
-    }
-
-    /* either full or contended */
-    for (i = 0; i < ARRAY_LENGTH (pool->pool); i++) {
-	if (_atomic_store (&pool->pool[i], ptr)) {
-	    pool->top = i + 1;
-	    return;
-	}
-    }
-
-    /* full */
-    pool->top = ARRAY_LENGTH (pool->pool);
-    free (ptr);
-}
-
-static void
-_freed_pool_reset (freed_pool_t *pool)
-{
-    int i;
-
-    for (i = 0; i < ARRAY_LENGTH (pool->pool); i++) {
-	free (pool->pool[i]);
-	pool->pool[i] = NULL;
-    }
-}
+#endif
 
 static cairo_clip_path_t *
 _cairo_clip_path_create (cairo_clip_t *clip)
 {
     cairo_clip_path_t *clip_path;
 
     clip_path = _freed_pool_get (&clip_path_pool);
     if (unlikely (clip_path == NULL)) {
@@ -153,19 +74,16 @@ static cairo_clip_path_t *
     clip->path = clip_path;
 
     return clip_path;
 }
 
 static cairo_clip_path_t *
 _cairo_clip_path_reference (cairo_clip_path_t *clip_path)
 {
-    if (clip_path == NULL)
-	return NULL;
-
     assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&clip_path->ref_count));
 
     _cairo_reference_count_inc (&clip_path->ref_count);
 
     return clip_path;
 }
 
 static void
@@ -242,57 +160,50 @@ static cairo_status_t
     assert (status == CAIRO_STATUS_SUCCESS);
     status = _cairo_path_fixed_rel_line_to (&clip_path->path,
 					    _cairo_fixed_from_int (-rect->width),
 					    _cairo_fixed_from_int (0));
     assert (status == CAIRO_STATUS_SUCCESS);
     status = _cairo_path_fixed_close_path (&clip_path->path);
     assert (status == CAIRO_STATUS_SUCCESS);
 
-    clip_path->extents = *rect;
     clip_path->fill_rule = CAIRO_FILL_RULE_WINDING;
     clip_path->tolerance = 1;
-    clip_path->antialias = CAIRO_ANTIALIAS_NONE;
+    clip_path->antialias = CAIRO_ANTIALIAS_DEFAULT;
     clip_path->flags |= CAIRO_CLIP_PATH_IS_BOX;
 
+    clip_path->extents = *rect;
+    if (clip_path->prev != NULL) {
+	if (! _cairo_rectangle_intersect (&clip_path->extents,
+					  &clip_path->prev->extents))
+	{
+	    _cairo_clip_set_all_clipped (clip);
+	}
+    }
+
     /* could preallocate the region if it proves worthwhile */
 
     return CAIRO_STATUS_SUCCESS;
 }
 
-/* XXX consider accepting a matrix, no users yet. */
-cairo_status_t
-_cairo_clip_init_rectangle (cairo_clip_t *clip,
-			    const cairo_rectangle_int_t *rect)
-{
-    _cairo_clip_init (clip);
-
-    if (rect == NULL)
-	return CAIRO_STATUS_SUCCESS;
-
-    if (rect->width == 0 || rect->height == 0) {
-	_cairo_clip_set_all_clipped (clip);
-	return CAIRO_STATUS_SUCCESS;
-    }
-
-    return _cairo_clip_intersect_rectangle (clip, rect);
-}
-
 cairo_clip_t *
 _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
 {
     if (other != NULL) {
 	clip->all_clipped = other->all_clipped;
-	clip->path = _cairo_clip_path_reference (other->path);
-
-	/* this guy is here because of the weird return semantics of _cairo_clip_init_copy */
-	if (!other->path)
-	    return NULL;
+	if (other->path == NULL) {
+	    clip->path = NULL;
+	    if (! clip->all_clipped)
+		clip = NULL;
+	} else {
+	    clip->path = _cairo_clip_path_reference (other->path);
+	}
     } else {
 	_cairo_clip_init (clip);
+	clip = NULL;
     }
 
     return clip;
 }
 
 void
 _cairo_clip_reset (cairo_clip_t *clip)
 {
@@ -313,19 +224,18 @@ static cairo_status_t
     cairo_clip_path_t *clip_path;
     cairo_status_t status;
     cairo_rectangle_int_t extents;
     cairo_box_t box;
     cairo_bool_t is_box = FALSE;
 
     if (clip->path != NULL) {
 	if (clip->path->fill_rule == fill_rule &&
-	    (path->is_rectilinear ||
-	     (tolerance == clip->path->tolerance &&
-	      antialias == clip->path->antialias)) &&
+	    (path->is_rectilinear || tolerance == clip->path->tolerance) &&
+	    antialias == clip->path->antialias &&
 	    _cairo_path_fixed_equal (&clip->path->path, path))
 	{
 	    return CAIRO_STATUS_SUCCESS;
 	}
     }
 
     _cairo_path_fixed_approximate_clip_extents (path, &extents);
     if (extents.width == 0 || extents.height == 0) {
@@ -367,16 +277,48 @@ static cairo_status_t
     clip_path->tolerance = tolerance;
     clip_path->antialias = antialias;
     if (is_box)
 	clip_path->flags |= CAIRO_CLIP_PATH_IS_BOX;
 
     return CAIRO_STATUS_SUCCESS;
 }
 
+cairo_bool_t
+_cairo_clip_equal (const cairo_clip_t *clip_a,
+		   const cairo_clip_t *clip_b)
+{
+    const cairo_clip_path_t *clip_path_a, *clip_path_b;
+
+    clip_path_a = clip_a->path;
+    clip_path_b = clip_b->path;
+
+    while (clip_path_a && clip_path_b) {
+	if (clip_path_a == clip_path_b)
+	    return TRUE;
+
+	if (clip_path_a->fill_rule != clip_path_b->fill_rule)
+	    return FALSE;
+
+	if (clip_path_a->tolerance != clip_path_b->tolerance)
+	    return FALSE;
+
+	if (clip_path_a->antialias != clip_path_b->antialias)
+	    return FALSE;
+
+	if (! _cairo_path_fixed_equal (&clip_path_a->path, &clip_path_b->path))
+	    return FALSE;
+
+	clip_path_a = clip_path_a->prev;
+	clip_path_b = clip_path_b->prev;
+    }
+
+    return clip_path_a == clip_path_b; /* ie both NULL */
+}
+
 cairo_status_t
 _cairo_clip_clip (cairo_clip_t       *clip,
 		  const cairo_path_fixed_t *path,
 		  cairo_fill_rule_t   fill_rule,
 		  double              tolerance,
 		  cairo_antialias_t   antialias)
 {
     if (clip->all_clipped)
@@ -404,17 +346,17 @@ cairo_status_t
 	_cairo_clip_set_all_clipped (clip);
 	return CAIRO_STATUS_SUCCESS;
     }
 
     /* if a smaller clip has already been set, ignore the new path */
     if (clip->path != NULL) {
 	if (rectangle->x <= clip->path->extents.x &&
 	    rectangle->y <= clip->path->extents.y &&
-	    rectangle->x + rectangle->width >= clip->path->extents.x + clip->path->extents.width &&
+	    rectangle->x + rectangle->width  >= clip->path->extents.x + clip->path->extents.width &&
 	    rectangle->y + rectangle->height >= clip->path->extents.y + clip->path->extents.height)
 	{
 	    return CAIRO_STATUS_SUCCESS;
 	}
     }
 
     return _cairo_clip_intersect_rectangle (clip, rectangle);
 }
@@ -438,16 +380,17 @@ static cairo_status_t
 
     clip_path = _cairo_clip_path_create (clip);
     if (unlikely (clip_path == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     status = _cairo_path_fixed_init_copy (&clip_path->path,
 					  &other_path->path);
     if (unlikely (status)) {
+	clip->path = clip->path->prev;
 	_cairo_clip_path_destroy (clip_path);
 	return status;
     }
 
     _cairo_path_fixed_transform (&clip_path->path, matrix);
     _cairo_path_fixed_approximate_clip_extents (&clip_path->path,
 						&clip_path->extents);
     if (clip_path->prev != NULL) {
@@ -480,31 +423,39 @@ static cairo_status_t
 
     clip_path = _cairo_clip_path_create (clip);
     if (unlikely (clip_path == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     status = _cairo_path_fixed_init_copy (&clip_path->path,
 					  &other_path->path);
     if (unlikely (status)) {
+	clip->path = clip->path->prev;
 	_cairo_clip_path_destroy (clip_path);
 	return status;
     }
 
     _cairo_path_fixed_translate (&clip_path->path,
 				 _cairo_fixed_from_int (tx),
 				 _cairo_fixed_from_int (ty));
 
     clip_path->fill_rule = other_path->fill_rule;
     clip_path->tolerance = other_path->tolerance;
     clip_path->antialias = other_path->antialias;
 
     clip_path->flags = other_path->flags;
     if (other_path->region != NULL) {
 	clip_path->region = cairo_region_copy (other_path->region);
+	status = clip_path->region->status;
+	if (unlikely (status)) {
+	    clip->path = clip->path->prev;
+	    _cairo_clip_path_destroy (clip_path);
+	    return status;
+	}
+
 	cairo_region_translate (clip_path->region, tx, ty);
     }
     clip_path->surface = cairo_surface_reference (other_path->surface);
 
     clip_path->extents = other_path->extents;
     clip_path->extents.x += tx;
     clip_path->extents.y += ty;
 
@@ -992,197 +943,224 @@ static cairo_int_status_t
 		return status;
 	}
     }
 
     *count = num_boxes;
     return CAIRO_STATUS_SUCCESS;
 }
 
-static cairo_status_t
-_combine_region (cairo_surface_t *surface,
-		 const cairo_region_t *region,
-		 const cairo_rectangle_int_t *extents)
+static cairo_surface_t *
+_cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
+			      cairo_surface_t *target,
+			      int *tx, int *ty)
 {
-    cairo_region_t clear_region;
+    const cairo_rectangle_int_t *clip_extents = &clip_path->extents;
+    cairo_bool_t need_translate;
+    cairo_surface_t *surface;
+    cairo_clip_path_t *prev;
     cairo_status_t status;
 
-    _cairo_region_init_rectangle (&clear_region, extents);
-    status = cairo_region_subtract (&clear_region, region);
-    if (unlikely (status))
-	return status;
-
-    if (! cairo_region_is_empty (&clear_region)) {
-	cairo_region_translate (&clear_region, -extents->x, -extents->y);
-	status = _cairo_surface_fill_region (surface,
-					     CAIRO_OPERATOR_CLEAR,
-					     CAIRO_COLOR_TRANSPARENT,
-					     &clear_region);
+    while (clip_path->prev != NULL &&
+	   clip_path->flags & CAIRO_CLIP_PATH_IS_BOX &&
+	   clip_path->path.maybe_fill_region)
+    {
+	clip_path = clip_path->prev;
     }
-    _cairo_region_fini (&clear_region);
 
-    return status;
-}
-
-static cairo_surface_t *
-_cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
-			      cairo_surface_t *target)
-{
-    cairo_surface_t *surface;
-    cairo_pattern_union_t pattern;
-    cairo_status_t status;
-    const cairo_rectangle_int_t *clip_extents = &clip_path->extents;
-    cairo_clip_path_t *prev;
-    cairo_bool_t need_translate;
-
+    clip_extents = &clip_path->extents;
     if (clip_path->surface != NULL &&
 	clip_path->surface->backend == target->backend)
     {
-	return cairo_surface_reference (clip_path->surface);
+	*tx = clip_extents->x;
+	*ty = clip_extents->y;
+	return clip_path->surface;
     }
 
-    surface = _cairo_surface_create_similar_solid (target,
-						   CAIRO_CONTENT_ALPHA,
-						   clip_extents->width,
-						   clip_extents->height,
-						   CAIRO_COLOR_TRANSPARENT,
-						   FALSE);
+    surface = _cairo_surface_create_similar_scratch (target,
+						     CAIRO_CONTENT_ALPHA,
+						     clip_extents->width,
+						     clip_extents->height);
     if (surface == NULL) {
-	if (clip_path->surface != NULL &&
-	    clip_path->surface->backend == &_cairo_image_surface_backend)
-	{
-	    return cairo_surface_reference (clip_path->surface);
-	}
-
-	surface =
-	    _cairo_image_surface_create_with_content (CAIRO_CONTENT_ALPHA,
-						      clip_extents->width,
-						      clip_extents->height);
+	surface = cairo_image_surface_create (CAIRO_FORMAT_A8,
+					      clip_extents->width,
+					      clip_extents->height);
     }
     if (unlikely (surface->status))
 	return surface;
 
-    _cairo_pattern_init_solid (&pattern.solid,
-			       CAIRO_COLOR_WHITE,
-			       CAIRO_CONTENT_COLOR);
-
-    status = _cairo_clip_path_to_region (clip_path);
-    if (unlikely (_cairo_status_is_error (status)))
-	goto BAIL;
-
     need_translate = clip_extents->x | clip_extents->y;
-    if (status == CAIRO_STATUS_SUCCESS) {
-	if (need_translate) {
-	    cairo_region_translate (clip_path->region,
-				    -clip_extents->x, -clip_extents->y);
-	}
-	status = _cairo_surface_fill_region (surface,
-					     CAIRO_OPERATOR_SOURCE,
-					     CAIRO_COLOR_WHITE,
-					     clip_path->region);
-	if (need_translate) {
-	    cairo_region_translate (clip_path->region,
-				    clip_extents->x, clip_extents->y);
-	}
+    if (clip_path->flags & CAIRO_CLIP_PATH_IS_BOX &&
+	clip_path->path.maybe_fill_region)
+    {
+	status = _cairo_surface_paint (surface,
+				       CAIRO_OPERATOR_SOURCE,
+				       &_cairo_pattern_white.base,
+				       NULL);
+	if (unlikely (status))
+	    goto BAIL;
+    }
+    else
+    {
+	status = _cairo_surface_paint (surface,
+				       CAIRO_OPERATOR_CLEAR,
+				       &_cairo_pattern_clear.base,
+				       NULL);
 	if (unlikely (status))
 	    goto BAIL;
 
-	goto DONE;
-    } else {
 	if (need_translate) {
 	    _cairo_path_fixed_translate (&clip_path->path,
 					 _cairo_fixed_from_int (-clip_extents->x),
 					 _cairo_fixed_from_int (-clip_extents->y));
 	}
 	status = _cairo_surface_fill (surface,
-				      CAIRO_OPERATOR_OVER,
-				      &pattern.base,
+				      CAIRO_OPERATOR_ADD,
+				      &_cairo_pattern_white.base,
 				      &clip_path->path,
 				      clip_path->fill_rule,
 				      clip_path->tolerance,
 				      clip_path->antialias,
 				      NULL);
 	if (need_translate) {
 	    _cairo_path_fixed_translate (&clip_path->path,
 					 _cairo_fixed_from_int (clip_extents->x),
 					 _cairo_fixed_from_int (clip_extents->y));
 	}
 
 	if (unlikely (status))
 	    goto BAIL;
     }
 
     prev = clip_path->prev;
-  NEXT_PATH:
-    if (prev != NULL) {
-	status = _cairo_clip_path_to_region (prev);
-	if (unlikely (_cairo_status_is_error (status)))
-	    goto BAIL;
-
-	if (status == CAIRO_STATUS_SUCCESS) {
-	    status = _combine_region (surface, prev->region, clip_extents);
-	    if (unlikely (status))
-		goto BAIL;
-	} else if (prev->flags & CAIRO_CLIP_PATH_IS_BOX) {
+    while (prev != NULL) {
+	if (prev->flags & CAIRO_CLIP_PATH_IS_BOX &&
+	    prev->path.maybe_fill_region)
+	{
 	    /* a simple box only affects the extents */
-	} else if (prev->path.is_rectilinear) {
+	}
+	else if (prev->path.is_rectilinear ||
+		prev->surface == NULL ||
+		prev->surface->backend != target->backend)
+	{
 	    if (need_translate) {
 		_cairo_path_fixed_translate (&prev->path,
 					     _cairo_fixed_from_int (-clip_extents->x),
 					     _cairo_fixed_from_int (-clip_extents->y));
 	    }
 	    status = _cairo_surface_fill (surface,
 					  CAIRO_OPERATOR_IN,
-					  &pattern.base,
+					  &_cairo_pattern_white.base,
 					  &prev->path,
 					  prev->fill_rule,
 					  prev->tolerance,
 					  prev->antialias,
 					  NULL);
 	    if (need_translate) {
 		_cairo_path_fixed_translate (&prev->path,
 					     _cairo_fixed_from_int (clip_extents->x),
 					     _cairo_fixed_from_int (clip_extents->y));
 	    }
 
 	    if (unlikely (status))
 		goto BAIL;
-
-	    prev = prev->prev;
-	    goto NEXT_PATH;
-	} else {
+	}
+	else
+	{
+	    cairo_surface_pattern_t pattern;
 	    cairo_surface_t *prev_surface;
+	    int prev_tx, prev_ty;
 
-	    prev_surface = _cairo_clip_path_get_surface (prev, target);
-	    _cairo_pattern_init_for_surface (&pattern.surface, prev_surface);
-	    cairo_surface_destroy (prev_surface);
+	    prev_surface = _cairo_clip_path_get_surface (prev, target, &prev_tx, &prev_ty);
+	    status = prev_surface->status;
+	    if (unlikely (status))
+		goto BAIL;
 
+	    _cairo_pattern_init_for_surface (&pattern, prev_surface);
+	    pattern.base.filter = CAIRO_FILTER_NEAREST;
 	    cairo_matrix_init_translate (&pattern.base.matrix,
-					 -prev->extents.x + clip_extents->x,
-					 -prev->extents.y + clip_extents->y);
+					 clip_extents->x - prev_tx,
+					 clip_extents->y - prev_ty);
 	    status = _cairo_surface_paint (surface,
 					   CAIRO_OPERATOR_IN,
 					   &pattern.base,
 					   NULL);
 	    _cairo_pattern_fini (&pattern.base);
 
 	    if (unlikely (status))
 		goto BAIL;
+
+	    break;
 	}
+
+	prev = prev->prev;
     }
 
-  DONE:
+    *tx = clip_extents->x;
+    *ty = clip_extents->y;
     cairo_surface_destroy (clip_path->surface);
-    return clip_path->surface = cairo_surface_reference (surface);
+    return clip_path->surface = surface;
 
   BAIL:
     cairo_surface_destroy (surface);
     return _cairo_surface_create_in_error (status);
 }
 
+cairo_bool_t
+_cairo_clip_contains_rectangle (cairo_clip_t *clip,
+				const cairo_rectangle_int_t *rect)
+{
+    cairo_clip_path_t *clip_path;
+
+    if (clip == NULL)
+	return FALSE;
+
+    clip_path = clip->path;
+    if (clip_path->extents.x > rect->x ||
+	clip_path->extents.y > rect->y ||
+	clip_path->extents.x + clip_path->extents.width  < rect->x + rect->width ||
+	clip_path->extents.y + clip_path->extents.height < rect->y + rect->height)
+    {
+	return FALSE;
+    }
+
+    do {
+	cairo_box_t box;
+
+	if ((clip_path->flags & CAIRO_CLIP_PATH_IS_BOX) == 0)
+	    return FALSE;
+
+	if (! _cairo_path_fixed_is_box (&clip_path->path, &box))
+	    return FALSE;
+
+	if (box.p1.x > _cairo_fixed_from_int (rect->x) ||
+	    box.p1.y > _cairo_fixed_from_int (rect->y) ||
+	    box.p2.x < _cairo_fixed_from_int (rect->x + rect->width) ||
+	    box.p2.y < _cairo_fixed_from_int (rect->y + rect->height))
+	{
+	    return FALSE;
+	}
+    } while ((clip_path = clip_path->prev) != NULL);
+
+    return TRUE;
+}
+
+cairo_bool_t
+_cairo_clip_contains_extents (cairo_clip_t *clip,
+			      const cairo_composite_rectangles_t *extents)
+{
+    const cairo_rectangle_int_t *rect;
+
+    if (clip == NULL)
+	return FALSE;
+
+    rect = extents->is_bounded ? &extents->bounded : &extents->unbounded;
+    return _cairo_clip_contains_rectangle (clip, rect);
+}
+
 void
 _cairo_debug_print_clip (FILE *stream, cairo_clip_t *clip)
 {
     cairo_clip_path_t *clip_path;
 
     if (clip == NULL) {
 	fprintf (stream, "no clip\n");
 	return;
@@ -1197,116 +1175,91 @@ void
 	fprintf (stream, "clip: empty\n");
 	return;
     }
 
     fprintf (stream, "clip:\n");
 
     clip_path = clip->path;
     do {
-	fprintf (stream, "path: has region? %s, has surface? %s: ",
+	fprintf (stream, "path: has region? %s, has surface? %s, aa=%d, tolerance=%f, rule=%d: ",
 		 clip_path->region == NULL ? "no" : "yes",
-		 clip_path->surface == NULL ? "no" : "yes");
+		 clip_path->surface == NULL ? "no" : "yes",
+		 clip_path->antialias,
+		 clip_path->tolerance,
+		 clip_path->fill_rule);
 	_cairo_debug_print_path (stream, &clip_path->path);
 	fprintf (stream, "\n");
     } while ((clip_path = clip_path->prev) != NULL);
 }
 
 cairo_surface_t *
-_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *target)
+_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *target, int *tx, int *ty)
 {
+    /* XXX is_clear -> all_clipped */
     assert (clip->path != NULL);
-    return _cairo_clip_path_get_surface (clip->path, target);
+    return _cairo_clip_path_get_surface (clip->path, target, tx, ty);
 }
 
 cairo_status_t
 _cairo_clip_combine_with_surface (cairo_clip_t *clip,
 				  cairo_surface_t *dst,
-				  const cairo_rectangle_int_t *extents)
+				  int dst_x, int dst_y)
 {
-    cairo_pattern_union_t pattern;
     cairo_clip_path_t *clip_path = clip->path;
     cairo_bool_t need_translate;
     cairo_status_t status;
 
     assert (clip_path != NULL);
 
-    if (clip_path->surface != NULL &&
-	clip_path->surface->backend == dst->backend)
-    {
-	_cairo_pattern_init_for_surface (&pattern.surface,
-					 clip_path->surface);
-	cairo_matrix_init_translate (&pattern.base.matrix,
-				     extents->x - clip_path->extents.x,
-				     extents->y - clip_path->extents.y);
-	status = _cairo_surface_paint (dst,
-				       CAIRO_OPERATOR_IN,
-				       &pattern.base,
-				       NULL);
-
-	_cairo_pattern_fini (&pattern.base);
-
-	return status;
-    }
-
-    _cairo_pattern_init_solid (&pattern.solid,
-			       CAIRO_COLOR_WHITE,
-			       CAIRO_CONTENT_COLOR);
-
-    need_translate = extents->x | extents->y;
+    need_translate = dst_x | dst_y;
     do {
-	status = _cairo_clip_path_to_region (clip_path);
-	if (unlikely (_cairo_status_is_error (status)))
-	    return status;
-
-	if (status == CAIRO_STATUS_SUCCESS)
-	    return _combine_region (dst, clip_path->region, extents);
-
 	if (clip_path->surface != NULL &&
 	    clip_path->surface->backend == dst->backend)
 	{
-	    _cairo_pattern_init_for_surface (&pattern.surface,
-					     clip_path->surface);
+	    cairo_surface_pattern_t pattern;
+
+	    _cairo_pattern_init_for_surface (&pattern, clip_path->surface);
 	    cairo_matrix_init_translate (&pattern.base.matrix,
-					 extents->x - clip_path->extents.x,
-					 extents->y - clip_path->extents.y);
+					 dst_x - clip_path->extents.x,
+					 dst_y - clip_path->extents.y);
+	    pattern.base.filter = CAIRO_FILTER_NEAREST;
 	    status = _cairo_surface_paint (dst,
 					   CAIRO_OPERATOR_IN,
 					   &pattern.base,
 					   NULL);
 
 	    _cairo_pattern_fini (&pattern.base);
 
 	    return status;
 	}
 
-	if (clip_path->flags & CAIRO_CLIP_PATH_IS_BOX) {
-	    cairo_region_t clip_region;
+	if (clip_path->flags & CAIRO_CLIP_PATH_IS_BOX &&
+	    clip_path->path.maybe_fill_region)
+	{
+	    continue;
+	}
 
-	    _cairo_region_init_rectangle (&clip_region, &clip_path->extents);
-	    status = _combine_region (dst, &clip_region, extents);
-	} else {
-	    if (need_translate) {
-		_cairo_path_fixed_translate (&clip_path->path,
-					     _cairo_fixed_from_int (-extents->x),
-					     _cairo_fixed_from_int (-extents->y));
-	    }
-	    status = _cairo_surface_fill (dst,
-					  CAIRO_OPERATOR_IN,
-					  &pattern.base,
-					  &clip_path->path,
-					  clip_path->fill_rule,
-					  clip_path->tolerance,
-					  clip_path->antialias,
-					  NULL);
-	    if (need_translate) {
-		_cairo_path_fixed_translate (&clip_path->path,
-					     _cairo_fixed_from_int (extents->x),
-					     _cairo_fixed_from_int (extents->y));
-	    }
+	if (need_translate) {
+	    _cairo_path_fixed_translate (&clip_path->path,
+					 _cairo_fixed_from_int (-dst_x),
+					 _cairo_fixed_from_int (-dst_y));
+	}
+	status = _cairo_surface_fill (dst,
+				      CAIRO_OPERATOR_IN,
+				      &_cairo_pattern_white.base,
+				      &clip_path->path,
+				      clip_path->fill_rule,
+				      clip_path->tolerance,
+				      clip_path->antialias,
+				      NULL);
+	if (need_translate) {
+	    _cairo_path_fixed_translate (&clip_path->path,
+					 _cairo_fixed_from_int (dst_x),
+					 _cairo_fixed_from_int (dst_y));
 	}
 
 	if (unlikely (status))
 	    return status;
     } while ((clip_path = clip_path->prev) != NULL);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -1427,16 +1380,100 @@ cairo_int_status_t
     if (*count == 0) {
 	_cairo_clip_set_all_clipped (clip);
 	return CAIRO_INT_STATUS_NOTHING_TO_DO;
     }
 
     return CAIRO_STATUS_SUCCESS;
 }
 
+static cairo_bool_t
+box_is_aligned (const cairo_box_t *box)
+{
+    return
+	_cairo_fixed_is_integer (box->p1.x) &&
+	_cairo_fixed_is_integer (box->p1.y) &&
+	_cairo_fixed_is_integer (box->p2.x) &&
+	_cairo_fixed_is_integer (box->p2.y);
+}
+
+static void
+intersect_with_boxes (cairo_composite_rectangles_t *extents,
+		      cairo_box_t *boxes,
+		      int num_boxes)
+{
+    cairo_rectangle_int_t rect;
+    cairo_box_t box;
+    cairo_bool_t is_empty;
+
+    box.p1.x = box.p1.y = INT_MIN;
+    box.p2.x = box.p2.y = INT_MAX;
+    while (num_boxes--) {
+	if (boxes->p1.x < box.p1.x)
+	    box.p1.x = boxes->p1.x;
+	if (boxes->p1.y < box.p1.y)
+	    box.p1.y = boxes->p1.y;
+
+	if (boxes->p2.x > box.p2.x)
+	    box.p2.x = boxes->p2.x;
+	if (boxes->p2.y > box.p2.y)
+	    box.p2.y = boxes->p2.y;
+    }
+
+    _cairo_box_round_to_rectangle (&box, &rect);
+    is_empty = _cairo_rectangle_intersect (&extents->bounded, &rect);
+    is_empty = _cairo_rectangle_intersect (&extents->unbounded, &rect);
+}
+
+cairo_status_t
+_cairo_clip_to_boxes (cairo_clip_t **clip,
+		      cairo_composite_rectangles_t *extents,
+		      cairo_box_t **boxes,
+		      int *num_boxes)
+{
+    cairo_status_t status;
+    const cairo_rectangle_int_t *rect;
+
+    rect = extents->is_bounded ? &extents->bounded : &extents->unbounded;
+
+    if (*clip == NULL)
+	goto EXTENTS;
+
+    status = _cairo_clip_rectangle (*clip, rect);
+    if (unlikely (status))
+	return status;
+
+    status = _cairo_clip_get_boxes (*clip, boxes, num_boxes);
+    switch ((int) status) {
+    case CAIRO_STATUS_SUCCESS:
+	intersect_with_boxes (extents, *boxes, *num_boxes);
+	if (rect->width == 0 || rect->height == 0 ||
+	    extents->is_bounded ||
+	    (*num_boxes == 1 && box_is_aligned (*boxes)))
+	{
+	    *clip = NULL;
+	}
+	goto DONE;
+
+    case CAIRO_INT_STATUS_UNSUPPORTED:
+	goto EXTENTS;
+
+    default:
+	return status;
+    }
+
+  EXTENTS:
+    status = CAIRO_STATUS_SUCCESS;
+    _cairo_box_from_rectangle (&(*boxes)[0], rect);
+    *num_boxes = 1;
+  DONE:
+    return status;
+}
+
+
 static cairo_rectangle_list_t *
 _cairo_rectangle_list_create_in_error (cairo_status_t status)
 {
     cairo_rectangle_list_t *list;
 
     if (status == CAIRO_STATUS_NO_MEMORY)
 	return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
     if (status == CAIRO_STATUS_CLIP_NOT_REPRESENTABLE)
--- a/gfx/cairo/cairo/src/cairo-color.c
+++ b/gfx/cairo/cairo/src/cairo-color.c
@@ -8,17 +8,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
@@ -62,23 +62,24 @@ const cairo_color_t *
 {
     switch (stock) {
     case CAIRO_STOCK_WHITE:
 	return &cairo_color_white;
     case CAIRO_STOCK_BLACK:
 	return &cairo_color_black;
     case CAIRO_STOCK_TRANSPARENT:
 	return &cairo_color_transparent;
+
+    case CAIRO_STOCK_NUM_COLORS:
+    default:
+	ASSERT_NOT_REACHED;
+	/* If the user can get here somehow, give a color that indicates a
+	 * problem. */
+	return &cairo_color_magenta;
     }
-
-    ASSERT_NOT_REACHED;
-
-    /* If the user can get here somehow, give a color that indicates a
-     * problem. */
-    return &cairo_color_magenta;
 }
 
 void
 _cairo_color_init (cairo_color_t *color)
 {
     *color = cairo_color_white;
 }
 
@@ -156,20 +157,55 @@ void
 				     double	   *alpha)
 {
     *red   = color->red   * color->alpha;
     *green = color->green * color->alpha;
     *blue  = color->blue  * color->alpha;
     *alpha = color->alpha;
 }
 
+/* NB: This function works both for unmultiplied and premultiplied colors */
 cairo_bool_t
 _cairo_color_equal (const cairo_color_t *color_a,
 	            const cairo_color_t *color_b)
 {
     if (color_a == color_b)
 	return TRUE;
 
+    if (color_a->alpha_short != color_b->alpha_short)
+        return FALSE;
+
+    if (color_a->alpha_short == 0)
+        return TRUE;
+
     return color_a->red_short   == color_b->red_short   &&
            color_a->green_short == color_b->green_short &&
-           color_a->blue_short  == color_b->blue_short  &&
-           color_a->alpha_short == color_b->alpha_short;
+           color_a->blue_short  == color_b->blue_short;
+}
+
+cairo_bool_t
+_cairo_color_stop_equal (const cairo_color_stop_t *color_a,
+			 const cairo_color_stop_t *color_b)
+{
+    if (color_a == color_b)
+	return TRUE;
+
+    return color_a->alpha_short == color_b->alpha_short &&
+           color_a->red_short   == color_b->red_short   &&
+           color_a->green_short == color_b->green_short &&
+           color_a->blue_short  == color_b->blue_short;
 }
+
+cairo_content_t
+_cairo_color_get_content (const cairo_color_t *color)
+{
+    if (CAIRO_COLOR_IS_OPAQUE (color))
+        return CAIRO_CONTENT_COLOR;
+
+    if (color->red_short == 0 &&
+	color->green_short == 0 &&
+	color->blue_short == 0)
+    {
+        return CAIRO_CONTENT_ALPHA;
+    }
+
+    return CAIRO_CONTENT_COLOR_ALPHA;
+}
--- a/gfx/cairo/cairo/src/cairo-combsort-private.h
+++ b/gfx/cairo/cairo/src/cairo-combsort-private.h
@@ -6,17 +6,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
--- a/gfx/cairo/cairo/src/cairo-compiler-private.h
+++ b/gfx/cairo/cairo/src/cairo-compiler-private.h
@@ -8,17 +8,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
@@ -39,16 +39,55 @@
 #define CAIRO_COMPILER_PRIVATE_H
 
 #include "cairo.h"
 
 #if HAVE_CONFIG_H
 #include "config.h"
 #endif
 
+/* Size in bytes of buffer to use off the stack per functions.
+ * Mostly used by text functions.  For larger allocations, they'll
+ * malloc(). */
+#ifndef CAIRO_STACK_BUFFER_SIZE
+#define CAIRO_STACK_BUFFER_SIZE (512 * sizeof (int))
+#endif
+
+#define CAIRO_STACK_ARRAY_LENGTH(T) (CAIRO_STACK_BUFFER_SIZE / sizeof(T))
+
+/*
+ * The goal of this block is to define the following macros for
+ * providing faster linkage to functions in the public API for calls
+ * from within cairo.
+ *
+ * slim_hidden_proto(f)
+ * slim_hidden_proto_no_warn(f)
+ *
+ *   Declares `f' as a library internal function and hides the
+ *   function from the global symbol table.  This macro must be
+ *   expanded after `f' has been declared with a prototype but before
+ *   any calls to the function are seen by the compiler.  The no_warn
+ *   variant inhibits warnings about the return value being unused at
+ *   call sites.  The macro works by renaming `f' to an internal name
+ *   in the symbol table and hiding that.  As far as cairo internal
+ *   calls are concerned they're calling a library internal function
+ *   and thus don't need to bounce via the PLT.
+ *
+ * slim_hidden_def(f)
+ *
+ *   Exports `f' back to the global symbol table.  This macro must be
+ *   expanded right after the function definition and only for symbols
+ *   hidden previously with slim_hidden_proto().  The macro works by
+ *   adding a global entry to the symbol table which points at the
+ *   internal name of `f' created by slim_hidden_proto().
+ *
+ * Functions in the public API which aren't called by the library
+ * don't need to be hidden and re-exported using the slim hidden
+ * macros.
+ */
 #if __GNUC__ >= 3 && defined(__ELF__) && !defined(__sun)
 # define slim_hidden_proto(name)		slim_hidden_proto1(name, slim_hidden_int_name(name)) cairo_private
 # define slim_hidden_proto_no_warn(name)	slim_hidden_proto1(name, slim_hidden_int_name(name)) cairo_private_no_warn
 # define slim_hidden_def(name)			slim_hidden_def1(name, slim_hidden_int_name(name))
 # define slim_hidden_int_name(name) INT_##name
 # define slim_hidden_proto1(name, internal)				\
   extern __typeof (name) name						\
 	__asm__ (slim_hidden_asmname (internal))
@@ -129,19 +168,21 @@
  *
  * Both these function attributes allow gcc to perform CSE and
  * constant-folding, with 'cairo_const 'also guaranteeing that pointer contents
  * do not change across the function call.
  */
 #if __GNUC__ >= 3
 #define cairo_pure __attribute__((pure))
 #define cairo_const __attribute__((const))
+#define cairo_always_inline inline __attribute__((always_inline))
 #else
 #define cairo_pure
 #define cairo_const
+#define cairo_always_inline inline
 #endif
 
 #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
 #define _CAIRO_BOOLEAN_EXPR(expr)                   \
  __extension__ ({                               \
    int _cairo_boolean_var_;                         \
    if (expr)                                    \
       _cairo_boolean_var_ = 1;                      \
@@ -166,16 +207,36 @@
 #define popen _popen
 #define pclose _pclose
 #define hypot _hypot
 #endif
 
 #ifdef _MSC_VER
 #undef inline
 #define inline __inline
+
+/* there are currently linkage problems that arise when trying to include intrin.h in c++:
+ * D:\sdks\v7.0\include\winnt.h(3674) : error C2733: second C linkage of overloaded function '_interlockedbittestandset' not allowed
+ * so avoid defining ffs in c++ code for now */
+#ifndef  __cplusplus
+/* Add a definition of ffs */
+#include <intrin.h>
+#pragma intrinsic(_BitScanForward)
+static __forceinline int
+ffs (int x)
+{
+    unsigned long i;
+
+    if (_BitScanForward(&i, x) != 0)
+	return i + 1;
+
+    return 0;
+}
+#endif
+
 #endif
 
 #if defined(_MSC_VER) && defined(_M_IX86)
 /* When compiling with /Gy and /OPT:ICF identical functions will be folded in together.
    The CAIRO_ENSURE_UNIQUE macro ensures that a function is always unique and
    will never be folded into another one. Something like this might eventually
    be needed for GCC but it seems fine for now. */
 #define CAIRO_ENSURE_UNIQUE                       \
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/cairo/src/cairo-composite-rectangles-private.h
@@ -0,0 +1,105 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2009 Intel 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is University of Southern
+ * California.
+ *
+ * Contributor(s):
+ *	Chris Wilson <chris@chris-wilson.co.u>
+ */
+
+#ifndef CAIRO_COMPOSITE_RECTANGLES_PRIVATE_H
+#define CAIRO_COMPOSITE_RECTANGLES_PRIVATE_H
+
+#include "cairo-types-private.h"
+
+CAIRO_BEGIN_DECLS
+
+/* Rectangles that take part in a composite operation.
+ *
+ * The source and mask track the extents of the respective patterns in device
+ * space. The unbounded rectangle is essentially the clip rectangle. And the
+ * intersection of all is the bounded rectangle, which is the minimum extents
+ * the operation may require. Whether or not the operation is actually bounded
+ * is tracked in the is_bounded boolean.
+ *
+ */
+struct _cairo_composite_rectangles {
+    cairo_rectangle_int_t source;
+    cairo_rectangle_int_t mask;
+    cairo_rectangle_int_t bounded; /* dst */
+    cairo_rectangle_int_t unbounded; /* clip */
+    uint32_t is_bounded;
+};
+
+cairo_private cairo_int_status_t
+_cairo_composite_rectangles_init_for_paint (cairo_composite_rectangles_t *extents,
+					 const cairo_rectangle_int_t *surface_extents,
+					 cairo_operator_t	 op,
+					 const cairo_pattern_t	*source,
+					 cairo_clip_t		*clip);
+
+cairo_private cairo_int_status_t
+_cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents,
+					const cairo_rectangle_int_t *surface_extents,
+					cairo_operator_t	 op,
+					const cairo_pattern_t	*source,
+					const cairo_pattern_t	*mask,
+					cairo_clip_t		*clip);
+
+cairo_private cairo_int_status_t
+_cairo_composite_rectangles_init_for_stroke (cairo_composite_rectangles_t *extents,
+					     const cairo_rectangle_int_t *surface_extents,
+					     cairo_operator_t	 op,
+					     const cairo_pattern_t	*source,
+					     cairo_path_fixed_t	*path,
+					     const cairo_stroke_style_t	*style,
+					     const cairo_matrix_t	*ctm,
+					     cairo_clip_t		*clip);
+
+cairo_private cairo_int_status_t
+_cairo_composite_rectangles_init_for_fill (cairo_composite_rectangles_t *extents,
+					   const cairo_rectangle_int_t *surface_extents,
+					   cairo_operator_t	 op,
+					   const cairo_pattern_t	*source,
+					   cairo_path_fixed_t	*path,
+					   cairo_clip_t		*clip);
+
+cairo_private cairo_int_status_t
+_cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *extents,
+					     const cairo_rectangle_int_t *surface_extents,
+					     cairo_operator_t		 op,
+					     const cairo_pattern_t	*source,
+					     cairo_scaled_font_t	*scaled_font,
+					     cairo_glyph_t		*glyphs,
+					     int			 num_glyphs,
+					     cairo_clip_t		*clip,
+					     cairo_bool_t		*overlap);
+
+#endif /* CAIRO_COMPOSITE_RECTANGLES_PRIVATE_H */
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/cairo/src/cairo-composite-rectangles.c
@@ -0,0 +1,195 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2009 Intel 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Red Hat, Inc.
+ *
+ * Contributor(s):
+ *      Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairoint.h"
+
+#include "cairo-error-private.h"
+#include "cairo-composite-rectangles-private.h"
+
+/* A collection of routines to facilitate writing compositors. */
+
+static inline cairo_bool_t
+_cairo_composite_rectangles_init (cairo_composite_rectangles_t *extents,
+				  const cairo_rectangle_int_t *surface_extents,
+				  cairo_operator_t op,
+				  const cairo_pattern_t *source,
+				  cairo_clip_t *clip)
+{
+    extents->unbounded = *surface_extents;
+
+    if (clip != NULL) {
+	const cairo_rectangle_int_t *clip_extents;
+
+	clip_extents = _cairo_clip_get_extents (clip);
+	if (clip_extents == NULL)
+	    return FALSE;
+
+	if (! _cairo_rectangle_intersect (&extents->unbounded, clip_extents))
+	    return FALSE;
+    }
+
+    extents->bounded = extents->unbounded;
+    extents->is_bounded = _cairo_operator_bounded_by_either (op);
+
+    _cairo_pattern_get_extents (source, &extents->source);
+    if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE) {
+	if (! _cairo_rectangle_intersect (&extents->bounded, &extents->source))
+	    return FALSE;
+    }
+
+    return TRUE;
+}
+
+cairo_int_status_t
+_cairo_composite_rectangles_init_for_paint (cairo_composite_rectangles_t *extents,
+					    const cairo_rectangle_int_t *surface_extents,
+					    cairo_operator_t		 op,
+					    const cairo_pattern_t	*source,
+					    cairo_clip_t		*clip)
+{
+    if (! _cairo_composite_rectangles_init (extents,
+					    surface_extents,
+					    op, source, clip))
+    {
+	return CAIRO_INT_STATUS_NOTHING_TO_DO;
+    }
+
+    extents->mask = extents->bounded;
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+_cairo_composite_rectangles_intersect (cairo_composite_rectangles_t *extents)
+{
+    cairo_bool_t ret;
+
+    ret = _cairo_rectangle_intersect (&extents->bounded, &extents->mask);
+    if (! ret && extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK)
+	return CAIRO_INT_STATUS_NOTHING_TO_DO;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_int_status_t
+_cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents,
+					   const cairo_rectangle_int_t *surface_extents,
+					   cairo_operator_t		 op,
+					   const cairo_pattern_t	*source,
+					   const cairo_pattern_t	*mask,
+					   cairo_clip_t			*clip)
+{
+    if (! _cairo_composite_rectangles_init (extents,
+					    surface_extents,
+					    op, source, clip))
+    {
+	return CAIRO_INT_STATUS_NOTHING_TO_DO;
+    }
+
+    _cairo_pattern_get_extents (mask, &extents->mask);
+
+    return _cairo_composite_rectangles_intersect (extents);
+}
+
+cairo_int_status_t
+_cairo_composite_rectangles_init_for_stroke (cairo_composite_rectangles_t *extents,
+					     const cairo_rectangle_int_t *surface_extents,
+					     cairo_operator_t		 op,
+					     const cairo_pattern_t	*source,
+					     cairo_path_fixed_t		*path,
+					     const cairo_stroke_style_t	*style,
+					     const cairo_matrix_t	*ctm,
+					     cairo_clip_t		*clip)
+{
+    if (! _cairo_composite_rectangles_init (extents,
+					    surface_extents,
+					    op, source, clip))
+    {
+	return CAIRO_INT_STATUS_NOTHING_TO_DO;
+    }
+
+    _cairo_path_fixed_approximate_stroke_extents (path, style, ctm, &extents->mask);
+
+    return _cairo_composite_rectangles_intersect (extents);
+}
+
+cairo_int_status_t
+_cairo_composite_rectangles_init_for_fill (cairo_composite_rectangles_t *extents,
+					   const cairo_rectangle_int_t *surface_extents,
+					   cairo_operator_t		 op,
+					   const cairo_pattern_t	*source,
+					   cairo_path_fixed_t		*path,
+					   cairo_clip_t			*clip)
+{
+    if (! _cairo_composite_rectangles_init (extents,
+					    surface_extents,
+					    op, source, clip))
+    {
+	return CAIRO_INT_STATUS_NOTHING_TO_DO;
+    }
+
+    _cairo_path_fixed_approximate_fill_extents (path, &extents->mask);
+
+    return _cairo_composite_rectangles_intersect (extents);
+}
+
+cairo_int_status_t
+_cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *extents,
+					     const cairo_rectangle_int_t *surface_extents,
+					     cairo_operator_t		 op,
+					     const cairo_pattern_t	*source,
+					     cairo_scaled_font_t	*scaled_font,
+					     cairo_glyph_t		*glyphs,
+					     int			 num_glyphs,
+					     cairo_clip_t		*clip,
+					     cairo_bool_t		*overlap)
+{
+    cairo_status_t status;
+
+    if (! _cairo_composite_rectangles_init (extents,
+					    surface_extents,
+					    op, source, clip))
+    {
+	return CAIRO_INT_STATUS_NOTHING_TO_DO;
+    }
+
+    status = _cairo_scaled_font_glyph_device_extents (scaled_font,
+						      glyphs, num_glyphs,
+						      &extents->mask,
+						      overlap);
+    if (unlikely (status))
+	return status;
+
+    return _cairo_composite_rectangles_intersect (extents);
+}
--- a/gfx/cairo/cairo/src/cairo-d2d-private.h
+++ b/gfx/cairo/cairo/src/cairo-d2d-private.h
@@ -38,20 +38,18 @@
 
 #ifdef CAIRO_HAS_D2D_SURFACE
 
 #include <windows.h>
 #include <d2d1.h>
 #include <d3d10.h>
 #include <dxgi.h>
 
-extern "C" {
 #include "cairoint.h"
 #include "cairo-surface-clipper-private.h"
-}
 
 #include "cairo-win32-refptr.h"
 #include "cairo-d2d-private-fx.h"
 #include "cairo-win32.h"
 
 /* describes the type of the currently applied clip so that we can pop it */
 struct d2d_clip;
 
--- a/gfx/cairo/cairo/src/cairo-d2d-surface.cpp
+++ b/gfx/cairo/cairo/src/cairo-d2d-surface.cpp
@@ -34,20 +34,19 @@
  *	Bas Schouten <bschouten@mozilla.com>
  */
 #define INITGUID
 
 #include "cairoint.h"
 #include "cairo-d2d-private.h"
 #include "cairo-dwrite-private.h"
 
-extern "C" {
 #include "cairo-win32.h"
 #include "cairo-analysis-surface-private.h"
-}
+#include "cairo-error-private.h"
 
 // Required for using placement new.
 #include <new>
 
 #define CAIRO_INT_STATUS_SUCCESS (cairo_int_status_t)CAIRO_STATUS_SUCCESS
 
 struct Vertex
 {
@@ -644,19 +643,19 @@ static cairo_bool_t
  * \return Return code, this can be CAIRO_ERROR_SURFACE_TYPE_MISMATCH,
  * CAIRO_INT_STATUS_UNSUPPORTED or CAIRO_STATUS_SUCCESS
  */
 static cairo_int_status_t
 _cairo_d2d_stroke(void			*surface,
 		  cairo_operator_t	 op,
 		  const cairo_pattern_t	*source,
 		  cairo_path_fixed_t	*path,
-		  cairo_stroke_style_t	*style,
-		  cairo_matrix_t	*ctm,
-		  cairo_matrix_t	*ctm_inverse,
+		  const cairo_stroke_style_t	*style,
+		  const cairo_matrix_t	*ctm,
+		  const cairo_matrix_t	*ctm_inverse,
 		  double		 tolerance,
 		  cairo_antialias_t	 antialias,
 		  cairo_clip_t		*clip);
 
 static const cairo_surface_backend_t cairo_d2d_surface_backend = {
     CAIRO_SURFACE_TYPE_D2D,
     _cairo_d2d_create_similar, /* create_similar */
     _cairo_d2d_finish, /* finish */
@@ -758,16 +757,26 @@ static void
 static int
 _cairo_d2d_compute_surface_mem_size(cairo_d2d_surface_t *surface)
 {
     int size = surface->rt->GetPixelSize().width * surface->rt->GetPixelSize().height;
     size *= surface->rt->GetPixelFormat().format == DXGI_FORMAT_A8_UNORM ? 1 : 4;
     return size;
 }
 
+static D2D1_COLOR_F
+_cairo_d2d_color_from_cairo_color_stop(const cairo_color_stop_t &color)
+{
+    return D2D1::ColorF((FLOAT)color.red, 
+			(FLOAT)color.green, 
+			(FLOAT)color.blue,
+			(FLOAT)color.alpha);
+}
+
+
 /**
  * Gets the surface buffer texture for window surfaces whose backbuffer
  * is not directly usable as a bitmap.
  *
  * \param surface D2D surface.
  * \return Buffer texture
  */
 static ID3D10Texture2D*
@@ -1430,40 +1439,40 @@ static RefPtr<ID2D1Brush>
 		    // Take the stop from the opposite side when reflected.
 		    stop = source_pattern->base.n_stops - stop - 1;
 		    // When reflected take 1 - offset as the offset.
 		    stops[i].position = (FLOAT)((repeat + 1.0f - source_pattern->base.stops[stop].offset) * stop_scale);
 		} else {
 		    stops[i].position = (FLOAT)((repeat + source_pattern->base.stops[stop].offset) * stop_scale);
 		}
 		stops[i].color =
-		    _cairo_d2d_color_from_cairo_color(source_pattern->base.stops[stop].color);
+		    _cairo_d2d_color_from_cairo_color_stop(source_pattern->base.stops[stop].color);
 	    }
 	} else {
 	    // Simple case, we don't need to reflect.
 	    for (int i = 0; i < num_stops; i++) {
 		// Calculate which repeat this is.
 		int repeat = i / source_pattern->base.n_stops;
 		// Calculate which stop this would be in the original pattern
 		cairo_gradient_stop_t *stop = &source_pattern->base.stops[i % source_pattern->base.n_stops];
 		stops[i].position = (FLOAT)((repeat + stop->offset) * stop_scale);
-		stops[i].color = _cairo_d2d_color_from_cairo_color(stop->color);
+		stops[i].color = _cairo_d2d_color_from_cairo_color_stop(stop->color);
 	    }
 	}
     } else if (source_pattern->base.base.extend == CAIRO_EXTEND_PAD) {
 	float offset_factor = (outer_radius - inner_radius) / outer_radius;
 	float global_offset = inner_radius / outer_radius;
 
 	stops = new D2D1_GRADIENT_STOP[num_stops];
 
 	// If the inner radius is not 0 we need to scale and offset the stops.
 	for (unsigned int i = 0; i < source_pattern->base.n_stops; i++) {
 	    cairo_gradient_stop_t *stop = &source_pattern->base.stops[i];
 	    stops[i].position = (FLOAT)(global_offset + stop->offset * offset_factor);
-	    stops[i].color = _cairo_d2d_color_from_cairo_color(stop->color);
+	    stops[i].color = _cairo_d2d_color_from_cairo_color_stop(stop->color);
 	}
     } else if (source_pattern->base.base.extend == CAIRO_EXTEND_NONE) {
 	float offset_factor = (outer_radius - inner_radius) / outer_radius;
 	float global_offset = inner_radius / outer_radius;
 
 	num_stops++; // Add a stop on the outer radius.
 	if (inner_radius != 0) {
 	    num_stops++; // Add a stop on the inner radius.
@@ -1477,17 +1486,17 @@ static RefPtr<ID2D1Brush>
 	if (inner_radius != 0) {
 	    stops[i].position = global_offset;
 	    stops[i].color = D2D1::ColorF(0, 0);
 	    i++;
 	}
 	for (unsigned int j = 0; j < source_pattern->base.n_stops; j++, i++) {
 	    cairo_gradient_stop_t *stop = &source_pattern->base.stops[j];
 	    stops[i].position = (FLOAT)(global_offset + stop->offset * offset_factor);
-	    stops[i].color = _cairo_d2d_color_from_cairo_color(stop->color);
+	    stops[i].color = _cairo_d2d_color_from_cairo_color_stop(stop->color);
 	}
 	stops[i].position = 1.0f;
 	stops[i].color = D2D1::ColorF(0, 0);
     } else {
 	return NULL;
     }
 
     RefPtr<ID2D1GradientStopCollection> stopCollection;
@@ -1509,17 +1518,17 @@ static RefPtr<ID2D1Brush>
 _cairo_d2d_create_linear_gradient_brush(cairo_d2d_surface_t *d2dsurf,
 					cairo_linear_pattern_t *source_pattern)
 {
     if (source_pattern->p1.x == source_pattern->p2.x &&
 	source_pattern->p1.y == source_pattern->p2.y) {
 	// Cairo behavior in this situation is to draw a solid color the size of the last stop.
 	RefPtr<ID2D1SolidColorBrush> brush;
 	d2dsurf->rt->CreateSolidColorBrush(
-	    _cairo_d2d_color_from_cairo_color(source_pattern->base.stops[source_pattern->base.n_stops - 1].color),
+	    _cairo_d2d_color_from_cairo_color_stop(source_pattern->base.stops[source_pattern->base.n_stops - 1].color),
 	    &brush);
 	return brush;
     }
 
     cairo_matrix_t inv_mat = source_pattern->base.base.matrix;
     /**
      * Cairo views this matrix as the transformation of the destination
      * when the pattern is imposed. We see this differently, D2D transformation
@@ -1614,45 +1623,45 @@ static RefPtr<ID2D1Brush>
 		    // Take the stop from the opposite side when reflected.
 		    stop = source_pattern->base.n_stops - stop - 1;
 		    // When reflected take 1 - offset as the offset.
 		    stops[i].position = (FLOAT)((repeat + 1.0f - source_pattern->base.stops[stop].offset) * stop_scale);
 		} else {
 		    stops[i].position = (FLOAT)((repeat + source_pattern->base.stops[stop].offset) * stop_scale);
 		}
 		stops[i].color =
-		    _cairo_d2d_color_from_cairo_color(source_pattern->base.stops[stop].color);
+		    _cairo_d2d_color_from_cairo_color_stop(source_pattern->base.stops[stop].color);
 	    }
 	} else {
 	    // Simple case, we don't need to reflect.
 	    for (int i = 0; i < num_stops; i++) {
 		// Calculate which repeat this is.
 		int repeat = i / source_pattern->base.n_stops;
 		// Calculate which stop this would be in the original pattern
 		cairo_gradient_stop_t *stop = &source_pattern->base.stops[i % source_pattern->base.n_stops];
 		stops[i].position = (FLOAT)((repeat + stop->offset) * stop_scale);
-		stops[i].color = _cairo_d2d_color_from_cairo_color(stop->color);
+		stops[i].color = _cairo_d2d_color_from_cairo_color_stop(stop->color);
 	    }
 	}
     } else if (source_pattern->base.base.extend == CAIRO_EXTEND_PAD) {
 	stops = new D2D1_GRADIENT_STOP[source_pattern->base.n_stops];
 	for (unsigned int i = 0; i < source_pattern->base.n_stops; i++) {
 	    cairo_gradient_stop_t *stop = &source_pattern->base.stops[i];
 	    stops[i].position = (FLOAT)stop->offset;
-	    stops[i].color = _cairo_d2d_color_from_cairo_color(stop->color);
+	    stops[i].color = _cairo_d2d_color_from_cairo_color_stop(stop->color);
 	}
     } else if (source_pattern->base.base.extend == CAIRO_EXTEND_NONE) {
 	num_stops += 2;
 	stops = new D2D1_GRADIENT_STOP[num_stops];
 	stops[0].position = 0;
 	stops[0].color = D2D1::ColorF(0, 0);
 	for (unsigned int i = 1; i < source_pattern->base.n_stops + 1; i++) {
 	    cairo_gradient_stop_t *stop = &source_pattern->base.stops[i - 1];
 	    stops[i].position = (FLOAT)stop->offset;
-	    stops[i].color = _cairo_d2d_color_from_cairo_color(stop->color);
+	    stops[i].color = _cairo_d2d_color_from_cairo_color_stop(stop->color);
 	}
 	stops[source_pattern->base.n_stops + 1].position = 1.0f;
 	stops[source_pattern->base.n_stops + 1].color = D2D1::ColorF(0, 0);
     }
     RefPtr<ID2D1GradientStopCollection> stopCollection;
     d2dsurf->rt->CreateGradientStopCollection(stops, num_stops, &stopCollection);
     RefPtr<ID2D1LinearGradientBrush> brush;
     d2dsurf->rt->CreateLinearGradientBrush(D2D1::LinearGradientBrushProperties(D2D1::Point2F((FLOAT)p1.x, (FLOAT)p1.y),
@@ -2304,28 +2313,38 @@ static cairo_operator_t _cairo_d2d_simpl
 	    if (solidpattern->color.alpha == 1.0) {
 		return CAIRO_OPERATOR_OVER;
 	    }
 	}
     }
     return op;
 }
 
+void
+_cairo_d2d_surface_init(cairo_d2d_surface_t *newSurf, cairo_d2d_device_t *d2d_device, cairo_format_t format)
+{
+    newSurf->format = format;
+
+    newSurf->device = d2d_device;
+    cairo_addref_device(&d2d_device->base);
+    d2d_device->mVRAMUsage += _cairo_d2d_compute_surface_mem_size(newSurf);
+}
+
 // Implementation
 static cairo_surface_t*
 _cairo_d2d_create_similar(void			*surface,
 			  cairo_content_t	 content,
 			  int			 width,
 			  int			 height)
 {
     cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
     cairo_d2d_surface_t *newSurf = static_cast<cairo_d2d_surface_t*>(malloc(sizeof(cairo_d2d_surface_t)));
     
     new (newSurf) cairo_d2d_surface_t();
-    _cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, content);
+    _cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, content);
 
 
     D2D1_SIZE_U sizePixels;
     D2D1_SIZE_F size;
     HRESULT hr;
 
     sizePixels.width = width;
     sizePixels.height = height;
@@ -2420,19 +2439,17 @@ static cairo_surface_t*
 	    goto FAIL_CREATESIMILAR;
 	}
     }
 
     newSurf->rt->CreateSolidColorBrush(D2D1::ColorF(0, 1.0), &newSurf->solidColorBrush);
 
     _d2d_clear_surface(newSurf);
 
-    newSurf->device = d2dsurf->device;
-    cairo_addref_device(&newSurf->device->base);
-    newSurf->device->mVRAMUsage += _cairo_d2d_compute_surface_mem_size(newSurf);
+    _cairo_d2d_surface_init(newSurf, d2dsurf->device, _cairo_format_from_content(content));
 
     return reinterpret_cast<cairo_surface_t*>(newSurf);
 
 FAIL_CREATESIMILAR:
     /** Ensure we call our surfaces desctructor */
     newSurf->~cairo_d2d_surface_t();
     free(newSurf);
     return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY));
@@ -2496,18 +2513,18 @@ static cairo_status_t
     d2dsurf->device->mD3D10Device->CopyResource(softTexture, d2dsurf->surface);
 
     D3D10_MAPPED_TEXTURE2D data;
     hr = softTexture->Map(0, D3D10_MAP_READ_WRITE, 0, &data);
     if (FAILED(hr)) {
 	return _cairo_error(CAIRO_STATUS_NO_DEVICE);
     }
     *image_out = 
-	(cairo_image_surface_t*)_cairo_image_surface_create_for_data_with_content((unsigned char*)data.pData,
-										  d2dsurf->base.content,
+	(cairo_image_surface_t*)cairo_image_surface_create_for_data((unsigned char*)data.pData,
+										  d2dsurf->format,
 										  size.width,
 										  size.height,
 										  data.RowPitch);
     *image_extra = softTexture.forget();
 
     return CAIRO_STATUS_SUCCESS;
 }
 
@@ -2568,18 +2585,18 @@ static cairo_status_t
     d2dsurf->device->mD3D10Device->CopyResource(softTexture, d2dsurf->surface);
 
     D3D10_MAPPED_TEXTURE2D data;
     hr = softTexture->Map(0, D3D10_MAP_READ_WRITE, 0, &data);
     if (FAILED(hr)) {
 	return _cairo_error(CAIRO_STATUS_NO_DEVICE);
     }
     *image_out = 
-	(cairo_image_surface_t*)_cairo_image_surface_create_for_data_with_content((unsigned char*)data.pData,
-										  d2dsurf->base.content,
+	(cairo_image_surface_t*)cairo_image_surface_create_for_data((unsigned char*)data.pData,
+										  _cairo_format_from_content(d2dsurf->base.content),
 										  size.width,
 										  size.height,
 										  data.RowPitch);
     *image_extra = softTexture.forget();
 
     return CAIRO_STATUS_SUCCESS;
 }
 
@@ -3173,17 +3190,17 @@ static cairo_int_status_t
 	    return status;
 
     bool isSolidAlphaMask = false;
     float solidAlphaValue = 1.0f;
 
     if (mask->type == CAIRO_PATTERN_TYPE_SOLID) {
 	cairo_solid_pattern_t *solidPattern =
 	    (cairo_solid_pattern_t*)mask;
-	if (solidPattern->content = CAIRO_CONTENT_ALPHA) {
+	if (_cairo_color_get_content (&solidPattern->color) == CAIRO_CONTENT_ALPHA) {
 	    isSolidAlphaMask = true;
 	    solidAlphaValue = solidPattern->color.alpha;
 	}
     }
 
     cairo_box_t box;
     _cairo_box_from_rectangle(&box, &extents);
 
@@ -3316,19 +3333,19 @@ static cairo_int_status_t
     return CAIRO_INT_STATUS_SUCCESS;
 }
 
 static cairo_int_status_t
 _cairo_d2d_stroke(void			*surface,
 		  cairo_operator_t	 op,
 		  const cairo_pattern_t	*source,
 		  cairo_path_fixed_t	*path,
-		  cairo_stroke_style_t	*style,
-		  cairo_matrix_t	*ctm,
-		  cairo_matrix_t	*ctm_inverse,
+		  const cairo_stroke_style_t	*style,
+		  const cairo_matrix_t	*ctm,
+		  const cairo_matrix_t	*ctm_inverse,
 		  double		 tolerance,
 		  cairo_antialias_t	 antialias,
 		  cairo_clip_t		*clip)
 {
     cairo_int_status_t status;
 
     cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
 
@@ -3521,17 +3538,22 @@ static cairo_int_status_t
 	if (!brush) {
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
 	}
 	target_rt->FillGeometry(d2dpath, brush);
     }
 
     if (target_rt.get() != d2dsurf->rt.get()) {
 	double x1, y1, x2, y2;
-	_cairo_path_fixed_bounds(path, &x1, &y1, &x2, &y2);
+        cairo_box_t box;
+        _cairo_path_fixed_extents (path, &box);
+        x1 = _cairo_fixed_to_double (box.p1.x);
+        y1 = _cairo_fixed_to_double (box.p1.y);
+        x2 = _cairo_fixed_to_double (box.p2.x);
+        y2 = _cairo_fixed_to_double (box.p2.y);
 	cairo_rectangle_int_t bounds;
 	_cairo_d2d_round_out_to_int_rect(&bounds, x1, y1, x2, y2);
 	return _cairo_d2d_blend_temp_surface(d2dsurf, op, target_rt, clip, &bounds);
     }
 
     return CAIRO_INT_STATUS_SUCCESS;
 }
 
@@ -4113,26 +4135,28 @@ static cairo_bool_t
     extents->width = size.width;
     extents->height = size.height;
     return TRUE;
 }
 
 
 /** Helper functions. */
 
+
+
 cairo_surface_t*
 cairo_d2d_surface_create_for_hwnd(cairo_device_t *cairo_device,
 				  HWND wnd,
 				  cairo_content_t content)
 {
     cairo_d2d_device_t *d2d_device = reinterpret_cast<cairo_d2d_device_t*>(cairo_device);
     cairo_d2d_surface_t *newSurf = static_cast<cairo_d2d_surface_t*>(malloc(sizeof(cairo_d2d_surface_t)));
     new (newSurf) cairo_d2d_surface_t();
 
-    _cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, content);
+    _cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, content);
 
     RECT rc;
     HRESULT hr;
 
     newSurf->isDrawing = false;
     ::GetClientRect(wnd, &rc);
 
     FLOAT dpiX;
@@ -4224,28 +4248,28 @@ cairo_d2d_surface_create_for_hwnd(cairo_
 
     bitProps = D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, 
 				      D2D1_ALPHA_MODE_PREMULTIPLIED));
     
     newSurf->rt->CreateSolidColorBrush(D2D1::ColorF(0, 1.0), &newSurf->solidColorBrush);
 
     _d2d_clear_surface(newSurf);
 
-    newSurf->device = d2d_device;
-    cairo_addref_device(cairo_device);
-    d2d_device->mVRAMUsage += _cairo_d2d_compute_surface_mem_size(newSurf);
+    _cairo_d2d_surface_init(newSurf, d2d_device, _cairo_format_from_content(content));
 
     return reinterpret_cast<cairo_surface_t*>(newSurf);
 
 FAIL_HWND:
     newSurf->~cairo_d2d_surface_t();
     free(newSurf);
     return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY));
 }
 
+
+
 cairo_surface_t *
 cairo_d2d_surface_create(cairo_device_t *device,
 			 cairo_format_t format,
 			 int width,
 			 int height)
 {
     if (width == 0 || height == 0) {
 	return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_INVALID_SIZE));
@@ -4253,22 +4277,22 @@ cairo_d2d_surface_create(cairo_device_t 
 
     cairo_d2d_device_t *d2d_device = reinterpret_cast<cairo_d2d_device_t*>(device);
     cairo_d2d_surface_t *newSurf = static_cast<cairo_d2d_surface_t*>(malloc(sizeof(cairo_d2d_surface_t)));
     new (newSurf) cairo_d2d_surface_t();
 
     DXGI_FORMAT dxgiformat = DXGI_FORMAT_B8G8R8A8_UNORM;
     D2D1_ALPHA_MODE alpha = D2D1_ALPHA_MODE_PREMULTIPLIED;
     if (format == CAIRO_FORMAT_ARGB32) {
-	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, CAIRO_CONTENT_COLOR_ALPHA);
+	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, CAIRO_CONTENT_COLOR_ALPHA);
     } else if (format == CAIRO_FORMAT_RGB24) {
-	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, CAIRO_CONTENT_COLOR);
+	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, CAIRO_CONTENT_COLOR);
 	alpha = D2D1_ALPHA_MODE_IGNORE;
     } else {
-	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, CAIRO_CONTENT_ALPHA);
+	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, CAIRO_CONTENT_ALPHA);
 	dxgiformat = DXGI_FORMAT_A8_UNORM;
     }
 
 
     newSurf->format = format;
 
     D2D1_SIZE_U sizePixels;
     HRESULT hr;
@@ -4338,19 +4362,17 @@ cairo_d2d_surface_create(cairo_device_t 
 	    goto FAIL_CREATE;
 	}
     }
 
     newSurf->rt->CreateSolidColorBrush(D2D1::ColorF(0, 1.0), &newSurf->solidColorBrush);
 
     _d2d_clear_surface(newSurf);
 
-    newSurf->device = d2d_device;
-    cairo_addref_device(device);
-    d2d_device->mVRAMUsage += _cairo_d2d_compute_surface_mem_size(newSurf);
+    _cairo_d2d_surface_init(newSurf, d2d_device, format);
 
     return reinterpret_cast<cairo_surface_t*>(newSurf);
 
 FAIL_CREATE:
     newSurf->~cairo_d2d_surface_t();
     free(newSurf);
     return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY));
 }
@@ -4393,26 +4415,26 @@ cairo_d2d_surface_create_for_handle(cair
     format = desc.Format;
     
     D2D1_ALPHA_MODE alpha = D2D1_ALPHA_MODE_PREMULTIPLIED;
     if (format == DXGI_FORMAT_B8G8R8A8_UNORM) {
 	if (content == CAIRO_CONTENT_ALPHA) {
 	    status = CAIRO_STATUS_INVALID_CONTENT;
 	    goto FAIL_CREATEHANDLE;
 	}
-	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, content);
+	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, content);
 	if (content == CAIRO_CONTENT_COLOR) {
 	    alpha = D2D1_ALPHA_MODE_IGNORE;
 	}
     } else if (format == DXGI_FORMAT_A8_UNORM) {
 	if (content != CAIRO_CONTENT_ALPHA) {
 	    status = CAIRO_STATUS_INVALID_CONTENT;
 	    goto FAIL_CREATEHANDLE;
 	}
-	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, CAIRO_CONTENT_ALPHA);
+	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, CAIRO_CONTENT_ALPHA);
     } else {
 	status = CAIRO_STATUS_INVALID_FORMAT;
 	// We don't know how to support this format!
 	goto FAIL_CREATEHANDLE;
     }
 
     props = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT,
 					 D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, alpha));
@@ -4439,19 +4461,17 @@ cairo_d2d_surface_create_for_handle(cair
 
 	if (FAILED(hr)) {
 	    goto FAIL_CREATEHANDLE;
 	}
     }
 
     newSurf->rt->CreateSolidColorBrush(D2D1::ColorF(0, 1.0), &newSurf->solidColorBrush);
 
-    newSurf->device = d2d_device;
-    cairo_addref_device(device);
-    d2d_device->mVRAMUsage += _cairo_d2d_compute_surface_mem_size(newSurf);
+    _cairo_d2d_surface_init(newSurf, d2d_device, _cairo_format_from_content(content));
 
     return &newSurf->base;
    
 FAIL_CREATEHANDLE:
     newSurf->~cairo_d2d_surface_t();
     free(newSurf);
     return _cairo_surface_create_in_error(_cairo_error(status));
 }
@@ -4462,20 +4482,20 @@ cairo_d2d_surface_create_for_texture(cai
 				     cairo_content_t content)
 {
     cairo_d2d_device_t *d2d_device = reinterpret_cast<cairo_d2d_device_t*>(device);
     cairo_d2d_surface_t *newSurf = static_cast<cairo_d2d_surface_t*>(malloc(sizeof(cairo_d2d_surface_t)));
     new (newSurf) cairo_d2d_surface_t();
 
     D2D1_ALPHA_MODE alpha = D2D1_ALPHA_MODE_PREMULTIPLIED;
     if (content == CAIRO_CONTENT_COLOR) {
-	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, CAIRO_CONTENT_COLOR);
+	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, CAIRO_CONTENT_COLOR);
 	alpha = D2D1_ALPHA_MODE_IGNORE;
     } else {
-	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, content);
+	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, content);
     }
 
     D2D1_SIZE_U sizePixels;
     HRESULT hr;
 
     D3D10_TEXTURE2D_DESC desc;
     RefPtr<IDXGISurface> dxgiSurface;
     D2D1_BITMAP_PROPERTIES bitProps;
@@ -4522,19 +4542,17 @@ cairo_d2d_surface_create_for_texture(cai
 
 	if (FAILED(hr)) {
 	    goto FAIL_CREATE;
 	}
     }
 
     newSurf->rt->CreateSolidColorBrush(D2D1::ColorF(0, 1.0), &newSurf->solidColorBrush);
 
-    newSurf->device = d2d_device;
-    cairo_addref_device(device);
-    d2d_device->mVRAMUsage += _cairo_d2d_compute_surface_mem_size(newSurf);
+    _cairo_d2d_surface_init(newSurf, d2d_device, _cairo_format_from_content(content));
 
     return reinterpret_cast<cairo_surface_t*>(newSurf);
 
 FAIL_CREATE:
     newSurf->~cairo_d2d_surface_t();
     free(newSurf);
     return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY));
 }
--- a/gfx/cairo/cairo/src/cairo-debug.c
+++ b/gfx/cairo/cairo/src/cairo-debug.c
@@ -7,17 +7,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
@@ -72,20 +72,24 @@ cairo_debug_reset_static_data (void)
     _cairo_intern_string_reset_static_data ();
 
     _cairo_scaled_font_reset_static_data ();
 
     _cairo_pattern_reset_static_data ();
 
     _cairo_clip_reset_static_data ();
 
+    _cairo_image_reset_static_data ();
+
 #if CAIRO_HAS_DRM_SURFACE
     _cairo_drm_device_reset_static_data ();
 #endif
 
+    _cairo_reset_static_data ();
+
     CAIRO_MUTEX_FINALIZE ();
 }
 
 #if HAVE_VALGRIND
 void
 _cairo_debug_check_image_surface_is_defined (const cairo_surface_t *surface)
 {
     const cairo_image_surface_t *image = (cairo_image_surface_t *) surface;
@@ -101,20 +105,24 @@ void
     bits = image->data;
     switch (image->format) {
     case CAIRO_FORMAT_A1:
 	width = (image->width + 7)/8;
 	break;
     case CAIRO_FORMAT_A8:
 	width = image->width;
 	break;
+    case CAIRO_FORMAT_RGB16_565:
+	width = image->width*2;
+	break;
     case CAIRO_FORMAT_RGB24:
     case CAIRO_FORMAT_ARGB32:
 	width = image->width*4;
 	break;
+    case CAIRO_FORMAT_INVALID:
     default:
 	/* XXX compute width from pixman bpp */
 	return;
     }
 
     for (row = 0; row < image->height; row++) {
 	VALGRIND_CHECK_MEM_IS_DEFINED (bits, width);
 	/* and then silence any future valgrind warnings */
@@ -216,16 +224,22 @@ static cairo_status_t
     return CAIRO_STATUS_SUCCESS;
 }
 
 void
 _cairo_debug_print_path (FILE *stream, cairo_path_fixed_t *path)
 {
     cairo_status_t status;
 
+    printf ("path: extents=(%f, %f), (%f, %f)\n",
+	    _cairo_fixed_to_double (path->extents.p1.x),
+	    _cairo_fixed_to_double (path->extents.p1.y),
+	    _cairo_fixed_to_double (path->extents.p2.x),
+	    _cairo_fixed_to_double (path->extents.p2.y));
+
     status = _cairo_path_fixed_interpret (path,
 					  CAIRO_DIRECTION_FORWARD,
 					  _print_move_to,
 					  _print_line_to,
 					  _print_curve_to,
 					  _print_close,
 					  stream);
     assert (status == CAIRO_STATUS_SUCCESS);
--- a/gfx/cairo/cairo/src/cairo-deflate-stream.c
+++ b/gfx/cairo/cairo/src/cairo-deflate-stream.c
@@ -8,17 +8,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
@@ -30,16 +30,17 @@
  *
  * The Initial Developer of the Original Code is Adrian Johnson.
  *
  * Author(s):
  *	Adrian Johnson <ajohnson@redneon.com>
  */
 
 #include "cairoint.h"
+#include "cairo-error-private.h"
 #include "cairo-output-stream-private.h"
 #include <zlib.h>
 
 #define BUFFER_SIZE 16384
 
 typedef struct _cairo_deflate_stream {
     cairo_output_stream_t  base;
     cairo_output_stream_t *output;
--- a/gfx/cairo/cairo/src/cairo-deprecated.h
+++ b/gfx/cairo/cairo/src/cairo-deprecated.h
@@ -7,17 +7,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
@@ -31,30 +31,16 @@
  *
  * Contributor(s):
  *	Carl D. Worth <cworth@cworth.org>
  */
 
 #ifndef CAIRO_DEPRECATED_H
 #define CAIRO_DEPRECATED_H
 
-/* The %CAIRO_FORMAT_RGB16_565 value was added in cairo 1.2.0 as part
- * of fixing cairo's xlib backend to work with X servers advertising a
- * 16-bit, 565 visual. But as it turned out, adding this format to
- * #cairo_format_t was not necessary, and was a mistake, (cairo's xlib
- * backend can work fine with 16-bit visuals in the same way it works
- * with BGR visuals without any BGR formats in
- * #cairo_format_t).
- *
- * Additionally, the support for the RGB16_565 format was never
- * completely implemented. So while this format value is currently
- * deprecated, it may eventually acquire complete support in the future.
- */
-/* #define CAIRO_FORMAT_RGB16_565 4 */
-
 #define CAIRO_FONT_TYPE_ATSUI CAIRO_FONT_TYPE_QUARTZ
 
 /* Obsolete functions. These definitions exist to coerce the compiler
  * into providing a little bit of guidance with its error
  * messages. The idea is to help users port their old code without
  * having to dig through lots of documentation.
  *
  * The first set of REPLACED_BY functions is for functions whose names
@@ -118,17 +104,16 @@
 #define cairo_surface_get_matrix	cairo_surface_get_matrix_DEPRECATED_BY_cairo_pattern_get_matrix
 #define cairo_surface_set_filter	cairo_surface_set_filter_DEPRECATED_BY_cairo_pattern_set_filter
 #define cairo_surface_get_filter	cairo_surface_get_filter_DEPRECATED_BY_cairo_pattern_get_filter
 #define cairo_matrix_create		cairo_matrix_create_DEPRECATED_BY_cairo_matrix_t
 #define cairo_matrix_destroy		cairo_matrix_destroy_DEPRECATED_BY_cairo_matrix_t
 #define cairo_matrix_copy		cairo_matrix_copy_DEPRECATED_BY_cairo_matrix_t
 #define cairo_matrix_get_affine		cairo_matrix_get_affine_DEPRECATED_BY_cairo_matrix_t
 #define cairo_set_target_surface	cairo_set_target_surface_DEPRECATED_BY_cairo_create
-#define cairo_set_target_glitz		cairo_set_target_glitz_DEPRECATED_BY_cairo_glitz_surface_create
 #define cairo_set_target_image		cairo_set_target_image_DEPRECATED_BY_cairo_image_surface_create_for_data
 #define cairo_set_target_pdf		cairo_set_target_pdf_DEPRECATED_BY_cairo_pdf_surface_create
 #define cairo_set_target_png		cairo_set_target_png_DEPRECATED_BY_cairo_surface_write_to_png
 #define cairo_set_target_ps		cairo_set_target_ps_DEPRECATED_BY_cairo_ps_surface_create
 #define cairo_set_target_quartz		cairo_set_target_quartz_DEPRECATED_BY_cairo_quartz_surface_create
 #define cairo_set_target_win32		cairo_set_target_win32_DEPRECATED_BY_cairo_win32_surface_create
 #define cairo_set_target_xcb		cairo_set_target_xcb_DEPRECATED_BY_cairo_xcb_surface_create
 #define cairo_set_target_drawable	cairo_set_target_drawable_DEPRECATED_BY_cairo_xlib_surface_create
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/cairo/src/cairo-device-private.h
@@ -0,0 +1,86 @@
+/* Cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2009 Intel 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Intel Corporation.
+ *
+ * Contributors(s):
+ *	Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#ifndef _CAIRO_DEVICE_PRIVATE_H_
+#define _CAIRO_DEVICE_PRIVATE_H_
+
+#include "cairo-compiler-private.h"
+#include "cairo-mutex-private.h"
+#include "cairo-reference-count-private.h"
+#include "cairo-types-private.h"
+
+struct _cairo_device {
+    cairo_reference_count_t ref_count;
+    cairo_status_t status;
+    cairo_user_data_array_t user_data;
+
+    const cairo_device_backend_t *backend;
+
+    cairo_recursive_mutex_t mutex;
+    unsigned mutex_depth;
+
+    cairo_bool_t finished;
+};
+
+struct _cairo_device_backend {
+    cairo_device_type_t type;
+
+    void (*lock) (void *device);
+    void (*unlock) (void *device);
+
+    cairo_warn cairo_status_t (*flush) (void *device);
+    void (*finish) (void *device);
+    void (*destroy) (void *device);
+};
+
+cairo_private cairo_device_t *
+_cairo_device_create_in_error (cairo_status_t status);
+
+cairo_private void
+_cairo_device_init (cairo_device_t *device,
+		    const cairo_device_backend_t *backend);
+
+cairo_private cairo_status_t
+_cairo_device_set_error (cairo_device_t *device,
+		         cairo_status_t error);
+
+slim_hidden_proto_no_warn (cairo_device_reference);
+slim_hidden_proto (cairo_device_acquire);
+slim_hidden_proto (cairo_device_release);
+slim_hidden_proto (cairo_device_flush);
+slim_hidden_proto (cairo_device_finish);
+slim_hidden_proto (cairo_device_destroy);
+
+#endif /* _CAIRO_DEVICE_PRIVATE_H_ */
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/cairo/src/cairo-device.c
@@ -0,0 +1,533 @@
+/* Cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2009 Intel 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Intel Corporation.
+ *
+ * Contributors(s):
+ *	Chris Wilson <chris@chris-wilson.co.uk>
+ */
+
+#include "cairoint.h"
+#include "cairo-device-private.h"
+#include "cairo-error-private.h"
+
+/**
+ * SECTION:cairo-device
+ * @Title: cairo_device_t
+ * @Short_Description: interface to underlying rendering system
+ * @See_Also: #cairo_surface_t
+ *
+ * Devices are the abstraction Cairo employs for the rendering system
+ * used by a #cairo_surface_t. You can get the device of a surface using
+ * cairo_surface_get_device().
+ *
+ * Devices are created using custom functions specific to the rendering
+ * system you want to use. See the documentation for the surface types
+ * for those functions.
+ *
+ * An important function that devices fulfill is sharing access to the
+ * rendering system between Cairo and your application. If you want to
+ * access a device directly that you used to draw to with Cairo, you must
+ * first call cairo_device_flush() to ensure that Cairo finishes all
+ * operations on the device and resets it to a clean state.
+ *
+ * Cairo also provides the functions cairo_device_acquire() and
+ * cairo_device_release() to synchronize access to the rendering system
+ * in a multithreaded environment. This is done internally, but can also
+ * be used by applications.
+ *
+ * Putting this all together, a function that works with devices should
+ * look something like this:
+ * <informalexample><programlisting>
+ * void
+ * my_device_modifying_function (cairo_device_t *device)
+ * {
+ *   cairo_status_t status;
+ *
+ *   // Ensure the device is properly reset
+ *   cairo_device_flush (device);
+ *   // Try to acquire the device
+ *   status = cairo_device_acquire (device);
+ *   if (status != CAIRO_STATUS_SUCCESS) {
+ *     printf ("Failed to acquire the device: %s\n", cairo_status_to_string (status));
+ *     return;
+ *   }
+ *
+ *   // Do the custom operations on the device here.
+ *   // But do not call any Cairo functions that might acquire devices.
+ *   
+ *   // Release the device when done.
+ *   cairo_device_release (device);
+ * }
+ * </programlisting></informalexample>
+ *
+ * <note><para>Please refer to the documentation of each backend for
+ * additional usage requirements, guarantees provided, and
+ * interactions with existing surface API of the device functions for
+ * surfaces of that type.
+ * </para></note>
+ */
+
+static const cairo_device_t _nil_device = {
+    CAIRO_REFERENCE_COUNT_INVALID,
+    CAIRO_STATUS_NO_MEMORY,
+};
+
+static const cairo_device_t _mismatch_device = {
+    CAIRO_REFERENCE_COUNT_INVALID,
+    CAIRO_STATUS_DEVICE_TYPE_MISMATCH,
+};
+
+static const cairo_device_t _invalid_device = {
+    CAIRO_REFERENCE_COUNT_INVALID,
+    CAIRO_STATUS_DEVICE_ERROR,
+};
+
+cairo_device_t *
+_cairo_device_create_in_error (cairo_status_t status)
+{
+    switch (status) {
+    case CAIRO_STATUS_NO_MEMORY:
+	return (cairo_device_t *) &_nil_device;
+    case CAIRO_STATUS_DEVICE_ERROR:
+	return (cairo_device_t *) &_invalid_device;
+    case CAIRO_STATUS_DEVICE_TYPE_MISMATCH:
+	return (cairo_device_t *) &_mismatch_device;
+
+    case CAIRO_STATUS_SUCCESS:
+    case CAIRO_STATUS_LAST_STATUS:
+	ASSERT_NOT_REACHED;
+	/* fall-through */
+    case CAIRO_STATUS_SURFACE_TYPE_MISMATCH:
+    case CAIRO_STATUS_INVALID_STATUS:
+    case CAIRO_STATUS_INVALID_FORMAT:
+    case CAIRO_STATUS_INVALID_VISUAL:
+    case CAIRO_STATUS_READ_ERROR:
+    case CAIRO_STATUS_WRITE_ERROR:
+    case CAIRO_STATUS_FILE_NOT_FOUND:
+    case CAIRO_STATUS_TEMP_FILE_ERROR:
+    case CAIRO_STATUS_INVALID_STRIDE:
+    case CAIRO_STATUS_INVALID_SIZE:
+    case CAIRO_STATUS_INVALID_RESTORE:
+    case CAIRO_STATUS_INVALID_POP_GROUP:
+    case CAIRO_STATUS_NO_CURRENT_POINT:
+    case CAIRO_STATUS_INVALID_MATRIX:
+    case CAIRO_STATUS_NULL_POINTER:
+    case CAIRO_STATUS_INVALID_STRING:
+    case CAIRO_STATUS_INVALID_PATH_DATA:
+    case CAIRO_STATUS_SURFACE_FINISHED:
+    case CAIRO_STATUS_PATTERN_TYPE_MISMATCH:
+    case CAIRO_STATUS_INVALID_DASH:
+    case CAIRO_STATUS_INVALID_DSC_COMMENT:
+    case CAIRO_STATUS_INVALID_INDEX:
+    case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE:
+    case CAIRO_STATUS_FONT_TYPE_MISMATCH:
+    case CAIRO_STATUS_USER_FONT_IMMUTABLE:
+    case CAIRO_STATUS_USER_FONT_ERROR:
+    case CAIRO_STATUS_NEGATIVE_COUNT:
+    case CAIRO_STATUS_INVALID_CLUSTERS:
+    case CAIRO_STATUS_INVALID_SLANT:
+    case CAIRO_STATUS_INVALID_WEIGHT:
+    case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED:
+    case CAIRO_STATUS_INVALID_CONTENT:
+    default:
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+	return (cairo_device_t *) &_nil_device;
+    }
+}
+
+void
+_cairo_device_init (cairo_device_t *device,
+		    const cairo_device_backend_t *backend)
+{
+    CAIRO_REFERENCE_COUNT_INIT (&device->ref_count, 1);
+    device->status = CAIRO_STATUS_SUCCESS;
+
+    device->backend = backend;
+
+    CAIRO_RECURSIVE_MUTEX_INIT (device->mutex);
+    device->mutex_depth = 0;
+
+    device->finished = FALSE;
+
+    _cairo_user_data_array_init (&device->user_data);
+}
+
+/**
+ * cairo_device_reference:
+ * @device: a #cairo_device_t
+ *
+ * Increases the reference count on @device by one. This prevents
+ * @device from being destroyed until a matching call to
+ * cairo_device_destroy() is made.
+ *
+ * The number of references to a #cairo_device_t can be get using
+ * cairo_device_get_reference_count().
+ *
+ * Return value: the referenced #cairo_device_t.
+ *
+ * Since: 1.10
+ **/
+cairo_device_t *
+cairo_device_reference (cairo_device_t *device)
+{
+    if (device == NULL ||
+	CAIRO_REFERENCE_COUNT_IS_INVALID (&device->ref_count))
+    {
+	return device;
+    }
+
+    assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&device->ref_count));
+    _cairo_reference_count_inc (&device->ref_count);
+
+    return device;
+}
+slim_hidden_def (cairo_device_reference);
+
+/**
+ * cairo_device_status:
+ * @device: a #cairo_device_t
+ *
+ * Checks whether an error has previously occurred for this
+ * device.
+ *
+ * Return value: %CAIRO_STATUS_SUCCESS on success or an error code if
+ *               the device is in an error state.
+ *
+ * Since: 1.10
+ **/
+cairo_status_t
+cairo_device_status (cairo_device_t *device)
+{
+    if (device == NULL)
+	return CAIRO_STATUS_NULL_POINTER;
+
+    return device->status;
+}
+
+/**
+ * cairo_device_flush:
+ * @device: a #cairo_device_t
+ *
+ * Finish any pending operations for the device and also restore any
+ * temporary modifications cairo has made to the device's state.
+ * This function must be called before switching from using the 
+ * device with Cairo to operating on it directly with native APIs.
+ * If the device doesn't support direct access, then this function
+ * does nothing.
+ *
+ * This function may acquire devices.
+ *
+ * Since: 1.10
+ **/
+void
+cairo_device_flush (cairo_device_t *device)
+{
+    cairo_status_t status;
+
+    if (device == NULL || device->status)
+	return;
+
+    if (device->backend->flush != NULL) {
+	status = device->backend->flush (device);
+	if (unlikely (status))
+	    status = _cairo_device_set_error (device, status);
+    }
+}
+slim_hidden_def (cairo_device_flush);
+
+/**
+ * cairo_device_finish:
+ * @device: the #cairo_device_t to finish
+ *
+ * This function finishes the device and drops all references to
+ * external resources. All surfaces, fonts and other objects created
+ * for this @device will be finished, too.
+ * Further operations on the @device will not affect the @device but
+ * will instead trigger a %CAIRO_STATUS_DEVICE_FINISHED error.
+ *
+ * When the last call to cairo_device_destroy() decreases the
+ * reference count to zero, cairo will call cairo_device_finish() if
+ * it hasn't been called already, before freeing the resources
+ * associated with the device.
+ *
+ * This function may acquire devices.
+ *
+ * Since: 1.10
+ **/
+void
+cairo_device_finish (cairo_device_t *device)
+{
+    if (device == NULL ||
+	CAIRO_REFERENCE_COUNT_IS_INVALID (&device->ref_count))
+    {
+	return;
+    }
+
+    if (device->finished)
+	return;
+
+    cairo_device_flush (device);
+
+    device->finished = TRUE;
+
+    if (device->backend->finish != NULL)
+	device->backend->finish (device);
+}
+slim_hidden_def (cairo_device_finish);
+
+/**
+ * cairo_device_destroy:
+ * @device: a #cairo_device_t
+ *
+ * Decreases the reference count on @device by one. If the result is
+ * zero, then @device and all associated resources are freed.  See
+ * cairo_device_reference().
+ *
+ * This function may acquire devices if the last reference was dropped.
+ *
+ * Since: 1.10
+ **/
+void
+cairo_device_destroy (cairo_device_t *device)
+{
+    cairo_user_data_array_t user_data;
+
+    if (device == NULL ||
+	CAIRO_REFERENCE_COUNT_IS_INVALID (&device->ref_count))
+    {
+	return;
+    }
+
+    assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&device->ref_count));
+    if (! _cairo_reference_count_dec_and_test (&device->ref_count))
+	return;
+
+    cairo_device_finish (device);
+
+    assert (device->mutex_depth == 0);
+    CAIRO_MUTEX_FINI (device->mutex);
+
+    user_data = device->user_data;
+
+    device->backend->destroy (device);
+
+    _cairo_user_data_array_fini (&user_data);
+
+}
+slim_hidden_def (cairo_device_destroy);
+
+/**
+ * cairo_device_get_type:
+ * @device: a #cairo_device_t
+ *
+ * This function returns the type of the device. See #cairo_device_type_t
+ * for available types.
+ *
+ * Return value: The type of @device.
+ *
+ * Since: 1.10
+ **/
+cairo_device_type_t
+cairo_device_get_type (cairo_device_t *device)
+{
+    if (device == NULL ||
+	CAIRO_REFERENCE_COUNT_IS_INVALID (&device->ref_count))
+    {
+	return (cairo_device_type_t) -1;
+    }
+
+    return device->backend->type;
+}
+
+/**
+ * cairo_device_acquire:
+ * @device: a #cairo_device_t
+ *
+ * Acquires the @device for the current thread. This function will block
+ * until no other thread has acquired the device.
+ *
+ * If the return value is %CAIRO_STATUS_SUCCESS, you successfully acquired the
+ * device. From now on your thread owns the device and no other thread will be
+ * able to acquire it until a matching call to cairo_device_release(). It is
+ * allowed to recursively acquire the device multiple times from the same
+ * thread.
+ *
+ * <note><para>You must never acquire two different devices at the same time
+ * unless this is explicitly allowed. Otherwise the possibility of deadlocks
+ * exist.
+ *
+ * As various Cairo functions can acquire devices when called, these functions
+ * may also cause deadlocks when you call them with an acquired device. So you
+ * must not have a device acquired when calling them. These functions are
+ * marked in the documentation.
+ * </para></note>
+ *
+ * Return value: %CAIRO_STATUS_SUCCESS on success or an error code if
+ *               the device is in an error state and could not be
+ *               acquired. After a successful call to cairo_device_acquire(),
+ *               a matching call to cairo_device_release() is required.
+ *
+ * Since: 1.10
+ **/
+cairo_status_t
+cairo_device_acquire (cairo_device_t *device)
+{
+    if (device == NULL)
+	return CAIRO_STATUS_SUCCESS;
+
+    if (unlikely (device->status))
+	return device->status;
+
+    if (unlikely (device->finished))
+	return _cairo_device_set_error (device, CAIRO_STATUS_SURFACE_FINISHED); /* XXX */
+
+    CAIRO_MUTEX_LOCK (device->mutex);
+    if (device->mutex_depth++ == 0) {
+	if (device->backend->lock != NULL)
+	    device->backend->lock (device);
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+slim_hidden_def (cairo_device_acquire);
+
+/**
+ * cairo_device_release:
+ * @device: a #cairo_device_t
+ *
+ * Releases a @device previously acquired using cairo_device_acquire(). See
+ * that function for details.
+ *
+ * Since: 1.10
+ **/
+void
+cairo_device_release (cairo_device_t *device)
+{
+    if (device == NULL)
+	return;
+
+    assert (device->mutex_depth > 0);
+
+    if (--device->mutex_depth == 0) {
+	if (device->backend->unlock != NULL)
+	    device->backend->unlock (device);
+    }
+
+    CAIRO_MUTEX_UNLOCK (device->mutex);
+}
+slim_hidden_def (cairo_device_release);
+
+cairo_status_t
+_cairo_device_set_error (cairo_device_t *device,
+			 cairo_status_t  status)
+{
+    if (status == CAIRO_STATUS_SUCCESS || status >= CAIRO_INT_STATUS_UNSUPPORTED)
+	return status;
+
+    /* Don't overwrite an existing error. This preserves the first
+     * error, which is the most significant. */
+    _cairo_status_set_error (&device->status, status);
+
+    return _cairo_error (status);
+}
+
+/**
+ * cairo_device_get_reference_count:
+ * @device: a #cairo_device_t
+ *
+ * Returns the current reference count of @device.
+ *
+ * Return value: the current reference count of @device.  If the
+ * object is a nil object, 0 will be returned.
+ *
+ * Since: 1.10
+ **/
+unsigned int
+cairo_device_get_reference_count (cairo_device_t *device)
+{
+    if (device == NULL ||
+	CAIRO_REFERENCE_COUNT_IS_INVALID (&device->ref_count))
+	return 0;
+
+    return CAIRO_REFERENCE_COUNT_GET_VALUE (&device->ref_count);
+}
+
+/**
+ * cairo_device_get_user_data:
+ * @device: a #cairo_device_t
+ * @key: the address of the #cairo_user_data_key_t the user data was
+ * attached to
+ *
+ * Return user data previously attached to @device using the
+ * specified key.  If no user data has been attached with the given
+ * key this function returns %NULL.
+ *
+ * Return value: the user data previously attached or %NULL.
+ *
+ * Since: 1.10
+ **/
+void *
+cairo_device_get_user_data (cairo_device_t		 *device,
+			    const cairo_user_data_key_t *key)
+{
+    return _cairo_user_data_array_get_data (&device->user_data,
+					    key);
+}
+
+/**
+ * cairo_device_set_user_data:
+ * @device: a #cairo_device_t
+ * @key: the address of a #cairo_user_data_key_t to attach the user data to
+ * @user_data: the user data to attach to the #cairo_device_t
+ * @destroy: a #cairo_destroy_func_t which will be called when the
+ * #cairo_t is destroyed or when new user data is attached using the
+ * same key.
+ *
+ * Attach user data to @device.  To remove user data from a surface,
+ * call this function with the key that was used to set it and %NULL
+ * for @data.
+ *
+ * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
+ * slot could not be allocated for the user data.
+ *
+ * Since: 1.10
+ **/
+cairo_status_t
+cairo_device_set_user_data (cairo_device_t		 *device,
+			    const cairo_user_data_key_t *key,
+			    void			 *user_data,
+			    cairo_destroy_func_t	  destroy)
+{
+    if (CAIRO_REFERENCE_COUNT_IS_INVALID (&device->ref_count))
+	return device->status;
+
+    return _cairo_user_data_array_set_data (&device->user_data,
+					    key, user_data, destroy);
+}
--- a/gfx/cairo/cairo/src/cairo-directfb-surface.c
+++ b/gfx/cairo/cairo/src/cairo-directfb-surface.c
@@ -7,17 +7,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
@@ -34,16 +34,17 @@
  *    Michael Emmel <mike.emmel@gmail.com>
  *    Claudio Ciccani <klan@users.sf.net>
  */
 
 #include "cairoint.h"
 #include "cairo-directfb.h"
 
 #include "cairo-clip-private.h"
+#include "cairo-error-private.h"
 
 #include <pixman.h>
 
 #include <directfb.h>
 #include <direct/types.h>
 #include <direct/debug.h>
 #include <direct/memcpy.h>
 #include <direct/util.h>
@@ -559,16 +560,17 @@ static cairo_surface_t *
 	if (status) {
 	    free (surface);
 	    return _cairo_surface_create_in_error (status);
 	}
     }
 
     _cairo_surface_init (&surface->base,
 			 &_cairo_directfb_surface_backend,
+			 NULL, /* device */
 			 content);
     surface->pixman_format = _directfb_to_pixman_format (format);
     surface->supported_destination = pixman_format_supported_destination (surface->pixman_format);
 
     surface->width   = width;
     surface->height  = height;
     surface->local   = TRUE;
     surface->blit_premultiplied = TRUE;
@@ -757,24 +759,24 @@ static cairo_status_t
 						 width, height,
 						 data, pitch);
 	if (unlikely (pixman_image == NULL)) {
 	    DirectFBError ("IDirectFBSurface::Lock()", ret);
 	    cairo_surface_destroy (&clone->base);
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	}
 
-	pixman_image_composite (PIXMAN_OP_SRC,
-				image_src->pixman_image,
-				NULL,
-				pixman_image,
-				src_x, src_y,
-				0, 0,
-				0, 0,
-				width, height);
+	pixman_image_composite32 (PIXMAN_OP_SRC,
+                                  image_src->pixman_image,
+                                  NULL,
+                                  pixman_image,
+                                  src_x, src_y,
+                                  0, 0,
+                                  0, 0,
+                                  width, height);
 
 	pixman_image_unref (pixman_image);
 
 	clone->dfbsurface->Unlock (clone->dfbsurface);
 
 	*clone_offset_x = src_x;
 	*clone_offset_y = src_y;
 	*clone_out = &clone->base;
@@ -1809,17 +1811,17 @@ static cairo_int_status_t
 					     cache->dfbsurface, rects, points, num));
 
     return CAIRO_STATUS_SUCCESS;
 }
 #endif /* DFB_SHOW_GLYPHS */
 
 
 static cairo_bool_t
-_cairo_directfb_surface_is_similar (void *surface_a, void *surface_b, cairo_content_t content)
+_cairo_directfb_surface_is_similar (void *surface_a, void *surface_b)
 {
     cairo_directfb_surface_t *a = (cairo_directfb_surface_t *) surface_a;
     cairo_directfb_surface_t *b = (cairo_directfb_surface_t *) surface_b;
 
     return a->dfb == b->dfb;
 }
 
 static cairo_surface_backend_t
@@ -1950,12 +1952,13 @@ cairo_directfb_surface_create (IDirectFB
     surface->supported_destination = pixman_format_supported_destination (surface->pixman_format);
 
     dfbsurface->GetCapabilities (dfbsurface, &caps);
     if (caps & DSCAPS_PREMULTIPLIED)
 	surface->blit_premultiplied = TRUE;
 
     _cairo_surface_init (&surface->base,
                          &_cairo_directfb_surface_backend,
+			 NULL, /* device */
 			 _directfb_format_to_content (format));
 
     return &surface->base;
 }
--- a/gfx/cairo/cairo/src/cairo-directfb.h
+++ b/gfx/cairo/cairo/src/cairo-directfb.h
@@ -7,17 +7,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
--- a/gfx/cairo/cairo/src/cairo-drm.h
+++ b/gfx/cairo/cairo/src/cairo-drm.h
@@ -7,17 +7,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
@@ -34,66 +34,51 @@
 #define CAIRO_DRM_H
 
 #include "cairo.h"
 
 #if CAIRO_HAS_DRM_SURFACE
 
 CAIRO_BEGIN_DECLS
 
-typedef struct _cairo_drm_device cairo_drm_device_t;
-
 struct udev_device;
 
-cairo_public cairo_drm_device_t *
+cairo_public cairo_device_t *
 cairo_drm_device_get (struct udev_device *device);
 
-cairo_public cairo_drm_device_t *
+cairo_public cairo_device_t *
 cairo_drm_device_get_for_fd (int fd);
 
-cairo_public cairo_drm_device_t *
+cairo_public cairo_device_t *
 cairo_drm_device_default (void);
 
-cairo_public cairo_drm_device_t *
-cairo_drm_device_reference (cairo_drm_device_t *device);
-
-cairo_public cairo_status_t
-cairo_drm_device_status (cairo_drm_device_t *device);
-
 cairo_public int
-cairo_drm_device_get_fd (cairo_drm_device_t *device);
+cairo_drm_device_get_fd (cairo_device_t *device);
 
 cairo_public void
-cairo_drm_device_throttle (cairo_drm_device_t *device);
-
-cairo_public void
-cairo_drm_device_destroy (cairo_drm_device_t *device);
-
+cairo_drm_device_throttle (cairo_device_t *device);
 
 cairo_public cairo_surface_t *
-cairo_drm_surface_create (cairo_drm_device_t *device,
-			  cairo_content_t content,
+cairo_drm_surface_create (cairo_device_t *device,
+			  cairo_format_t format,
 			  int width, int height);
 
 cairo_public cairo_surface_t *
-cairo_drm_surface_create_for_name (cairo_drm_device_t *device,
+cairo_drm_surface_create_for_name (cairo_device_t *device,
 				   unsigned int name,
 	                           cairo_format_t format,
 				   int width, int height, int stride);
 
 cairo_public cairo_surface_t *
-cairo_drm_surface_create_from_cacheable_image (cairo_drm_device_t *device,
+cairo_drm_surface_create_from_cacheable_image (cairo_device_t *device,
 	                                       cairo_surface_t *surface);
 
 cairo_public cairo_status_t
 cairo_drm_surface_enable_scan_out (cairo_surface_t *surface);
 
-cairo_public cairo_drm_device_t *
-cairo_drm_surface_get_device (cairo_surface_t *abstract_surface);
-
 cairo_public unsigned int
 cairo_drm_surface_get_handle (cairo_surface_t *surface);
 
 cairo_public unsigned int
 cairo_drm_surface_get_name (cairo_surface_t *surface);
 
 cairo_public cairo_format_t
 cairo_drm_surface_get_format (cairo_surface_t *surface);
@@ -115,17 +100,17 @@ cairo_drm_surface_get_stride (cairo_surf
  *   from the GPU, maps it into the CPU domain and gives you direct access to
  *   the pixels.  With the unmap(), the buffer is ready to be used again by the
  *   GPU and *until* the unmap(), all operations will be done in software.
  *
  *  (Technically calling cairo_surface_flush() on the underlying drm-surface
  *  will also disassociate the mapping.)
 */
 cairo_public cairo_surface_t *
-cairo_drm_surface_map (cairo_surface_t *surface);
+cairo_drm_surface_map_to_image (cairo_surface_t *surface);
 
 cairo_public void
 cairo_drm_surface_unmap (cairo_surface_t *drm_surface,
 	                 cairo_surface_t *image_surface);
 
 CAIRO_END_DECLS
 
 #else  /* CAIRO_HAS_DRM_SURFACE */
--- a/gfx/cairo/cairo/src/cairo-dwrite-font.cpp
+++ b/gfx/cairo/cairo/src/cairo-dwrite-font.cpp
@@ -29,23 +29,22 @@
  * The Original Code is the cairo graphics library.
  *
  * The Initial Developer of the Original Code is the Mozilla Foundation
  *
  * Contributor(s):
  *	Bas Schouten <bschouten@mozilla.com>
  */
 
-extern "C" {
 #include "cairoint.h"
 
 #include "cairo-win32-private.h"
 #include "cairo-surface-private.h"
 #include "cairo-clip-private.h"
-}
+
 #include "cairo-d2d-private.h"
 #include "cairo-dwrite-private.h"
 #include <float.h>
 
 typedef HRESULT (WINAPI*D2D1CreateFactoryFunc)(
     __in D2D1_FACTORY_TYPE factoryType,
     __in REFIID iid,
     __in_opt CONST D2D1_FACTORY_OPTIONS *pFactoryOptions,
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/cairo/src/cairo-error-private.h
@@ -0,0 +1,60 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2002 University of Southern California
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is University of Southern
+ * California.
+ *
+ * Contributor(s):
+ *	Carl D. Worth <cworth@cworth.org>
+ */
+
+#ifndef _CAIRO_ERROR_PRIVATE_H_
+#define _CAIRO_ERROR_PRIVATE_H_
+
+#include "cairo.h"
+#include "cairo-compiler-private.h"
+
+CAIRO_BEGIN_DECLS
+
+#define _cairo_status_is_error(status) \
+    (status != CAIRO_STATUS_SUCCESS && status <= CAIRO_STATUS_LAST_STATUS)
+
+cairo_private cairo_status_t
+_cairo_error (cairo_status_t status);
+
+/* hide compiler warnings when discarding the return value */
+#define _cairo_error_throw(status) do { \
+    cairo_status_t status__ = _cairo_error (status); \
+    (void) status__; \
+} while (0)
+
+CAIRO_END_DECLS
+
+#endif /* _CAIRO_ERROR_PRIVATE_H_ */
--- a/gfx/cairo/cairo/src/cairo-features.h.in
+++ b/gfx/cairo/cairo/src/cairo-features.h.in
@@ -84,12 +84,14 @@
 @WIN32_FONT_FEATURE@
 
 @WIN32_DWRITE_FONT_FEATURE@
 
 @WIN32_D2D_SURFACE_FEATURE@
 
 @QUARTZ_FONT_FEATURE@
 
+@TEE_SURFACE_FEATURE@
+
 @PNG_FUNCTIONS_FEATURE@
 
 @FC_FONT_FEATURE@
 #endif
--- a/gfx/cairo/cairo/src/cairo-fixed-private.h
+++ b/gfx/cairo/cairo/src/cairo-fixed-private.h
@@ -8,17 +8,17 @@
  * 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
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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/
  *
@@ -48,17 +48,17 @@
 # error To remove this limitation, you will have to fix the tesselator.
 #endif