Backed out changeset 9480726de986
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Thu, 08 Apr 2010 09:44:28 -0400
changeset 40590 733e8efbaf26d971261753110a4ce482d6b8524b
parent 40574 9480726de986979132443714b9f9d6e89f0b4720
child 40591 5b8f688d42442e06a609ceeec80a1b0f84d1001c
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9.3a5pre
backs out9480726de986979132443714b9f9d6e89f0b4720
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
Backed out changeset 9480726de986 Rendering/Invalidation problems showed up.
gfx/cairo/README
gfx/cairo/add-a-stash-of-cairo_t-s.patch
gfx/cairo/bgr.patch
gfx/cairo/cairo/src/Makefile.in
gfx/cairo/cairo/src/cairo-analysis-surface-private.h
gfx/cairo/cairo/src/cairo-analysis-surface.c
gfx/cairo/cairo/src/cairo-arc.c
gfx/cairo/cairo/src/cairo-atomic-private.h
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-clip-private.h
gfx/cairo/cairo/src/cairo-clip.c
gfx/cairo/cairo/src/cairo-combsort-private.h
gfx/cairo/cairo/src/cairo-d2d-private.h
gfx/cairo/cairo/src/cairo-d2d-surface.cpp
gfx/cairo/cairo/src/cairo-ddraw-private.h
gfx/cairo/cairo/src/cairo-ddraw-surface.c
gfx/cairo/cairo/src/cairo-debug.c
gfx/cairo/cairo/src/cairo-directfb-surface.c
gfx/cairo/cairo/src/cairo-drm.h
gfx/cairo/cairo/src/cairo-dwrite-font.cpp
gfx/cairo/cairo/src/cairo-dwrite-private.h
gfx/cairo/cairo/src/cairo-eagle-context.c
gfx/cairo/cairo/src/cairo-features-win32.h
gfx/cairo/cairo/src/cairo-fixed-private.h
gfx/cairo/cairo/src/cairo-fixed-type-private.h
gfx/cairo/cairo/src/cairo-font-face-twin.c
gfx/cairo/cairo/src/cairo-freelist-private.h
gfx/cairo/cairo/src/cairo-freelist.c
gfx/cairo/cairo/src/cairo-ft-font.c
gfx/cairo/cairo/src/cairo-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-glitz-surface.c
gfx/cairo/cairo/src/cairo-glx-context.c
gfx/cairo/cairo/src/cairo-gstate.c
gfx/cairo/cairo/src/cairo-hash.c
gfx/cairo/cairo/src/cairo-hull.c
gfx/cairo/cairo/src/cairo-image-surface.c
gfx/cairo/cairo/src/cairo-matrix.c
gfx/cairo/cairo/src/cairo-meta-surface.c
gfx/cairo/cairo/src/cairo-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-no-features.h
gfx/cairo/cairo/src/cairo-os2-surface.c
gfx/cairo/cairo/src/cairo-output-stream-private.h
gfx/cairo/cairo/src/cairo-output-stream.c
gfx/cairo/cairo/src/cairo-paginated-private.h
gfx/cairo/cairo/src/cairo-paginated-surface-private.h
gfx/cairo/cairo/src/cairo-paginated-surface.c
gfx/cairo/cairo/src/cairo-path-bounds.c
gfx/cairo/cairo/src/cairo-path-fill.c
gfx/cairo/cairo/src/cairo-path-fixed-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-stroke.c
gfx/cairo/cairo/src/cairo-pattern.c
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-pen.c
gfx/cairo/cairo/src/cairo-polygon.c
gfx/cairo/cairo/src/cairo-ps-surface-private.h
gfx/cairo/cairo/src/cairo-ps-surface.c
gfx/cairo/cairo/src/cairo-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-private.h
gfx/cairo/cairo/src/cairo-quartz-surface.c
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-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.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-skiplist-private.h
gfx/cairo/cairo/src/cairo-skiplist.c
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-private.h
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-tee-surface-private.h
gfx/cairo/cairo/src/cairo-tee-surface.c
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.c
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-user-font.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-xcb-surface.c
gfx/cairo/cairo/src/cairo-xlib-display.c
gfx/cairo/cairo/src/cairo-xlib-private.h
gfx/cairo/cairo/src/cairo-xlib-screen.c
gfx/cairo/cairo/src/cairo-xlib-surface-private.h
gfx/cairo/cairo/src/cairo-xlib-surface.c
gfx/cairo/cairo/src/cairo-xlib-xrender-private.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-paginated-surface.c
gfx/cairo/cairo/src/test-paginated-surface.h
gfx/cairo/clip-invariant.patch
gfx/cairo/d2d.patch
gfx/cairo/disable-server-gradients.patch
gfx/cairo/fix-clip-copy.patch
gfx/cairo/fix-clip-region-simplification.patch
gfx/cairo/fix-unnecessary-fallback.patch
gfx/cairo/fix-zero-length-gradient.patch
gfx/cairo/handle-a1.patch
gfx/cairo/surface-clipper.patch
gfx/thebes/src/gfxContext.cpp
layout/reftests/bugs/456219-1-mask-wArA.png
layout/reftests/bugs/456219-1-mask-wArB.png
layout/reftests/bugs/456219-1-mask-wArC.png
layout/reftests/bugs/456219-1-mask-wArD.png
layout/reftests/bugs/456219-1-mask-wArE.png
layout/reftests/bugs/456219-1-mask-wBrA.png
layout/reftests/bugs/456219-1-mask-wBrB.png
layout/reftests/bugs/456219-1-mask-wBrC.png
layout/reftests/bugs/456219-1-mask-wBrD.png
layout/reftests/bugs/456219-1-mask-wBrE.png
layout/reftests/bugs/456219-1-mask-wCrA.png
layout/reftests/bugs/456219-1-mask-wCrB.png
layout/reftests/bugs/456219-1-mask-wCrC.png
layout/reftests/bugs/456219-1-mask-wCrD.png
layout/reftests/bugs/456219-1-mask-wCrE.png
layout/reftests/bugs/456219-1-mask-wDrA.png
layout/reftests/bugs/456219-1-mask-wDrB.png
layout/reftests/bugs/456219-1-mask-wDrC.png
layout/reftests/bugs/456219-1-mask-wDrD.png
layout/reftests/bugs/456219-1-mask-wDrE.png
layout/reftests/bugs/456219-1-mask-wErA.png
layout/reftests/bugs/456219-1-mask-wErB.png
layout/reftests/bugs/456219-1-mask-wErC.png
layout/reftests/bugs/456219-1-mask-wErD.png
layout/reftests/bugs/456219-1-mask-wErE.png
layout/reftests/bugs/reftest.list
layout/svg/base/src/nsSVGImageFrame.cpp
--- a/gfx/cairo/README
+++ b/gfx/cairo/README
@@ -63,44 +63,16 @@ quartz-minimze-gradient-repeat.patch: re
 quartz-first-stop.patch: return the first stop for negative positions on the gradient line of a nonrepeating linear gradient
 
 quartz-glyph-extents.patch: bug 534260; work around incorrect glyph extents returned by quartz for anomalous empty glyphs
 
 premultiply-alpha-solid-gradients.patch: bug 539165; multiply the solid color by the alpha component before using it for a solid surface
 
 xlib-initialize-members.path: bug 548793; initialize XRender version if the server doesn't have the extension
 
-remove-comma: remove a comma from enum
-
-d2d.patch: add d2d support
-
-fix-zero-len-graident.patch: fix zero length gradients
-
-fix-clip-copy.patch: fix clip copying
-
-fix-clip-region-simplification.patch: fixes a bug in clip region simplifications
-
-expand-in-stroke-limits.patch: expand the in-stroke limits to avoid a bug
-
-d2d-dwrite.patch: update the d2d/dwrite stuff
-
-add-a-stash-of-cairo_t-s.patch: use the stash to avoid malloc/freeing cairo_t's
-
-bgr.patch: fix image wrapping
-
-disable-server-graidents.patch: disable server-side gradients
-
-clip-invariant.patch: make rasterization closer to being clip invariant
-
-fix-unnecessary-fallback.patch: avoid unnecessary fallback
-
-handle-a1-upload.patch: handle a1 image uploads through converter
-
-surface-clipper.patch: remove an incorrect optimization
-
 ==== pixman patches ====
 
 pixman-neon.patch: add ARM NEON optimized compositing functions
 
 pixman-rename-and-endian.patch: include cairo-platform.h for renaming of external symbols and endian macros
 
 ==== disable printing patch ====
 
deleted file mode 100644
--- a/gfx/cairo/add-a-stash-of-cairo_t-s.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-commit dfec2c249915560cedd2b49326c6629ad8a0b0f2
-Author: Jeff Muizelaar <jmuizelaar@mozilla.com>
-Date:   Tue Mar 2 16:01:41 2010 -0500
-
-    add a stash of cairo_t's
-
-diff --git a/src/cairo.c b/src/cairo.c
-index 3c9d892..4b27b83 100644
---- a/src/cairo.c
-+++ b/src/cairo.c
-@@ -119,7 +119,63 @@ _cairo_set_error (cairo_t *cr, cairo_status_t status)
-     _cairo_status_set_error (&cr->status, _cairo_error (status));
- }
- 
--#if HAS_ATOMIC_OPS
-+#if defined(_MSC_VER)
-+#pragma intrinsic(_BitScanForward)
-+static __forceinline int
-+ffs(int x)
-+{
-+    unsigned long i;
-+
-+    if (_BitScanForward(&i, x) != 0)
-+	return i + 1;
-+
-+    return 0;
-+}
-+#endif
-+
-+
-+#if CAIRO_NO_MUTEX
-+/* We keep a small stash of contexts to reduce malloc pressure */
-+#define CAIRO_STASH_SIZE 4
-+static struct {
-+    cairo_t pool[CAIRO_STASH_SIZE];
-+    int occupied;
-+} _context_stash;
-+
-+static cairo_t *
-+_context_get (void)
-+{
-+    int avail, old, new;
-+
-+    old = _context_stash.occupied;
-+    avail = ffs (~old) - 1;
-+    if (avail >= CAIRO_STASH_SIZE)
-+	return malloc (sizeof (cairo_t));
-+
-+    new = old | (1 << avail);
-+    _context_stash.occupied = new;
-+
-+    return &_context_stash.pool[avail];
-+}
-+
-+static void
-+_context_put (cairo_t *cr)
-+{
-+    int old, new, avail;
-+
-+    if (cr < &_context_stash.pool[0] ||
-+	cr >= &_context_stash.pool[CAIRO_STASH_SIZE])
-+    {
-+	free (cr);
-+	return;
-+    }
-+
-+    avail = ~(1 << (cr - &_context_stash.pool[0]));
-+    old = _context_stash.occupied;
-+    new = old & avail;
-+    _context_stash.occupied = new;
-+}
-+#elif HAS_ATOMIC_OPS
- /* We keep a small stash of contexts to reduce malloc pressure */
- #define CAIRO_STASH_SIZE 4
- static struct {
deleted file mode 100644
--- a/gfx/cairo/bgr.patch
+++ /dev/null
@@ -1,104 +0,0 @@
-commit d2120bdb06c9aacc470bb346d6bc2071c2e0749d
-Author: Jeff Muizelaar <jmuizelaar@mozilla.com>
-Date:   Fri Mar 12 15:32:09 2010 -0500
-
-    BGR
-
-diff --git a/src/cairo-surface.c b/src/cairo-surface.c
-index 332e3ab..4a1d6a0 100644
---- a/src/cairo-surface.c
-+++ b/src/cairo-surface.c
-@@ -1501,7 +1501,9 @@ static void
- _wrap_release_source_image (void *data)
- {
-     struct acquire_source_image_data *acquire_data = data;
--    _cairo_surface_release_source_image (acquire_data->src, acquire_data->image, acquire_data->image_extra);
-+    _cairo_surface_release_source_image (acquire_data->src,
-+					 acquire_data->image,
-+					 acquire_data->image_extra);
-     free(data);
- }
- 
-@@ -1515,42 +1517,47 @@ _wrap_image (cairo_surface_t *src,
-     cairo_image_surface_t *surface;
-     cairo_status_t status;
- 
--    struct acquire_source_image_data *data = malloc(sizeof(*data));
-+    struct acquire_source_image_data *data = malloc (sizeof (*data));
-+    if (unlikely (data == NULL))
-+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-     data->src = src;
-     data->image = image;
-     data->image_extra = image_extra;
- 
--    surface = (cairo_image_surface_t*)cairo_image_surface_create_for_data (image->data,
--	    image->format,
--	    image->width,
--	    image->height,
--	    image->stride);
-+    surface = (cairo_image_surface_t*)
-+	_cairo_image_surface_create_with_pixman_format (image->data,
-+							image->pixman_format,
-+							image->width,
-+							image->height,
-+							image->stride);
-     status = surface->base.status;
--    if (status)
-+    if (status) {
-+	free (data);
- 	return status;
-+    }
- 
-     status = _cairo_user_data_array_set_data (&surface->base.user_data,
--	    &wrap_image_key,
--	    data,
--	    _wrap_release_source_image);
-+					      &wrap_image_key,
-+					      data,
-+					      _wrap_release_source_image);
-     if (status) {
- 	cairo_surface_destroy (&surface->base);
-+	free (data);
- 	return status;
-     }
--/*
--    pixman_image_set_component_alpha (surface->pixman_image,
--            pixman_image_get_component_alpha (image->pixman_image));
--*/
-+
-+    pixman_image_set_component_alpha (
-+	surface->pixman_image,
-+	pixman_image_get_component_alpha (image->pixman_image));
-+
-     *out = surface;
-     return CAIRO_STATUS_SUCCESS;
- }
- 
--
- /**
-  * _cairo_surface_clone_similar:
-  * @surface: a #cairo_surface_t
-  * @src: the source image
-- * @content: target content mask
-  * @src_x: extent for the rectangle in src we actually care about
-  * @src_y: extent for the rectangle in src we actually care about
-  * @width: extent for the rectangle in src we actually care about
-@@ -1627,12 +1634,12 @@ _cairo_surface_clone_similar (cairo_surface_t  *surface,
- 		    _cairo_surface_release_source_image (src, image, image_extra);
- 		} else {
- 		    status =
--		    surface->backend->clone_similar (surface, &image->base,
--						     src_x, src_y,
--						     width, height,
--						     clone_offset_x,
--						     clone_offset_y,
--						     clone_out);
-+			surface->backend->clone_similar (surface, &image->base,
-+							 src_x, src_y,
-+							 width, height,
-+							 clone_offset_x,
-+							 clone_offset_y,
-+							 clone_out);
- 		    cairo_surface_destroy(&image->base);
- 		}
- 	    }
--- a/gfx/cairo/cairo/src/Makefile.in
+++ b/gfx/cairo/cairo/src/Makefile.in
@@ -69,20 +69,17 @@ endif
 
 CSRCS   = \
         cairo.c \
         cairo-analysis-surface.c \
         cairo-arc.c \
         cairo-array.c \
 	cairo-atomic.c \
         cairo-bentley-ottmann.c \
-	cairo-bentley-ottmann-rectilinear.c \
-	cairo-bentley-ottmann-rectangular.c \
-        cairo-base64-stream.c \
-	cairo-cache.c \
+        cairo-cache.c \
         cairo-clip.c \
         cairo-color.c \
         cairo-debug.c \
         cairo-deflate-stream.c \
         cairo-fixed.c \
 	cairo-font-face.c \
 	cairo-font-face-twin.c \
 	cairo-font-face-twin-data.c \
@@ -90,43 +87,41 @@ CSRCS   = \
         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-meta-surface.c \
 	cairo-misc.c \
 	cairo-mutex.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-region.c \
         cairo-scaled-font.c \
         cairo-scaled-font-subsets.c \
+        cairo-skiplist.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-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)
--- a/gfx/cairo/cairo/src/cairo-analysis-surface-private.h
+++ b/gfx/cairo/cairo/src/cairo-analysis-surface-private.h
@@ -33,21 +33,23 @@
  */
 
 #ifndef CAIRO_ANALYSIS_SURFACE_H
 #define CAIRO_ANALYSIS_SURFACE_H
 
 #include "cairoint.h"
 
 cairo_private cairo_surface_t *
-_cairo_analysis_surface_create (cairo_surface_t		*target);
+_cairo_analysis_surface_create (cairo_surface_t		*target,
+				int			 width,
+				int			 height);
 
 cairo_private void
 _cairo_analysis_surface_set_ctm (cairo_surface_t *surface,
-				 const cairo_matrix_t  *ctm);
+				 cairo_matrix_t  *ctm);
 
 cairo_private void
 _cairo_analysis_surface_get_ctm (cairo_surface_t *surface,
 				 cairo_matrix_t  *ctm);
 
 cairo_private cairo_region_t *
 _cairo_analysis_surface_get_supported (cairo_surface_t *surface);
 
--- a/gfx/cairo/cairo/src/cairo-analysis-surface.c
+++ b/gfx/cairo/cairo/src/cairo-analysis-surface.c
@@ -33,30 +33,32 @@
  *      Keith Packard <keithp@keithp.com>
  *      Adrian Johnson <ajohnson@redneon.com>
  */
 
 #include "cairoint.h"
 
 #include "cairo-analysis-surface-private.h"
 #include "cairo-paginated-private.h"
-#include "cairo-recording-surface-private.h"
-#include "cairo-region-private.h"
+#include "cairo-meta-surface-private.h"
 
 typedef struct {
     cairo_surface_t base;
+    int width;
+    int height;
 
-    cairo_surface_t *target;
+    cairo_surface_t	*target;
 
     cairo_bool_t first_op;
     cairo_bool_t has_supported;
     cairo_bool_t has_unsupported;
 
     cairo_region_t supported_region;
     cairo_region_t fallback_region;
+    cairo_rectangle_int_t current_clip;
     cairo_box_t page_bbox;
 
     cairo_bool_t has_ctm;
     cairo_matrix_t ctm;
 
 } cairo_analysis_surface_t;
 
 cairo_int_status_t
@@ -71,67 +73,90 @@ cairo_int_status_t
     if (status_a == CAIRO_INT_STATUS_UNSUPPORTED ||
 	status_b == CAIRO_INT_STATUS_UNSUPPORTED)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     if (status_a == CAIRO_INT_STATUS_IMAGE_FALLBACK ||
 	status_b == CAIRO_INT_STATUS_IMAGE_FALLBACK)
 	return CAIRO_INT_STATUS_IMAGE_FALLBACK;
 
-    if (status_a == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN ||
-	status_b == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
-	return CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN;
+    if (status_a == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN ||
+	status_b == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
+	return CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN;
 
     if (status_a == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY ||
 	status_b == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
 	return CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
 
     /* at this point we have checked all the valid internal codes, so... */
     assert (status_a == CAIRO_STATUS_SUCCESS &&
 	    status_b == CAIRO_STATUS_SUCCESS);
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_int_status_t
-_analyze_recording_surface_pattern (cairo_analysis_surface_t *surface,
-				    const cairo_pattern_t    *pattern)
+_analyze_meta_surface_pattern (cairo_analysis_surface_t	*surface,
+			       const cairo_pattern_t *pattern)
 {
+    cairo_surface_t *analysis = &surface->base;
     const cairo_surface_pattern_t *surface_pattern;
+    cairo_status_t status;
     cairo_bool_t old_has_ctm;
     cairo_matrix_t old_ctm, p2d;
-    cairo_status_t status;
+    cairo_rectangle_int_t old_clip;
+    cairo_rectangle_int_t meta_extents;
+    int old_width;
+    int old_height;
 
     assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
     surface_pattern = (const cairo_surface_pattern_t *) pattern;
-    assert (_cairo_surface_is_recording (surface_pattern->surface));
+    assert (_cairo_surface_is_meta (surface_pattern->surface));
 
+    old_width = surface->width;
+    old_height = surface->height;
+    old_clip = surface->current_clip;
+    status = _cairo_surface_get_extents (surface_pattern->surface, &meta_extents);
+    if (_cairo_status_is_error (status))
+	return status;
+
+    surface->width = meta_extents.width;
+    surface->height = meta_extents.height;
+    surface->current_clip.x = 0;
+    surface->current_clip.y = 0;
+    surface->current_clip.width = surface->width;
+    surface->current_clip.height = surface->height;
     old_ctm = surface->ctm;
     old_has_ctm = surface->has_ctm;
-
     p2d = pattern->matrix;
     status = cairo_matrix_invert (&p2d);
+    /* _cairo_pattern_set_matrix guarantees invertibility */
     assert (status == CAIRO_STATUS_SUCCESS);
 
     cairo_matrix_multiply (&surface->ctm, &p2d, &surface->ctm);
-    surface->has_ctm = ! _cairo_matrix_is_identity (&surface->ctm);
+    surface->has_ctm = !_cairo_matrix_is_identity (&surface->ctm);
 
-    status = _cairo_recording_surface_replay_and_create_regions (surface_pattern->surface,
-							    &surface->base);
+    status = _cairo_meta_surface_replay_and_create_regions (surface_pattern->surface,
+							    analysis);
+    if (status == CAIRO_STATUS_SUCCESS)
+	status = analysis->status;
 
     surface->ctm = old_ctm;
     surface->has_ctm = old_has_ctm;
+    surface->current_clip = old_clip;
+    surface->width = old_width;
+    surface->height = old_height;
 
     return status;
 }
 
 static cairo_int_status_t
-_add_operation (cairo_analysis_surface_t *surface,
-		cairo_rectangle_int_t    *rect,
-		cairo_int_status_t        backend_status)
+_add_operation  (cairo_analysis_surface_t *surface,
+		 cairo_rectangle_int_t    *rect,
+		 cairo_int_status_t        backend_status)
 {
     cairo_int_status_t status;
     cairo_box_t bbox;
 
     if (rect->width == 0 || rect->height == 0) {
 	/* Even though the operation is not visible we must be careful
 	 * to not allow unsupported operations to be replayed to the
 	 * backend during CAIRO_PAGINATED_MODE_RENDER */
@@ -144,43 +169,36 @@ static cairo_int_status_t
 	{
 	    return CAIRO_INT_STATUS_IMAGE_FALLBACK;
 	}
     }
 
     _cairo_box_from_rectangle (&bbox, rect);
 
     if (surface->has_ctm) {
-	int tx, ty;
 
-	if (_cairo_matrix_is_integer_translation (&surface->ctm, &tx, &ty)) {
-	    rect->x += tx;
-	    rect->y += ty;
-	} else {
-	    _cairo_matrix_transform_bounding_box_fixed (&surface->ctm,
-							&bbox, NULL);
+	_cairo_matrix_transform_bounding_box_fixed (&surface->ctm, &bbox, NULL);
 
-	    if (bbox.p1.x == bbox.p2.x || bbox.p1.y == bbox.p2.y) {
-		/* Even though the operation is not visible we must be
-		 * careful to not allow unsupported operations to be
-		 * replayed to the backend during
-		 * CAIRO_PAGINATED_MODE_RENDER */
-		if (backend_status == CAIRO_STATUS_SUCCESS ||
-		    backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
-		{
-		    return CAIRO_STATUS_SUCCESS;
-		}
-		else
-		{
-		    return CAIRO_INT_STATUS_IMAGE_FALLBACK;
-		}
+	if (bbox.p1.x == bbox.p2.x || bbox.p1.y == bbox.p2.y) {
+	    /* Even though the operation is not visible we must be
+	     * careful to not allow unsupported operations to be
+	     * replayed to the backend during
+	     * CAIRO_PAGINATED_MODE_RENDER */
+	    if (backend_status == CAIRO_STATUS_SUCCESS ||
+		backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
+	    {
+		return CAIRO_STATUS_SUCCESS;
 	    }
+	    else
+	    {
+		return CAIRO_INT_STATUS_IMAGE_FALLBACK;
+	    }
+	}
 
-	    _cairo_box_round_to_rectangle (&bbox, rect);
-	}
+	_cairo_box_round_to_rectangle (&bbox, rect);
     }
 
     if (surface->first_op) {
 	surface->first_op = FALSE;
 	surface->page_bbox = bbox;
     } else {
 	if (bbox.p1.x < surface->page_bbox.p1.x)
 	    surface->page_bbox.p1.x = bbox.p1.x;
@@ -211,28 +229,29 @@ static cairo_int_status_t
 	    backend_status = CAIRO_STATUS_SUCCESS;
     }
 
     if (backend_status == CAIRO_STATUS_SUCCESS) {
 	/* Add the operation to the supported region. Operations in
 	 * this region will be emitted as native operations.
 	 */
 	surface->has_supported = TRUE;
-	return cairo_region_union_rectangle (&surface->supported_region, rect);
+	status = cairo_region_union_rectangle (&surface->supported_region, rect);
+	return status;
     }
 
     /* Add the operation to the unsupported region. This region will
      * be painted as an image after all native operations have been
      * emitted.
      */
     surface->has_unsupported = TRUE;
     status = cairo_region_union_rectangle (&surface->fallback_region, rect);
 
     /* The status CAIRO_INT_STATUS_IMAGE_FALLBACK is used to indicate
-     * unsupported operations to the recording surface as using
+     * unsupported operations to the meta surface as using
      * CAIRO_INT_STATUS_UNSUPPORTED would cause cairo-surface to
      * invoke the cairo-surface-fallback path then return
      * CAIRO_STATUS_SUCCESS.
      */
     if (status == CAIRO_STATUS_SUCCESS)
 	return CAIRO_INT_STATUS_IMAGE_FALLBACK;
     else
 	return status;
@@ -246,342 +265,360 @@ static cairo_status_t
     _cairo_region_fini (&surface->supported_region);
     _cairo_region_fini (&surface->fallback_region);
 
     cairo_surface_destroy (surface->target);
 
     return CAIRO_STATUS_SUCCESS;
 }
 
-static cairo_bool_t
+static cairo_int_status_t
+_cairo_analysis_surface_intersect_clip_path (void		*abstract_surface,
+					     cairo_path_fixed_t *path,
+					     cairo_fill_rule_t   fill_rule,
+					     double		 tolerance,
+					     cairo_antialias_t   antialias)
+{
+    cairo_analysis_surface_t *surface = abstract_surface;
+
+    if (path == NULL) {
+	surface->current_clip.x = 0;
+	surface->current_clip.y = 0;
+	surface->current_clip.width  = surface->width;
+	surface->current_clip.height = surface->height;
+    } else {
+	cairo_rectangle_int_t extents;
+	cairo_bool_t is_empty;
+
+	_cairo_path_fixed_approximate_clip_extents (path, &extents);
+	is_empty = _cairo_rectangle_intersect (&surface->current_clip,
+					       &extents);
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
 _cairo_analysis_surface_get_extents (void			*abstract_surface,
 				     cairo_rectangle_int_t	*rectangle)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
 
     return _cairo_surface_get_extents (surface->target, rectangle);
 }
 
-static void
-_rectangle_intersect_clip (cairo_rectangle_int_t *extents, cairo_clip_t *clip)
-{
-    const cairo_rectangle_int_t *clip_extents;
-    cairo_bool_t is_empty;
-
-    clip_extents = NULL;
-    if (clip != NULL)
-	clip_extents = _cairo_clip_get_extents (clip);
-
-    if (clip_extents != NULL)
-	is_empty = _cairo_rectangle_intersect (extents, clip_extents);
-}
-
-static void
-_cairo_analysis_surface_operation_extents (cairo_analysis_surface_t *surface,
-					   cairo_operator_t op,
-					   const cairo_pattern_t *source,
-					   cairo_clip_t *clip,
-					   cairo_rectangle_int_t *extents)
-{
-    cairo_bool_t is_empty;
-
-    is_empty = _cairo_surface_get_extents (&surface->base, extents);
-
-    if (_cairo_operator_bounded_by_source (op)) {
-	cairo_rectangle_int_t source_extents;
-
-	_cairo_pattern_get_extents (source, &source_extents);
-	is_empty = _cairo_rectangle_intersect (extents, &source_extents);
-    }
-
-    _rectangle_intersect_clip (extents, clip);
-}
-
 static cairo_int_status_t
 _cairo_analysis_surface_paint (void			*abstract_surface,
 			       cairo_operator_t		op,
 			       const cairo_pattern_t	*source,
-			       cairo_clip_t		*clip)
+			       cairo_rectangle_int_t    *paint_extents)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
-    cairo_status_t	     backend_status;
+    cairo_status_t	     status, backend_status;
     cairo_rectangle_int_t  extents;
+    cairo_bool_t is_empty;
 
-    if (surface->target->backend->paint == NULL) {
+    if (!surface->target->backend->paint)
 	backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
-    } else {
-	backend_status =
-	    surface->target->backend->paint (surface->target,
-					     op, source, clip);
-	if (_cairo_status_is_error (backend_status))
-	    return backend_status;
+    else
+	backend_status = (*surface->target->backend->paint) (surface->target, op,
+                                                             source, NULL);
+
+    if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
+	backend_status = _analyze_meta_surface_pattern (surface, source);
+
+    status = _cairo_surface_get_extents (&surface->base, &extents);
+    if (_cairo_status_is_error (status))
+	return status;
+
+    if (_cairo_operator_bounded_by_source (op)) {
+	cairo_rectangle_int_t source_extents;
+
+	status = _cairo_pattern_get_extents (source, &source_extents);
+	if (unlikely (status))
+	    return status;
+
+	is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
     }
 
-    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
-	backend_status = _analyze_recording_surface_pattern (surface, source);
+    is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
+    if (paint_extents)
+	*paint_extents = extents;
 
-    _cairo_analysis_surface_operation_extents (surface,
-					       op, source, clip,
-					       &extents);
+    status = _add_operation (surface, &extents, backend_status);
 
-    return _add_operation (surface, &extents, backend_status);
+    return status;
 }
 
 static cairo_int_status_t
-_cairo_analysis_surface_mask (void			*abstract_surface,
-			      cairo_operator_t		 op,
+_cairo_analysis_surface_mask (void		*abstract_surface,
+			      cairo_operator_t	 op,
 			      const cairo_pattern_t	*source,
 			      const cairo_pattern_t	*mask,
-			      cairo_clip_t		*clip)
+			      cairo_rectangle_int_t 	*mask_extents)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
-    cairo_int_status_t	      backend_status;
+    cairo_int_status_t	      status, backend_status;
     cairo_rectangle_int_t   extents;
     cairo_bool_t is_empty;
 
-    if (surface->target->backend->mask == NULL) {
+    if (!surface->target->backend->mask)
 	backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
-    } else {
-	backend_status =
-	    surface->target->backend->mask (surface->target,
-					    op, source, mask, clip);
-	if (_cairo_status_is_error (backend_status))
-	    return backend_status;
-    }
+    else
+	backend_status = (*surface->target->backend->mask) (surface->target, op,
+                                                            source, mask, NULL);
 
-    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) {
+    if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN) {
 	cairo_int_status_t backend_source_status = CAIRO_STATUS_SUCCESS;
 	cairo_int_status_t backend_mask_status = CAIRO_STATUS_SUCCESS;
 
 	if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
 	    const cairo_surface_pattern_t *surface_pattern = (const cairo_surface_pattern_t *) source;
-	    if (_cairo_surface_is_recording (surface_pattern->surface)) {
+	    if (_cairo_surface_is_meta (surface_pattern->surface)) {
 		backend_source_status =
-		    _analyze_recording_surface_pattern (surface, source);
+		    _analyze_meta_surface_pattern (surface, source);
 		if (_cairo_status_is_error (backend_source_status))
 		    return backend_source_status;
 	    }
 	}
 
 	if (mask->type == CAIRO_PATTERN_TYPE_SURFACE) {
 	    cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) mask;
-	    if (_cairo_surface_is_recording (surface_pattern->surface)) {
+	    if (_cairo_surface_is_meta (surface_pattern->surface)) {
 		backend_mask_status =
-		    _analyze_recording_surface_pattern (surface, mask);
+		    _analyze_meta_surface_pattern (surface, mask);
 		if (_cairo_status_is_error (backend_mask_status))
 		    return backend_mask_status;
 	    }
 	}
 
 	backend_status =
 	    _cairo_analysis_surface_merge_status (backend_source_status,
 						  backend_mask_status);
     }
 
-    _cairo_analysis_surface_operation_extents (surface,
-					       op, source, clip,
-					       &extents);
+    status = _cairo_surface_get_extents (&surface->base, &extents);
+    if (_cairo_status_is_error (status))
+	return status;
+
+    if (_cairo_operator_bounded_by_source (op)) {
+	cairo_rectangle_int_t source_extents;
+
+	status = _cairo_pattern_get_extents (source, &source_extents);
+	if (unlikely (status))
+	    return status;
+
+	is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
+    }
 
     if (_cairo_operator_bounded_by_mask (op)) {
 	cairo_rectangle_int_t mask_extents;
 
-	_cairo_pattern_get_extents (mask, &mask_extents);
+	status = _cairo_pattern_get_extents (mask, &mask_extents);
+	if (unlikely (status))
+	    return status;
+
 	is_empty = _cairo_rectangle_intersect (&extents, &mask_extents);
-
     }
 
-    return _add_operation (surface, &extents, backend_status);
+    is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
+    if (mask_extents)
+	*mask_extents = extents;
+
+    status = _add_operation (surface, &extents, backend_status);
+
+    return 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,
 				double			 tolerance,
 				cairo_antialias_t	 antialias,
-				cairo_clip_t		*clip)
+				cairo_rectangle_int_t   *stroke_extents)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
-    cairo_status_t	     backend_status;
+    cairo_status_t	     status, backend_status;
     cairo_rectangle_int_t    extents;
     cairo_bool_t             is_empty;
 
-    if (surface->target->backend->stroke == NULL) {
+    if (!surface->target->backend->stroke)
 	backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
-    } else {
-	backend_status =
-	    surface->target->backend->stroke (surface->target, op,
-					      source, path, style,
-					      ctm, ctm_inverse,
-					      tolerance, antialias,
-					      clip);
-	if (_cairo_status_is_error (backend_status))
-	    return backend_status;
+    else
+	backend_status = (*surface->target->backend->stroke) (surface->target, op,
+							      source, path, style,
+							      ctm, ctm_inverse,
+							      tolerance, antialias, NULL);
+
+    if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
+	backend_status = _analyze_meta_surface_pattern (surface, source);
+
+    status = _cairo_surface_get_extents (&surface->base, &extents);
+    if (_cairo_status_is_error (status))
+	return status;
+
+    if (_cairo_operator_bounded_by_source (op)) {
+	cairo_rectangle_int_t source_extents;
+
+	status = _cairo_pattern_get_extents (source, &source_extents);
+	if (unlikely (status))
+	    return status;
+
+	is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
     }
 
-    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
-	backend_status = _analyze_recording_surface_pattern (surface, source);
-
-    _cairo_analysis_surface_operation_extents (surface,
-					       op, source, clip,
-					       &extents);
+    is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
 
     if (_cairo_operator_bounded_by_mask (op)) {
 	cairo_rectangle_int_t mask_extents;
 
-	/* If the backend can handle the stroke, then mark the approximate
-	 * extents of the operation. However, if we need to fallback in order
-	 * to draw the stroke, then ensure that the fallback is as tight as
-	 * possible -- both to minimise output file size and to ensure good
-	 * quality printed output for neighbouring regions.
-	 */
-	if (backend_status == CAIRO_STATUS_SUCCESS) {
-	    _cairo_path_fixed_approximate_stroke_extents (path,
-							  style, ctm,
-							  &mask_extents);
-	} else {
-	    cairo_status_t status;
-
-	    status = _cairo_path_fixed_stroke_extents (path, style,
-						       ctm, ctm_inverse,
-						       tolerance,
-						       &mask_extents);
-	    if (unlikely (status))
-		return status;
-	}
+	_cairo_path_fixed_approximate_stroke_extents (path,
+						      style, ctm,
+						      &mask_extents);
 
 	is_empty = _cairo_rectangle_intersect (&extents, &mask_extents);
     }
+    if (stroke_extents)
+	*stroke_extents = extents;
 
-    return _add_operation (surface, &extents, backend_status);
+    status = _add_operation (surface, &extents, backend_status);
+
+    return status;
 }
 
 static cairo_int_status_t
 _cairo_analysis_surface_fill (void			*abstract_surface,
 			      cairo_operator_t		 op,
 			      const cairo_pattern_t	*source,
 			      cairo_path_fixed_t	*path,
 			      cairo_fill_rule_t		 fill_rule,
 			      double			 tolerance,
 			      cairo_antialias_t		 antialias,
-			      cairo_clip_t		*clip)
+			      cairo_rectangle_int_t     *fill_extents)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
-    cairo_status_t	     backend_status;
+    cairo_status_t	     status, backend_status;
     cairo_rectangle_int_t    extents;
     cairo_bool_t             is_empty;
 
-    if (surface->target->backend->fill == NULL) {
+    if (!surface->target->backend->fill)
 	backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
-    } else {
-	backend_status =
-	    surface->target->backend->fill (surface->target, op,
-					    source, path, fill_rule,
-					    tolerance, antialias,
-					    clip);
-	if (_cairo_status_is_error (backend_status))
-	    return backend_status;
+    else
+	backend_status = (*surface->target->backend->fill) (surface->target, op,
+						    source, path, fill_rule,
+							    tolerance, antialias, NULL);
+
+    if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
+	backend_status = _analyze_meta_surface_pattern (surface, source);
+
+    status = _cairo_surface_get_extents (&surface->base, &extents);
+    if (_cairo_status_is_error (status))
+	return status;
+
+    if (_cairo_operator_bounded_by_source (op)) {
+	cairo_rectangle_int_t source_extents;
+
+	status = _cairo_pattern_get_extents (source, &source_extents);
+	if (unlikely (status))
+	    return status;
+
+	is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
     }
 
-    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
-	backend_status = _analyze_recording_surface_pattern (surface, source);
-
-    _cairo_analysis_surface_operation_extents (surface,
-					       op, source, clip,
-					       &extents);
+    is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
 
     if (_cairo_operator_bounded_by_mask (op)) {
 	cairo_rectangle_int_t mask_extents;
 
-	/* We want speed for the likely case where the operation can be
-	 * performed natively, but accuracy if we have to resort to
-	 * using images.
-	 */
-	if (backend_status == CAIRO_STATUS_SUCCESS) {
-	    _cairo_path_fixed_approximate_fill_extents (path, &mask_extents);
-	} else {
-	     _cairo_path_fixed_fill_extents (path, fill_rule, tolerance,
-					     &mask_extents);
-	}
+	_cairo_path_fixed_approximate_fill_extents (path,
+						    &mask_extents);
+
 	is_empty = _cairo_rectangle_intersect (&extents, &mask_extents);
     }
+    if (fill_extents)
+	*fill_extents = extents;
 
-    return _add_operation (surface, &extents, backend_status);
+    status = _add_operation (surface, &extents, backend_status);
+
+    return status;
 }
 
 static cairo_int_status_t
 _cairo_analysis_surface_show_glyphs (void		  *abstract_surface,
 				     cairo_operator_t	   op,
 				     const cairo_pattern_t *source,
 				     cairo_glyph_t	  *glyphs,
 				     int		   num_glyphs,
 				     cairo_scaled_font_t  *scaled_font,
-				     cairo_clip_t         *clip,
-				     int                  *remaining_glyphs)
+				     int                  *remaining_glyphs,
+				     cairo_rectangle_int_t *show_glyphs_extents)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
     cairo_status_t	     status, backend_status;
     cairo_rectangle_int_t    extents, glyph_extents;
     cairo_bool_t             is_empty;
 
     /* Adapted from _cairo_surface_show_glyphs */
-    if (surface->target->backend->show_glyphs != NULL) {
-	backend_status =
-	    surface->target->backend->show_glyphs (surface->target, op,
-						   source,
-						   glyphs, num_glyphs,
-						   scaled_font,
-						   clip,
-						   remaining_glyphs);
-	if (_cairo_status_is_error (backend_status))
-	    return backend_status;
-    }
-    else if (surface->target->backend->show_text_glyphs != NULL)
-    {
-	backend_status =
-	    surface->target->backend->show_text_glyphs (surface->target, op,
-							source,
-							NULL, 0,
-							glyphs, num_glyphs,
-							NULL, 0,
-							FALSE,
-							scaled_font,
-							clip);
-	if (_cairo_status_is_error (backend_status))
-	    return backend_status;
-    }
+    if (surface->target->backend->show_glyphs)
+	backend_status = (*surface->target->backend->show_glyphs) (surface->target, op,
+								   source,
+								   glyphs, num_glyphs,
+								   scaled_font,
+								   remaining_glyphs, NULL);
+    else if (surface->target->backend->show_text_glyphs)
+	backend_status = surface->target->backend->show_text_glyphs (surface->target, op,
+								     source,
+								     NULL, 0,
+								     glyphs, num_glyphs,
+								     NULL, 0,
+								     FALSE,
+								     scaled_font, NULL);
     else
-    {
 	backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
+
+    if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
+	backend_status = _analyze_meta_surface_pattern (surface, source);
+
+    status = _cairo_surface_get_extents (&surface->base, &extents);
+    if (_cairo_status_is_error (status))
+	return status;
+
+    if (_cairo_operator_bounded_by_source (op)) {
+	cairo_rectangle_int_t source_extents;
+
+	status = _cairo_pattern_get_extents (source, &source_extents);
+	if (unlikely (status))
+	    return status;
+
+	is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
     }
 
-    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
-	backend_status = _analyze_recording_surface_pattern (surface, source);
-
-    _cairo_analysis_surface_operation_extents (surface,
-					       op, source, clip,
-					       &extents);
+    is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
 
     if (_cairo_operator_bounded_by_mask (op)) {
 	status = _cairo_scaled_font_glyph_device_extents (scaled_font,
 							  glyphs,
 							  num_glyphs,
-							  &glyph_extents,
-							  NULL);
+							  &glyph_extents);
 	if (unlikely (status))
 	    return status;
 
 	is_empty = _cairo_rectangle_intersect (&extents, &glyph_extents);
     }
+    if (show_glyphs_extents)
+	*show_glyphs_extents = extents;
 
-    return _add_operation (surface, &extents, backend_status);
+    status = _add_operation (surface, &extents, backend_status);
+
+    return status;
 }
 
 static cairo_bool_t
 _cairo_analysis_surface_has_show_text_glyphs (void *abstract_surface)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
 
     return cairo_surface_has_show_text_glyphs (surface->target);
@@ -594,78 +631,80 @@ static cairo_int_status_t
 					  const char		    *utf8,
 					  int			     utf8_len,
 					  cairo_glyph_t		    *glyphs,
 					  int			     num_glyphs,
 					  const cairo_text_cluster_t *clusters,
 					  int			     num_clusters,
 					  cairo_text_cluster_flags_t cluster_flags,
 					  cairo_scaled_font_t	    *scaled_font,
-					  cairo_clip_t		    *clip)
+					  cairo_rectangle_int_t     *show_text_glyphs_extents)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
     cairo_status_t	     status, backend_status;
     cairo_rectangle_int_t    extents, glyph_extents;
     cairo_bool_t             is_empty;
 
     /* Adapted from _cairo_surface_show_glyphs */
     backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
-    if (surface->target->backend->show_text_glyphs != NULL) {
-	backend_status =
-	    surface->target->backend->show_text_glyphs (surface->target, op,
-							source,
-							utf8, utf8_len,
-							glyphs, num_glyphs,
-							clusters, num_clusters,
-							cluster_flags,
-							scaled_font,
-							clip);
-	if (_cairo_status_is_error (backend_status))
-	    return backend_status;
-    }
-    if (backend_status == CAIRO_INT_STATUS_UNSUPPORTED &&
-	surface->target->backend->show_glyphs != NULL)
-    {
+    if (surface->target->backend->show_text_glyphs)
+	backend_status = surface->target->backend->show_text_glyphs (surface->target, op,
+								     source,
+								     utf8, utf8_len,
+								     glyphs, num_glyphs,
+								     clusters, num_clusters, cluster_flags,
+								     scaled_font, NULL);
+    if (backend_status == CAIRO_INT_STATUS_UNSUPPORTED && surface->target->backend->show_glyphs) {
 	int remaining_glyphs = num_glyphs;
-	backend_status =
-	    surface->target->backend->show_glyphs (surface->target, op,
-						   source,
-						   glyphs, num_glyphs,
-						   scaled_font,
-						   clip,
-						   &remaining_glyphs);
-	if (_cairo_status_is_error (backend_status))
-	    return backend_status;
-
+	backend_status = surface->target->backend->show_glyphs (surface->target, op,
+								source,
+								glyphs, num_glyphs,
+								scaled_font,
+								&remaining_glyphs, NULL);
 	glyphs += num_glyphs - remaining_glyphs;
 	num_glyphs = remaining_glyphs;
 	if (remaining_glyphs == 0)
 	    backend_status = CAIRO_STATUS_SUCCESS;
     }
 
-    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
-	backend_status = _analyze_recording_surface_pattern (surface, source);
+    if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
+	backend_status = _analyze_meta_surface_pattern (surface, source);
+
+    status = _cairo_surface_get_extents (&surface->base, &extents);
+    if (_cairo_status_is_error (status))
+	return status;
 
-    _cairo_analysis_surface_operation_extents (surface,
-					       op, source, clip,
-					       &extents);
+    if (_cairo_operator_bounded_by_source (op)) {
+	cairo_rectangle_int_t source_extents;
+
+	status = _cairo_pattern_get_extents (source, &source_extents);
+	if (unlikely (status))
+	    return status;
+
+	is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
+    }
+
+    is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
 
     if (_cairo_operator_bounded_by_mask (op)) {
 	status = _cairo_scaled_font_glyph_device_extents (scaled_font,
 							  glyphs,
 							  num_glyphs,
-							  &glyph_extents,
-							  NULL);
+							  &glyph_extents);
 	if (unlikely (status))
 	    return status;
 
 	is_empty = _cairo_rectangle_intersect (&extents, &glyph_extents);
     }
+    if (show_text_glyphs_extents)
+	*show_text_glyphs_extents = extents;
 
-    return _add_operation (surface, &extents, backend_status);
+    status = _add_operation (surface, &extents, backend_status);
+
+    return status;
 }
 
 static const cairo_surface_backend_t cairo_analysis_surface_backend = {
     CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS,
     NULL, /* create_similar */
     _cairo_analysis_surface_finish,
     NULL, /* acquire_source_image */
     NULL, /* release_source_image */
@@ -674,39 +713,44 @@ static const cairo_surface_backend_t cai
     NULL, /* clone_similar */
     NULL, /* composite */
     NULL, /* fill_rectangles */
     NULL, /* composite_trapezoids */
     NULL, /* create_span_renderer */
     NULL, /* check_span_renderer */
     NULL, /* copy_page */
     NULL, /* show_page */
+    NULL, /* set_clip_region */
+    _cairo_analysis_surface_intersect_clip_path,
     _cairo_analysis_surface_get_extents,
     NULL, /* old_show_glyphs */
     NULL, /* get_font_options */
     NULL, /* flush */
     NULL, /* mark_dirty_rectangle */
     NULL, /* scaled_font_fini */
     NULL, /* scaled_glyph_fini */
     _cairo_analysis_surface_paint,
     _cairo_analysis_surface_mask,
     _cairo_analysis_surface_stroke,
     _cairo_analysis_surface_fill,
     _cairo_analysis_surface_show_glyphs,
     NULL, /* snapshot */
     NULL, /* is_similar */
+    NULL, /* reset */
     NULL, /* fill_stroke */
     NULL, /* create_solid_pattern_surface */
     NULL, /* can_repaint_solid_pattern_surface */
     _cairo_analysis_surface_has_show_text_glyphs,
     _cairo_analysis_surface_show_text_glyphs
 };
 
 cairo_surface_t *
-_cairo_analysis_surface_create (cairo_surface_t		*target)
+_cairo_analysis_surface_create (cairo_surface_t		*target,
+				int			 width,
+				int			 height)
 {
     cairo_analysis_surface_t *surface;
     cairo_status_t status;
 
     status = target->status;
     if (unlikely (status))
 	return _cairo_surface_create_in_error (status);
 
@@ -714,48 +758,62 @@ cairo_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_CONTENT_COLOR_ALPHA);
 
+    surface->width = width;
+    surface->height = height;
     cairo_matrix_init_identity (&surface->ctm);
     surface->has_ctm = FALSE;
 
     surface->target = cairo_surface_reference (target);
     surface->first_op  = TRUE;
     surface->has_supported = FALSE;
     surface->has_unsupported = FALSE;
 
     _cairo_region_init (&surface->supported_region);
     _cairo_region_init (&surface->fallback_region);
 
     surface->page_bbox.p1.x = 0;
     surface->page_bbox.p1.y = 0;
     surface->page_bbox.p2.x = 0;
     surface->page_bbox.p2.y = 0;
 
+    if (width == -1 && height == -1) {
+	surface->current_clip.x      = CAIRO_RECT_INT_MIN;
+	surface->current_clip.y      = CAIRO_RECT_INT_MIN;
+	surface->current_clip.width  = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN;
+	surface->current_clip.height = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN;
+    } else {
+	surface->current_clip.x = 0;
+	surface->current_clip.y = 0;
+	surface->current_clip.width = width;
+	surface->current_clip.height = height;
+    }
+
     return &surface->base;
 }
 
 void
 _cairo_analysis_surface_set_ctm (cairo_surface_t *abstract_surface,
-				 const cairo_matrix_t  *ctm)
+				 cairo_matrix_t  *ctm)
 {
     cairo_analysis_surface_t	*surface;
 
     if (abstract_surface->status)
 	return;
 
     surface = (cairo_analysis_surface_t *) abstract_surface;
 
     surface->ctm = *ctm;
-    surface->has_ctm = ! _cairo_matrix_is_identity (&surface->ctm);
+    surface->has_ctm = !_cairo_matrix_is_identity (&surface->ctm);
 }
 
 void
 _cairo_analysis_surface_get_ctm (cairo_surface_t *abstract_surface,
 				 cairo_matrix_t  *ctm)
 {
     cairo_analysis_surface_t	*surface = (cairo_analysis_surface_t *) abstract_surface;
 
@@ -809,59 +867,63 @@ void
 static cairo_int_status_t
 _return_success (void)
 {
     return CAIRO_STATUS_SUCCESS;
 }
 
 /* These typedefs are just to silence the compiler... */
 typedef cairo_int_status_t
+(*_set_clip_region_func)	(void			*surface,
+				 cairo_region_t		*region);
+
+typedef cairo_int_status_t
 (*_paint_func)			(void			*surface,
 			         cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
-				 cairo_clip_t		*clip);
+				 cairo_rectangle_int_t  *extents);
 
 typedef cairo_int_status_t
 (*_mask_func)			(void			*surface,
 			         cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
 				 const cairo_pattern_t	*mask,
-				 cairo_clip_t		*clip);
+				 cairo_rectangle_int_t  *extents);
 
 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,
 				 double			 tolerance,
 				 cairo_antialias_t	 antialias,
-				 cairo_clip_t		*clip);
+				 cairo_rectangle_int_t  *extents);
 
 typedef cairo_int_status_t
 (*_fill_func)			(void			*surface,
 			         cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
 				 cairo_path_fixed_t	*path,
 				 cairo_fill_rule_t	 fill_rule,
 				 double			 tolerance,
 				 cairo_antialias_t	 antialias,
-				 cairo_clip_t		*clip);
+				 cairo_rectangle_int_t  *extents);
 
 typedef cairo_int_status_t
 (*_show_glyphs_func)		(void			*surface,
 			         cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
 				 cairo_glyph_t		*glyphs,
 				 int			 num_glyphs,
 				 cairo_scaled_font_t	*scaled_font,
-				 cairo_clip_t		*clip,
-				 int			*remaining_glyphs);
+				 int			*remaining_glyphs,
+				 cairo_rectangle_int_t  *extents);
 
 static const cairo_surface_backend_t cairo_null_surface_backend = {
     CAIRO_INTERNAL_SURFACE_TYPE_NULL,
 
     NULL, /* create_similar */
     NULL, /* finish */
     NULL, /* acquire_source_image */
     NULL, /* release_source_image */
@@ -870,30 +932,33 @@ static const cairo_surface_backend_t cai
     NULL, /* clone_similar */
     NULL, /* composite */
     NULL, /* fill_rectangles */
     NULL, /* composite_trapezoids */
     NULL, /* create_span_renderer */
     NULL, /* check_span_renderer */
     NULL, /* copy_page */
     NULL, /* show_page */
+    (_set_clip_region_func) _return_success, /* set_clip_region */
+    NULL, /* intersect_clip_path */
     NULL, /* get_extents */
     NULL, /* old_show_glyphs */
     NULL, /* get_font_options */
     NULL, /* flush */
     NULL, /* mark_dirty_rectangle */
     NULL, /* scaled_font_fini */
     NULL, /* scaled_glyph_fini */
     (_paint_func) _return_success,	    /* paint */
     (_mask_func) _return_success,	    /* mask */
     (_stroke_func) _return_success,	    /* stroke */
     (_fill_func) _return_success,	    /* fill */
     (_show_glyphs_func) _return_success,    /* show_glyphs */
     NULL, /* snapshot */
     NULL, /* is_similar */
+    NULL, /* reset */
     NULL, /* fill_stroke */
     NULL, /* create_solid_pattern_surface */
     NULL, /* can_repaint_solid_pattern_surface */
     NULL, /* has_show_text_glyphs */
     NULL  /* show_text_glyphs */
 };
 
 cairo_surface_t *
--- a/gfx/cairo/cairo/src/cairo-arc.c
+++ b/gfx/cairo/cairo/src/cairo-arc.c
@@ -111,17 +111,17 @@ static int
     double major_axis, max_angle;
 
     /* the error is amplified by at most the length of the
      * major axis of the circle; see cairo-pen.c for a more detailed analysis
      * of this. */
     major_axis = _cairo_matrix_transformed_circle_major_axis (ctm, radius);
     max_angle = _arc_max_angle_for_tolerance_normalized (tolerance / major_axis);
 
-    return ceil (fabs (angle) / max_angle);
+    return (int) ceil (angle / max_angle);
 }
 
 /* We want to draw a single spline approximating a circular arc radius
    R from angle A to angle B. Since we want a symmetric spline that
    matches the endpoints of the arc in position and slope, we know
    that the spline control points must be:
 
 	(R * cos(A), R * sin(A))
--- a/gfx/cairo/cairo/src/cairo-atomic-private.h
+++ b/gfx/cairo/cairo/src/cairo-atomic-private.h
@@ -38,33 +38,24 @@
 #define CAIRO_ATOMIC_PRIVATE_H
 
 # include "cairo-compiler-private.h"
 
 #if HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-/* The autoconf on OpenBSD 4.5 produces the malformed constant name
- * SIZEOF_VOID__ rather than SIZEOF_VOID_P.  Work around that here. */
-#if !defined(SIZEOF_VOID_P) && defined(SIZEOF_VOID__)
-# define SIZEOF_VOID_P SIZEOF_VOID__
-#endif
-
 CAIRO_BEGIN_DECLS
 
 #if HAVE_INTEL_ATOMIC_PRIMITIVES
 
 #define HAS_ATOMIC_OPS 1
 
 typedef int cairo_atomic_int_t;
 
-# define _cairo_atomic_int_get(x) (*x)
-# define _cairo_atomic_int_set(x, value) ((*x) = value)
-
 # 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)
 
 #if SIZEOF_VOID_P==SIZEOF_INT
 typedef int cairo_atomic_intptr_t;
 #elif SIZEOF_VOID_P==SIZEOF_LONG
 typedef long cairo_atomic_intptr_t;
@@ -74,45 +65,16 @@ typedef long long cairo_atomic_intptr_t;
 #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)
 
 #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)
-
-#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_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)
-
-#endif
-
 
 #ifndef HAS_ATOMIC_OPS
 
 typedef int cairo_atomic_int_t;
 
 cairo_private void
 _cairo_atomic_int_inc (int *x);
 
@@ -120,16 +82,19 @@ cairo_private cairo_bool_t
 _cairo_atomic_int_dec_and_test (int *x);
 
 cairo_private int
 _cairo_atomic_int_cmpxchg (int *x, int oldv, int newv);
 
 cairo_private void *
 _cairo_atomic_ptr_cmpxchg (void **x, void *oldv, void *newv);
 
+#endif
+
+
 #ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER
 
 # include "cairo-compiler-private.h"
 
 cairo_private int
 _cairo_atomic_int_get (int *x);
 
 cairo_private void
@@ -137,24 +102,22 @@ cairo_private void
 
 #else
 
 # define _cairo_atomic_int_get(x) (*x)
 # define _cairo_atomic_int_set(x, value) ((*x) = value)
 
 #endif
 
-#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)
+    _cairo_atomic_int_cmpxchg((int *)x, oldv, newv)
 
 #define _cairo_status_set_error(status, err) do { \
     /* hide compiler warnings about cairo_status_t != int (gcc treats its as \
      * an unsigned integer instead, and about ignoring the return value. */  \
-    int ret__ = _cairo_atomic_int_cmpxchg ((cairo_atomic_int_t *) status, CAIRO_STATUS_SUCCESS, err); \
+    int ret__ = _cairo_atomic_int_cmpxchg ((int *) status, CAIRO_STATUS_SUCCESS, err); \
     (void) ret__; \
 } while (0)
 
 CAIRO_END_DECLS
 
 #endif
deleted file mode 100644
--- a/gfx/cairo/cairo/src/cairo-base64-stream.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2005-2007 Emmanuel Pacaud <emmanuel.pacaud@free.fr>
- * Copyright © 2009 Chris Wilson
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Red Hat, Inc.
- *
- * Author(s):
- *	Kristian Høgsberg <krh@redhat.com>
- *	Chris Wilson <chris@chris-wilson.co.uk>
- */
-
-#include "cairoint.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];
-} cairo_base64_stream_t;
-
-static char const base64_table[64] =
-"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-static cairo_status_t
-_cairo_base64_stream_write (cairo_output_stream_t *base,
-			    const unsigned char	  *data,
-			    unsigned int	   length)
-{
-    cairo_base64_stream_t * stream = (cairo_base64_stream_t *) base;
-    unsigned char *src = stream->src;
-    unsigned int i;
-
-    if (stream->in_mem + length < 3) {
-	for (i = 0; i < length; i++) {
-	    src[i + stream->in_mem] = *data++;
-	}
-	stream->in_mem += length;
-	return CAIRO_STATUS_SUCCESS;
-    }
-
-    do {
-	unsigned char dst[4];
-
-	for (i = stream->in_mem; i < 3; i++) {
-	    src[i] = *data++;
-	    length--;
-	}
-	stream->in_mem = 0;
-
-	dst[0] = base64_table[src[0] >> 2];
-	dst[1] = base64_table[(src[0] & 0x03) << 4 | src[1] >> 4];
-	dst[2] = base64_table[(src[1] & 0x0f) << 2 | src[2] >> 6];
-	dst[3] = base64_table[src[2] & 0xfc >> 2];
-	/* Special case for the last missing bits */
-	switch (stream->trailing) {
-	    case 2:
-		dst[2] = '=';
-	    case 1:
-		dst[3] = '=';
-	    default:
-		break;
-	}
-	_cairo_output_stream_write (stream->output, dst, 4);
-    } while (length >= 3);
-
-    for (i = 0; i < length; i++) {
-	src[i] = *data++;
-    }
-    stream->in_mem = length;
-
-    return _cairo_output_stream_get_status (stream->output);
-}
-
-static cairo_status_t
-_cairo_base64_stream_close (cairo_output_stream_t *base)
-{
-    cairo_base64_stream_t *stream = (cairo_base64_stream_t *) base;
-    cairo_status_t status = CAIRO_STATUS_SUCCESS;
-
-    if (stream->in_mem > 0) {
-	memset (stream->src + stream->in_mem, 0, 3 - stream->in_mem);
-	stream->trailing = 3 - stream->in_mem;
-	stream->in_mem = 3;
-	status = _cairo_base64_stream_write (base, NULL, 0);
-    }
-
-    return status;
-}
-
-cairo_output_stream_t *
-_cairo_base64_stream_create (cairo_output_stream_t *output)
-{
-    cairo_base64_stream_t *stream;
-
-    if (output->status)
-	return _cairo_output_stream_create_in_error (output->status);
-
-    stream = malloc (sizeof (cairo_base64_stream_t));
-    if (unlikely (stream == NULL)) {
-	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
-	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
-    }
-
-    _cairo_output_stream_init (&stream->base,
-			       _cairo_base64_stream_write,
-			       NULL,
-			       _cairo_base64_stream_close);
-
-    stream->output = output;
-    stream->in_mem = 0;
-    stream->trailing = 0;
-
-    return &stream->base;
-}
--- a/gfx/cairo/cairo/src/cairo-base85-stream.c
+++ b/gfx/cairo/cairo/src/cairo-base85-stream.c
@@ -97,16 +97,19 @@ static cairo_status_t
     unsigned char five_tuple[5];
 
     if (stream->pending) {
 	memset (stream->four_tuple + stream->pending, 0, 4 - stream->pending);
 	_expand_four_tuple_to_five (stream->four_tuple, five_tuple, NULL);
 	_cairo_output_stream_write (stream->output, five_tuple, stream->pending + 1);
     }
 
+    /* Mark end of base85 data */
+    _cairo_output_stream_printf (stream->output, "~>");
+
     return _cairo_output_stream_get_status (stream->output);
 }
 
 cairo_output_stream_t *
 _cairo_base85_stream_create (cairo_output_stream_t *output)
 {
     cairo_base85_stream_t *stream;
 
deleted file mode 100644
--- a/gfx/cairo/cairo/src/cairo-bentley-ottmann-rectangular.c
+++ /dev/null
@@ -1,739 +0,0 @@
-/*
- * Copyright © 2004 Carl Worth
- * Copyright © 2006 Red Hat, Inc.
- * Copyright © 2009 Chris Wilson
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Carl Worth
- *
- * 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-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;
-
-/* 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;
-    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;
-};
-
-/* 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];
-} 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;
-    int32_t current_y;
-    int32_t last_y;
-} cairo_bo_sweep_line_t;
-
-#define DEBUG_TRAPS 0
-
-#if DEBUG_TRAPS
-static void
-dump_traps (cairo_traps_t *traps, const char *filename)
-{
-    FILE *file;
-    int n;
-
-    if (getenv ("CAIRO_DEBUG_TRAPS") == NULL)
-	return;
-
-    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,
-		     traps->traps[n].left.p1.y,
-		     traps->traps[n].left.p2.x,
-		     traps->traps[n].left.p2.y,
-		     traps->traps[n].right.p1.x,
-		     traps->traps[n].right.p1.y,
-		     traps->traps[n].right.p2.x,
-		     traps->traps[n].right.p2.y);
-	}
-	fprintf (file, "\n");
-	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)
-{
-    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)
-{
-    return a->bottom - b->bottom;
-}
-
-static inline void
-_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)
-{
-    if (pq->elements != pq->elements_embedded)
-	free (pq->elements);
-}
-
-static cairo_status_t
-_pqueue_grow (pqueue_t *pq)
-{
-    cairo_bo_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 *));
-	if (unlikely (new_elements == NULL))
-	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
-	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 *));
-	if (unlikely (new_elements == NULL))
-	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-    }
-
-    pq->elements = new_elements;
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static inline cairo_status_t
-_pqueue_push (pqueue_t *pq, cairo_bo_rectangle_t *rectangle)
-{
-    cairo_bo_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;
-    }
-
-    elements = pq->elements;
-
-    for (i = ++pq->size;
-	 i != PQ_FIRST_ENTRY &&
-	 _cairo_bo_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)
-{
-    cairo_bo_rectangle_t **elements = pq->elements;
-    cairo_bo_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)
-	{
-	    child++;
-	}
-
-	if (_cairo_bo_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)
-{
-    return *sweep_line->rectangles++;
-}
-
-static inline cairo_bo_rectangle_t *
-_cairo_bo_rectangle_peek_stop (cairo_bo_sweep_line_t *sweep_line)
-{
-    return sweep_line->stop.elements[PQ_FIRST_ENTRY];
-}
-
-CAIRO_COMBSORT_DECLARE (_cairo_bo_rectangle_sort,
-			cairo_bo_rectangle_t *,
-			cairo_bo_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)
-{
-    _cairo_bo_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->current_y = INT32_MIN;
-    sweep_line->last_y = INT32_MIN;
-
-    _pqueue_init (&sweep_line->stop);
-}
-
-static void
-_cairo_bo_sweep_line_fini (cairo_bo_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);
-}
-
-static cairo_status_t
-_cairo_bo_edge_end_trap (cairo_bo_edge_t	*left,
-			 int32_t		 bot,
-			 cairo_traps_t	        *traps)
-{
-    cairo_bo_trap_t *trap = &left->deferred_trap;
-
-    /* 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);
-    }
-
-    trap->right = NULL;
-
-    return _cairo_traps_status (traps);
-}
-
-/* Start a new trapezoid at the given top y coordinate, whose edges
- * are `edge' and `edge->next'. If `edge' already has a trapezoid,
- * then either add it to the traps in `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_status_t status;
-
-    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) {
-	    /* 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);
-	if (unlikely (status))
-	    return status;
-    }
-
-    if (right != NULL && left->x != right->x) {
-	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_sweep_line_t	*sweep,
-			cairo_fill_rule_t	 fill_rule,
-			cairo_traps_t	        *traps)
-{
-    int top = sweep->current_y;
-    cairo_list_t *pos = &sweep->sweep;
-    cairo_status_t status;
-
-    if (sweep->last_y == sweep->current_y)
-	return CAIRO_STATUS_SUCCESS;
-
-    if (fill_rule == CAIRO_FILL_RULE_WINDING) {
-	do {
-	    cairo_bo_edge_t *left, *right;
-	    int in_out;
-
-	    pos = pos->next;
-	    if (pos == &sweep->sweep)
-		break;
-
-	    left = link_to_edge (pos);
-	    in_out = left->dir;
-
-	    /* Check if there is a co-linear edge with an existing trap */
-	    if (left->deferred_trap.right == NULL) {
-		right = link_to_edge (pos->next);
-		while (unlikely (right->x == left->x)) {
-		    if (right->deferred_trap.right != NULL) {
-			/* continuation on left */
-			left->deferred_trap = right->deferred_trap;
-			right->deferred_trap.right = NULL;
-			break;
-		    }
-
-		    if (right->link.next == &sweep->sweep)
-			break;
-		    right = link_to_edge (right->link.next);
-		}
-	    }
-
-	    /* 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;
-		}
-
-		in_out += right->dir;
-		if (in_out == 0) {
-		    /* skip co-linear edges */
-		    if (likely (right->link.next == &sweep->sweep ||
-				right->x != link_to_edge (right->link.next)->x))
-		    {
-			break;
-		    }
-		}
-
-		right = link_to_edge (right->link.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;
-
-	    pos = pos->next;
-	    if (pos == &sweep->sweep)
-		break;
-
-	    left = link_to_edge (pos);
-
-	    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;
-		}
-
-		if ((in_out++ & 1) == 0) {
-		    cairo_list_t *next;
-		    cairo_bool_t skip = FALSE;
-
-		    /* skip co-linear edges */
-		    next = pos->next;
-		    if (next != &sweep->sweep)
-			skip = right->x == link_to_edge (next)->x;
-
-		    if (! skip)
-			break;
-		}
-		pos = pos->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);
-    }
-
-    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)
-{
-    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;
-	} else {
-	    cairo_status_t status;
-
-	    status = _cairo_bo_edge_end_trap (edge,
-		                              sweep_line->current_y,
-					      traps);
-	    if (unlikely (status))
-		return status;
-	}
-    }
-
-    if (sweep_line->current_left == &edge->link)
-	sweep_line->current_left = edge->link.prev;
-
-    if (sweep_line->current_right == &edge->link)
-	sweep_line->current_right = edge->link.next;
-
-    cairo_list_del (&edge->link);
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-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)
-{
-    cairo_status_t status;
-
-    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;
-    }
-
-    status = _cairo_bo_sweep_line_delete_edge (sweep_line,
-	                                       &rectangle->left,
-					       traps);
-    if (unlikely (status))
-	return status;
-
-    status = _cairo_bo_sweep_line_delete_edge (sweep_line,
-	                                       &rectangle->right,
-					       traps);
-    if (unlikely (status))
-	return status;
-
-    _pqueue_pop (&sweep_line->stop);
-    return CAIRO_STATUS_SUCCESS;
-}
-
-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)
-{
-    cairo_list_t *pos;
-    cairo_status_t status;
-
-    if (rectangle->top != sweep_line->current_y) {
-	cairo_bo_rectangle_t *stop;
-
-	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;
-
-	    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;
-    }
-
-    /* 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));
-
-    /* left edge */
-    pos = sweep_line->current_left;
-    if (pos == &sweep_line->sweep)
-	pos = sweep_line->sweep.next;
-    if (pos != &sweep_line->sweep) {
-	int cmp;
-
-	if (link_to_edge (pos)->x >= rectangle->right.x) {
-	    pos = rectangle->right.link.prev;
-	    if (pos == &sweep_line->sweep)
-		goto left_done;
-	}
-
-	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);
-	}
-    }
-  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);
-}
-
-static cairo_status_t
-_cairo_bentley_ottmann_tessellate_rectangular (cairo_bo_rectangle_t	**rectangles,
-					       int			  num_rectangles,
-					       cairo_fill_rule_t	  fill_rule,
-					       cairo_traps_t		 *traps)
-{
-    cairo_bo_sweep_line_t sweep_line;
-    cairo_bo_rectangle_t *rectangle;
-    cairo_status_t status = CAIRO_STATUS_SUCCESS;
-
-    _cairo_bo_sweep_line_init (&sweep_line, rectangles, num_rectangles);
-
-    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;
-    }
-
-    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);
-    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;
-    cairo_status_t status;
-    int i;
-
-    if (unlikely (traps->num_traps == 0))
-	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 *));
-	if (unlikely (rectangles == NULL))
-	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
-	rectangles_ptrs = (cairo_bo_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;
-	    rectangles[i].right.dir = -1;
-	} 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].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);
-    traps->is_rectilinear = TRUE;
-    traps->is_rectangular = TRUE;
-
-    if (rectangles != stack_rectangles)
-	free (rectangles);
-
-    dump_traps (traps, "bo-rects-traps-out.txt");
-
-
-    return status;
-}
deleted file mode 100644
--- a/gfx/cairo/cairo/src/cairo-bentley-ottmann-rectilinear.c
+++ /dev/null
@@ -1,582 +0,0 @@
-/*
- * Copyright © 2004 Carl Worth
- * Copyright © 2006 Red Hat, Inc.
- * Copyright © 2008 Chris Wilson
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is Carl Worth
- *
- * 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-combsort-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;
-};
-
-struct _cairo_bo_edge {
-    cairo_edge_t edge;
-    cairo_bo_edge_t *prev;
-    cairo_bo_edge_t *next;
-    cairo_bo_trap_t deferred_trap;
-};
-
-typedef enum {
-    CAIRO_BO_EVENT_TYPE_START,
-    CAIRO_BO_EVENT_TYPE_STOP
-} cairo_bo_event_type_t;
-
-typedef struct _cairo_bo_event {
-    cairo_bo_event_type_t type;
-    cairo_point_t point;
-    cairo_bo_edge_t *edge;
-} cairo_bo_event_t;
-
-typedef struct _cairo_bo_sweep_line {
-    cairo_bo_event_t **events;
-    cairo_bo_edge_t *head;
-    cairo_bo_edge_t *stopped;
-    int32_t current_y;
-    cairo_bo_edge_t *current_edge;
-} cairo_bo_sweep_line_t;
-
-static inline int
-_cairo_point_compare (const cairo_point_t *a,
-		      const cairo_point_t *b)
-{
-    int cmp;
-
-    cmp = a->y - b->y;
-    if (likely (cmp))
-	return cmp;
-
-    return a->x - b->x;
-}
-
-static inline int
-_cairo_bo_edge_compare (const cairo_bo_edge_t	*a,
-			const cairo_bo_edge_t	*b)
-{
-    int cmp;
-
-    cmp = a->edge.line.p1.x - b->edge.line.p1.x;
-    if (likely (cmp))
-	return cmp;
-
-    return b->edge.bottom - a->edge.bottom;
-}
-
-static inline int
-cairo_bo_event_compare (const cairo_bo_event_t *a,
-			const cairo_bo_event_t *b)
-{
-    int cmp;
-
-    cmp = _cairo_point_compare (&a->point, &b->point);
-    if (likely (cmp))
-	return cmp;
-
-    cmp = a->type - b->type;
-    if (cmp)
-	return cmp;
-
-    return a - b;
-}
-
-static inline cairo_bo_event_t *
-_cairo_bo_event_dequeue (cairo_bo_sweep_line_t *sweep_line)
-{
-    return *sweep_line->events++;
-}
-
-CAIRO_COMBSORT_DECLARE (_cairo_bo_event_queue_sort,
-			cairo_bo_event_t *,
-			cairo_bo_event_compare)
-
-static void
-_cairo_bo_sweep_line_init (cairo_bo_sweep_line_t *sweep_line,
-			   cairo_bo_event_t	**events,
-			   int			  num_events)
-{
-    _cairo_bo_event_queue_sort (events, num_events);
-    events[num_events] = NULL;
-    sweep_line->events = events;
-
-    sweep_line->head = NULL;
-    sweep_line->current_y = INT32_MIN;
-    sweep_line->current_edge = NULL;
-}
-
-static void
-_cairo_bo_sweep_line_insert (cairo_bo_sweep_line_t	*sweep_line,
-			     cairo_bo_edge_t		*edge)
-{
-    if (sweep_line->current_edge != NULL) {
-	cairo_bo_edge_t *prev, *next;
-	int cmp;
-
-	cmp = _cairo_bo_edge_compare (sweep_line->current_edge, edge);
-	if (cmp < 0) {
-	    prev = sweep_line->current_edge;
-	    next = prev->next;
-	    while (next != NULL && _cairo_bo_edge_compare (next, edge) < 0)
-		prev = next, next = prev->next;
-
-	    prev->next = edge;
-	    edge->prev = prev;
-	    edge->next = next;
-	    if (next != NULL)
-		next->prev = edge;
-	} else if (cmp > 0) {
-	    next = sweep_line->current_edge;
-	    prev = next->prev;
-	    while (prev != NULL && _cairo_bo_edge_compare (prev, edge) > 0)
-		next = prev, prev = next->prev;
-
-	    next->prev = edge;
-	    edge->next = next;
-	    edge->prev = prev;
-	    if (prev != NULL)
-		prev->next = edge;
-	    else
-		sweep_line->head = edge;
-	} else {
-	    prev = sweep_line->current_edge;
-	    edge->prev = prev;
-	    edge->next = prev->next;
-	    if (prev->next != NULL)
-		prev->next->prev = edge;
-	    prev->next = edge;
-	}
-    } else {
-	sweep_line->head = edge;
-    }
-
-    sweep_line->current_edge = edge;
-}
-
-static void
-_cairo_bo_sweep_line_delete (cairo_bo_sweep_line_t	*sweep_line,
-			     cairo_bo_edge_t	*edge)
-{
-    if (edge->prev != NULL)
-	edge->prev->next = edge->next;
-    else
-	sweep_line->head = edge->next;
-
-    if (edge->next != NULL)
-	edge->next->prev = edge->prev;
-
-    if (sweep_line->current_edge == edge)
-	sweep_line->current_edge = edge->prev ? edge->prev : edge->next;
-}
-
-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_bo_trap_t *trap = &left->deferred_trap;
-
-    /* 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);
-    }
-
-    trap->right = NULL;
-
-    return _cairo_traps_status (traps);
-}
-
-/* Start a new trapezoid at the given top y coordinate, whose edges
- * are `edge' and `edge->next'. If `edge' already has a trapezoid,
- * then either add it to the traps in `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_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);
-	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_bo_edge_t *right;
-    cairo_status_t status;
-
-    if (fill_rule == CAIRO_FILL_RULE_WINDING) {
-	while (left != NULL) {
-	    int in_out;
-
-	    /* Greedily search for the closing edge, so that we generate the
-	     * maximal span width with the minimal number of trapezoids.
-	     */
-	    in_out = left->edge.dir;
-
-	    /* Check if there is a co-linear edge with an existing trap */
-	    right = left->next;
-	    if (left->deferred_trap.right == NULL) {
-		while (right != NULL && right->deferred_trap.right == NULL)
-		    right = right->next;
-
-		if (right != NULL && edges_collinear (left, right)) {
-		    /* continuation on left */
-		    left->deferred_trap = right->deferred_trap;
-		    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);
-		    if (unlikely (status))
-			return status;
-		}
-
-		in_out += right->edge.dir;
-		if (in_out == 0) {
-		    /* skip co-linear edges */
-		    if (right->next == NULL ||
-			! edges_collinear (right, right->next))
-		    {
-			break;
-		    }
-		}
-
-		right = right->next;
-	    }
-
-	    status = _cairo_bo_edge_start_or_continue_trap (left, right,
-							    top, traps);
-	    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);
-		    if (unlikely (status))
-			return status;
-		}
-
-		if ((in_out++ & 1) == 0) {
-		    cairo_bo_edge_t *next;
-		    cairo_bool_t skip = FALSE;
-
-		    /* skip co-linear edges */
-		    next = right->next;
-		    if (next != NULL)
-			skip = edges_collinear (right, next);
-
-		    if (! skip)
-			break;
-		}
-
-		right = right->next;
-	    }
-
-	    status = _cairo_bo_edge_start_or_continue_trap (left, right,
-							    top, traps);
-	    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_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);
-	    if (unlikely (status))
-		return status;
-
-	    sweep_line.current_y = event->point.y;
-	}
-
-	switch (event->type) {
-	case CAIRO_BO_EVENT_TYPE_START:
-	    _cairo_bo_sweep_line_insert (&sweep_line, event->edge);
-	    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);
-		if (unlikely (status))
-		    return status;
-	    }
-
-	    break;
-	}
-    }
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-cairo_status_t
-_cairo_bentley_ottmann_tessellate_rectilinear_polygon (cairo_traps_t	 *traps,
-						       const cairo_polygon_t *polygon,
-						       cairo_fill_rule_t	  fill_rule)
-{
-    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, traps);
-    if (events != stack_events)
-	free (events);
-
-    traps->is_rectilinear = TRUE;
-
-    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)];
-    cairo_bo_edge_t *edges;
-    cairo_status_t status;
-    int i, j, k;
-
-    if (unlikely (traps->num_traps == 0))
-	return CAIRO_STATUS_SUCCESS;
-
-    assert (traps->is_rectilinear);
-
-    i = 4 * traps->num_traps;
-
-    events = stack_events;
-    event_ptrs = stack_event_ptrs;
-    edges = stack_edges;
-    if (i > ARRAY_LENGTH (stack_events)) {
-	events = _cairo_malloc_ab_plus_c (i,
-					  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 + i);
-	edges = (cairo_bo_edge_t *) (event_ptrs + i + 1);
-    }
-
-    for (i = j = k = 0; i < traps->num_traps; i++) {
-	edges[k].edge.top = traps->traps[i].top;
-	edges[k].edge.bottom = traps->traps[i].bottom;
-	edges[k].edge.line = traps->traps[i].left;
-	edges[k].edge.dir = 1;
-	edges[k].deferred_trap.right = NULL;
-	edges[k].prev = NULL;
-	edges[k].next = NULL;
-
-	event_ptrs[j] = &events[j];
-	events[j].type = CAIRO_BO_EVENT_TYPE_START;
-	events[j].point.y = traps->traps[i].top;
-	events[j].point.x = traps->traps[i].left.p1.x;
-	events[j].edge = &edges[k];
-	j++;
-
-	event_ptrs[j] = &events[j];
-	events[j].type = CAIRO_BO_EVENT_TYPE_STOP;
-	events[j].point.y = traps->traps[i].bottom;
-	events[j].point.x = traps->traps[i].left.p1.x;
-	events[j].edge = &edges[k];
-	j++;
-	k++;
-
-	edges[k].edge.top = traps->traps[i].top;
-	edges[k].edge.bottom = traps->traps[i].bottom;
-	edges[k].edge.line = traps->traps[i].right;
-	edges[k].edge.dir = -1;
-	edges[k].deferred_trap.right = NULL;
-	edges[k].prev = NULL;
-	edges[k].next = NULL;
-
-	event_ptrs[j] = &events[j];
-	events[j].type = CAIRO_BO_EVENT_TYPE_START;
-	events[j].point.y = traps->traps[i].top;
-	events[j].point.x = traps->traps[i].right.p1.x;
-	events[j].edge = &edges[k];
-	j++;
-
-	event_ptrs[j] = &events[j];
-	events[j].type = CAIRO_BO_EVENT_TYPE_STOP;
-	events[j].point.y = traps->traps[i].bottom;
-	events[j].point.x = traps->traps[i].right.p1.x;
-	events[j].edge = &edges[k];
-	j++;
-	k++;
-    }
-
-    _cairo_traps_clear (traps);
-    status = _cairo_bentley_ottmann_tessellate_rectilinear (event_ptrs, j,
-							    fill_rule,
-							    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
@@ -1,12 +1,11 @@
 /*
  * Copyright © 2004 Carl Worth
  * Copyright © 2006 Red Hat, Inc.
- * Copyright © 2008 Chris Wilson
  *
  * 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.
@@ -27,224 +26,145 @@
  * 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>
- *	Chris Wilson <chris@chris-wilson.co.uk>
  */
 
 /* Provide definitions for standalone compilation */
 #include "cairoint.h"
 
+#include "cairo-skiplist-private.h"
 #include "cairo-freelist-private.h"
 #include "cairo-combsort-private.h"
 
+#define DEBUG_VALIDATE 0
 #define DEBUG_PRINT_STATE 0
-#define DEBUG_EVENTS 0
-#define DEBUG_TRAPS 0
 
 typedef cairo_point_t cairo_bo_point32_t;
 
+typedef struct _cairo_bo_point128 {
+    cairo_int128_t x;
+    cairo_int128_t y;
+} cairo_bo_point128_t;
+
 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;
 
 typedef struct _cairo_bo_edge cairo_bo_edge_t;
+typedef struct _sweep_line_elt sweep_line_elt_t;
 typedef struct _cairo_bo_trap cairo_bo_trap_t;
+typedef struct _cairo_bo_traps cairo_bo_traps_t;
 
-/* A deferred trapezoid of an edge */
+/* A deferred trapezoid of an edge. */
 struct _cairo_bo_trap {
     cairo_bo_edge_t *right;
     int32_t top;
 };
 
-struct _cairo_bo_edge {
-    cairo_edge_t edge;
-    cairo_bo_edge_t *prev;
-    cairo_bo_edge_t *next;
-    cairo_bo_trap_t deferred_trap;
+struct _cairo_bo_traps {
+    cairo_traps_t *traps;
+    cairo_freelist_t freelist;
+
+    /* These form the closed bounding box of the original input
+     * points. */
+    cairo_fixed_t xmin;
+    cairo_fixed_t ymin;
+    cairo_fixed_t xmax;
+    cairo_fixed_t ymax;
 };
 
-/* the parent is always given by index/2 */
-#define PQ_PARENT_INDEX(i) ((i) >> 1)
-#define PQ_FIRST_ENTRY 1
+struct _cairo_bo_edge {
+    cairo_bo_point32_t top;
+    cairo_bo_point32_t middle;
+    cairo_bo_point32_t bottom;
+    int dir;
+    cairo_bo_edge_t *prev;
+    cairo_bo_edge_t *next;
+    cairo_bo_trap_t *deferred_trap;
+    sweep_line_elt_t *sweep_line_elt;
+};
 
-/* left and right children are index * 2 and (index * 2) +1 respectively */
-#define PQ_LEFT_CHILD_INDEX(i) ((i) << 1)
+struct _sweep_line_elt {
+    cairo_bo_edge_t *edge;
+    skip_elt_t elt;
+};
+
+#define SKIP_ELT_TO_EDGE_ELT(elt)	SKIP_LIST_ELT_TO_DATA (sweep_line_elt_t, (elt))
+#define SKIP_ELT_TO_EDGE(elt) 		(SKIP_ELT_TO_EDGE_ELT (elt)->edge)
 
 typedef enum {
+    CAIRO_BO_STATUS_INTERSECTION,
+    CAIRO_BO_STATUS_PARALLEL,
+    CAIRO_BO_STATUS_NO_INTERSECTION
+} cairo_bo_status_t;
+
+typedef enum {
+    CAIRO_BO_EVENT_TYPE_START,
     CAIRO_BO_EVENT_TYPE_STOP,
-    CAIRO_BO_EVENT_TYPE_INTERSECTION,
-    CAIRO_BO_EVENT_TYPE_START
+    CAIRO_BO_EVENT_TYPE_INTERSECTION
 } cairo_bo_event_type_t;
 
 typedef struct _cairo_bo_event {
     cairo_bo_event_type_t type;
-    cairo_point_t point;
-} cairo_bo_event_t;
-
-typedef struct _cairo_bo_start_event {
-    cairo_bo_event_type_t type;
-    cairo_point_t point;
-    cairo_bo_edge_t edge;
-} cairo_bo_start_event_t;
-
-typedef struct _cairo_bo_queue_event {
-    cairo_bo_event_type_t type;
-    cairo_point_t point;
     cairo_bo_edge_t *e1;
     cairo_bo_edge_t *e2;
-} cairo_bo_queue_event_t;
+    cairo_bo_point32_t point;
+    skip_elt_t elt;
+} cairo_bo_event_t;
 
-typedef struct _pqueue {
-    int size, max_size;
-
-    cairo_bo_event_t **elements;
-    cairo_bo_event_t *elements_embedded[1024];
-} pqueue_t;
+#define SKIP_ELT_TO_EVENT(elt) SKIP_LIST_ELT_TO_DATA (cairo_bo_event_t, (elt))
 
 typedef struct _cairo_bo_event_queue {
-    cairo_freepool_t pool;
-    pqueue_t pqueue;
-    cairo_bo_event_t **start_events;
+    cairo_skip_list_t intersection_queue;
+
+    cairo_bo_event_t *startstop_events;
+    cairo_bo_event_t **sorted_startstop_event_ptrs;
 } cairo_bo_event_queue_t;
 
+/* This structure extends #cairo_skip_list_t, which must come first. */
 typedef struct _cairo_bo_sweep_line {
+    cairo_skip_list_t active_edges;
     cairo_bo_edge_t *head;
-    cairo_bo_edge_t *stopped;
+    cairo_bo_edge_t *tail;
     int32_t current_y;
-    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;
-    int n;
-
-    if (getenv ("CAIRO_DEBUG_TRAPS") == NULL)
-	return;
-
-    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);
-    }
-    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);
-
-    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,
-		     traps->traps[n].left.p1.y,
-		     traps->traps[n].left.p2.x,
-		     traps->traps[n].left.p2.y,
-		     traps->traps[n].right.p1.x,
-		     traps->traps[n].right.p1.y,
-		     traps->traps[n].right.p2.x,
-		     traps->traps[n].right.p2.y);
-	}
-	fprintf (file, "\n");
-	fclose (file);
-    }
-}
-
-static void
-dump_edges (cairo_bo_start_event_t *events,
-	    int num_edges,
-	    const char *filename)
-{
-    FILE *file;
-    int n;
-
-    if (getenv ("CAIRO_DEBUG_TRAPS") == NULL)
-	return;
-
-    file = fopen (filename, "a");
-    if (file != NULL) {
-	for (n = 0; n < num_edges; n++) {
-	    fprintf (file, "(%d, %d), (%d, %d) %d %d %d\n",
-		     events[n].edge.edge.line.p1.x,
-		     events[n].edge.edge.line.p1.y,
-		     events[n].edge.edge.line.p2.x,
-		     events[n].edge.edge.line.p2.y,
-		     events[n].edge.edge.top,
-		     events[n].edge.edge.bottom,
-		     events[n].edge.edge.dir);
-	}
-	fprintf (file, "\n");
-	fclose (file);
-    }
-}
-#endif
-
-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;
-}
 
 static inline int
 _cairo_bo_point32_compare (cairo_bo_point32_t const *a,
 			   cairo_bo_point32_t const *b)
 {
-    int cmp;
-
-    cmp = a->y - b->y;
-    if (cmp)
-	return cmp;
-
+    int cmp = a->y - b->y;
+    if (cmp) return cmp;
     return a->x - b->x;
 }
 
 /* Compare the slope of a to the slope of b, returning 1, 0, -1 if the
  * slope a is respectively greater than, equal to, or less than the
  * slope of b.
  *
  * For each edge, consider the direction vector formed from:
  *
  *	top -> bottom
  *
  * which is:
  *
- *	(dx, dy) = (line.p2.x - line.p1.x, line.p2.y - line.p1.y)
+ *	(dx, dy) = (bottom.x - top.x, bottom.y - top.y)
  *
  * We then define the slope of each edge as dx/dy, (which is the
  * inverse of the slope typically used in math instruction). We never
  * compute a slope directly as the value approaches infinity, but we
  * can derive a slope comparison without division as follows, (where
  * the ? represents our compare operator).
  *
  * 1.	   slope(a) ? slope(b)
@@ -258,27 +178,27 @@ static inline int
  * When using this slope comparison to sort edges, some care is needed
  * when interpreting the results. Since the slope compare operates on
  * distance vectors from top to bottom it gives a correct left to
  * right sort for edges that have a common top point, (such as two
  * edges with start events at the same location). On the other hand,
  * the sense of the result will be exactly reversed for two edges that
  * have a common stop point.
  */
-static inline int
-_slope_compare (const cairo_bo_edge_t *a,
-		const cairo_bo_edge_t *b)
+static int
+_slope_compare (cairo_bo_edge_t *a,
+		cairo_bo_edge_t *b)
 {
     /* 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 adx = a->edge.line.p2.x - a->edge.line.p1.x;
-    int32_t bdx = b->edge.line.p2.x - b->edge.line.p1.x;
+    int32_t adx = a->bottom.x - a->top.x;
+    int32_t bdx = b->bottom.x - b->top.x;
 
     /* Since the dy's are all positive by construction we can fast
      * path several common cases.
      */
 
     /* First check for vertical lines. */
     if (adx == 0)
 	return -bdx;
@@ -286,18 +206,18 @@ static inline int
 	return adx;
 
     /* Then where the two edges point in different directions wrt x. */
     if ((adx ^ bdx) < 0)
 	return adx;
 
     /* Finally we actually need to do the general comparison. */
     {
-	int32_t ady = a->edge.line.p2.y - a->edge.line.p1.y;
-	int32_t bdy = b->edge.line.p2.y - b->edge.line.p1.y;
+	int32_t ady = a->bottom.y - a->top.y;
+	int32_t bdy = b->bottom.y - b->top.y;
 	cairo_int64_t adx_bdy = _cairo_int32x32_64_mul (adx, bdy);
 	cairo_int64_t bdx_ady = _cairo_int32x32_64_mul (bdx, ady);
 
 	return _cairo_int64_cmp (adx_bdy, bdx_ady);
     }
 }
 
 /*
@@ -345,56 +265,33 @@ edges_compare_x_for_y_general (const cai
        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->edge.line.p1.x < a->edge.line.p2.x) {
-                   amin = a->edge.line.p1.x;
-                   amax = a->edge.line.p2.x;
-           } else {
-                   amin = a->edge.line.p2.x;
-                   amax = a->edge.line.p1.x;
-           }
-           if (b->edge.line.p1.x < b->edge.line.p2.x) {
-                   bmin = b->edge.line.p1.x;
-                   bmax = b->edge.line.p2.x;
-           } else {
-                   bmin = b->edge.line.p2.x;
-                   bmax = b->edge.line.p1.x;
-           }
-           if (amax < bmin) return -1;
-           if (amin > bmax) return +1;
-    }
-
-    ady = a->edge.line.p2.y - a->edge.line.p1.y;
-    adx = a->edge.line.p2.x - a->edge.line.p1.x;
+    ady = a->bottom.y - a->top.y;
+    adx = a->bottom.x - a->top.x;
     if (adx == 0)
 	have_dx_adx_bdx &= ~HAVE_ADX;
 
-    bdy = b->edge.line.p2.y - b->edge.line.p1.y;
-    bdx = b->edge.line.p2.x - b->edge.line.p1.x;
+    bdy = b->bottom.y - b->top.y;
+    bdx = b->bottom.x - b->top.x;
     if (bdx == 0)
 	have_dx_adx_bdx &= ~HAVE_BDX;
 
-    dx = a->edge.line.p1.x - b->edge.line.p1.x;
+    dx = a->top.x - b->top.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->edge.line.p1.y)
-#define B _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (bdx, ady), y - b->edge.line.p1.y)
+#define A _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (adx, bdy), y - a->top.y)
+#define B _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (bdx, ady), y - b->top.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:
@@ -402,17 +299,17 @@ edges_compare_x_for_y_general (const cai
 	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->edge.line.p1.y == b->edge.line.p1.y) { /* common origin */
+	} else if (a->top.y == b->top.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);
@@ -421,34 +318,33 @@ edges_compare_x_for_y_general (const cai
     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->edge.line.p1.y - y, adx);
+	    dy_adx = _cairo_int32x32_64_mul (a->top.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->edge.line.p1.y, bdx);
+	    dy_bdx = _cairo_int32x32_64_mul (y - b->top.y, bdx);
 
 	    return _cairo_int64_cmp (bdy_dx, dy_bdx);
 	}
     case HAVE_ALL:
-	/* XXX try comparing (a->edge.line.p2.x - b->edge.line.p2.x) et al */
 	return _cairo_int128_cmp (L, _cairo_int128_sub (B, A));
     }
 #undef B
 #undef A
 #undef L
 }
 
 /*
@@ -476,31 +372,26 @@ static int
 edge_compare_for_y_against_x (const cairo_bo_edge_t *a,
 			      int32_t y,
 			      int32_t x)
 {
     int32_t adx, ady;
     int32_t dx, dy;
     cairo_int64_t L, R;
 
-    if (x < a->edge.line.p1.x && x < a->edge.line.p2.x)
-	return 1;
-    if (x > a->edge.line.p1.x && x > a->edge.line.p2.x)
-	return -1;
-
-    adx = a->edge.line.p2.x - a->edge.line.p1.x;
-    dx = x - a->edge.line.p1.x;
+    adx = a->bottom.x - a->top.x;
+    dx = x - a->top.x;
 
     if (adx == 0)
 	return -dx;
-    if (dx == 0 || (adx ^ dx) < 0)
+    if ((adx ^ dx) < 0)
 	return adx;
 
-    dy = y - a->edge.line.p1.y;
-    ady = a->edge.line.p2.y - a->edge.line.p1.y;
+    dy = y - a->top.y;
+    ady = a->bottom.y - a->top.y;
 
     L = _cairo_int32x32_64_mul (dy, adx);
     R = _cairo_int32x32_64_mul (dx, ady);
 
     return _cairo_int64_cmp (L, R);
 }
 
 static int
@@ -516,125 +407,311 @@ edges_compare_x_for_y (const cairo_bo_ed
     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;
 
-    if (y == a->edge.line.p1.y)
-	ax = a->edge.line.p1.x;
-    else if (y == a->edge.line.p2.y)
-	ax = a->edge.line.p2.x;
+    if (y == a->top.y)
+	ax = a->top.x;
+    else if (y == a->bottom.y)
+	ax = a->bottom.x;
     else
 	have_ax_bx &= ~HAVE_AX;
 
-    if (y == b->edge.line.p1.y)
-	bx = b->edge.line.p1.x;
-    else if (y == b->edge.line.p2.y)
-	bx = b->edge.line.p2.x;
+    if (y == b->top.y)
+	bx = b->top.x;
+    else if (y == b->bottom.y)
+	bx = b->bottom.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
-_line_equal (const cairo_line_t *a, const cairo_line_t *b)
+static int
+_cairo_bo_sweep_line_compare_edges (cairo_bo_sweep_line_t	*sweep_line,
+				    cairo_bo_edge_t		*a,
+				    cairo_bo_edge_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;
+    int cmp;
+
+    if (a == b)
+	return 0;
+
+    /* 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->middle.x < a->bottom.x) {
+                   amin = a->middle.x;
+                   amax = a->bottom.x;
+           } else {
+                   amin = a->bottom.x;
+                   amax = a->middle.x;
+           }
+           if (b->middle.x < b->bottom.x) {
+                   bmin = b->middle.x;
+                   bmax = b->bottom.x;
+           } else {
+                   bmin = b->bottom.x;
+                   bmax = b->middle.x;
+           }
+           if (amax < bmin) return -1;
+           if (amin > bmax) return +1;
+    }
+
+    cmp = edges_compare_x_for_y (a, b, sweep_line->current_y);
+    if (cmp)
+	return cmp;
+
+    /* The two edges intersect exactly at y, so fall back on slope
+     * comparison. We know that this compare_edges function will be
+     * called only when starting a new edge, (not when stopping an
+     * edge), so we don't have to worry about conditionally inverting
+     * the sense of _slope_compare. */
+    cmp = _slope_compare (a, b);
+    if (cmp)
+	return cmp;
+
+    /* We've got two collinear edges now. */
+
+    /* Since we're dealing with start events, prefer comparing top
+     * edges before bottom edges. */
+    cmp = _cairo_bo_point32_compare (&a->top, &b->top);
+    if (cmp)
+	return cmp;
+
+    cmp = _cairo_bo_point32_compare (&a->bottom, &b->bottom);
+    if (cmp)
+	return cmp;
+
+    /* Finally, we've got two identical edges. Let's finally
+     * discriminate by a simple pointer comparison, (which works only
+     * because we "know" the edges are all in a single array and don't
+     * move. */
+    if (a > b)
+	return 1;
+    else
+	return -1;
 }
 
 static int
-_cairo_bo_sweep_line_compare_edges (cairo_bo_sweep_line_t	*sweep_line,
-				    const cairo_bo_edge_t	*a,
-				    const cairo_bo_edge_t	*b)
+_sweep_line_elt_compare (void	*list,
+			 void	*a,
+			 void	*b)
+{
+    cairo_bo_sweep_line_t *sweep_line = list;
+    sweep_line_elt_t *edge_elt_a = a;
+    sweep_line_elt_t *edge_elt_b = b;
+
+    return _cairo_bo_sweep_line_compare_edges (sweep_line,
+					       edge_elt_a->edge,
+					       edge_elt_b->edge);
+}
+
+static inline int
+cairo_bo_event_compare (cairo_bo_event_t const *a,
+			cairo_bo_event_t const *b)
 {
     int cmp;
 
-    /* compare the edges if not identical */
-    if (! _line_equal (&a->edge.line, &b->edge.line)) {
-	cmp = edges_compare_x_for_y (a, b, sweep_line->current_y);
+    /* The major motion of the sweep line is vertical (top-to-bottom),
+     * and the minor motion is horizontal (left-to-right), dues to the
+     * infinitesimal tilt rule.
+     *
+     * Our point comparison function respects these rules.
+     */
+    cmp = _cairo_bo_point32_compare (&a->point, &b->point);
+    if (cmp)
+	return cmp;
+
+    /* The events share a common point, so further discrimination is
+     * determined by the event type. Due to the infinitesimal
+     * shortening rule, stop events come first, then intersection
+     * events, then start events.
+     */
+    if (a->type != b->type) {
+	if (a->type == CAIRO_BO_EVENT_TYPE_STOP)
+	    return -1;
+	if (a->type == CAIRO_BO_EVENT_TYPE_START)
+	    return 1;
+
+	if (b->type == CAIRO_BO_EVENT_TYPE_STOP)
+	    return 1;
+	if (b->type == CAIRO_BO_EVENT_TYPE_START)
+	    return -1;
+    }
+
+    /* At this stage we are looking at two events of the same type at
+     * the same point. The final sort key is a slope comparison. We
+     * need a different sense for start and stop events based on the
+     * shortening rule.
+     *
+     * Note: Fortunately, we get to ignore errors in the relative
+     * ordering of intersection events. This means we don't even have
+     * to look at e2 here, nor worry about which sense of the slope
+     * comparison test is used for intersection events.
+     */
+    cmp = _slope_compare (a->e1, b->e1);
+    if (cmp) {
+	if (a->type == CAIRO_BO_EVENT_TYPE_START)
+	    return cmp;
+	else
+	    return - cmp;
+    }
+
+    /* Next look at the opposite point. This leaves ambiguities only
+     * for identical edges. */
+    if (a->type == CAIRO_BO_EVENT_TYPE_START) {
+	cmp = _cairo_bo_point32_compare (&b->e1->bottom,
+					 &a->e1->bottom);
 	if (cmp)
 	    return cmp;
-
-	/* The two edges intersect exactly at y, so fall back on slope
-	 * comparison. We know that this compare_edges function will be
-	 * called only when starting a new edge, (not when stopping an
-	 * edge), so we don't have to worry about conditionally inverting
-	 * the sense of _slope_compare. */
-	cmp = _slope_compare (a, b);
+    }
+    else if (a->type == CAIRO_BO_EVENT_TYPE_STOP) {
+	cmp = _cairo_bo_point32_compare (&a->e1->top,
+					 &b->e1->top);
 	if (cmp)
 	    return cmp;
     }
+    else { /* CAIRO_BO_EVENT_TYPE_INTERSECT */
+	/* For two intersection events at the identical point, we
+	 * don't care what order they sort in, but we do care that we
+	 * have a stable sort. In particular intersections between
+	 * different pairs of edges must never return 0. */
+	cmp = _cairo_bo_point32_compare (&a->e2->top, &b->e2->top);
+	if (cmp)
+	    return cmp;
+	cmp = _cairo_bo_point32_compare (&a->e2->bottom, &b->e2->bottom);
+	if (cmp)
+	    return cmp;
+	cmp = _cairo_bo_point32_compare (&a->e1->top, &b->e1->top);
+	if (cmp)
+	    return cmp;
+	cmp = _cairo_bo_point32_compare (&a->e1->bottom, &b->e1->bottom);
+	if (cmp)
+	    return cmp;
+     }
 
-    /* We've got two collinear edges now. */
-    return b->edge.bottom - a->edge.bottom;
+    /* Discrimination based on the edge pointers. */
+    if (a->e1 < b->e1)
+	return -1;
+    if (a->e1 > b->e1)
+	return +1;
+    if (a->e2 < b->e2)
+	return -1;
+    if (a->e2 > b->e2)
+	return +1;
+    return 0;
+}
+
+static int
+cairo_bo_event_compare_abstract (void		*list,
+				 void	*a,
+				 void	*b)
+{
+    cairo_bo_event_t *event_a = a;
+    cairo_bo_event_t *event_b = b;
+
+    return cairo_bo_event_compare (event_a, event_b);
+}
+
+static int
+cairo_bo_event_compare_pointers (const cairo_bo_event_t *a,
+				 const cairo_bo_event_t *b)
+{
+    int cmp;
+
+    if (a == b)
+	return 0;
+    cmp = cairo_bo_event_compare (a, b);
+    if (cmp)
+	return cmp;
+
+    return a - b;
 }
 
 static inline cairo_int64_t
-det32_64 (int32_t a, int32_t b,
-	  int32_t c, int32_t d)
+det32_64 (int32_t a,
+	  int32_t b,
+	  int32_t c,
+	  int32_t d)
 {
+    cairo_int64_t ad;
+    cairo_int64_t bc;
+
     /* det = a * d - b * c */
-    return _cairo_int64_sub (_cairo_int32x32_64_mul (a, d),
-			     _cairo_int32x32_64_mul (b, c));
+    ad = _cairo_int32x32_64_mul (a, d);
+    bc = _cairo_int32x32_64_mul (b, c);
+
+    return _cairo_int64_sub (ad, bc);
 }
 
 static inline cairo_int128_t
-det64x32_128 (cairo_int64_t a, int32_t       b,
-	      cairo_int64_t c, int32_t       d)
+det64x32_128 (cairo_int64_t a,
+	      int32_t       b,
+	      cairo_int64_t c,
+	      int32_t       d)
 {
+    cairo_int128_t ad;
+    cairo_int128_t bc;
+
     /* det = a * d - b * c */
-    return _cairo_int128_sub (_cairo_int64x32_128_mul (a, d),
-			      _cairo_int64x32_128_mul (c, b));
+    ad = _cairo_int64x32_128_mul (a, d);
+    bc = _cairo_int64x32_128_mul (c, b);
+
+    return _cairo_int128_sub (ad, bc);
 }
 
 /* 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
+static cairo_bo_status_t
 intersect_lines (cairo_bo_edge_t		*a,
 		 cairo_bo_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 dx1 = a->top.x - a->bottom.x;
+    int32_t dy1 = a->top.y - a->bottom.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;
+    int32_t dx2 = b->top.x - b->bottom.x;
+    int32_t dy2 = b->top.y - b->bottom.y;
 
     cairo_int64_t den_det;
     cairo_int64_t R;
     cairo_quorem64_t qr;
 
     den_det = det32_64 (dx1, dy1, dx2, dy2);
+    if (_cairo_int64_is_zero (den_det))
+	return CAIRO_BO_STATUS_PARALLEL;
 
      /* 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)
@@ -645,92 +722,68 @@ intersect_lines (cairo_bo_edge_t		*a,
       *   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);
+    R = det32_64 (dx2, dy2, b->top.x - a->top.x, b->top.y - a->top.y);
+    if (_cairo_int64_is_zero (R))
+	return CAIRO_BO_STATUS_NO_INTERSECTION;
+    if (_cairo_int64_negative (den_det) ^ _cairo_int64_negative (R))
+	return CAIRO_BO_STATUS_NO_INTERSECTION;
     if (_cairo_int64_negative (den_det)) {
 	if (_cairo_int64_ge (den_det, R))
-	    return FALSE;
+	    return CAIRO_BO_STATUS_NO_INTERSECTION;
     } else {
 	if (_cairo_int64_le (den_det, R))
-	    return FALSE;
+	    return CAIRO_BO_STATUS_NO_INTERSECTION;
     }
 
-    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);
+    R = det32_64 (dy1, dx1, a->top.y - b->top.y, a->top.x - b->top.x);
+    if (_cairo_int64_is_zero (R))
+	return CAIRO_BO_STATUS_NO_INTERSECTION;
+    if (_cairo_int64_negative (den_det) ^ _cairo_int64_negative (R))
+	return CAIRO_BO_STATUS_NO_INTERSECTION;
     if (_cairo_int64_negative (den_det)) {
 	if (_cairo_int64_ge (den_det, R))
-	    return FALSE;
+	    return CAIRO_BO_STATUS_NO_INTERSECTION;
     } else {
 	if (_cairo_int64_le (den_det, R))
-	    return FALSE;
+	    return CAIRO_BO_STATUS_NO_INTERSECTION;
     }
 
     /* 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);
+    a_det = det32_64 (a->top.x, a->top.y,
+		      a->bottom.x, a->bottom.y);
+    b_det = det32_64 (b->top.x, b->top.y,
+		      b->bottom.x, b->bottom.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
+	return CAIRO_BO_STATUS_NO_INTERSECTION;
+    intersection->x.ordinate = _cairo_int64_to_int32 (qr.quo);
     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
+	return CAIRO_BO_STATUS_NO_INTERSECTION;
+    intersection->y.ordinate = _cairo_int64_to_int32 (qr.quo);
     intersection->y.exactness = _cairo_int64_is_zero (qr.rem) ? EXACT : INEXACT;
-#else
-    intersection->y.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->y.exactness = INEXACT;
-    }
-#endif
-    intersection->y.ordinate = _cairo_int64_to_int32 (qr.quo);
 
-    return TRUE;
+    return CAIRO_BO_STATUS_INTERSECTION;
 }
 
 static int
 _cairo_bo_intersect_ordinate_32_compare (cairo_bo_intersect_ordinate_t	a,
 					 int32_t			b)
 {
     /* First compare the quotient */
     if (a.ordinate > b)
@@ -767,20 +820,18 @@ static cairo_bool_t
 
     /* 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 = _cairo_bo_intersect_ordinate_32_compare (point->y,
-						       edge->edge.top);
-    cmp_bottom = _cairo_bo_intersect_ordinate_32_compare (point->y,
-							  edge->edge.bottom);
+    cmp_top = _cairo_bo_intersect_ordinate_32_compare (point->y, edge->top.y);
+    cmp_bottom = _cairo_bo_intersect_ordinate_32_compare (point->y, edge->bottom.y);
 
     if (cmp_top < 0 || cmp_bottom > 0)
     {
 	return FALSE;
     }
 
     if (cmp_top > 0 && cmp_bottom < 0)
     {
@@ -793,29 +844,20 @@ static cairo_bool_t
 
     /* 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 _cairo_bo_intersect_ordinate_32_compare (point->x, top_x) > 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 _cairo_bo_intersect_ordinate_32_compare (point->x, bot_x) < 0;
-    }
+    if (cmp_top == 0)
+	return (_cairo_bo_intersect_ordinate_32_compare (point->x, edge->top.x) > 0);
+    else /* cmp_bottom == 0 */
+	return (_cairo_bo_intersect_ordinate_32_compare (point->x, edge->bottom.x) < 0);
 }
 
 /* Compute the intersection of two edges. The result is provided as a
  * coordinate pair of 128-bit integers.
  *
  * Returns %CAIRO_BO_STATUS_INTERSECTION if there is an intersection
  * that is within both edges, %CAIRO_BO_STATUS_NO_INTERSECTION if the
  * intersection of the lines defined by the edges occurs outside of
@@ -824,394 +866,317 @@ static cairo_bool_t
  *
  * Note that when determining if a candidate intersection is "inside"
  * an edge, we consider both the infinitesimal shortening and the
  * infinitesimal tilt rules described by John Hobby. Specifically, if
  * the intersection is exactly the same as an edge point, it is
  * effectively outside (no intersection is returned). Also, if the
  * intersection point has the same
  */
-static cairo_bool_t
+static cairo_bo_status_t
 _cairo_bo_edge_intersect (cairo_bo_edge_t	*a,
 			  cairo_bo_edge_t	*b,
 			  cairo_bo_point32_t	*intersection)
 {
+    cairo_bo_status_t status;
     cairo_bo_intersect_point_t quorem;
 
-    if (! intersect_lines (a, b, &quorem))
-	return FALSE;
+    status = intersect_lines (a, b, &quorem);
+    if (status)
+	return status;
 
     if (! _cairo_bo_edge_contains_intersect_point (a, &quorem))
-	return FALSE;
+	return CAIRO_BO_STATUS_NO_INTERSECTION;
 
     if (! _cairo_bo_edge_contains_intersect_point (b, &quorem))
-	return FALSE;
+	return CAIRO_BO_STATUS_NO_INTERSECTION;
 
     /* 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;
+    return CAIRO_BO_STATUS_INTERSECTION;
 }
 
-static inline int
-cairo_bo_event_compare (const cairo_bo_event_t *a,
-			const cairo_bo_event_t *b)
+static void
+_cairo_bo_event_init (cairo_bo_event_t		*event,
+		      cairo_bo_event_type_t	 type,
+		      cairo_bo_edge_t	*e1,
+		      cairo_bo_edge_t	*e2,
+		      cairo_bo_point32_t	 point)
 {
-    int cmp;
-
-    cmp = _cairo_bo_point32_compare (&a->point, &b->point);
-    if (cmp)
-	return cmp;
-
-    cmp = a->type - b->type;
-    if (cmp)
-	return cmp;
-
-    return a - b;
-}
-
-static inline void
-_pqueue_init (pqueue_t *pq)
-{
-    pq->max_size = ARRAY_LENGTH (pq->elements_embedded);
-    pq->size = 0;
-
-    pq->elements = pq->elements_embedded;
-}
-
-static inline void
-_pqueue_fini (pqueue_t *pq)
-{
-    if (pq->elements != pq->elements_embedded)
-	free (pq->elements);
+    event->type = type;
+    event->e1 = e1;
+    event->e2 = e2;
+    event->point = point;
 }
 
 static cairo_status_t
-_pqueue_grow (pqueue_t *pq)
-{
-    cairo_bo_event_t **new_elements;
-    pq->max_size *= 2;
-
-    if (pq->elements == pq->elements_embedded) {
-	new_elements = _cairo_malloc_ab (pq->max_size,
-					 sizeof (cairo_bo_event_t *));
-	if (unlikely (new_elements == NULL))
-	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
-	memcpy (new_elements, pq->elements_embedded,
-		sizeof (pq->elements_embedded));
-    } else {
-	new_elements = _cairo_realloc_ab (pq->elements,
-					  pq->max_size,
-					  sizeof (cairo_bo_event_t *));
-	if (unlikely (new_elements == NULL))
-	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-    }
-
-    pq->elements = new_elements;
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static inline cairo_status_t
-_pqueue_push (pqueue_t *pq, cairo_bo_event_t *event)
+_cairo_bo_event_queue_insert (cairo_bo_event_queue_t *queue,
+			      cairo_bo_event_t	     *event)
 {
-    cairo_bo_event_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;
-    }
-
-    elements = pq->elements;
-
-    for (i = ++pq->size;
-	 i != PQ_FIRST_ENTRY &&
-	 cairo_bo_event_compare (event,
-				 elements[parent = PQ_PARENT_INDEX (i)]) < 0;
-	 i = parent)
-    {
-	elements[i] = elements[parent];
-    }
-
-    elements[i] = event;
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static inline void
-_pqueue_pop (pqueue_t *pq)
-{
-    cairo_bo_event_t **elements = pq->elements;
-    cairo_bo_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 &&
-	    cairo_bo_event_compare (elements[child+1],
-				    elements[child]) < 0)
-	{
-	    child++;
-	}
-
-	if (cairo_bo_event_compare (elements[child], tail) >= 0)
-	    break;
-
-	elements[i] = elements[child];
-    }
-    elements[i] = tail;
-}
-
-static inline cairo_status_t
-_cairo_bo_event_queue_insert (cairo_bo_event_queue_t	*queue,
-			      cairo_bo_event_type_t	 type,
-			      cairo_bo_edge_t		*e1,
-			      cairo_bo_edge_t		*e2,
-			      const cairo_point_t	 *point)
-{
-    cairo_bo_queue_event_t *event;
-
-    event = _cairo_freepool_alloc (&queue->pool);
-    if (unlikely (event == NULL))
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
-    event->type = type;
-    event->e1 = e1;
-    event->e2 = e2;
-    event->point = *point;
-
-    return _pqueue_push (&queue->pqueue, (cairo_bo_event_t *) event);
+    cairo_status_t status = CAIRO_STATUS_SUCCESS;
+    /* Don't insert if there's already an equivalent intersection event in the queue. */
+    if (_cairo_skip_list_insert (&queue->intersection_queue, event,
+		      event->type == CAIRO_BO_EVENT_TYPE_INTERSECTION) == NULL)
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    return status;
 }
 
 static void
 _cairo_bo_event_queue_delete (cairo_bo_event_queue_t *queue,
 			      cairo_bo_event_t	     *event)
 {
-    _cairo_freepool_free (&queue->pool, event);
+    if (CAIRO_BO_EVENT_TYPE_INTERSECTION == event->type)
+	_cairo_skip_list_delete_given ( &queue->intersection_queue, &event->elt );
 }
 
 static cairo_bo_event_t *
 _cairo_bo_event_dequeue (cairo_bo_event_queue_t *event_queue)
 {
-    cairo_bo_event_t *event, *cmp;
+    skip_elt_t *elt = event_queue->intersection_queue.chains[0];
+    cairo_bo_event_t *intersection = elt ? SKIP_ELT_TO_EVENT (elt) : NULL;
+    cairo_bo_event_t *startstop;
 
-    event = event_queue->pqueue.elements[PQ_FIRST_ENTRY];
-    cmp = *event_queue->start_events;
-    if (event == NULL ||
-	(cmp != NULL && cairo_bo_event_compare (cmp, event) < 0))
+    startstop = *event_queue->sorted_startstop_event_ptrs;
+    if (startstop == NULL)
+	return intersection;
+
+    if (intersection == NULL ||
+	cairo_bo_event_compare (startstop, intersection) <= 0)
     {
-	event = cmp;
-	event_queue->start_events++;
-    }
-    else
-    {
-	_pqueue_pop (&event_queue->pqueue);
+	event_queue->sorted_startstop_event_ptrs++;
+	return startstop;
     }
 
-    return event;
+    return intersection;
 }
 
 CAIRO_COMBSORT_DECLARE (_cairo_bo_event_queue_sort,
 			cairo_bo_event_t *,
-			cairo_bo_event_compare)
-
-static void
-_cairo_bo_event_queue_init (cairo_bo_event_queue_t	 *event_queue,
-			    cairo_bo_event_t		**start_events,
-			    int				  num_events)
-{
-    _cairo_bo_event_queue_sort (start_events, num_events);
-    start_events[num_events] = NULL;
-
-    event_queue->start_events = start_events;
-
-    _cairo_freepool_init (&event_queue->pool,
-			  sizeof (cairo_bo_queue_event_t));
-    _pqueue_init (&event_queue->pqueue);
-    event_queue->pqueue.elements[PQ_FIRST_ENTRY] = NULL;
-}
+			cairo_bo_event_compare_pointers)
 
 static cairo_status_t
-_cairo_bo_event_queue_insert_stop (cairo_bo_event_queue_t	*event_queue,
-				   cairo_bo_edge_t		*edge)
+_cairo_bo_event_queue_init (cairo_bo_event_queue_t	*event_queue,
+			    cairo_bo_edge_t	*edges,
+			    int				 num_edges)
 {
-    cairo_bo_point32_t point;
+    int i;
+    cairo_bo_event_t *events, **sorted_event_ptrs;
+    unsigned num_events = 2*num_edges;
+
+    /* The skip_elt_t field of a cairo_bo_event_t isn't used for start
+     * or stop events, so this allocation is safe.  XXX: make the
+     * event type a union so it doesn't always contain the skip
+     * elt? */
+    events = _cairo_malloc_ab_plus_c (num_events,
+				      sizeof (cairo_bo_event_t) +
+				      sizeof (cairo_bo_event_t *),
+				      sizeof (cairo_bo_event_t *));
+    if (unlikely (events == NULL))
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    sorted_event_ptrs = (cairo_bo_event_t **) (events + num_events);
+    event_queue->startstop_events = events;
+    event_queue->sorted_startstop_event_ptrs = sorted_event_ptrs;
 
-    point.y = edge->edge.bottom;
-    point.x = _line_compute_intersection_x_for_y (&edge->edge.line,
-						  point.y);
-    return _cairo_bo_event_queue_insert (event_queue,
-					 CAIRO_BO_EVENT_TYPE_STOP,
-					 edge, NULL,
-					 &point);
+    for (i = 0; i < num_edges; i++) {
+	sorted_event_ptrs[i] = &events[2*i];
+	sorted_event_ptrs[i+num_edges] = &events[2*i+1];
+
+	/* Initialize "middle" to top */
+	edges[i].middle = edges[i].top;
+
+	_cairo_bo_event_init (&events[2*i],
+			      CAIRO_BO_EVENT_TYPE_START,
+			      &edges[i], NULL,
+			      edges[i].top);
+
+	_cairo_bo_event_init (&events[2*i+1],
+			      CAIRO_BO_EVENT_TYPE_STOP,
+			      &edges[i], NULL,
+			      edges[i].bottom);
+    }
+
+    _cairo_bo_event_queue_sort (sorted_event_ptrs, num_events);
+    event_queue->sorted_startstop_event_ptrs[num_events] = NULL;
+
+    _cairo_skip_list_init (&event_queue->intersection_queue,
+			   cairo_bo_event_compare_abstract,
+			   sizeof (cairo_bo_event_t));
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static void
 _cairo_bo_event_queue_fini (cairo_bo_event_queue_t *event_queue)
 {
-    _pqueue_fini (&event_queue->pqueue);
-    _cairo_freepool_fini (&event_queue->pool);
+    _cairo_skip_list_fini (&event_queue->intersection_queue);
+    if (event_queue->startstop_events)
+	free (event_queue->startstop_events);
 }
 
-static inline cairo_status_t
+static cairo_status_t
 _cairo_bo_event_queue_insert_if_intersect_below_current_y (cairo_bo_event_queue_t	*event_queue,
 							   cairo_bo_edge_t	*left,
-							   cairo_bo_edge_t *right)
+							   cairo_bo_edge_t	*right)
 {
+    cairo_bo_status_t status;
     cairo_bo_point32_t intersection;
+    cairo_bo_event_t event;
 
-    if (_line_equal (&left->edge.line, &right->edge.line))
+    if (left == NULL || right == NULL)
 	return CAIRO_STATUS_SUCCESS;
 
     /* The names "left" and "right" here are correct descriptions of
      * the order of the two edges within the active edge list. So if a
      * slope comparison also puts left less than right, then we know
-     * that the intersection of these two segments has already
+     * that the intersection of these two segments has oalready
      * occurred before the current sweep line position. */
-    if (_slope_compare (left, right) <= 0)
+    if (_slope_compare (left, right) < 0)
 	return CAIRO_STATUS_SUCCESS;
 
-    if (! _cairo_bo_edge_intersect (left, right, &intersection))
+    status = _cairo_bo_edge_intersect (left, right, &intersection);
+    if (status == CAIRO_BO_STATUS_PARALLEL ||
+	status == CAIRO_BO_STATUS_NO_INTERSECTION)
+    {
 	return CAIRO_STATUS_SUCCESS;
+    }
 
-    return _cairo_bo_event_queue_insert (event_queue,
-					 CAIRO_BO_EVENT_TYPE_INTERSECTION,
-					 left, right,
-					 &intersection);
+    _cairo_bo_event_init (&event,
+			  CAIRO_BO_EVENT_TYPE_INTERSECTION,
+			  left, right,
+			  intersection);
+
+    return _cairo_bo_event_queue_insert (event_queue, &event);
 }
 
 static void
 _cairo_bo_sweep_line_init (cairo_bo_sweep_line_t *sweep_line)
 {
+    _cairo_skip_list_init (&sweep_line->active_edges,
+			   _sweep_line_elt_compare,
+			   sizeof (sweep_line_elt_t));
+
     sweep_line->head = NULL;
-    sweep_line->stopped = NULL;
-    sweep_line->current_y = INT32_MIN;
-    sweep_line->current_edge = NULL;
+    sweep_line->tail = NULL;
+    sweep_line->current_y = 0;
+}
+
+static void
+_cairo_bo_sweep_line_fini (cairo_bo_sweep_line_t *sweep_line)
+{
+    _cairo_skip_list_fini (&sweep_line->active_edges);
 }
 
 static cairo_status_t
 _cairo_bo_sweep_line_insert (cairo_bo_sweep_line_t	*sweep_line,
 			     cairo_bo_edge_t		*edge)
 {
-    if (sweep_line->current_edge != NULL) {
-	cairo_bo_edge_t *prev, *next;
-	int cmp;
+    skip_elt_t *next_elt;
+    sweep_line_elt_t *sweep_line_elt;
+    cairo_bo_edge_t **prev_of_next, **next_of_prev;
 
-	cmp = _cairo_bo_sweep_line_compare_edges (sweep_line,
-						  sweep_line->current_edge,
-						  edge);
-	if (cmp < 0) {
-	    prev = sweep_line->current_edge;
-	    next = prev->next;
-	    while (next != NULL &&
-		   _cairo_bo_sweep_line_compare_edges (sweep_line,
-						       next, edge) < 0)
-	    {
-		prev = next, next = prev->next;
-	    }
+    sweep_line_elt = _cairo_skip_list_insert (&sweep_line->active_edges, &edge,
+					      1 /* unique inserts*/);
+    if (unlikely (sweep_line_elt == NULL))
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
-	    prev->next = edge;
-	    edge->prev = prev;
-	    edge->next = next;
-	    if (next != NULL)
-		next->prev = edge;
-	} else if (cmp > 0) {
-	    next = sweep_line->current_edge;
-	    prev = next->prev;
-	    while (prev != NULL &&
-		   _cairo_bo_sweep_line_compare_edges (sweep_line,
-						       prev, edge) > 0)
-	    {
-		next = prev, prev = next->prev;
-	    }
+    next_elt = sweep_line_elt->elt.next[0];
+    if (next_elt)
+	prev_of_next = & (SKIP_ELT_TO_EDGE (next_elt)->prev);
+    else
+	prev_of_next = &sweep_line->tail;
 
-	    next->prev = edge;
-	    edge->next = next;
-	    edge->prev = prev;
-	    if (prev != NULL)
-		prev->next = edge;
-	    else
-		sweep_line->head = edge;
-	} else {
-	    prev = sweep_line->current_edge;
-	    edge->prev = prev;
-	    edge->next = prev->next;
-	    if (prev->next != NULL)
-		prev->next->prev = edge;
-	    prev->next = edge;
-	}
-    } else {
-	sweep_line->head = edge;
-    }
+    if (*prev_of_next)
+	next_of_prev = &(*prev_of_next)->next;
+    else
+	next_of_prev = &sweep_line->head;
 
-    sweep_line->current_edge = edge;
+    edge->prev = *prev_of_next;
+    edge->next = *next_of_prev;
+    *prev_of_next = edge;
+    *next_of_prev = edge;
+
+    edge->sweep_line_elt = sweep_line_elt;
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static void
 _cairo_bo_sweep_line_delete (cairo_bo_sweep_line_t	*sweep_line,
 			     cairo_bo_edge_t	*edge)
 {
-    if (edge->prev != NULL)
-	edge->prev->next = edge->next;
-    else
-	sweep_line->head = edge->next;
+    cairo_bo_edge_t **left_next, **right_prev;
+
+    _cairo_skip_list_delete_given (&sweep_line->active_edges,
+				   &edge->sweep_line_elt->elt);
 
-    if (edge->next != NULL)
-	edge->next->prev = edge->prev;
+    left_next = &sweep_line->head;
+    if (edge->prev)
+	left_next = &edge->prev->next;
 
-    if (sweep_line->current_edge == edge)
-	sweep_line->current_edge = edge->prev ? edge->prev : edge->next;
+    right_prev = &sweep_line->tail;
+    if (edge->next)
+	right_prev = &edge->next->prev;
+
+    *left_next = edge->next;
+    *right_prev = edge->prev;
 }
 
 static void
 _cairo_bo_sweep_line_swap (cairo_bo_sweep_line_t	*sweep_line,
 			   cairo_bo_edge_t		*left,
 			   cairo_bo_edge_t		*right)
 {
-    if (left->prev != NULL)
-	left->prev->next = right;
-    else
-	sweep_line->head = right;
+    sweep_line_elt_t *left_elt, *right_elt;
+    cairo_bo_edge_t **before_left, **after_right;
+
+    /* Within the skip list we can do the swap simply by swapping the
+     * pointers to the edge elements and leaving all of the skip list
+     * elements and pointers unchanged. */
+    left_elt = left->sweep_line_elt;
+    right_elt = SKIP_ELT_TO_EDGE_ELT (left_elt->elt.next[0]);
+
+    left_elt->edge = right;
+    right->sweep_line_elt = left_elt;
 
-    if (right->next != NULL)
-	right->next->prev = left;
+    right_elt->edge = left;
+    left->sweep_line_elt = right_elt;
+
+    /* Within the doubly-linked list of edges, there's a bit more
+     * bookkeeping involved with the swap. */
+    before_left = &sweep_line->head;
+    if (left->prev)
+	before_left = &left->prev->next;
+    *before_left = right;
+
+    after_right = &sweep_line->tail;
+    if (right->next)
+	after_right = &right->next->prev;
+    *after_right = left;
 
     left->next = right->next;
     right->next = left;
 
     right->prev = left->prev;
     left->prev = right;
 }
 
 #if DEBUG_PRINT_STATE
 static void
 _cairo_bo_edge_print (cairo_bo_edge_t *edge)
 {
     printf ("(0x%x, 0x%x)-(0x%x, 0x%x)",
-	    edge->edge.line.p1.x, edge->edge.line.p1.y,
-	    edge->edge.line.p2.x, edge->edge.line.p2.y);
+	    edge->top.x, edge->top.y,
+	    edge->bottom.x, edge->bottom.y);
 }
 
 static void
 _cairo_bo_event_print (cairo_bo_event_t *event)
 {
     switch (event->type) {
     case CAIRO_BO_EVENT_TYPE_START:
 	printf ("Start: ");
@@ -1230,648 +1195,618 @@ static void
 	_cairo_bo_edge_print (event->e2);
     }
     printf ("\n");
 }
 
 static void
 _cairo_bo_event_queue_print (cairo_bo_event_queue_t *event_queue)
 {
+    skip_elt_t *elt;
     /* XXX: fixme to print the start/stop array too. */
+    cairo_skip_list_t *queue = &event_queue->intersection_queue;
+    cairo_bo_event_t *event;
+
     printf ("Event queue:\n");
+
+    for (elt = queue->chains[0];
+	 elt;
+	 elt = elt->next[0])
+    {
+	event = SKIP_ELT_TO_EVENT (elt);
+	_cairo_bo_event_print (event);
+    }
 }
 
 static void
 _cairo_bo_sweep_line_print (cairo_bo_sweep_line_t *sweep_line)
 {
     cairo_bool_t first = TRUE;
+    skip_elt_t *elt;
     cairo_bo_edge_t *edge;
 
+    printf ("Sweep line (reversed):     ");
+
+    for (edge = sweep_line->tail;
+	 edge;
+	 edge = edge->prev)
+    {
+	if (!first)
+	    printf (", ");
+	_cairo_bo_edge_print (edge);
+	first = FALSE;
+    }
+    printf ("\n");
+
+
     printf ("Sweep line from edge list: ");
     first = TRUE;
     for (edge = sweep_line->head;
 	 edge;
 	 edge = edge->next)
     {
 	if (!first)
 	    printf (", ");
 	_cairo_bo_edge_print (edge);
 	first = FALSE;
     }
     printf ("\n");
+
+    printf ("Sweep line from skip list: ");
+    first = TRUE;
+    for (elt = sweep_line->active_edges.chains[0];
+	 elt;
+	 elt = elt->next[0])
+    {
+	if (!first)
+	    printf (", ");
+	_cairo_bo_edge_print (SKIP_ELT_TO_EDGE (elt));
+	first = FALSE;
+    }
+    printf ("\n");
 }
 
 static void
 print_state (const char			*msg,
-	     cairo_bo_event_t		*event,
 	     cairo_bo_event_queue_t	*event_queue,
 	     cairo_bo_sweep_line_t	*sweep_line)
 {
-    printf ("%s ", msg);
-    _cairo_bo_event_print (event);
+    printf ("%s\n", msg);
     _cairo_bo_event_queue_print (event_queue);
     _cairo_bo_sweep_line_print (sweep_line);
     printf ("\n");
 }
 #endif
 
-#if DEBUG_EVENTS
-static void CAIRO_PRINTF_FORMAT (1, 2)
-event_log (const char *fmt, ...)
+/* Adds the trapezoid, if any, of the left edge to the #cairo_traps_t
+ * of bo_traps. */
+static cairo_status_t
+_cairo_bo_edge_end_trap (cairo_bo_edge_t	*left,
+			 int32_t		bot,
+			 cairo_bo_traps_t	*bo_traps)
 {
-    FILE *file;
+    cairo_fixed_t fixed_top, fixed_bot;
+    cairo_bo_trap_t *trap = left->deferred_trap;
+    cairo_bo_edge_t *right;
+
+    if (!trap)
+	return CAIRO_STATUS_SUCCESS;
+
+     /* If the right edge of the trapezoid stopped earlier than the
+      * left edge, then cut the trapezoid bottom early. */
+    right = trap->right;
+    if (right->bottom.y < bot)
+	bot = right->bottom.y;
+
+    fixed_top = trap->top;
+    fixed_bot = bot;
+
+    /* Only emit trapezoids with positive height. */
+    if (fixed_top < fixed_bot) {
+	cairo_line_t left_line;
+	cairo_line_t right_line;
+	cairo_fixed_t xmin = bo_traps->xmin;
+	cairo_fixed_t ymin = bo_traps->ymin;
+	fixed_top += ymin;
+	fixed_bot += ymin;
+
+	left_line.p1.x  = left->top.x + xmin;
+	left_line.p1.y  = left->top.y + ymin;
+	right_line.p1.x = right->top.x + xmin;
+	right_line.p1.y = right->top.y + ymin;
 
-    if (getenv ("CAIRO_DEBUG_EVENTS") == NULL)
-	return;
+	left_line.p2.x  = left->bottom.x + xmin;
+	left_line.p2.y  = left->bottom.y + ymin;
+	right_line.p2.x = right->bottom.x + xmin;
+	right_line.p2.y = right->bottom.y + ymin;
+
+	/* Avoid emitting the trapezoid if it is obviously degenerate.
+	 * TODO: need a real collinearity test here for the cases
+	 * where the trapezoid is degenerate, yet the top and bottom
+	 * coordinates aren't equal.  */
+	if (left_line.p1.x != right_line.p1.x ||
+	    left_line.p1.y != right_line.p1.y ||
+	    left_line.p2.x != right_line.p2.x ||
+	    left_line.p2.y != right_line.p2.y)
+	{
+	    _cairo_traps_add_trap (bo_traps->traps,
+				   fixed_top, fixed_bot,
+				   &left_line, &right_line);
+
+#if DEBUG_PRINT_STATE
+	    printf ("Deferred trap: left=(%08x, %08x)-(%08x,%08x) "
+		    "right=(%08x,%08x)-(%08x,%08x) top=%08x, bot=%08x\n",
+		    left->top.x, left->top.y, left->bottom.x, left->bottom.y,
+		    right->top.x, right->top.y, right->bottom.x, right->bottom.y,
+		    trap->top, bot);
+#endif
+	}
+    }
+
+    _cairo_freelist_free (&bo_traps->freelist, trap);
+    left->deferred_trap = NULL;
+
+    return _cairo_traps_status (bo_traps->traps);
+}
 
-    file = fopen ("bo-events.txt", "a");
-    if (file != NULL) {
-	va_list ap;
+/* Start a new trapezoid at the given top y coordinate, whose edges
+ * are `edge' and `edge->next'. If `edge' already has a trapezoid,
+ * then either add it to the traps in `bo_traps', if the trapezoid's
+ * right edge differs from `edge->next', or do nothing if the new
+ * trapezoid would be a continuation of the existing one. */
+static cairo_status_t
+_cairo_bo_edge_start_or_continue_trap (cairo_bo_edge_t	*edge,
+				       int32_t		top,
+				       cairo_bo_traps_t	*bo_traps)
+{
+    cairo_status_t status;
+    cairo_bo_trap_t *trap = edge->deferred_trap;
+
+    if (trap) {
+	if (trap->right == edge->next) return CAIRO_STATUS_SUCCESS;
+	status = _cairo_bo_edge_end_trap (edge, top, bo_traps);
+	if (status)
+	    return status;
+    }
+
+    if (edge->next) {
+	trap = edge->deferred_trap = _cairo_freelist_alloc (&bo_traps->freelist);
+	if (!edge->deferred_trap)
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+	trap->right = edge->next;
+	trap->top = top;
+    }
+    return CAIRO_STATUS_SUCCESS;
+}
 
-	va_start (ap, fmt);
-	vfprintf (file, fmt, ap);
-	va_end (ap);
+static void
+_cairo_bo_traps_init (cairo_bo_traps_t	*bo_traps,
+		      cairo_traps_t	*traps,
+		      cairo_fixed_t	 xmin,
+		      cairo_fixed_t	 ymin,
+		      cairo_fixed_t	 xmax,
+		      cairo_fixed_t	 ymax)
+{
+    bo_traps->traps = traps;
+    _cairo_freelist_init (&bo_traps->freelist, sizeof(cairo_bo_trap_t));
+    bo_traps->xmin = xmin;
+    bo_traps->ymin = ymin;
+    bo_traps->xmax = xmax;
+    bo_traps->ymax = ymax;
+}
+
+static void
+_cairo_bo_traps_fini (cairo_bo_traps_t *bo_traps)
+{
+    _cairo_freelist_fini (&bo_traps->freelist);
+}
 
-	fclose (file);
+#if DEBUG_VALIDATE
+static void
+_cairo_bo_sweep_line_validate (cairo_bo_sweep_line_t *sweep_line)
+{
+    cairo_bo_edge_t *edge;
+    skip_elt_t *elt;
+
+    /* March through both the skip list's singly-linked list and the
+     * sweep line's own list through pointers in the edges themselves
+     * and make sure they agree at every point. */
+
+    for (edge = sweep_line->head, elt = sweep_line->active_edges.chains[0];
+	 edge && elt;
+	 edge = edge->next, elt = elt->next[0])
+    {
+	if (SKIP_ELT_TO_EDGE (elt) != edge) {
+	    fprintf (stderr, "*** Error: Sweep line fails to validate: Inconsistent data in the two lists.\n");
+	    abort ();
+	}
+    }
+
+    if (edge || elt) {
+	fprintf (stderr, "*** Error: Sweep line fails to validate: One list ran out before the other.\n");
+	abort ();
     }
 }
 #endif
 
-static inline cairo_bool_t
-edges_colinear (const cairo_bo_edge_t *a, const cairo_bo_edge_t *b)
-{
-    if (_line_equal (&a->edge.line, &b->edge.line))
-	return TRUE;
 
-    if (_slope_compare (a, b))
-	return FALSE;
-
-    /* The choice of y is not truly arbitrary since we must guarantee that it
-     * is greater than the start of either line.
-     */
-    if (a->edge.line.p1.y == b->edge.line.p1.y) {
-	return a->edge.line.p1.x == b->edge.line.p1.x;
-    } else if (a->edge.line.p1.y < b->edge.line.p1.y) {
-	return edge_compare_for_y_against_x (b,
-					     a->edge.line.p1.y,
-					     a->edge.line.p1.x) == 0;
-    } else {
-	return edge_compare_for_y_against_x (a,
-					     b->edge.line.p1.y,
-					     b->edge.line.p1.x) == 0;
-    }
-}
-
-/* Adds the trapezoid, if any, of the left edge to the #cairo_traps_t */
 static cairo_status_t
-_cairo_bo_edge_end_trap (cairo_bo_edge_t	*left,
-			 int32_t		 bot,
-			 cairo_traps_t	        *traps)
-{
-    cairo_bo_trap_t *trap = &left->deferred_trap;
-
-    /* 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 DEBUG_PRINT_STATE
-	printf ("Deferred trap: left=(%x, %x)-(%x,%x) "
-		"right=(%x,%x)-(%x,%x) top=%x, bot=%x\n",
-		left->edge.line.p1.x, left->edge.line.p1.y,
-		left->edge.line.p2.x, left->edge.line.p2.y,
-		trap->right->edge.line.p1.x, trap->right->edge.line.p1.y,
-		trap->right->edge.line.p2.x, trap->right->edge.line.p2.y,
-		trap->top, bot);
-#endif
-#if DEBUG_EVENTS
-	event_log ("end trap: %lu %lu %d %d\n",
-		   (long) left,
-		   (long) trap->right,
-		   trap->top,
-		   bot);
-#endif
-    }
-
-    trap->right = NULL;
-
-    return _cairo_traps_status (traps);
-}
-
-
-/* Start a new trapezoid at the given top y coordinate, whose edges
- * are `edge' and `edge->next'. If `edge' already has a trapezoid,
- * then either add it to the traps in `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)
+_active_edges_to_traps (cairo_bo_edge_t		*head,
+			int32_t			 top,
+			cairo_fill_rule_t	 fill_rule,
+			cairo_bo_traps_t	*bo_traps)
 {
     cairo_status_t status;
-
-    if (left->deferred_trap.right == right)
-	return CAIRO_STATUS_SUCCESS;
+    int in_out = 0;
+    cairo_bo_edge_t *edge;
 
-    if (left->deferred_trap.right != NULL) {
-	if (right != NULL && edges_colinear (left->deferred_trap.right, right))
-	{
-	    /* continuation on right, so just swap edges */
-	    left->deferred_trap.right = right;
-	    return CAIRO_STATUS_SUCCESS;
+    for (edge = head; edge; edge = edge->next) {
+	if (fill_rule == CAIRO_FILL_RULE_WINDING) {
+	    in_out += edge->dir;
+	    if (in_out == 0) {
+		status = _cairo_bo_edge_end_trap (edge, top, bo_traps);
+		if (status)
+		    return status;
+		continue;
+	    }
+	} else {
+	    in_out++;
+	    if ((in_out & 1) == 0) {
+		status = _cairo_bo_edge_end_trap (edge, top, bo_traps);
+		if (status)
+		    return status;
+		continue;
+	    }
 	}
 
-	status = _cairo_bo_edge_end_trap (left, top, traps);
-	if (unlikely (status))
+	status = _cairo_bo_edge_start_or_continue_trap (edge, top, bo_traps);
+	if (status)
 	    return status;
     }
 
-    if (right != NULL && ! edges_colinear (left, right)) {
-	left->deferred_trap.top = top;
-	left->deferred_trap.right = right;
-
-#if DEBUG_EVENTS
-	event_log ("begin trap: %lu %lu %d\n",
-		   (long) left,
-		   (long) right,
-		   top);
-#endif
-    }
-
     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_bo_edge_t *right;
-    cairo_status_t status;
-
-#if DEBUG_PRINT_STATE
-    printf ("Processing active edges for %x\n", top);
-#endif
-
-    if (fill_rule == CAIRO_FILL_RULE_WINDING) {
-	while (left != NULL) {
-	    int in_out;
-
-	    /* Greedily search for the closing edge, so that we generate the
-	     * maximal span width with the minimal number of trapezoids.
-	     */
-	    in_out = left->edge.dir;
-
-	    /* Check if there is a co-linear edge with an existing trap */
-	    right = left->next;
-	    if (left->deferred_trap.right == NULL) {
-		while (right != NULL && right->deferred_trap.right == NULL)
-		    right = right->next;
-
-		if (right != NULL && edges_colinear (left, right)) {
-		    /* continuation on left */
-		    left->deferred_trap = right->deferred_trap;
-		    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);
-		    if (unlikely (status))
-			return status;
-		}
-
-		in_out += right->edge.dir;
-		if (in_out == 0) {
-		    cairo_bo_edge_t *next;
-		    cairo_bool_t skip = FALSE;
-
-		    /* skip co-linear edges */
-		    next = right->next;
-		    if (next != NULL)
-			skip = edges_colinear (right, next);
-
-		    if (! skip)
-			break;
-		}
-
-		right = right->next;
-	    }
-
-	    status = _cairo_bo_edge_start_or_continue_trap (left, right,
-							    top, traps);
-	    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);
-		    if (unlikely (status))
-			return status;
-		}
-
-		if ((in_out++ & 1) == 0) {
-		    cairo_bo_edge_t *next;
-		    cairo_bool_t skip = FALSE;
-
-		    /* skip co-linear edges */
-		    next = right->next;
-		    if (next != NULL)
-			skip = edges_colinear (right, next);
-
-		    if (! skip)
-			break;
-		}
-
-		right = right->next;
-	    }
-
-	    status = _cairo_bo_edge_start_or_continue_trap (left, right,
-							    top, traps);
-	    if (unlikely (status))
-		return status;
-
-	    left = right;
-	    if (left != NULL)
-		left = left->next;
-	}
-    }
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-
 /* Execute a single pass of the Bentley-Ottmann algorithm on edges,
  * generating trapezoids according to the fill_rule and appending them
  * to traps. */
 static cairo_status_t
-_cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_event_t   **start_events,
-					    int			 num_events,
+_cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_edge_t	*edges,
+					    int			 num_edges,
 					    cairo_fill_rule_t	 fill_rule,
 					    cairo_traps_t	*traps,
+					    cairo_fixed_t	xmin,
+					    cairo_fixed_t	ymin,
+					    cairo_fixed_t	xmax,
+					    cairo_fixed_t	ymax,
 					    int			*num_intersections)
 {
-    cairo_status_t status = CAIRO_STATUS_SUCCESS; /* silence compiler */
+    cairo_status_t status;
     int intersection_count = 0;
     cairo_bo_event_queue_t event_queue;
     cairo_bo_sweep_line_t sweep_line;
-    cairo_bo_event_t *event;
+    cairo_bo_traps_t bo_traps;
+    cairo_bo_event_t *event, event_saved;
+    cairo_bo_edge_t *edge;
     cairo_bo_edge_t *left, *right;
-    cairo_bo_edge_t *e1, *e2;
+    cairo_bo_edge_t *edge1, *edge2;
 
-#if DEBUG_EVENTS
-    {
-	int i;
+    if (num_edges == 0)
+	return CAIRO_STATUS_SUCCESS;
 
-	for (i = 0; i < num_events; i++) {
-	    cairo_bo_start_event_t *event =
-		((cairo_bo_start_event_t **) start_events)[i];
-	    event_log ("edge: %lu (%d, %d) (%d, %d) (%d, %d) %d\n",
-		       (long) &events[i].edge,
-		       event->edge.edge.line.p1.x,
-		       event->edge.edge.line.p1.y,
-		       event->edge.edge.line.p2.x,
-		       event->edge.edge.line.p2.y,
-		       event->edge.top,
-		       event->edge.bottom,
-		       event->edge.edge.dir);
-	}
-    }
+    status = _cairo_bo_event_queue_init (&event_queue, edges, num_edges);
+    if (status)
+	return status;
+
+    _cairo_bo_sweep_line_init (&sweep_line);
+
+    _cairo_bo_traps_init (&bo_traps, traps, xmin, ymin, xmax, ymax);
+
+#if DEBUG_PRINT_STATE
+    print_state ("After initializing", &event_queue, &sweep_line);
 #endif
 
-    _cairo_bo_event_queue_init (&event_queue, start_events, num_events);
-    _cairo_bo_sweep_line_init (&sweep_line);
+    while (1)
+    {
+	event = _cairo_bo_event_dequeue (&event_queue);
+	if (!event)
+	    break;
 
-    while ((event = _cairo_bo_event_dequeue (&event_queue))) {
 	if (event->point.y != sweep_line.current_y) {
-	    for (e1 = sweep_line.stopped; e1; e1 = e1->next) {
-		if (e1->deferred_trap.right != NULL) {
-		    status = _cairo_bo_edge_end_trap (e1,
-						      e1->edge.bottom,
-						      traps);
-		    if (unlikely (status))
-			goto unwind;
-		}
-	    }
-	    sweep_line.stopped = NULL;
-
 	    status = _active_edges_to_traps (sweep_line.head,
 					     sweep_line.current_y,
-					     fill_rule, traps);
-	    if (unlikely (status))
+					     fill_rule, &bo_traps);
+	    if (status)
 		goto unwind;
 
 	    sweep_line.current_y = event->point.y;
 	}
 
-#if DEBUG_EVENTS
-	event_log ("event: %d (%ld, %ld) %lu, %lu\n",
-		   event->type,
-		   (long) event->point.x,
-		   (long) event->point.y,
-		   (long) event->e1,
-		   (long) event->e2);
-#endif
+	event_saved = *event;
+	_cairo_bo_event_queue_delete (&event_queue, event);
+	event = &event_saved;
 
 	switch (event->type) {
 	case CAIRO_BO_EVENT_TYPE_START:
-	    e1 = &((cairo_bo_start_event_t *) event)->edge;
+	    edge = event->e1;
 
-	    status = _cairo_bo_sweep_line_insert (&sweep_line, e1);
-	    if (unlikely (status))
+	    status = _cairo_bo_sweep_line_insert (&sweep_line, edge);
+	    if (status)
 		goto unwind;
+	    /* Cache the insert position for use in pass 2.
+	    event->e2 = Sortlist::prev (sweep_line, edge);
+	    */
 
-	    status = _cairo_bo_event_queue_insert_stop (&event_queue, e1);
-	    if (unlikely (status))
+	    left = edge->prev;
+	    right = edge->next;
+
+	    status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, edge);
+	    if (status)
 		goto unwind;
 
-	    /* check to see if this is a continuation of a stopped edge */
-	    /* XXX change to an infinitesimal lengthening rule */
-	    for (left = sweep_line.stopped; left; left = left->next) {
-		if (e1->edge.top <= left->edge.bottom &&
-		    edges_colinear (e1, left))
-		{
-		    e1->deferred_trap = left->deferred_trap;
-		    if (left->prev != NULL)
-			left->prev = left->next;
-		    else
-			sweep_line.stopped = left->next;
-		    if (left->next != NULL)
-			left->next->prev = left->prev;
-		    break;
-		}
-	    }
+	    status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, edge, right);
+	    if (status)
+		goto unwind;
 
-	    left = e1->prev;
-	    right = e1->next;
-
-	    if (left != NULL) {
-		status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, e1);
-		if (unlikely (status))
-		    goto unwind;
-	    }
-
-	    if (right != NULL) {
-		status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, e1, right);
-		if (unlikely (status))
-		    goto unwind;
-	    }
-
+#if DEBUG_PRINT_STATE
+	    print_state ("After processing start", &event_queue, &sweep_line);
+#endif
 	    break;
 
 	case CAIRO_BO_EVENT_TYPE_STOP:
-	    e1 = ((cairo_bo_queue_event_t *) event)->e1;
-	    _cairo_bo_event_queue_delete (&event_queue, event);
+	    edge = event->e1;
 
-	    left = e1->prev;
-	    right = e1->next;
+	    left = edge->prev;
+	    right = edge->next;
 
-	    _cairo_bo_sweep_line_delete (&sweep_line, e1);
+	    _cairo_bo_sweep_line_delete (&sweep_line, edge);
 
-	    /* first, check to see if we have a continuation via a fresh edge */
-	    if (e1->deferred_trap.right != NULL) {
-		e1->next = sweep_line.stopped;
-		if (sweep_line.stopped != NULL)
-		    sweep_line.stopped->prev = e1;
-		sweep_line.stopped = e1;
-		e1->prev = NULL;
-	    }
+	    status = _cairo_bo_edge_end_trap (edge, edge->bottom.y, &bo_traps);
+	    if (status)
+		goto unwind;
 
-	    if (left != NULL && right != NULL) {
-		status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, right);
-		if (unlikely (status))
-		    goto unwind;
-	    }
+	    status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, right);
+	    if (status)
+		goto unwind;
 
+#if DEBUG_PRINT_STATE
+	    print_state ("After processing stop", &event_queue, &sweep_line);
+#endif
 	    break;
 
 	case CAIRO_BO_EVENT_TYPE_INTERSECTION:
-	    e1 = ((cairo_bo_queue_event_t *) event)->e1;
-	    e2 = ((cairo_bo_queue_event_t *) event)->e2;
-	    _cairo_bo_event_queue_delete (&event_queue, event);
+	    edge1 = event->e1;
+	    edge2 = event->e2;
 
 	    /* skip this intersection if its edges are not adjacent */
-	    if (e2 != e1->next)
+	    if (edge2 != edge1->next)
 		break;
 
 	    intersection_count++;
 
-	    left = e1->prev;
-	    right = e2->next;
+	    edge1->middle = event->point;
+	    edge2->middle = event->point;
 
-	    _cairo_bo_sweep_line_swap (&sweep_line, e1, e2);
+	    left = edge1->prev;
+	    right = edge2->next;
+
+	    _cairo_bo_sweep_line_swap (&sweep_line, edge1, edge2);
 
 	    /* after the swap e2 is left of e1 */
 
-	    if (left != NULL) {
-		status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, e2);
-		if (unlikely (status))
-		    goto unwind;
-	    }
+	    status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue,
+								       left, edge2);
+	    if (status)
+		goto unwind;
 
-	    if (right != NULL) {
-		status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, e1, right);
-		if (unlikely (status))
-		    goto unwind;
-	    }
+	    status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue,
+								       edge1, right);
+	    if (status)
+		goto unwind;
 
+#if DEBUG_PRINT_STATE
+	    print_state ("After processing intersection", &event_queue, &sweep_line);
+#endif
 	    break;
 	}
+#if DEBUG_VALIDATE
+	_cairo_bo_sweep_line_validate (&sweep_line);
+#endif
     }
 
     *num_intersections = intersection_count;
-    for (e1 = sweep_line.stopped; e1; e1 = e1->next) {
-	if (e1->deferred_trap.right != NULL) {
-	    status = _cairo_bo_edge_end_trap (e1, e1->edge.bottom, traps);
-	    if (unlikely (status))
-		break;
-	}
+ unwind:
+    for (edge = sweep_line.head; edge; edge = edge->next) {
+	cairo_status_t status2 = _cairo_bo_edge_end_trap (edge,
+							  sweep_line.current_y,
+							  &bo_traps);
+	if (!status)
+	    status = status2;
     }
- unwind:
+    _cairo_bo_traps_fini (&bo_traps);
+    _cairo_bo_sweep_line_fini (&sweep_line);
     _cairo_bo_event_queue_fini (&event_queue);
+    return status;
+}
 
-#if DEBUG_EVENTS
-    event_log ("\n");
-#endif
-
-    return status;
+static void
+update_minmax(cairo_fixed_t *inout_min,
+	      cairo_fixed_t *inout_max,
+	      cairo_fixed_t v)
+{
+    if (v < *inout_min)
+	*inout_min = v;
+    if (v > *inout_max)
+	*inout_max = v;
 }
 
 cairo_status_t
 _cairo_bentley_ottmann_tessellate_polygon (cairo_traps_t	 *traps,
 					   const cairo_polygon_t *polygon,
 					   cairo_fill_rule_t	  fill_rule)
 {
     int intersections;
     cairo_status_t status;
-    cairo_bo_start_event_t stack_events[CAIRO_STACK_ARRAY_LENGTH (cairo_bo_start_event_t)];
-    cairo_bo_start_event_t *events;
-    cairo_bo_event_t *stack_event_ptrs[ARRAY_LENGTH (stack_events) + 1];
-    cairo_bo_event_t **event_ptrs;
-    int num_events;
+    cairo_bo_edge_t stack_edges[CAIRO_STACK_ARRAY_LENGTH (cairo_bo_edge_t)];
+    cairo_bo_edge_t *edges;
+    cairo_fixed_t xmin = 0x7FFFFFFF;
+    cairo_fixed_t ymin = 0x7FFFFFFF;
+    cairo_fixed_t xmax = -0x80000000;
+    cairo_fixed_t ymax = -0x80000000;
+    cairo_box_t limit;
+    cairo_bool_t has_limits;
+    int num_bo_edges;
     int i;
 
-    num_events = polygon->num_edges;
-    if (unlikely (0 == num_events))
+    if (0 == polygon->num_edges)
 	return CAIRO_STATUS_SUCCESS;
 
-    events = stack_events;
-    event_ptrs = stack_event_ptrs;
-    if (num_events > ARRAY_LENGTH (stack_events)) {
-	events = _cairo_malloc_ab_plus_c (num_events,
-					  sizeof (cairo_bo_start_event_t) +
-					  sizeof (cairo_bo_event_t *),
-					  sizeof (cairo_bo_event_t *));
-	if (unlikely (events == NULL))
+    if (CAIRO_INJECT_FAULT ())
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    has_limits = _cairo_traps_get_limit (traps, &limit);
+
+    edges = stack_edges;
+    if (polygon->num_edges > ARRAY_LENGTH (stack_edges)) {
+	edges = _cairo_malloc_ab (polygon->num_edges, sizeof (cairo_bo_edge_t));
+	if (unlikely (edges == NULL))
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    }
 
-	event_ptrs = (cairo_bo_event_t **) (events + num_events);
+    /* Figure out the bounding box of the input coordinates and
+     * validate that we're not given invalid polygon edges. */
+    for (i = 0; i < polygon->num_edges; i++) {
+	update_minmax (&xmin, &xmax, polygon->edges[i].edge.p1.x);
+	update_minmax (&ymin, &ymax, polygon->edges[i].edge.p1.y);
+	update_minmax (&xmin, &xmax, polygon->edges[i].edge.p2.x);
+	update_minmax (&ymin, &ymax, polygon->edges[i].edge.p2.y);
+	assert (polygon->edges[i].edge.p1.y <= polygon->edges[i].edge.p2.y &&
+		"BUG: tessellator given upside down or horizontal edges");
     }
 
-    for (i = 0; i < num_events; i++) {
-	event_ptrs[i] = (cairo_bo_event_t *) &events[i];
+    /* The tessellation functions currently assume that no line
+     * segment extends more than 2^31-1 in either dimension.  We
+     * guarantee this by offsetting the internal coordinates to the
+     * range [0,2^31-1], and clamping to 2^31-1 if a coordinate
+     * exceeds the range (and yes, this generates an incorrect
+     * result).  First we have to clamp the bounding box itself. */
+    /* XXX: Rather than changing the input values, a better approach
+     * would be to detect out-of-bounds input and return a
+     * CAIRO_STATUS_OVERFLOW value to the user. */
+    if (xmax - xmin < 0)
+	xmax = xmin + 0x7FFFFFFF;
+    if (ymax - ymin < 0)
+	ymax = ymin + 0x7FFFFFFF;
 
-	events[i].type = CAIRO_BO_EVENT_TYPE_START;
-	events[i].point.y = polygon->edges[i].top;
-	events[i].point.x =
-	    _line_compute_intersection_x_for_y (&polygon->edges[i].line,
-						events[i].point.y);
+    for (i = 0, num_bo_edges = 0; i < polygon->num_edges; i++) {
+	cairo_bo_edge_t *edge = &edges[num_bo_edges];
+	cairo_point_t top = polygon->edges[i].edge.p1;
+	cairo_point_t bot = polygon->edges[i].edge.p2;
+
+	/* Discard the edge if it lies outside the limits of traps. */
+	if (has_limits) {
+	    /* Strictly above or below the limits? */
+	    if (bot.y <= limit.p1.y || top.y >= limit.p2.y)
+		continue;
+	}
 
-	events[i].edge.edge = polygon->edges[i];
-	events[i].edge.deferred_trap.right = NULL;
-	events[i].edge.prev = NULL;
-	events[i].edge.next = NULL;
+	/* Offset coordinates into the non-negative range. */
+	top.x -= xmin;
+	top.y -= ymin;
+	bot.x -= xmin;
+	bot.y -= ymin;
+
+	/* If the coordinates are still negative, then their extent is
+	 * overflowing 2^31-1.  We're going to kludge it and clamp the
+	 * coordinates into the clamped bounding box.  */
+	if (top.x < 0) top.x = xmax - xmin;
+	if (top.y < 0) top.y = ymax - ymin;
+	if (bot.x < 0) bot.x = xmax - xmin;
+	if (bot.y < 0) bot.y = ymax - ymin;
+
+	if (top.y == bot.y) {
+	    /* Clamping might have produced horizontal edges.  Ignore
+	     * those. */
+	    continue;
+	}
+	assert (top.y < bot.y &&
+		"BUG: clamping the input range flipped the "
+		"orientation of an edge");
+
+	edge->top.x = top.x;
+	edge->top.y = top.y;
+	edge->bottom.x = bot.x;
+	edge->bottom.y = bot.y;
+	edge->dir = polygon->edges[i].dir;
+	edge->deferred_trap = NULL;
+	edge->prev = NULL;
+	edge->next = NULL;
+	edge->sweep_line_elt = NULL;
+
+	num_bo_edges++;
     }
 
-#if DEBUG_TRAPS
-    dump_edges (events, num_events, "bo-polygon-edges.txt");
-#endif
-
     /* XXX: This would be the convenient place to throw in multiple
      * passes of the Bentley-Ottmann algorithm. It would merely
      * require storing the results of each pass into a temporary
      * cairo_traps_t. */
-    status = _cairo_bentley_ottmann_tessellate_bo_edges (event_ptrs,
-							 num_events,
+    status = _cairo_bentley_ottmann_tessellate_bo_edges (edges, num_bo_edges,
 							 fill_rule, traps,
+							 xmin, ymin, xmax, ymax,
 							 &intersections);
-#if DEBUG_TRAPS
-    dump_traps (traps, "bo-polygon-out.txt");
-#endif
-
-    if (events != stack_events)
-	free (events);
-
-    return status;
-}
-
-cairo_status_t
-_cairo_bentley_ottmann_tessellate_traps (cairo_traps_t *traps,
-					 cairo_fill_rule_t fill_rule)
-{
-    cairo_status_t status;
-    cairo_polygon_t polygon;
-    int i;
-
-    if (unlikely (0 == traps->num_traps))
-	return CAIRO_STATUS_SUCCESS;
-
-#if DEBUG_TRAPS
-    dump_traps (traps, "bo-traps-in.txt");
-#endif
 
-    _cairo_polygon_init (&polygon);
-    _cairo_polygon_limit (&polygon, traps->limits, traps->num_limits);
-
-    for (i = 0; i < traps->num_traps; i++) {
-	status = _cairo_polygon_add_line (&polygon,
-					  &traps->traps[i].left,
-					  traps->traps[i].top,
-					  traps->traps[i].bottom,
-					  1);
-	if (unlikely (status))
-	    goto CLEANUP;
-
-	status = _cairo_polygon_add_line (&polygon,
-					  &traps->traps[i].right,
-					  traps->traps[i].top,
-					  traps->traps[i].bottom,
-					  -1);
-	if (unlikely (status))
-	    goto CLEANUP;
-    }
-
-    _cairo_traps_clear (traps);
-    status = _cairo_bentley_ottmann_tessellate_polygon (traps,
-							&polygon,
-							fill_rule);
-
-#if DEBUG_TRAPS
-    dump_traps (traps, "bo-traps-out.txt");
-#endif
-
-  CLEANUP:
-    _cairo_polygon_fini (&polygon);
+    if (edges != stack_edges)
+	free (edges);
 
     return status;
 }
 
 #if 0
 static cairo_bool_t
 edges_have_an_intersection_quadratic (cairo_bo_edge_t	*edges,
 				      int		 num_edges)
 
 {
     int i, j;
     cairo_bo_edge_t *a, *b;
     cairo_bo_point32_t intersection;
+    cairo_bo_status_t status;
 
     /* We must not be given any upside-down edges. */
     for (i = 0; i < num_edges; i++) {
 	assert (_cairo_bo_point32_compare (&edges[i].top, &edges[i].bottom) < 0);
-	edges[i].line.p1.x <<= CAIRO_BO_GUARD_BITS;
-	edges[i].line.p1.y <<= CAIRO_BO_GUARD_BITS;
-	edges[i].line.p2.x <<= CAIRO_BO_GUARD_BITS;
-	edges[i].line.p2.y <<= CAIRO_BO_GUARD_BITS;
+	edges[i].top.x <<= CAIRO_BO_GUARD_BITS;
+	edges[i].top.y <<= CAIRO_BO_GUARD_BITS;
+	edges[i].bottom.x <<= CAIRO_BO_GUARD_BITS;
+	edges[i].bottom.y <<= CAIRO_BO_GUARD_BITS;
     }
 
     for (i = 0; i < num_edges; i++) {
 	for (j = 0; j < num_edges; j++) {
 	    if (i == j)
 		continue;
 
 	    a = &edges[i];
 	    b = &edges[j];
 
-	    if (! _cairo_bo_edge_intersect (a, b, &intersection))
+	    status = _cairo_bo_edge_intersect (a, b, &intersection);
+	    if (status == CAIRO_BO_STATUS_PARALLEL ||
+		status == CAIRO_BO_STATUS_NO_INTERSECTION)
+	    {
 		continue;
+	    }
 
 	    printf ("Found intersection (%d,%d) between (%d,%d)-(%d,%d) and (%d,%d)-(%d,%d)\n",
 		    intersection.x,
 		    intersection.y,
-		    a->line.p1.x, a->line.p1.y,
-		    a->line.p2.x, a->line.p2.y,
-		    b->line.p1.x, b->line.p1.y,
-		    b->line.p2.x, b->line.p2.y);
+		    a->top.x, a->top.y,
+		    a->bottom.x, a->bottom.y,
+		    b->top.x, b->top.y,
+		    b->bottom.x, b->bottom.y);
 
 	    return TRUE;
 	}
     }
     return FALSE;
 }
 
 #define TEST_MAX_EDGES 10
@@ -2101,28 +2036,29 @@ main (void)
 	run_test (test->name, test->edges, test->num_edges);
     }
 
     for (num_random = 0; num_random < MAX_RANDOM; num_random++) {
 	srand (0);
 	for (i = 0; i < num_random; i++) {
 	    do {
 		edge = &random_edges[i];
-		edge->line.p1.x = (int32_t) (10.0 * (rand() / (RAND_MAX + 1.0)));
-		edge->line.p1.y = (int32_t) (10.0 * (rand() / (RAND_MAX + 1.0)));
-		edge->line.p2.x = (int32_t) (10.0 * (rand() / (RAND_MAX + 1.0)));
-		edge->line.p2.y = (int32_t) (10.0 * (rand() / (RAND_MAX + 1.0)));
-		if (edge->line.p1.y > edge->line.p2.y) {
-		    int32_t tmp = edge->line.p1.y;
-		    edge->line.p1.y = edge->line.p2.y;
-		    edge->line.p2.y = tmp;
+		edge->top.x = (int32_t) (10.0 * (rand() / (RAND_MAX + 1.0)));
+		edge->top.y = (int32_t) (10.0 * (rand() / (RAND_MAX + 1.0)));
+		edge->bottom.x = (int32_t) (10.0 * (rand() / (RAND_MAX + 1.0)));
+		edge->bottom.y = (int32_t) (10.0 * (rand() / (RAND_MAX + 1.0)));
+		if (edge->top.y > edge->bottom.y) {
+		    int32_t tmp = edge->top.y;
+		    edge->top.y = edge->bottom.y;
+		    edge->bottom.y = tmp;
 		}
-	    } while (edge->line.p1.y == edge->line.p2.y);
+	    } while (edge->top.y == edge->bottom.y);
 	}
 
 	sprintf (random_name, "random-%02d", num_random);
 
 	run_test (random_name, random_edges, num_random);
     }
 
     return 0;
 }
 #endif
+
--- a/gfx/cairo/cairo/src/cairo-clip-private.h
+++ b/gfx/cairo/cairo/src/cairo-clip-private.h
@@ -38,100 +38,97 @@
 
 #include "cairo-types-private.h"
 #include "cairo-compiler-private.h"
 #include "cairo-path-fixed-private.h"
 #include "cairo-reference-count-private.h"
 
 extern const cairo_private cairo_rectangle_list_t _cairo_rectangles_nil;
 
-enum {
-    CAIRO_CLIP_PATH_HAS_REGION = 0x1,
-    CAIRO_CLIP_PATH_REGION_IS_UNSUPPORTED = 0x2,
-    CAIRO_CLIP_PATH_IS_BOX = 0x4
-};
-
 struct _cairo_clip_path {
     cairo_reference_count_t	 ref_count;
     cairo_path_fixed_t		 path;
     cairo_fill_rule_t		 fill_rule;
     double			 tolerance;
     cairo_antialias_t		 antialias;
     cairo_clip_path_t		*prev;
-
-    cairo_rectangle_int_t extents;
-
-    /* partial caches */
-    unsigned int flags;
-    cairo_region_t *region;
-    cairo_surface_t *surface;
 };
 
 struct _cairo_clip {
-    /* can be used as a cairo_hash_entry_t for live clips */
-    cairo_clip_path_t *path;
+    cairo_clip_mode_t mode;
 
     cairo_bool_t all_clipped;
 
+    /*
+     * Mask-based clipping for cases where the backend
+     * clipping isn't sufficiently able.
+     *
+     * The rectangle here represents the
+     * portion of the destination surface that this
+     * clip surface maps to, it does not
+     * represent the extents of the clip region or
+     * clip paths
+     */
+    cairo_surface_t *surface;
+    cairo_rectangle_int_t surface_rect;
+    /*
+     * Surface clip serial number to store
+     * in the surface when this clip is set
+     */
+    unsigned int serial;
+    /*
+     * A clip region that can be placed in the surface
+     */
+    cairo_region_t *region;
+    /*
+     * If the surface supports path clipping, we store the list of
+     * clipping paths that has been set here as a linked list.
+     */
+    cairo_clip_path_t *path;
 };
 
 cairo_private void
-_cairo_clip_init (cairo_clip_t *clip);
+_cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target);
 
 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_clip_init_deep_copy (cairo_clip_t    *clip,
+                            cairo_clip_t    *other,
+                            cairo_surface_t *target);
 
 cairo_private void
 _cairo_clip_reset (cairo_clip_t *clip);
 
-#define _cairo_clip_fini(clip) _cairo_clip_reset (clip)
+cairo_private cairo_status_t
+_cairo_clip_clip (cairo_clip_t       *clip,
+		  cairo_path_fixed_t *path,
+		  cairo_fill_rule_t   fill_rule,
+		  double              tolerance,
+		  cairo_antialias_t   antialias,
+		  cairo_surface_t    *target);
 
 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,
-		  const cairo_path_fixed_t *path,
-		  cairo_fill_rule_t   fill_rule,
-		  double              tolerance,
-		  cairo_antialias_t   antialias);
+_cairo_clip_intersect_to_rectangle (cairo_clip_t            *clip,
+				    cairo_rectangle_int_t   *rectangle);
 
 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_intersect_to_region (cairo_clip_t      *clip,
+				 cairo_region_t *region);
 
 cairo_private cairo_status_t
-_cairo_clip_combine_with_surface (cairo_clip_t *clip,
-				  cairo_surface_t *dst,
-				  const cairo_rectangle_int_t *extents);
-
-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_clip_combine_to_surface (cairo_clip_t                  *clip,
+				cairo_operator_t               op,
+				cairo_surface_t               *dst,
+				int                            dst_x,
+				int                            dst_y,
+				const cairo_rectangle_int_t   *extents);
 
 cairo_private void
-_cairo_clip_drop_cache (cairo_clip_t  *clip);
+_cairo_clip_translate (cairo_clip_t  *clip,
+                       cairo_fixed_t  tx,
+                       cairo_fixed_t  ty);
 
 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
@@ -1,14 +1,13 @@
 /* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
 /* cairo - a vector graphics library with display and print output
  *
  * Copyright © 2002 University of Southern California
  * Copyright © 2005 Red Hat, Inc.
- * Copyright © 2009 Chris Wilson
  *
  * 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.
@@ -31,133 +30,265 @@
  * The Original Code is the cairo graphics library.
  *
  * The Initial Developer of the Original Code is University of Southern
  * California.
  *
  * Contributor(s):
  *	Carl D. Worth <cworth@cworth.org>
  *	Kristian Høgsberg <krh@redhat.com>
- *	Chris Wilson <chris@chris-wilson.co.uk>
  */
 
 #include "cairoint.h"
 #include "cairo-clip-private.h"
-#include "cairo-path-fixed-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;
+static cairo_clip_path_t *
+_cairo_clip_path_reference (cairo_clip_path_t *clip_path);
+
+static void
+_cairo_clip_path_destroy (cairo_clip_path_t *clip_path);
 
-static freed_pool_t clip_path_pool;
-
-static void *
-_atomic_fetch (void **slot)
+void
+_cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target)
 {
-    return _cairo_atomic_ptr_cmpxchg (slot, *slot, NULL);
-}
+    if (target && target->backend)
+	clip->mode = _cairo_surface_get_clip_mode (target);
+    else
+	clip->mode = CAIRO_CLIP_MODE_MASK;
+
+    clip->all_clipped = FALSE;
 
-static cairo_bool_t
-_atomic_store (void **slot, void *ptr)
-{
-    return _cairo_atomic_ptr_cmpxchg (slot, NULL, ptr) == NULL;
+    clip->surface = NULL;
+    clip->surface_rect.x = 0;
+    clip->surface_rect.y = 0;
+    clip->surface_rect.width  = 0;
+    clip->surface_rect.height = 0;
+
+    clip->serial = 0;
+
+    clip->region = NULL;
+
+    clip->path = NULL;
 }
 
-static void *
-_freed_pool_get (freed_pool_t *pool)
+cairo_status_t
+_cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
 {
-    void *ptr;
-    int i;
+    clip->mode = other->mode;
+
+    clip->all_clipped = other->all_clipped;
+    
+    clip->surface = cairo_surface_reference (other->surface);
+    clip->surface_rect = other->surface_rect;
+
+    clip->serial = other->serial;
+
+    if (other->region) {
+	cairo_status_t status;
+	
+	clip->region = cairo_region_copy (other->region);
 
-    i = pool->top - 1;
-    if (i < 0)
-	i = 0;
+	status = cairo_region_status (clip->region);
+	if (unlikely (status)) {
+	    cairo_surface_destroy (clip->surface);
+	    cairo_region_destroy (clip->region);
+	    clip->region = NULL;
+	    
+	    return status;
+	}
+    } else {
+	clip->region = NULL;
+    }
+    
+    clip->path = _cairo_clip_path_reference (other->path);
 
-    ptr = _atomic_fetch (&pool->pool[i]);
-    if (ptr != NULL) {
-	pool->top = i;
-	return ptr;
+    return CAIRO_STATUS_SUCCESS;
+}
+
+void
+_cairo_clip_reset (cairo_clip_t *clip)
+{
+    clip->all_clipped = FALSE;
+
+    /* destroy any existing clip-region artifacts */
+    cairo_surface_destroy (clip->surface);
+    clip->surface = NULL;
+
+    clip->serial = 0;
+
+    if (clip->region) {
+	cairo_region_destroy (clip->region);
+
+	clip->region = NULL;
     }
 
-    /* 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;
+    _cairo_clip_path_destroy (clip->path);
+    clip->path = NULL;
 }
 
 static void
-_freed_pool_put (freed_pool_t *pool, void *ptr)
+_cairo_clip_set_all_clipped (cairo_clip_t *clip, cairo_surface_t *target)
 {
-    int i = pool->top;
+    _cairo_clip_reset (clip);
+
+    clip->all_clipped = TRUE;
+    clip->serial = _cairo_surface_allocate_clip_serial (target);
+}
+
 
-    if (_atomic_store (&pool->pool[i], ptr)) {
-	pool->top = i + 1;
-	return;
+static cairo_status_t
+_cairo_clip_path_intersect_to_rectangle (cairo_clip_path_t       *clip_path,
+				         cairo_rectangle_int_t   *rectangle)
+{
+    while (clip_path) {
+        cairo_rectangle_int_t extents;
+
+	_cairo_path_fixed_approximate_clip_extents (&clip_path->path, &extents);
+
+        if (! _cairo_rectangle_intersect (rectangle, &extents))
+	    return CAIRO_STATUS_SUCCESS;
+
+        clip_path = clip_path->prev;
     }
 
-    /* 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;
-	}
+    return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_status_t
+_cairo_clip_intersect_to_rectangle (cairo_clip_t            *clip,
+				    cairo_rectangle_int_t *rectangle)
+{
+    cairo_status_t status;
+    cairo_bool_t is_empty;
+
+    if (!clip)
+	return CAIRO_STATUS_SUCCESS;
+
+    if (clip->all_clipped) {
+	*rectangle = clip->surface_rect;
+	return CAIRO_STATUS_SUCCESS;
     }
 
-    /* full */
-    pool->top = ARRAY_LENGTH (pool->pool);
-    free (ptr);
+    if (clip->path) {
+        status = _cairo_clip_path_intersect_to_rectangle (clip->path,
+                                                          rectangle);
+        if (unlikely (status))
+            return status;
+    }
+
+    if (clip->region) {
+	cairo_rectangle_int_t extents;
+
+	cairo_region_get_extents (clip->region, &extents);
+	is_empty = _cairo_rectangle_intersect (rectangle, &extents);
+	if (is_empty)
+	    return CAIRO_STATUS_SUCCESS;
+    }
+
+    if (clip->surface)
+	is_empty = _cairo_rectangle_intersect (rectangle, &clip->surface_rect);
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
-static void
-_freed_pool_reset (freed_pool_t *pool)
+cairo_status_t
+_cairo_clip_intersect_to_region (cairo_clip_t   *clip,
+				 cairo_region_t *region)
 {
-    int i;
+    cairo_status_t status;
+
+    if (!clip)
+	return CAIRO_STATUS_SUCCESS;
+
+    if (clip->all_clipped)
+	return cairo_region_intersect_rectangle (region, &clip->surface_rect);
 
-    for (i = 0; i < ARRAY_LENGTH (pool->pool); i++) {
-	free (pool->pool[i]);
-	pool->pool[i] = NULL;
+    if (clip->path) {
+	/* Intersect clip path into region. */
     }
+
+    if (clip->region) {
+	status = cairo_region_intersect (region, clip->region);
+	if (unlikely (status))
+	    return status;
+    }
+
+    if (clip->surface)
+	return cairo_region_intersect_rectangle (region, &clip->surface_rect);
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
-static cairo_clip_path_t *
-_cairo_clip_path_create (cairo_clip_t *clip)
+/* Combines the region of clip->surface given by extents in
+ * device backend coordinates into the given temporary surface,
+ * which has its origin at dst_x, dst_y in backend coordinates
+ */
+cairo_status_t
+_cairo_clip_combine_to_surface (cairo_clip_t                  *clip,
+				cairo_operator_t              op,
+				cairo_surface_t               *dst,
+				int                           dst_x,
+				int                           dst_y,
+				const cairo_rectangle_int_t *extents)
+{
+    cairo_surface_pattern_t pattern;
+    cairo_status_t status;
+
+    if (clip->all_clipped)
+	return CAIRO_STATUS_SUCCESS;
+
+    _cairo_pattern_init_for_surface (&pattern, clip->surface);
+
+    status = _cairo_surface_composite (op,
+				       &pattern.base,
+				       NULL,
+				       dst,
+				       extents->x - clip->surface_rect.x,
+				       extents->y - clip->surface_rect.y,
+				       0, 0,
+				       extents->x - dst_x,
+				       extents->y - dst_y,
+				       extents->width, extents->height);
+
+    _cairo_pattern_fini (&pattern.base);
+
+    return status;
+}
+
+static cairo_status_t
+_cairo_clip_intersect_path (cairo_clip_t       *clip,
+			    cairo_path_fixed_t *path,
+			    cairo_fill_rule_t   fill_rule,
+			    double              tolerance,
+			    cairo_antialias_t   antialias)
 {
     cairo_clip_path_t *clip_path;
+    cairo_status_t status;
 
-    clip_path = _freed_pool_get (&clip_path_pool);
-    if (unlikely (clip_path == NULL)) {
-	clip_path = malloc (sizeof (cairo_clip_path_t));
-	if (unlikely (clip_path == NULL))
-	    return NULL;
+    if (clip->mode != CAIRO_CLIP_MODE_PATH)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    clip_path = malloc (sizeof (cairo_clip_path_t));
+    if (unlikely (clip_path == NULL))
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    status = _cairo_path_fixed_init_copy (&clip_path->path, path);
+    if (unlikely (status)) {
+	free (clip_path);
+	return status;
     }
 
     CAIRO_REFERENCE_COUNT_INIT (&clip_path->ref_count, 1);
-
-    clip_path->flags = 0;
-    clip_path->region = NULL;
-    clip_path->surface = NULL;
-
+    clip_path->fill_rule = fill_rule;
+    clip_path->tolerance = tolerance;
+    clip_path->antialias = antialias;
     clip_path->prev = clip->path;
     clip->path = clip_path;
 
-    return clip_path;
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_clip_path_t *
 _cairo_clip_path_reference (cairo_clip_path_t *clip_path)
 {
     if (clip_path == NULL)
 	return NULL;
 
@@ -166,1187 +297,545 @@ static cairo_clip_path_t *
     _cairo_reference_count_inc (&clip_path->ref_count);
 
     return clip_path;
 }
 
 static void
 _cairo_clip_path_destroy (cairo_clip_path_t *clip_path)
 {
+    if (clip_path == NULL)
+	return;
+
     assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&clip_path->ref_count));
 
     if (! _cairo_reference_count_dec_and_test (&clip_path->ref_count))
 	return;
 
     _cairo_path_fixed_fini (&clip_path->path);
-    if (clip_path->region != NULL)
-	cairo_region_destroy (clip_path->region);
-    if (clip_path->surface != NULL)
-	cairo_surface_destroy (clip_path->surface);
-
-    if (clip_path->prev != NULL)
-	_cairo_clip_path_destroy (clip_path->prev);
-
-    _freed_pool_put (&clip_path_pool, clip_path);
+    _cairo_clip_path_destroy (clip_path->prev);
+    free (clip_path);
 }
 
-void
-_cairo_clip_init (cairo_clip_t *clip)
+
+static cairo_int_status_t
+_cairo_clip_intersect_region (cairo_clip_t    *clip,
+			      cairo_traps_t   *traps,
+			      cairo_surface_t *target)
 {
-    clip->all_clipped = FALSE;
-    clip->path = NULL;
-}
+    cairo_region_t *region;
+    cairo_int_status_t status;
+
+    if (clip->all_clipped)
+	return CAIRO_STATUS_SUCCESS;
+
+    if (clip->mode != CAIRO_CLIP_MODE_REGION)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-static void
-_cairo_clip_set_all_clipped (cairo_clip_t *clip)
-{
-    clip->all_clipped = TRUE;
-    if (clip->path != NULL) {
-	_cairo_clip_path_destroy (clip->path);
-	clip->path = NULL;
+    status = _cairo_traps_extract_region (traps, &region);
+    if (status)
+	return status;
+
+    if (clip->region) {
+	status = cairo_region_intersect (clip->region, region);
+	cairo_region_destroy (region);
+    } else {
+	clip->region = region;
     }
+
+    clip->serial = _cairo_surface_allocate_clip_serial (target);
+
+    if (!clip->region || cairo_region_is_empty (clip->region))
+	_cairo_clip_set_all_clipped (clip, target);
+
+    return status;
 }
 
 static cairo_status_t
-_cairo_clip_intersect_rectangle (cairo_clip_t *clip,
-				 const cairo_rectangle_int_t *rect)
+_cairo_clip_intersect_mask (cairo_clip_t      *clip,
+			    cairo_traps_t     *traps,
+			    cairo_antialias_t antialias,
+			    cairo_surface_t   *target)
 {
-    cairo_clip_path_t *clip_path;
-    cairo_status_t status;
+    cairo_pattern_union_t pattern;
+    cairo_box_t extents;
+    cairo_rectangle_int_t surface_rect, target_rect;
+    cairo_surface_t *surface = NULL;
+    cairo_status_t status = CAIRO_STATUS_SUCCESS;
 
-    if (clip->path != NULL) {
-	if (rect->x <= clip->path->extents.x &&
-	    rect->y <= clip->path->extents.y &&
-	    rect->x + rect->width >= clip->path->extents.x + clip->path->extents.width &&
-	    rect->y + rect->height >= clip->path->extents.y + clip->path->extents.height)
-	{
-	    return CAIRO_STATUS_SUCCESS;
-	}
+    if (clip->all_clipped)
+	return CAIRO_STATUS_SUCCESS;
+
+    /* Represent the clip as a mask surface.  We create a new surface
+     * the size of the intersection of the old mask surface and the
+     * extents of the new clip path. */
+
+    _cairo_traps_extents (traps, &extents);
+    _cairo_box_round_to_rectangle (&extents, &surface_rect);
+
+    if (clip->surface != NULL) {
+	if (! _cairo_rectangle_intersect (&surface_rect, &clip->surface_rect))
+	    goto DONE;
     }
 
-    clip_path = _cairo_clip_path_create (clip);
-    if (unlikely (clip_path == NULL))
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
-    _cairo_path_fixed_init (&clip_path->path);
-
-    status = _cairo_path_fixed_move_to (&clip_path->path,
-					_cairo_fixed_from_int (rect->x),
-					_cairo_fixed_from_int (rect->y));
-    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_rel_line_to (&clip_path->path,
-					    _cairo_fixed_from_int (0),
-					    _cairo_fixed_from_int (rect->height));
-    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->flags |= CAIRO_CLIP_PATH_IS_BOX;
-
-    /* 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;
+    /* Intersect with the target surface rectangle so we don't use
+     * more memory and time than we need to. */
+    status = _cairo_surface_get_extents (target, &target_rect);
+    if (status == CAIRO_STATUS_SUCCESS) {
+	if (! _cairo_rectangle_intersect (&surface_rect, &target_rect))
+	    goto DONE;
     }
 
-    return _cairo_clip_intersect_rectangle (clip, rect);
-}
+    if (surface_rect.width == 0 || surface_rect.height == 0)
+	goto DONE;
+
+    _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE,
+			       CAIRO_CONTENT_COLOR);
+    /* The clipping operation should ideally be something like the following to
+     * avoid having to do as many passes over the data
 
-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);
+	if (clip->surface != NULL) {
+	    _cairo_pattern_init_for_surface (&pattern.surface, clip->surface);
+	} else {
+	    _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE,
+			       CAIRO_CONTENT_COLOR);
+	}
+	status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_IN,
+						  &pattern.base,
+						  surface,
+						  antialias,
+						  0, 0,
+						  0, 0,
+						  surface_rect.width,
+						  surface_rect.height,
+						  traps->traps,
+						  traps->num_traps);
 
-	/* this guy is here because of the weird return semantics of _cairo_clip_init_copy */
-	if (!other->path)
-	    return NULL;
-    } else {
-	_cairo_clip_init (clip);
+	However this operation is not accelerated by pixman
+
+	I believe the best possible operation would probably an unbounded SRC
+	operator.  Using SRC we could potentially avoid having to initialize
+	the surface which would be ideal from an efficiency point of view.
+	However, CAIRO_OPERATOR_SOURCE is bounded by the trapezoid mask and
+	_cairo_surface_composite_trapezoids (CAIRO_OPERATOR_SOURCE) will assert
+	because it assumes CAIRO_OPERATOR_SOURCE has been converted into other
+	operations.
+    */
+
+    surface = _cairo_surface_create_similar_solid (target,
+						   CAIRO_CONTENT_ALPHA,
+						   surface_rect.width,
+						   surface_rect.height,
+						   CAIRO_COLOR_TRANSPARENT);
+    if (surface->status) {
+	_cairo_pattern_fini (&pattern.base);
+	return surface->status;
     }
 
-    return clip;
-}
-
-void
-_cairo_clip_reset (cairo_clip_t *clip)
-{
-    clip->all_clipped = FALSE;
-    if (clip->path != NULL) {
-	_cairo_clip_path_destroy (clip->path);
-	clip->path = NULL;
-    }
-}
+    /* Render the new clipping path into the new mask surface. */
 
-static cairo_status_t
-_cairo_clip_intersect_path (cairo_clip_t       *clip,
-			    const cairo_path_fixed_t *path,
-			    cairo_fill_rule_t   fill_rule,
-			    double              tolerance,
-			    cairo_antialias_t   antialias)
-{
-    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;
+    _cairo_traps_translate (traps, -surface_rect.x, -surface_rect.y);
 
-    if (clip->path != NULL) {
-	if (clip->path->fill_rule == fill_rule &&
-	    (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) {
-	_cairo_clip_set_all_clipped (clip);
-	return CAIRO_STATUS_SUCCESS;
-    }
+    status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_ADD,
+						  &pattern.base,
+						  surface,
+						  antialias,
+						  0, 0,
+						  0, 0,
+						  surface_rect.width,
+						  surface_rect.height,
+						  traps->traps,
+						  traps->num_traps);
 
-    is_box = _cairo_path_fixed_is_box (path, &box);
-    if (clip->path != NULL) {
-	if (! _cairo_rectangle_intersect (&extents, &clip->path->extents)) {
-	    _cairo_clip_set_all_clipped (clip);
-	    return CAIRO_STATUS_SUCCESS;
-	}
+    _cairo_pattern_fini (&pattern.base);
 
-	/* does this clip wholly subsume the others? */
-	if (is_box &&
-	    box.p1.x <= _cairo_fixed_from_int (clip->path->extents.x) &&
-	    box.p2.x >= _cairo_fixed_from_int (clip->path->extents.x + clip->path->extents.width) &&
-	    box.p1.y <= _cairo_fixed_from_int (clip->path->extents.y) &&
-	    box.p2.y >= _cairo_fixed_from_int (clip->path->extents.y + clip->path->extents.height))
-	{
-	    return CAIRO_STATUS_SUCCESS;
-	}
-    }
-
-    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, path);
     if (unlikely (status)) {
-	clip->path = clip->path->prev;
-	_cairo_clip_path_destroy (clip_path);
+	cairo_surface_destroy (surface);
 	return status;
     }
 
-    clip_path->extents = extents;
-    clip_path->fill_rule = fill_rule;
-    clip_path->tolerance = tolerance;
-    clip_path->antialias = antialias;
-    if (is_box)
-	clip_path->flags |= CAIRO_CLIP_PATH_IS_BOX;
-
-    return CAIRO_STATUS_SUCCESS;
-}
+    /* If there was a clip surface already, combine it with the new
+     * mask surface using the IN operator, so we get the intersection
+     * of the old and new clipping paths. */
 
-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)
-	return CAIRO_STATUS_SUCCESS;
-
-    /* catch the empty clip path */
-    if (_cairo_path_fixed_fill_is_empty (path)) {
-	_cairo_clip_set_all_clipped (clip);
-	return CAIRO_STATUS_SUCCESS;
-    }
+    if (clip->surface != NULL) {
+	_cairo_pattern_init_for_surface (&pattern.surface, clip->surface);
 
-    return _cairo_clip_intersect_path (clip,
-				       path, fill_rule, tolerance,
-				       antialias);
-}
-
-cairo_status_t
-_cairo_clip_rectangle (cairo_clip_t       *clip,
-		       const cairo_rectangle_int_t *rectangle)
-{
-    if (clip->all_clipped)
-	return CAIRO_STATUS_SUCCESS;
+	status = _cairo_surface_composite (CAIRO_OPERATOR_IN,
+					   &pattern.base,
+					   NULL,
+					   surface,
+					   surface_rect.x - clip->surface_rect.x,
+					   surface_rect.y - clip->surface_rect.y,
+					   0, 0,
+					   0, 0,
+					   surface_rect.width,
+					   surface_rect.height);
 
-    if (rectangle->width == 0 || rectangle->height == 0) {
-	_cairo_clip_set_all_clipped (clip);
-	return CAIRO_STATUS_SUCCESS;
-    }
+	_cairo_pattern_fini (&pattern.base);
 
-    /* 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.x &&
-	    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;
+	if (unlikely (status)) {
+	    cairo_surface_destroy (surface);
+	    return status;
 	}
     }
 
-    return _cairo_clip_intersect_rectangle (clip, rectangle);
-}
-
-static cairo_status_t
-_cairo_clip_path_reapply_clip_path_transform (cairo_clip_t      *clip,
-					      cairo_clip_path_t *other_path,
-					      const cairo_matrix_t *matrix)
-{
-    cairo_status_t status;
-    cairo_clip_path_t *clip_path;
-    cairo_bool_t is_empty;
-
-    if (other_path->prev != NULL) {
-        status = _cairo_clip_path_reapply_clip_path_transform (clip,
-							       other_path->prev,
-							       matrix);
-	if (unlikely (status))
-	    return status;
-    }
-
-    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)) {
-	_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) {
-	is_empty = _cairo_rectangle_intersect (&clip_path->extents,
-					       &clip_path->prev->extents);
-    }
-
-    clip_path->fill_rule = other_path->fill_rule;
-    clip_path->tolerance = other_path->tolerance;
-    clip_path->antialias = other_path->antialias;
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-_cairo_clip_path_reapply_clip_path_translate (cairo_clip_t      *clip,
-					      cairo_clip_path_t *other_path,
-					      int tx, int ty)
-{
-    cairo_status_t status;
-    cairo_clip_path_t *clip_path;
-
-    if (other_path->prev != NULL) {
-        status = _cairo_clip_path_reapply_clip_path_translate (clip,
-							       other_path->prev,
-							       tx, ty);
-	if (unlikely (status))
-	    return status;
-    }
-
-    clip_path = _cairo_clip_path_create (clip);
-    if (unlikely (clip_path == NULL))
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ DONE:
+    cairo_surface_destroy (clip->surface);
+    clip->surface = surface;
+    clip->surface_rect = surface_rect;
+    clip->serial = _cairo_surface_allocate_clip_serial (target);
 
-    status = _cairo_path_fixed_init_copy (&clip_path->path,
-					  &other_path->path);
-    if (unlikely (status)) {
-	_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);
-	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;
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-cairo_status_t
-_cairo_clip_init_copy_transformed (cairo_clip_t    *clip,
-				   cairo_clip_t    *other,
-				   const cairo_matrix_t *matrix)
-{
-    cairo_status_t status = CAIRO_STATUS_SUCCESS;
-    int tx, ty;
-
-    if (other == NULL) {
-	_cairo_clip_init (clip);
-	return CAIRO_STATUS_SUCCESS;
-    }
-
-    if (other->all_clipped) {
-	_cairo_clip_init (clip);
-	clip->all_clipped = TRUE;
-	return CAIRO_STATUS_SUCCESS;
-    }
-
-    if (_cairo_matrix_is_identity (matrix)) {
-	_cairo_clip_init_copy (clip, other);
-	return CAIRO_STATUS_SUCCESS;
-    }
-
-    if (other->path != NULL) {
-	_cairo_clip_init (clip);
-
-	/* if we only need to translate, so we can reuse the caches... */
-	/* XXX we still loose the benefit of constructs when the copy is
-	 * deleted though. Indirect clip_paths?
-	 */
-	if (_cairo_matrix_is_integer_translation (matrix, &tx, &ty)) {
-	    status = _cairo_clip_path_reapply_clip_path_translate (clip,
-								   other->path,
-								   tx, ty);
-	} else {
-	    status = _cairo_clip_path_reapply_clip_path_transform (clip,
-								   other->path,
-								   matrix);
-	    if (clip->path->extents.width == 0 &&
-		clip->path->extents.height == 0)
-	    {
-		_cairo_clip_set_all_clipped (clip);
-	    }
-	}
-    }
+    if (surface_rect.width == 0 || surface_rect.height == 0)
+	_cairo_clip_set_all_clipped (clip, target);
 
     return status;
 }
 
 static cairo_status_t
-_cairo_clip_apply_clip_path (cairo_clip_t *clip,
-			     const cairo_clip_path_t *path)
+_cairo_clip_intersect_mask_using_spans (cairo_clip_t       *clip,
+					cairo_path_fixed_t *path,
+					cairo_fill_rule_t   fill_rule,
+					double		    tolerance,
+					cairo_antialias_t   antialias,
+					cairo_surface_t    *target)
 {
+    cairo_span_renderer_t *renderer = NULL;
+    cairo_pattern_union_t pattern;
+    cairo_rectangle_int_t surface_rect;
+    cairo_surface_t *surface = NULL;
     cairo_status_t status;
-
-    if (path->prev != NULL)
-	status = _cairo_clip_apply_clip_path (clip, path->prev);
-
-    return _cairo_clip_intersect_path (clip,
-				       &path->path,
-				       path->fill_rule,
-				       path->tolerance,
-				       path->antialias);
-}
-
-cairo_status_t
-_cairo_clip_apply_clip (cairo_clip_t *clip,
-			const cairo_clip_t *other)
-{
-    cairo_status_t status;
+    cairo_operator_t op;
+    cairo_composite_rectangles_t rects;
 
     if (clip->all_clipped)
 	return CAIRO_STATUS_SUCCESS;
 
-    if (other->all_clipped) {
-	_cairo_clip_set_all_clipped (clip);
-	return CAIRO_STATUS_SUCCESS;
+    _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE,
+			       CAIRO_CONTENT_COLOR);
+
+    /* If we have a clip surface we're going to use IN to combine our
+     * new clip with the old clip.  The ADD is done to a transparent
+     * surface, as that's a fast way of doing it currently.  We should
+     * really be using SOURCE instead, but _cairo_surface_composite()
+     * checks that it's not called with SOURCE or DEST. */
+    op = clip->surface ? CAIRO_OPERATOR_IN : CAIRO_OPERATOR_ADD;
+
+    /* Test if the target can composite spans.  We're going to assume
+     * this is a good indicator of whether a similar surface is going
+     * to be able to composite spans too. */
+    if ( !_cairo_surface_check_span_renderer (op,
+					      &pattern.base,
+					      target,
+					      antialias,
+					      NULL))
+    {
+	status = CAIRO_INT_STATUS_UNSUPPORTED;
+	goto BAIL;
+    }
+
+    status = _cairo_surface_get_extents (target, &surface_rect);
+    if (status)
+	goto BAIL;
+
+    /* We'll create a new surface the size of the intersection of the
+     * old mask surface and the extents of the new clip path. */
+    {
+	cairo_rectangle_int_t extents;
+
+	_cairo_path_fixed_approximate_clip_extents (path, &extents);
+	if (! _cairo_rectangle_intersect (&surface_rect, &extents))
+	    goto SUCCESS;
+
+	if (clip->surface != NULL &&
+	    ! _cairo_rectangle_intersect (&surface_rect, &clip->surface_rect))
+	    goto SUCCESS;
+    }
+
+    /* Make the new mask surface and optionally initialise it from the
+     * previous clip if we have one. */
+    surface = _cairo_surface_create_similar_solid (target,
+						   CAIRO_CONTENT_ALPHA,
+						   surface_rect.width,
+						   surface_rect.height,
+						   CAIRO_COLOR_TRANSPARENT);
+    if (surface->status) {
+	_cairo_pattern_fini (&pattern.base);
+	return surface->status;
     }
 
-    status = CAIRO_STATUS_SUCCESS;
-    if (other->path != NULL)
-	status = _cairo_clip_apply_clip_path (clip, other->path);
+    if (clip->surface) {
+	cairo_surface_pattern_t old_clip;
+	_cairo_pattern_init_for_surface (&old_clip, clip->surface);
+	status = _cairo_surface_composite (CAIRO_OPERATOR_ADD,
+					   &old_clip.base,
+					   NULL,
+					   surface,
+					   surface_rect.x - clip->surface_rect.x,
+					   surface_rect.y - clip->surface_rect.y,
+					   0, 0,
+					   0, 0,
+					   surface_rect.width,
+					   surface_rect.height);
+	_cairo_pattern_fini (&old_clip.base);
+	if (status)
+	    goto BAIL;
+    }
+
+    _cairo_composite_rectangles_init (&rects,
+				      surface_rect.x,
+				      surface_rect.y,
+				      surface_rect.width,
+				      surface_rect.height);
+    rects.dst.x = 0;
+    rects.dst.y = 0;
 
+    /* Render the new clipping path into the new mask surface. We've
+     * chosen op to either combine the new clip path with the existing
+     * clip mask (if there is one) or just render it. */
+    status =_cairo_path_fixed_fill_using_spans (op, &pattern.base,
+						path, surface,
+						fill_rule, tolerance,
+						antialias, &rects);
+    if (status)
+	goto BAIL;
+
+ SUCCESS:
+    if (clip->surface != NULL)
+	cairo_surface_destroy (clip->surface);
+    clip->surface = surface;
+    clip->surface_rect = surface_rect;
+    clip->serial = _cairo_surface_allocate_clip_serial (target);
+    surface = NULL;
+
+    if (surface_rect.width == 0 || surface_rect.height == 0)
+	_cairo_clip_set_all_clipped (clip, target);
+
+ BAIL:
+    if (renderer)
+	renderer->destroy(renderer);
+    if (surface)
+	cairo_surface_destroy (surface);
+    _cairo_pattern_fini (&pattern.base);
     return status;
 }
 
-static inline cairo_bool_t
-_clip_paths_are_rectilinear (cairo_clip_path_t *clip_path)
+cairo_status_t
+_cairo_clip_clip (cairo_clip_t       *clip,
+		  cairo_path_fixed_t *path,
+		  cairo_fill_rule_t   fill_rule,
+		  double              tolerance,
+		  cairo_antialias_t   antialias,
+		  cairo_surface_t    *target)
 {
-    while (clip_path != NULL) {
-	if (! clip_path->path.is_rectilinear)
-	    return FALSE;
-
-	clip_path = clip_path->prev;
-    }
-
-    return TRUE;
-}
-
-static cairo_int_status_t
-_cairo_clip_path_to_region_geometric (cairo_clip_path_t *clip_path)
-{
+    cairo_status_t status;
+    cairo_rectangle_int_t limits, extents;
     cairo_traps_t traps;
-    cairo_box_t stack_boxes[CAIRO_STACK_ARRAY_LENGTH (cairo_box_t)];
-    cairo_box_t *boxes = stack_boxes;
-    cairo_status_t status;
-    int n;
-
-    /* If we have nothing to intersect with this path, then it cannot
-     * magically be reduced into a region.
-     */
-    if (clip_path->prev == NULL)
-	goto UNSUPPORTED;
+    cairo_box_t ignored_box;
+    cairo_bool_t have_limits;
 
-    /* Start simple... Intersect some boxes with an arbitrary path. */
-    if (! clip_path->path.is_rectilinear)
-	goto UNSUPPORTED;
-    if (clip_path->prev->prev != NULL)
-	goto UNSUPPORTED;
-
-    _cairo_traps_init (&traps);
-    _cairo_box_from_rectangle (&boxes[0], &clip_path->extents);
-    _cairo_traps_limit (&traps, boxes, 1);
+    if (clip->all_clipped)
+	return CAIRO_STATUS_SUCCESS;
 
-    status = _cairo_path_fixed_fill_rectilinear_to_traps (&clip_path->path,
-							  clip_path->fill_rule,
-							  &traps);
-    if (unlikely (_cairo_status_is_error (status)))
-	return status;
-    if (status == CAIRO_INT_STATUS_UNSUPPORTED)
-	goto UNSUPPORTED;
-
-    if (traps.num_traps > ARRAY_LENGTH (stack_boxes)) {
-	boxes = _cairo_malloc_ab (traps.num_traps, sizeof (cairo_box_t));
-	if (unlikely (boxes == NULL))
-	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-    }
-
-    for (n = 0; n < traps.num_traps; n++) {
-	boxes[n].p1.x = traps.traps[n].left.p1.x;
-	boxes[n].p1.y = traps.traps[n].top;
-	boxes[n].p2.x = traps.traps[n].right.p1.x;
-	boxes[n].p2.y = traps.traps[n].bottom;
+    /* catch the empty clip path */
+    if (! path->has_current_point) {
+	_cairo_clip_set_all_clipped (clip, target);
+	return CAIRO_STATUS_SUCCESS;
     }
 
-    _cairo_traps_clear (&traps);
-    _cairo_traps_limit (&traps, boxes, n);
-    status = _cairo_path_fixed_fill_to_traps (&clip_path->prev->path,
-					      clip_path->prev->fill_rule,
-					      clip_path->prev->tolerance,
-					      &traps);
-    if (boxes != stack_boxes)
-	free (boxes);
+    status = _cairo_clip_intersect_path (clip,
+					 path, fill_rule, tolerance,
+					 antialias);
+    if (status == CAIRO_STATUS_SUCCESS)
+        clip->serial = _cairo_surface_allocate_clip_serial (target);
 
-    if (unlikely (status))
-	return status;
-
-    status = _cairo_traps_extract_region (&traps, &clip_path->region);
-    _cairo_traps_fini (&traps);
-
-    if (status == CAIRO_INT_STATUS_UNSUPPORTED)
-	goto UNSUPPORTED;
-    if (unlikely (status))
+    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
 	return status;
 
-    clip_path->flags |= CAIRO_CLIP_PATH_HAS_REGION;
-    return CAIRO_STATUS_SUCCESS;
-
-UNSUPPORTED:
-    clip_path->flags |= CAIRO_CLIP_PATH_REGION_IS_UNSUPPORTED;
-    return CAIRO_INT_STATUS_UNSUPPORTED;
-}
-
-static cairo_int_status_t
-_cairo_clip_path_to_region (cairo_clip_path_t *clip_path)
-{
-    cairo_int_status_t status;
-    cairo_region_t *prev = NULL;
-
-    if (clip_path->flags &
-	(CAIRO_CLIP_PATH_HAS_REGION |
-	 CAIRO_CLIP_PATH_REGION_IS_UNSUPPORTED))
+    /* TODO: allow ANTIALIAS_NONE when we have a mono scan converter
+     * again. */
+    if (antialias != CAIRO_ANTIALIAS_NONE &&
+	!_cairo_path_fixed_is_box (path, &ignored_box) &&
+	!_cairo_path_fixed_is_region (path))
     {
-	return clip_path->flags & CAIRO_CLIP_PATH_REGION_IS_UNSUPPORTED ?
-	    CAIRO_INT_STATUS_UNSUPPORTED :
-	    CAIRO_STATUS_SUCCESS;
-    }
-
-    if (! clip_path->path.maybe_fill_region)
-	return _cairo_clip_path_to_region_geometric (clip_path);
-
-    /* first retrieve the region for our antecedents */
-    if (clip_path->prev != NULL) {
-	status = _cairo_clip_path_to_region (clip_path->prev);
-	if (status) {
-	    if (status == CAIRO_INT_STATUS_UNSUPPORTED)
-		return _cairo_clip_path_to_region_geometric (clip_path);
-
-	    return status;
-	}
-
-	prev = clip_path->prev->region;
-    }
-
-    /* now extract the region for ourselves */
-    clip_path->region =
-	_cairo_path_fixed_fill_rectilinear_to_region (&clip_path->path,
-						      clip_path->fill_rule,
-						      &clip_path->extents);
-    assert (clip_path->region != NULL);
-
-    status = clip_path->region->status;
-    if (unlikely (status))
-	return status;
-
-    if (prev != NULL) {
-	status = cairo_region_intersect (clip_path->region, prev);
-	if (unlikely (status))
+	status = _cairo_clip_intersect_mask_using_spans (
+	    clip, path, fill_rule, tolerance, antialias, target);
+	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
 	    return status;
     }
 
-    clip_path->flags |= CAIRO_CLIP_PATH_HAS_REGION;
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static inline int
-pot (int v)
-{
-    v--;
-    v |= v >> 1;
-    v |= v >> 2;
-    v |= v >> 4;
-    v |= v >> 8;
-    v |= v >> 16;
-    v++;
-    return v;
-}
-
-/* XXX there is likely a faster method! ;-) */
-static cairo_status_t
-_region_clip_to_boxes (const cairo_region_t *region,
-		       cairo_box_t **boxes,
-		       int *num_boxes,
-		       int *size_boxes)
-{
-    cairo_traps_t traps;
-    cairo_status_t status;
-    int n, num_rects;
-
     _cairo_traps_init (&traps);
-    _cairo_traps_limit (&traps, *boxes, *num_boxes);
-    traps.is_rectilinear = TRUE;
-    traps.is_rectangular = TRUE;
 
-    num_rects = cairo_region_num_rectangles (region);
-    for (n = 0; n < num_rects; n++) {
-	cairo_rectangle_int_t rect;
-	cairo_point_t p1, p2;
-
-	cairo_region_get_rectangle (region, n, &rect);
-
-	p1.x = _cairo_fixed_from_int (rect.x);
-	p1.y = _cairo_fixed_from_int (rect.y);
-	p2.x = _cairo_fixed_from_int (rect.x + rect.width);
-	p2.y = _cairo_fixed_from_int (rect.y + rect.height);
-
-	status = _cairo_traps_tessellate_rectangle (&traps, &p1, &p2);
-	if (unlikely (status))
-	    goto CLEANUP;
-    }
-
-    status = _cairo_bentley_ottmann_tessellate_rectangular_traps (&traps, CAIRO_FILL_RULE_WINDING);
-    if (unlikely (status))
-	goto CLEANUP;
-
-    n = *size_boxes;
-    if (n < 0)
-	n = -n;
-
-    if (traps.num_traps > n) {
-	cairo_box_t *new_boxes;
-
-	new_boxes = _cairo_malloc_ab (traps.num_traps, sizeof (cairo_box_t));
-	if (unlikely (new_boxes == NULL)) {
-	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	    goto CLEANUP;
-	}
-
-	if (*size_boxes > 0)
-	    free (*boxes);
-
-	*boxes = new_boxes;
-	*size_boxes = traps.num_traps;
+    /* Limit the traps to the target surface and current clip
+     * - so we don't add more traps than needed. */
+    have_limits = FALSE;
+    if (clip->region != NULL) {
+	cairo_region_get_extents (clip->region, &limits);
+	have_limits = TRUE;
     }
 
-    for (n = 0; n < traps.num_traps; n++) {
-	(*boxes)[n].p1.x = traps.traps[n].left.p1.x;
-	(*boxes)[n].p1.y = traps.traps[n].top;
-	(*boxes)[n].p2.x = traps.traps[n].right.p1.x;
-	(*boxes)[n].p2.y = traps.traps[n].bottom;
-    }
-    *num_boxes = n;
-
-  CLEANUP:
-    _cairo_traps_fini (&traps);
-
-    return status;
-}
-
-static cairo_status_t
-_rectilinear_clip_to_boxes (const cairo_path_fixed_t *path,
-			    cairo_fill_rule_t fill_rule,
-			    cairo_box_t **boxes,
-			    int *num_boxes,
-			    int *size_boxes)
-{
-    cairo_polygon_t polygon;
-    cairo_traps_t traps;
-    cairo_status_t status;
-
-    _cairo_traps_init (&traps);
-    _cairo_traps_limit (&traps, *boxes, *num_boxes);
-
-    _cairo_polygon_init (&polygon);
-    _cairo_polygon_limit (&polygon, *boxes, *num_boxes);
-
-    status = _cairo_path_fixed_fill_rectilinear_to_traps (path,
-							  fill_rule,
-							  &traps);
-    if (unlikely (_cairo_status_is_error (status)))
-	goto CLEANUP;
-    if (status == CAIRO_STATUS_SUCCESS)
-	goto BOXES;
-
-    /* tolerance will be ignored as the path is rectilinear */
-    status = _cairo_path_fixed_fill_to_polygon (path, 0., &polygon);
-    if (unlikely (status))
-	goto CLEANUP;
-
-    if (polygon.num_edges == 0) {
-	*num_boxes = 0;
-    } else {
-	status = _cairo_bentley_ottmann_tessellate_rectilinear_polygon (&traps,
-									&polygon,
-									fill_rule);
-	if (likely (status == CAIRO_STATUS_SUCCESS)) {
-	    int i;
-
-          BOXES:
-	    i = *size_boxes;
-	    if (i < 0)
-		i = -i;
-
-	    if (traps.num_traps > i) {
-		cairo_box_t *new_boxes;
-		int new_size;
-
-		new_size = pot (traps.num_traps);
-		new_boxes = _cairo_malloc_ab (new_size, sizeof (cairo_box_t));
-		if (unlikely (new_boxes == NULL)) {
-		    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-		    goto CLEANUP;
-		}
-
-		if (*size_boxes > 0)
-		    free (*boxes);
-
-		*boxes = new_boxes;
-		*size_boxes = new_size;
+    if (clip->surface != NULL) {
+	if (have_limits) {
+	    if (! _cairo_rectangle_intersect (&limits, &clip->surface_rect)) {
+		_cairo_clip_set_all_clipped (clip, target);
+		return CAIRO_STATUS_SUCCESS;
 	    }
-
-	    for (i = 0; i < traps.num_traps; i++) {
-		(*boxes)[i].p1.x = traps.traps[i].left.p1.x;
-		(*boxes)[i].p1.y = traps.traps[i].top;
-		(*boxes)[i].p2.x = traps.traps[i].right.p1.x;
-		(*boxes)[i].p2.y = traps.traps[i].bottom;
-	    }
-	    *num_boxes = i;
+	} else {
+	    limits = clip->surface_rect;
+	    have_limits = TRUE;
 	}
     }
 
-  CLEANUP:
-    _cairo_polygon_fini (&polygon);
+    status = _cairo_surface_get_extents (target, &extents);
+    if (status == CAIRO_STATUS_SUCCESS) {
+	if (have_limits) {
+	    if (! _cairo_rectangle_intersect (&limits, &extents)) {
+		_cairo_clip_set_all_clipped (clip, target);
+		return CAIRO_STATUS_SUCCESS;
+	    }
+	} else {
+	    limits = extents;
+	    have_limits = TRUE;
+	}
+    }
+
+    if (have_limits) {
+	cairo_box_t box;
+
+	_cairo_box_from_rectangle (&box, &limits);
+	_cairo_traps_limit (&traps, &box);
+    }
+
+    status = _cairo_path_fixed_fill_to_traps (path,
+					      fill_rule,
+					      tolerance,
+					      &traps);
+    if (unlikely (status))
+	goto bail;
+
+    status = _cairo_clip_intersect_region (clip, &traps, target);
+    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+	goto bail;
+
+    status = _cairo_clip_intersect_mask (clip, &traps, antialias, target);
+
+ bail:
     _cairo_traps_fini (&traps);
 
     return status;
 }
 
-static cairo_int_status_t
-_cairo_clip_path_to_boxes (cairo_clip_path_t *clip_path,
-			   cairo_box_t **boxes,
-			   int *count)
+void
+_cairo_clip_translate (cairo_clip_t  *clip,
+                       cairo_fixed_t  tx,
+                       cairo_fixed_t  ty)
 {
-    int size = -*count;
-    int num_boxes = 0;
-    cairo_status_t status;
-
-    if (clip_path->region != NULL) {
-	int num_rects, n;
-
-	num_rects = cairo_region_num_rectangles (clip_path->region);
-	if (num_rects > -size) {
-	    cairo_box_t *new_boxes;
+    if (clip->all_clipped)
+	return;
 
-	    new_boxes = _cairo_malloc_ab (num_rects, sizeof (cairo_box_t));
-	    if (unlikely (new_boxes == NULL))
-		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
-	    *boxes = new_boxes;
-	}
-
-	for (n = 0; n < num_rects; n++) {
-	    cairo_rectangle_int_t rect;
-
-	    cairo_region_get_rectangle (clip_path->region, n, &rect);
-	    (*boxes)[n].p1.x = _cairo_fixed_from_int (rect.x);
-	    (*boxes)[n].p1.y = _cairo_fixed_from_int (rect.y);
-	    (*boxes)[n].p2.x = _cairo_fixed_from_int (rect.x + rect.width);
-	    (*boxes)[n].p2.y = _cairo_fixed_from_int (rect.y + rect.height);
-	}
-
-	*count = num_rects;
-	return CAIRO_STATUS_SUCCESS;
+    if (clip->region) {
+        cairo_region_translate (clip->region,
+				_cairo_fixed_integer_part (tx),
+				_cairo_fixed_integer_part (ty));
     }
 
-    /* keep it simple at first */
-    if (! _clip_paths_are_rectilinear (clip_path))
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    assert (-size >= 1);
-    if (_cairo_path_fixed_is_box (&clip_path->path, *boxes)) {
-	num_boxes = 1;
-    } else {
-	status = _rectilinear_clip_to_boxes (&clip_path->path,
-					     clip_path->fill_rule,
-					     boxes, &num_boxes, &size);
-	if (unlikely (status))
-	    return status;
+    if (clip->surface) {
+        clip->surface_rect.x += _cairo_fixed_integer_part (tx);
+        clip->surface_rect.y += _cairo_fixed_integer_part (ty);
     }
 
-    while (num_boxes > 0 && (clip_path = clip_path->prev) != NULL) {
-	cairo_box_t box;
-
-	if (clip_path->region != NULL) {
-	    status = _region_clip_to_boxes (clip_path->region,
-					    boxes, &num_boxes, &size);
-	    if (unlikely (status))
-		return status;
-
-	    break;
-	} else if (_cairo_path_fixed_is_box (&clip_path->path, &box)) {
-	    int i, j;
-
-	    for (i = j = 0; i < num_boxes; i++) {
-		if (j != i)
-		    (*boxes)[j] = (*boxes)[i];
-
-		if (box.p1.x > (*boxes)[j].p1.x)
-		    (*boxes)[j].p1.x = box.p1.x;
-		if (box.p2.x < (*boxes)[j].p2.x)
-		    (*boxes)[j].p2.x = box.p2.x;
+    if (clip->path) {
+        cairo_clip_path_t *clip_path = clip->path;
+	cairo_matrix_t matrix;
 
-		if (box.p1.y > (*boxes)[j].p1.y)
-		    (*boxes)[j].p1.y = box.p1.y;
-		if (box.p2.y < (*boxes)[j].p2.y)
-		    (*boxes)[j].p2.y = box.p2.y;
-
-		j += (*boxes)[j].p2.x > (*boxes)[j].p1.x &&
-		     (*boxes)[j].p2.y > (*boxes)[j].p1.y;
-	    }
+	cairo_matrix_init_translate (&matrix,
+				     _cairo_fixed_to_double (tx),
+				     _cairo_fixed_to_double (ty));
 
-	    num_boxes = j;
-	} else {
-	    status = _rectilinear_clip_to_boxes (&clip_path->path,
-						 clip_path->fill_rule,
-						 boxes, &num_boxes, &size);
-	    if (unlikely (status))
-		return status;
-	}
+        while (clip_path) {
+            _cairo_path_fixed_transform (&clip_path->path, &matrix);
+            clip_path = clip_path->prev;
+        }
     }
-
-    *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)
+_cairo_clip_path_reapply_clip_path (cairo_clip_t      *clip,
+                                    cairo_clip_path_t *clip_path)
 {
-    cairo_region_t clear_region;
     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);
-    }
-    _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;
-
-    if (clip_path->surface != NULL &&
-	clip_path->surface->backend == target->backend)
-    {
-	return cairo_surface_reference (clip_path->surface);
+    if (clip_path->prev) {
+        status = _cairo_clip_path_reapply_clip_path (clip, clip_path->prev);
+	if (_cairo_status_is_error (status))
+	    return status;
     }
 
-    surface = _cairo_surface_create_similar_solid (target,
-						   CAIRO_CONTENT_ALPHA,
-						   clip_extents->width,
-						   clip_extents->height,
-						   CAIRO_COLOR_TRANSPARENT,
-						   FALSE);
-    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);
-    }
-    if (unlikely (surface->status))
-	return surface;
+    return _cairo_clip_intersect_path (clip,
+                                       &clip_path->path,
+				       clip_path->fill_rule,
+				       clip_path->tolerance,
+				       clip_path->antialias);
+}
 
-    _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;
+cairo_status_t
+_cairo_clip_init_deep_copy (cairo_clip_t    *clip,
+                            cairo_clip_t    *other,
+                            cairo_surface_t *target)
+{
+    cairo_status_t status;
 
-    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 (unlikely (status))
-	    goto BAIL;
+    _cairo_clip_init (clip, target);
 
-	goto DONE;
+    if (other->mode != clip->mode) {
+        /* We should reapply the original clip path in this case, and let
+         * whatever the right handling is happen */
     } else {
-	if (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,
-				      &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;
-    }
+        if (other->region) {
+	    clip->region = cairo_region_copy (other->region);
+	    if (unlikely ((status = cairo_region_status (clip->region))))
+		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) {
-	    /* a simple box only affects the extents */
-	} else if (prev->path.is_rectilinear) {
-	    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,
-					  &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 (other->surface) {
+	    int dx, dy;
+            status = _cairo_surface_clone_similar (target, other->surface,
+						   CAIRO_CONTENT_ALPHA,
+					           0,
+						   0,
+						   other->surface_rect.width,
+						   other->surface_rect.height,
+						   &dx, &dy,
+						   &clip->surface);
 	    if (unlikely (status))
 		goto BAIL;
 
-	    prev = prev->prev;
-	    goto NEXT_PATH;
-	} else {
-	    cairo_surface_t *prev_surface;
-
-	    prev_surface = _cairo_clip_path_get_surface (prev, target);
-	    _cairo_pattern_init_for_surface (&pattern.surface, prev_surface);
-	    cairo_surface_destroy (prev_surface);
-
-	    cairo_matrix_init_translate (&pattern.base.matrix,
-					 -prev->extents.x + clip_extents->x,
-					 -prev->extents.y + clip_extents->y);
-	    status = _cairo_surface_paint (surface,
-					   CAIRO_OPERATOR_IN,
-					   &pattern.base,
-					   NULL);
-	    _cairo_pattern_fini (&pattern.base);
-
-	    if (unlikely (status))
-		goto BAIL;
-	}
-    }
+            clip->surface_rect = other->surface_rect;
 
-  DONE:
-    cairo_surface_destroy (clip_path->surface);
-    return clip_path->surface = cairo_surface_reference (surface);
-
-  BAIL:
-    cairo_surface_destroy (surface);
-    return _cairo_surface_create_in_error (status);
-}
-
-void
-_cairo_debug_print_clip (FILE *stream, cairo_clip_t *clip)
-{
-    cairo_clip_path_t *clip_path;
+	    /* src offset was 0, so we expect an exact replica of the surface */
+	    assert (dx == 0);
+	    assert (dy == 0);
+        }
 
-    if (clip == NULL) {
-	fprintf (stream, "no clip\n");
-	return;
-    }
-
-    if (clip->all_clipped) {
-	fprintf (stream, "clip: all-clipped\n");
-	return;
-    }
-
-    if (clip->path == NULL) {
-	fprintf (stream, "clip: empty\n");
-	return;
+        if (other->path) {
+            status = _cairo_clip_path_reapply_clip_path (clip, other->path);
+	    if (_cairo_status_is_error (status))
+		goto BAIL;
+        }
     }
 
-    fprintf (stream, "clip:\n");
-
-    clip_path = clip->path;
-    do {
-	fprintf (stream, "path: has region? %s, has surface? %s: ",
-		 clip_path->region == NULL ? "no" : "yes",
-		 clip_path->surface == NULL ? "no" : "yes");
-	_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)
-{
-    assert (clip->path != NULL);
-    return _cairo_clip_path_get_surface (clip->path, target);
-}
-
-cairo_status_t
-_cairo_clip_combine_with_surface (cairo_clip_t *clip,
-				  cairo_surface_t *dst,
-				  const cairo_rectangle_int_t *extents)
-{
-    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;
-    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);
+    return CAIRO_STATUS_SUCCESS;
 
-	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;
-	}
-
-	if (clip_path->flags & CAIRO_CLIP_PATH_IS_BOX) {
-	    cairo_region_t clip_region;
+BAIL:
+    if (clip->region)
+	cairo_region_destroy (clip->region);
+    if (clip->surface)
+	cairo_surface_destroy (clip->surface);
 
-	    _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 (unlikely (status))
-	    return status;
-    } while ((clip_path = clip_path->prev) != NULL);
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-const cairo_rectangle_int_t *
-_cairo_clip_get_extents (const cairo_clip_t *clip)
-{
-    if (clip->path == NULL)
-	return NULL;
-
-    return &clip->path->extents;
-}
-
-void
-_cairo_clip_drop_cache (cairo_clip_t  *clip)
-{
-    cairo_clip_path_t *clip_path;
-
-    if (clip->path == NULL)
-	return;
-
-    clip_path = clip->path;
-    do {
-	if (clip_path->region != NULL) {
-	    cairo_region_destroy (clip_path->region);
-	    clip_path->region = NULL;
-	}
-
-	if (clip_path->surface != NULL) {
-	    cairo_surface_destroy (clip_path->surface);
-	    clip_path->surface = NULL;
-	}
-
-	clip_path->flags &= ~CAIRO_CLIP_PATH_HAS_REGION;
-    } while ((clip_path = clip_path->prev) != NULL);
+    return status;
 }
 
 const cairo_rectangle_list_t _cairo_rectangles_nil =
   { CAIRO_STATUS_NO_MEMORY, NULL, 0 };
 static const cairo_rectangle_list_t _cairo_rectangles_not_representable =
   { CAIRO_STATUS_CLIP_NOT_REPRESENTABLE, NULL, 0 };
 
 static cairo_bool_t
@@ -1368,172 +857,87 @@ static cairo_bool_t
     user_rect->x = x1;
     user_rect->y = y1;
     user_rect->width  = x2 - x1;
     user_rect->height = y2 - y1;
 
     return is_tight;
 }
 
-cairo_int_status_t
-_cairo_clip_get_region (cairo_clip_t *clip,
-			cairo_region_t **region)
-{
-    cairo_int_status_t status;
-
-    if (clip->all_clipped)
-	goto CLIPPED;
-
-    assert (clip->path != NULL);
-
-    status = _cairo_clip_path_to_region (clip->path);
-    if (status)
-	return status;
-
-    if (cairo_region_is_empty (clip->path->region)) {
-	_cairo_clip_set_all_clipped (clip);
-	goto CLIPPED;
-    }
-
-    if (region)
-	*region = clip->path->region;
-    return CAIRO_STATUS_SUCCESS;
-
-  CLIPPED:
-    if (region)
-	*region = NULL;
-    return CAIRO_INT_STATUS_NOTHING_TO_DO;
-}
-
-cairo_int_status_t
-_cairo_clip_get_boxes (cairo_clip_t *clip,
-		       cairo_box_t **boxes,
-		       int *count)
-{
-    cairo_int_status_t status;
-
-    if (clip->all_clipped)
-	return CAIRO_INT_STATUS_NOTHING_TO_DO;
-
-    assert (clip->path != NULL);
-
-    status = _cairo_clip_path_to_boxes (clip->path, boxes, count);
-    if (status)
-	return status;
-
-    if (*count == 0) {
-	_cairo_clip_set_all_clipped (clip);
-	return CAIRO_INT_STATUS_NOTHING_TO_DO;
-    }
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-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)
-	return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
-
-    list = malloc (sizeof (*list));
-    if (unlikely (list == NULL)) {
-	_cairo_error_throw (status);
-	return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
-    }
-
-    list->status = status;
-    list->rectangles = NULL;
-    list->num_rectangles = 0;
-
-    return list;
-}
-
 cairo_rectangle_list_t *
 _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
 {
-#define ERROR_LIST(S) _cairo_rectangle_list_create_in_error (_cairo_error (S));
-
     cairo_rectangle_list_t *list;
     cairo_rectangle_t *rectangles = NULL;
-    cairo_region_t *region = NULL;
-    cairo_int_status_t status;
     int n_rects = 0;
-    int i;
 
-    if (clip != NULL && clip->path != NULL) {
-	status = _cairo_clip_get_region (clip, &region);
-	if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
-	    goto DONE;
-	} else if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
-	    return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE)
-	} else if (unlikely (status)) {
-	    return ERROR_LIST (status);
-	}
+    if (clip->all_clipped)
+	goto DONE;
+
+    if (clip->path || clip->surface) {
+	_cairo_error_throw (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
+	return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
     }
 
-    if (region != NULL) {
-	n_rects = cairo_region_num_rectangles (region);
+    if (clip->region) {
+        int i;
+
+	n_rects = cairo_region_num_rectangles (clip->region);
+
 	if (n_rects) {
 	    rectangles = _cairo_malloc_ab (n_rects, sizeof (cairo_rectangle_t));
 	    if (unlikely (rectangles == NULL)) {
-		return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
+		_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+		return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
 	    }
 
 	    for (i = 0; i < n_rects; ++i) {
 		cairo_rectangle_int_t clip_rect;
 
-		cairo_region_get_rectangle (region, i, &clip_rect);
-
-		if (! _cairo_clip_int_rect_to_user (gstate,
-						    &clip_rect,
-						    &rectangles[i]))
-		{
+		cairo_region_get_rectangle (clip->region, i, &clip_rect);
+		
+		if (!_cairo_clip_int_rect_to_user(gstate, &clip_rect, &rectangles[i])) {
+		    _cairo_error_throw (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
 		    free (rectangles);
-		    return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
+		    return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
 		}
 	    }
 	}
     } else {
         cairo_rectangle_int_t extents;
 
-	if (! _cairo_surface_get_extents (_cairo_gstate_get_target (gstate),
-					  &extents))
-	{
-	    /* unbounded surface -> unclipped */
-	    goto DONE;
+	n_rects = 1;
+
+	rectangles = malloc(sizeof (cairo_rectangle_t));
+	if (unlikely (rectangles == NULL)) {
+	    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+	    return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
 	}
 
-	n_rects = 1;
-	rectangles = malloc(sizeof (cairo_rectangle_t));
-	if (unlikely (rectangles == NULL))
-	    return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
-
-	if (! _cairo_clip_int_rect_to_user (gstate, &extents, rectangles)) {
+	if (_cairo_surface_get_extents (_cairo_gstate_get_target (gstate), &extents) ||
+	    !_cairo_clip_int_rect_to_user(gstate, &extents, rectangles))
+	{
+	    _cairo_error_throw (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
 	    free (rectangles);
-	    return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
+	    return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
 	}
     }
 
  DONE:
     list = malloc (sizeof (cairo_rectangle_list_t));
     if (unlikely (list == NULL)) {
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
         free (rectangles);
-	return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
+        return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
     }
 
     list->status = CAIRO_STATUS_SUCCESS;
     list->rectangles = rectangles;
     list->num_rectangles = n_rects;
     return list;
-
-#undef ERROR_LIST
 }
 
 /**
  * cairo_rectangle_list_destroy:
  * @rectangle_list: a rectangle list, as obtained from cairo_copy_clip_rectangles()
  *
  * Unconditionally frees @rectangle_list and all associated
  * references. After this call, the @rectangle_list pointer must not
@@ -1546,14 +950,8 @@ cairo_rectangle_list_destroy (cairo_rect
 {
     if (rectangle_list == NULL || rectangle_list == &_cairo_rectangles_nil ||
         rectangle_list == &_cairo_rectangles_not_representable)
         return;
 
     free (rectangle_list->rectangles);
     free (rectangle_list);
 }
-
-void
-_cairo_clip_reset_static_data (void)
-{
-    _freed_pool_reset (&clip_path_pool);
-}
--- a/gfx/cairo/cairo/src/cairo-combsort-private.h
+++ b/gfx/cairo/cairo/src/cairo-combsort-private.h
@@ -51,21 +51,21 @@ static inline unsigned int
 static void \
 NAME (TYPE *base, unsigned int nmemb) \
 { \
   unsigned int gap = nmemb; \
   unsigned int i, j; \
   int swapped; \
   do { \
       gap = _cairo_combsort_newgap (gap); \
-      swapped = gap > 1; \
+      swapped = 0; \
       for (i = 0; i < nmemb-gap ; i++) { \
 	  j = i + gap; \
 	  if (CMP (base[i], base[j]) > 0 ) { \
 	      TYPE tmp; \
 	      tmp = base[i]; \
 	      base[i] = base[j]; \
 	      base[j] = tmp; \
 	      swapped = 1; \
 	  } \
       } \
-  } while (swapped); \
+  } while (gap > 1 || swapped); \
 }
--- a/gfx/cairo/cairo/src/cairo-d2d-private.h
+++ b/gfx/cairo/cairo/src/cairo-d2d-private.h
@@ -40,17 +40,16 @@
 
 #include <windows.h>
 #include <d2d1.h>
 #include <d3d10.h>
 #include <dxgi.h>
 
 extern "C" {
 #include "cairoint.h"
-#include "cairo-surface-clipper-private.h"
 }
 
 struct _cairo_d2d_surface {
     cairo_surface_t base;
     /** Render target of the texture we render to */
     ID2D1RenderTarget *rt;
     /** Surface containing our backstore */
     ID3D10Resource *surface;
@@ -87,18 +86,16 @@ struct _cairo_d2d_surface {
     /** Brush used for bitmaps */
     ID2D1BitmapBrush *bitmapBrush;
     /** Brush used for solid colors */
     ID2D1SolidColorBrush *solidColorBrush;
     /** Indicates if our render target is currently in drawing mode */
     bool isDrawing;
     /** Indicates if text rendering is initialized */
     bool textRenderingInit;
-
-    cairo_surface_clipper_t clipper;
 };
 typedef struct _cairo_d2d_surface cairo_d2d_surface_t;
 
 typedef HRESULT (WINAPI*D2D1CreateFactoryFunc)(
     __in D2D1_FACTORY_TYPE factoryType,
     __in REFIID iid,
     __in_opt CONST D2D1_FACTORY_OPTIONS *pFactoryOptions,
     __out void **factory
@@ -215,13 +212,10 @@ private:
 
 ID2D1Brush*
 _cairo_d2d_create_brush_for_pattern(cairo_d2d_surface_t *d2dsurf, 
 			            const cairo_pattern_t *pattern,
 				    unsigned int lastrun,
 				    unsigned int *runs_remaining,
 				    bool *pushed_clip,
 				    bool unique = false);
-void
-_cairo_d2d_begin_draw_state(cairo_d2d_surface_t *d2dsurf);
-
 #endif /* CAIRO_HAS_D2D_SURFACE */
 #endif /* CAIRO_D2D_PRIVATE_H */
--- a/gfx/cairo/cairo/src/cairo-d2d-surface.cpp
+++ b/gfx/cairo/cairo/src/cairo-d2d-surface.cpp
@@ -37,17 +37,16 @@
 
 #include "cairo.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-surface-clipper-private.h"
 }
 
 
 ID2D1Factory *D2DSurfFactory::mFactoryInstance = NULL;
 ID3D10Device1 *D3D10Factory::mDeviceInstance = NULL;
 
 #define CAIRO_INT_STATUS_SUCCESS (cairo_int_status_t)CAIRO_STATUS_SUCCESS
 
@@ -155,111 +154,115 @@ static cairo_status_t
  * \param surface The surface to apply this operation to, must be
  * a D2D surface
  * \param op The operator to use
  * \param source The source pattern to fill this path with
  * \param path The path to fill
  * \param fill_rule The fill rule to uses on the path
  * \param tolerance The tolerance applied to the filling
  * \param antialias The anti-alias mode to use
- * \param clip The clip of this operation
+ * \param extents The extents of the surface to which to apply this operation
  * \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_fill(void			*surface,
 		cairo_operator_t	 op,
 		const cairo_pattern_t	*source,
 		cairo_path_fixed_t	*path,
 		cairo_fill_rule_t	 fill_rule,
 		double			 tolerance,
 		cairo_antialias_t	 antialias,
-		cairo_clip_t		*clip);
+		cairo_rectangle_int_t	*extents);
 
 /**
  * Paint this surface, applying the operation to the entire surface
+ * or to the passed in 'extents' of the surface.
  *
  * \param surface The surface to apply this operation to, must be
  * a D2D surface
  * \param op Operator to use when painting
  * \param source The pattern to fill this surface with, source of the op
- * \param clip The clip of this operation
+ * \param Extents of the surface to apply this operation to
  * \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_paint(void			*surface,
 		 cairo_operator_t	 op,
 		 const cairo_pattern_t	*source,
-		 cairo_clip_t		*clip);
+		 cairo_rectangle_int_t  *extents);
 
 /**
  * Paint something on the surface applying a certain mask to that
  * source.
  *
  * \param surface The surface to apply this oepration to, must be
  * a D2D surface
  * \param op Operator to use
  * \param source Source for this operation
  * \param mask Pattern to mask source with
- * \param clip The clip of this operation
+ * \param extents Extents of the surface to apply this operation to
  * \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_mask(void			*surface,
 		cairo_operator_t	 op,
 		const cairo_pattern_t	*source,
 		const cairo_pattern_t	*mask,
-		cairo_clip_t		*clip);
+		cairo_rectangle_int_t  *extents);
 
 /**
  * Show a glyph run on the target D2D surface.
  *
  * \param surface The surface to apply this oepration to, must be
  * a D2D surface
  * \param op Operator to use
  * \param source Source for this operation
  * \param glyphs Glyphs to draw
  * \param num_gluphs Amount of glyphs stored at glyphs
  * \param scaled_font Scaled font to draw
  * \param remaining_glyphs Pointer to store amount of glyphs still
  * requiring drawing.
- * \param clip The clip of this operation
+ * \param extents Extents this operation applies to.
  * \return CAIRO_ERROR_SURFACE_TYPE_MISMATCH, CAIRO_ERROR_FONT_TYPE_MISMATCH,
  * CAIRO_INT_STATUS_UNSUPPORTED or CAIRO_STATUS_SUCCESS
  */
 static cairo_int_status_t
 _cairo_d2d_show_glyphs (void			*surface,
 			cairo_operator_t	 op,
 			const cairo_pattern_t	*source,
 			cairo_glyph_t		*glyphs,
 			int			 num_glyphs,
 			cairo_scaled_font_t	*scaled_font,
-			cairo_clip_t		*clip,
-			int			*remaining_glyphs);
+			int			*remaining_glyphs,
+			cairo_rectangle_int_t	*extents);
 
 /**
  * Get the extents of this surface.
  *
  * \param surface D2D surface to get the extents for
  * \param extents Pointer to where to store the extents
  * \param CAIRO_ERROR_SURFACE_TYPE_MISTMATCH or CAIRO_STATUS_SUCCESS
  */
-static cairo_bool_t
+static cairo_int_status_t
 _cairo_d2d_getextents(void		       *surface,
 		      cairo_rectangle_int_t    *extents);
 
 
-static cairo_status_t
-_cairo_d2d_surface_clipper_intersect_clip_path(cairo_surface_clipper_t *clipper,
-					       cairo_path_fixed_t	*path,
-					       cairo_fill_rule_t	fill_rule,
-					       double			tolerance,
-					       cairo_antialias_t	antialias);
+/**
+ * See cairo backend documentation.
+ */
+static cairo_int_status_t
+_cairo_d2d_intersect_clip_path(void			*dst,
+			       cairo_path_fixed_t	*path,
+			       cairo_fill_rule_t	fill_rule,
+			       double			tolerance,
+			       cairo_antialias_t	antialias);
 
 /**
  * Stroke a path on this D2D surface.
  *
  * \param surface The surface to apply this operation to, must be
  * a D2D surface
  * \param op The operator to use
  * \param source The source pattern to fill this path with
@@ -267,31 +270,31 @@ static cairo_status_t
  * \param style The style of the stroke
  * \param ctm A logical to device matrix, since the path might be in
  * device space the miter angle and such are not, hence we need to
  * be aware of the transformation to apply correct stroking.
  * \param ctm_inverse Inverse of ctm, used to transform the path back
  * to logical space.
  * \param tolerance Tolerance to stroke with
  * \param antialias Antialias mode to use
- * \param clip The clip of this operation
+ * \param extents Extents of the surface to apply this operation to
  * \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,
 		  double		 tolerance,
 		  cairo_antialias_t	 antialias,
-		  cairo_clip_t		*clip);
+		  cairo_rectangle_int_t  *extents);
 
 static const cairo_surface_backend_t cairo_d2d_surface_backend = {
     CAIRO_SURFACE_TYPE_D2D,
     _cairo_d2d_create_similar, /* create_similar */
     _cairo_d2d_finish, /* finish */
     _cairo_d2d_acquire_source_image, /* acquire_source_image */
     _cairo_d2d_release_source_image, /* release_source_image */
     _cairo_d2d_acquire_dest_image, /* acquire_dest_image */
@@ -299,29 +302,32 @@ static const cairo_surface_backend_t cai
     NULL, /* clone_similar */
     NULL, /* composite */
     NULL, /* fill_rectangles */
     NULL, /* composite_trapezoids */
     NULL, /* create_span_renderer */
     NULL, /* check_span_renderer */
     NULL, /* copy_page */
     NULL, /* show_page */
-    _cairo_d2d_getextents, /* get_extents */
+    NULL, /* set_clip_region */
+    _cairo_d2d_intersect_clip_path, /* intersect_clip_path */
+    _cairo_d2d_getextents, /* getextents */
     NULL, /* old_show_glyphs */
     NULL, /* get_font_options */
     _cairo_d2d_flush, /* flush */
     NULL, /* mark_dirty_rectangle */
     NULL, /* scaled_font_fini */
     NULL, /* scaled_glyph_fini */
     _cairo_d2d_paint, /* paint */
     _cairo_d2d_mask, /* mask */
     _cairo_d2d_stroke, /* stroke */
     _cairo_d2d_fill, /* fill */
     _cairo_d2d_show_glyphs, /* show_glyphs */
     NULL, /* snapshot */
+    NULL,
     NULL
 };
 
 /*
  * Helper functions.
  */
 
 static D2D1_POINT_2F
@@ -491,25 +497,16 @@ static void _begin_draw_state(cairo_d2d_
 	surface->rt->BeginDraw();
 	surface->isDrawing = true;
     }
     if (!surface->clipping) {
 	_cairo_d2d_surface_push_clip(surface);
     }
 }
 
-/* External helper called from dwrite code.
- * Will hopefully go away when/if that code
- * moves into here */
-void
-_cairo_d2d_begin_draw_state(cairo_d2d_surface_t *d2dsurf)
-{
-	_begin_draw_state(d2dsurf);
-}
-
 /**
  * Get a D2D matrix from a cairo matrix. Note that D2D uses row vectors where cairo
  * uses column vectors. Hence the transposition.
  *
  * \param Cairo matrix
  * \return D2D matrix
  */
 static D2D1::Matrix3x2F
@@ -1283,17 +1280,16 @@ static cairo_surface_t*
 			  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)));
     
     memset(newSurf, 0, sizeof(cairo_d2d_surface_t));
 
     _cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, content);
-    _cairo_surface_clipper_init(&newSurf->clipper, _cairo_d2d_surface_clipper_intersect_clip_path);
 
     D2D1_SIZE_U sizePixels;
     D2D1_SIZE_F size;
     HRESULT hr;
 
     sizePixels.width = width;
     sizePixels.height = height;
     FLOAT dpiX;
@@ -1390,19 +1386,16 @@ FAIL_D3DTEXTURE:
     free(newSurf);
     return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY));
 }
 
 static cairo_status_t
 _cairo_d2d_finish(void	    *surface)
 {
     cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
-
-    _cairo_surface_clipper_reset (&d2dsurf->clipper);
-
     if (d2dsurf->rt) {
 	d2dsurf->rt->Release();
     }
     if (d2dsurf->surfaceBitmap) {
 	d2dsurf->surfaceBitmap->Release();
     }
     if (d2dsurf->backBuf) {
 	d2dsurf->backBuf->Release();
@@ -1432,17 +1425,16 @@ static cairo_status_t
 	d2dsurf->surface->Release();
     }
     if (d2dsurf->helperLayer) {
 	d2dsurf->helperLayer->Release();
     }
     if (d2dsurf->bufferTexture) {
 	d2dsurf->bufferTexture->Release();
     }
-
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
 _cairo_d2d_acquire_source_image(void                    *abstract_surface,
 				cairo_image_surface_t  **image_out,
 				void                   **image_extra)
 {
@@ -1591,65 +1583,64 @@ static void
 
     cairo_surface_destroy(&image->base);
 
     softTexture->Unmap(0);
     D3D10Factory::Device()->CopyResource(d2dsurf->surface, softTexture);
     softTexture->Release();
 }
 
-static cairo_status_t
-_cairo_d2d_surface_clipper_intersect_clip_path(cairo_surface_clipper_t *clipper,
-					       cairo_path_fixed_t      *path,
-					       cairo_fill_rule_t	fill_rule,
-					       double			tolerance,
-					       cairo_antialias_t	antialias)
+cairo_int_status_t
+_cairo_d2d_intersect_clip_path(void			*dst,
+			       cairo_path_fixed_t	*path,
+			       cairo_fill_rule_t	fill_rule,
+			       double			tolerance,
+			       cairo_antialias_t	antialias)
 {
-    cairo_d2d_surface_t *d2dsurf = cairo_container_of (clipper, cairo_d2d_surface_t, clipper);
+    cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(dst);
 
     _cairo_d2d_surface_pop_clip(d2dsurf);
     if (!path) {
 	if (d2dsurf->clipMask) {
 	    d2dsurf->clipMask->Release();
 	    d2dsurf->clipMask = NULL;
 	}
 	if (d2dsurf->clipRect) {
 	    delete d2dsurf->clipRect;
 	    d2dsurf->clipRect = NULL;
 	}
-	return CAIRO_STATUS_SUCCESS;
+	return CAIRO_INT_STATUS_SUCCESS;
     }
     cairo_box_t box;
 
     if (_cairo_path_fixed_is_box(path, &box) && box.p1.y < box.p2.y) {
 	/** 
 	 * Nice axis aligned rectangular clip, try and do our best to keep it
 	 * that way.
 	 */
 	if (!d2dsurf->clipRect && !d2dsurf->clipMask) {
 	    /** Nothing yet, just use this clip rect */
-	    //XXX: unchecked allocation
 	    d2dsurf->clipRect = new D2D1_RECT_F(D2D1::RectF(_cairo_fixed_to_float(box.p1.x),
 							    _cairo_fixed_to_float(box.p1.y),
 							    _cairo_fixed_to_float(box.p2.x),
 							    _cairo_fixed_to_float(box.p2.y)));
-	    return CAIRO_STATUS_SUCCESS;
+	    return CAIRO_INT_STATUS_SUCCESS;
 	} else if (!d2dsurf->clipMask) {
 	    /** We have a clip rect, intersect of two rects is simple */
 	    d2dsurf->clipRect->top = max(_cairo_fixed_to_float(box.p1.y), d2dsurf->clipRect->top);
 	    d2dsurf->clipRect->left = max(d2dsurf->clipRect->left, _cairo_fixed_to_float(box.p1.x));
 	    d2dsurf->clipRect->bottom = min(d2dsurf->clipRect->bottom, _cairo_fixed_to_float(box.p2.y));
 	    d2dsurf->clipRect->right = min(d2dsurf->clipRect->right, _cairo_fixed_to_float(box.p2.x));
 	    if (d2dsurf->clipRect->top > d2dsurf->clipRect->bottom) {
 		d2dsurf->clipRect->top = d2dsurf->clipRect->bottom;
 	    }
 	    if (d2dsurf->clipRect->left > d2dsurf->clipRect->right) {
 		d2dsurf->clipRect->left = d2dsurf->clipRect->right;
 	    }
-	    return CAIRO_STATUS_SUCCESS;
+	    return CAIRO_INT_STATUS_SUCCESS;
 	} else {
 	    /** 
 	     * We have a mask, see if this rect is completely contained by it, so we
 	     * can optimize by just using this rect rather than a geometry mask.
 	     */
 	    ID2D1RectangleGeometry *newMask;
 	    D2DSurfFactory::Instance()->CreateRectangleGeometry(D2D1::RectF(_cairo_fixed_to_float(box.p1.x),
 									    _cairo_fixed_to_float(box.p1.y),
@@ -1657,22 +1648,21 @@ static cairo_status_t
 									    _cairo_fixed_to_float(box.p2.y)), 
 								&newMask);
 	    D2D1_GEOMETRY_RELATION relation;
 	    d2dsurf->clipMask->CompareWithGeometry(newMask, D2D1::Matrix3x2F::Identity(), &relation);
 	    if (relation == D2D1_GEOMETRY_RELATION_CONTAINS) {
 	        d2dsurf->clipMask->Release();
 		d2dsurf->clipMask = NULL;
 	        newMask->Release();
-		//XXX: unchecked allocation
 	        d2dsurf->clipRect = new D2D1_RECT_F(D2D1::RectF(_cairo_fixed_to_float(box.p1.x),
 								_cairo_fixed_to_float(box.p1.y),
 								_cairo_fixed_to_float(box.p2.x),
 								_cairo_fixed_to_float(box.p2.y)));
-		return CAIRO_STATUS_SUCCESS;
+		return CAIRO_INT_STATUS_SUCCESS;		    
 		
 	    }
 	    newMask->Release();
 	}
     }
     
     if (!d2dsurf->clipRect && !d2dsurf->clipMask) {
 	/** Nothing yet, just use this clip path */
@@ -1702,17 +1692,17 @@ static cairo_status_t
 	ID2D1RectangleGeometry *currentMask;
 	D2DSurfFactory::Instance()->CreateRectangleGeometry(d2dsurf->clipRect, &currentMask);
 	ID2D1Geometry *newMask = _cairo_d2d_create_path_geometry_for_path(path, fill_rule, D2D1_FIGURE_BEGIN_FILLED);
         D2D1_GEOMETRY_RELATION relation;
 	newMask->CompareWithGeometry(currentMask, D2D1::Matrix3x2F::Identity(), &relation);
 	if (relation == D2D1_GEOMETRY_RELATION_CONTAINS) {
 	    currentMask->Release();
 	    newMask->Release();
-	    return CAIRO_STATUS_SUCCESS;
+	    return CAIRO_INT_STATUS_SUCCESS;
 	} else if (relation == D2D1_GEOMETRY_RELATION_IS_CONTAINED) {
 	    currentMask->Release();
 	    d2dsurf->clipMask = newMask;
 	} else {
 	    ID2D1PathGeometry *finalMask;
 	    D2DSurfFactory::Instance()->CreatePathGeometry(&finalMask);
 	    ID2D1GeometrySink *sink;
 	    finalMask->Open(&sink);
@@ -1728,17 +1718,17 @@ static cairo_status_t
 	}
     }
 
     if (d2dsurf->clipRect) {
 	delete d2dsurf->clipRect;
 	d2dsurf->clipRect = NULL;
     }
   
-    return CAIRO_STATUS_SUCCESS;
+    return CAIRO_INT_STATUS_SUCCESS;
 }
 
 static cairo_status_t
 _cairo_d2d_flush(void                  *surface)
 {
     cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
 
     if (d2dsurf->isDrawing) {
@@ -1748,25 +1738,19 @@ static cairo_status_t
     }
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_int_status_t
 _cairo_d2d_paint(void			*surface,
 		 cairo_operator_t	 op,
 		 const cairo_pattern_t	*source,
-		 cairo_clip_t		*clip)
+		 cairo_rectangle_int_t  *extents)
 {
     cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
-    cairo_int_status_t status;
-
-    status = (cairo_int_status_t)_cairo_surface_clipper_set_clip (&d2dsurf->clipper, clip);
-    if (unlikely(status))
-	return status;
-
     _begin_draw_state(d2dsurf);
 
     op = _cairo_d2d_simplify_operator(op, source);
 
     if (op == CAIRO_OPERATOR_CLEAR) {
 	_cairo_d2d_clear_geometry(d2dsurf, NULL);
 	return CAIRO_INT_STATUS_SUCCESS;
     }
@@ -1782,24 +1766,30 @@ static cairo_int_status_t
 								source,
 								last_run++,
 								&runs_remaining,
 								&pushed_clip);
 
 	if (!brush) {
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
 	}
-	if (op == CAIRO_OPERATOR_OVER) {
+	if (op == CAIRO_OPERATOR_OVER && extents) {
+	    d2dsurf->rt->FillRectangle(D2D1::RectF((FLOAT)extents->x,
+						   (FLOAT)extents->y,
+						   (FLOAT)extents->x + extents->width,
+						   (FLOAT)extents->y + extents->height),
+				       brush);
+	} else if (op == CAIRO_OPERATOR_OVER) {
 	    D2D1_SIZE_F size = d2dsurf->rt->GetSize();
 	    d2dsurf->rt->FillRectangle(D2D1::RectF((FLOAT)0,
 						   (FLOAT)0,
 						   (FLOAT)size.width,
 						   (FLOAT)size.height),
 				       brush);
-        } else if (op == CAIRO_OPERATOR_SOURCE) {
+        } else if (op == CAIRO_OPERATOR_SOURCE && !extents) {
 	    D2D1_SIZE_F size = d2dsurf->rt->GetSize();
             d2dsurf->rt->Clear(D2D1::ColorF(0, 0));
             d2dsurf->rt->FillRectangle(D2D1::RectF((FLOAT)0,
 						   (FLOAT)0,
 						   (FLOAT)size.width,
 						   (FLOAT)size.height),
 				       brush);
         } else {
@@ -1815,58 +1805,43 @@ static cairo_int_status_t
     return CAIRO_INT_STATUS_SUCCESS;
 }
 
 static cairo_int_status_t
 _cairo_d2d_mask(void			*surface,
 		cairo_operator_t	 op,
 		const cairo_pattern_t	*source,
 		const cairo_pattern_t	*mask,
-		cairo_clip_t		*clip)
+		cairo_rectangle_int_t	*extents)
 {
     cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
-    cairo_rectangle_int_t extents;
+    _begin_draw_state(d2dsurf);
 
     unsigned int runs_remaining = 0;
     bool pushed_clip;
-    cairo_int_status_t status;
-
-    status = (cairo_int_status_t)_cairo_surface_clipper_set_clip (&d2dsurf->clipper, clip);
-    if (unlikely (status))
-	return status;
-
-    _begin_draw_state(d2dsurf);
-
-    status = (cairo_int_status_t)_cairo_surface_mask_extents (&d2dsurf->base,
-		    op, source,
-		    mask,
-		    clip, &extents);
-    if (unlikely (status))
-	    return status;
-
 
     ID2D1Brush *brush = _cairo_d2d_create_brush_for_pattern(d2dsurf, source, 0, &runs_remaining, &pushed_clip);
     if (!brush) {
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
     if (runs_remaining) {
 	brush->Release();
 	// TODO: Implement me!!
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
     D2D1_RECT_F rect = D2D1::RectF(0,
 				   0,
 				   (FLOAT)d2dsurf->rt->GetPixelSize().width,
 				   (FLOAT)d2dsurf->rt->GetPixelSize().height);
-
-    rect.left = (FLOAT)extents.x;
-    rect.right = (FLOAT)(extents.x + extents.width);
-    rect.top = (FLOAT)extents.y;
-    rect.bottom = (FLOAT)(extents.y + extents.height);
-
+    if (extents) {
+	rect.left = (FLOAT)extents->x;
+	rect.right = (FLOAT)(extents->x + extents->width);
+	rect.top = (FLOAT)extents->y;
+	rect.bottom = (FLOAT)(extents->y + extents->height);
+    }
 
     if (mask->type == CAIRO_PATTERN_TYPE_SOLID) {
 	cairo_solid_pattern_t *solidPattern =
 	    (cairo_solid_pattern_t*)mask;
 	if (solidPattern->content = CAIRO_CONTENT_ALPHA) {
 	    brush->SetOpacity((FLOAT)solidPattern->color.alpha);
 	    d2dsurf->rt->FillRectangle(rect,
 				       brush);
@@ -1909,40 +1884,33 @@ static cairo_int_status_t
 		  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,
 		  double		 tolerance,
 		  cairo_antialias_t	 antialias,
-		  cairo_clip_t		*clip)
+		  cairo_rectangle_int_t  *extents)
 {
-    cairo_int_status_t status;
-
     cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
+    _begin_draw_state(d2dsurf);
 
     op = _cairo_d2d_simplify_operator(op, source);
 
     if (op != CAIRO_OPERATOR_OVER && op != CAIRO_OPERATOR_ADD &&
 	op != CAIRO_OPERATOR_CLEAR) {
 	/** 
 	 * We don't really support ADD yet. True ADD support requires getting
 	 * the tesselated mesh from D2D, and blending that using D3D which has
 	 * an add operator available.
 	 */
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
-    status = (cairo_int_status_t)_cairo_surface_clipper_set_clip (&d2dsurf->clipper, clip);
-    if (unlikely(status))
-	return status;
-
-    _begin_draw_state(d2dsurf);
-
     if (antialias == CAIRO_ANTIALIAS_NONE) {
 	d2dsurf->rt->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
     } else {
 	d2dsurf->rt->SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
     }
     ID2D1StrokeStyle *strokeStyle = _cairo_d2d_create_strokestyle_for_stroke_style(style);
 
     if (!strokeStyle) {
@@ -2045,40 +2013,36 @@ static cairo_int_status_t
 static cairo_int_status_t
 _cairo_d2d_fill(void			*surface,
 		cairo_operator_t	 op,
 		const cairo_pattern_t	*source,
 		cairo_path_fixed_t	*path,
 		cairo_fill_rule_t	 fill_rule,
 		double			 tolerance,
 		cairo_antialias_t	 antialias,
-		cairo_clip_t		*clip)
+		cairo_rectangle_int_t	*extents)
 {
-    cairo_int_status_t status;
-
+    if (((cairo_surface_t*)surface)->type != CAIRO_SURFACE_TYPE_D2D) {
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+    }
     cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
+    _begin_draw_state(d2dsurf);
 
     op = _cairo_d2d_simplify_operator(op, source);
 
     if (op != CAIRO_OPERATOR_OVER && op != CAIRO_OPERATOR_ADD &&
 	op != CAIRO_OPERATOR_CLEAR) {
 	/** 
 	 * We don't really support ADD yet. True ADD support requires getting
 	 * the tesselated mesh from D2D, and blending that using D3D which has
 	 * an add operator available.
 	 */
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
-    status = (cairo_int_status_t)_cairo_surface_clipper_set_clip (&d2dsurf->clipper, clip);
-    if (unlikely (status))
-	return status;
-
-    _begin_draw_state(d2dsurf);
-
     if (antialias == CAIRO_ANTIALIAS_NONE) {
 	d2dsurf->rt->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
     } else {
 	d2dsurf->rt->SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
     }
 
     unsigned int runs_remaining = 1;
     unsigned int last_run = 0;
@@ -2149,59 +2113,61 @@ static cairo_int_status_t
 		d2dsurf->rt->PopLayer();
 	    }
 	}
 	d2dpath->Release();
     }
     return CAIRO_INT_STATUS_SUCCESS;
 }
 
-
 static cairo_int_status_t
 _cairo_d2d_show_glyphs (void			*surface,
 			cairo_operator_t	 op,
 			const cairo_pattern_t	*source,
 			cairo_glyph_t		*glyphs,
 			int			 num_glyphs,
 			cairo_scaled_font_t	*scaled_font,
-			cairo_clip_t            *clip,
-			int			*remaining_glyphs)
+			int			*remaining_glyphs,
+			cairo_rectangle_int_t	*extents)
 {
     if (((cairo_surface_t*)surface)->type != CAIRO_SURFACE_TYPE_D2D) {
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
     cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
     if (!d2dsurf->textRenderingInit) {
 	IDWriteRenderingParams *params;
 	DWriteFactory::Instance()->CreateRenderingParams(&params);
 	d2dsurf->rt->SetTextRenderingParams(params);
 	d2dsurf->textRenderingInit = true;
 	params->Release();
     }
+    _begin_draw_state(d2dsurf);
     cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
     if (scaled_font->backend->type == CAIRO_FONT_TYPE_DWRITE) {
         status = (cairo_int_status_t)
-	    _cairo_dwrite_show_glyphs_on_d2d_surface(surface, op, source, glyphs, num_glyphs, scaled_font, clip);
+	    cairo_dwrite_show_glyphs_on_d2d_surface(surface, op, source, glyphs, num_glyphs, scaled_font, extents);
     }
 
     return status;
 }
 
-
-static cairo_bool_t
+static cairo_int_status_t
 _cairo_d2d_getextents(void		       *surface,
 		      cairo_rectangle_int_t    *extents)
 {
+    if (((cairo_surface_t*)surface)->type != CAIRO_SURFACE_TYPE_D2D) {
+	return (cairo_int_status_t)CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
+    }
     cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
     extents->x = 0;
     extents->y = 0;
     D2D1_SIZE_U size = d2dsurf->rt->GetPixelSize(); 
     extents->width = size.width;
     extents->height = size.height;
-    return TRUE;
+    return CAIRO_INT_STATUS_SUCCESS;
 }
 
 
 /** Helper functions. */
 
 cairo_surface_t*
 cairo_d2d_surface_create_for_hwnd(HWND wnd)
 {
@@ -2212,17 +2178,16 @@ cairo_d2d_surface_create_for_hwnd(HWND w
 	 */
 	return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_DEVICE));
     }
 
     cairo_d2d_surface_t *newSurf = static_cast<cairo_d2d_surface_t*>(malloc(sizeof(cairo_d2d_surface_t)));
 
     memset(newSurf, 0, sizeof(cairo_d2d_surface_t));
     _cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, CAIRO_CONTENT_COLOR);
-    _cairo_surface_clipper_init(&newSurf->clipper, _cairo_d2d_surface_clipper_intersect_clip_path);
 
     RECT rc;
     HRESULT hr;
 
     newSurf->isDrawing = false;
     ::GetClientRect(wnd, &rc);
 
     FLOAT dpiX;
@@ -2348,19 +2313,16 @@ cairo_d2d_surface_create(cairo_format_t 
 	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, CAIRO_CONTENT_COLOR_ALPHA);
     } else if (format == CAIRO_FORMAT_RGB24) {
 	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, CAIRO_CONTENT_COLOR);
 	alpha = D2D1_ALPHA_MODE_IGNORE;
     } else {
 	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, CAIRO_CONTENT_ALPHA);
 	dxgiformat = DXGI_FORMAT_A8_UNORM;
     }
-
-    _cairo_surface_clipper_init(&newSurf->clipper, _cairo_d2d_surface_clipper_intersect_clip_path);
-
     newSurf->format = format;
 
     D2D1_SIZE_U sizePixels;
     HRESULT hr;
 
     sizePixels.width = width;
     sizePixels.height = height;
 
--- a/gfx/cairo/cairo/src/cairo-ddraw-private.h
+++ b/gfx/cairo/cairo/src/cairo-ddraw-private.h
@@ -32,17 +32,16 @@
  * Contributor(s):
  */
 
 #ifndef CAIRO_DDRAW_PRIVATE_H
 #define CAIRO_DDRAW_PRIVATE_H
 
 #include "cairo-ddraw.h"
 #include "cairoint.h"
-#include "cairo-region-private.h"
 
 #ifdef CAIRO_DDRAW_USE_GL
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 #endif
 
--- a/gfx/cairo/cairo/src/cairo-ddraw-surface.c
+++ b/gfx/cairo/cairo/src/cairo-ddraw-surface.c
@@ -237,16 +237,38 @@ static cairo_status_t
 # else
 # define CHECK_OGL_ERROR(context)
 # endif
 #endif
 
 #endif /* CAIRO_DDRAW_USE_GL */
 
 static cairo_status_t
+_cairo_ddraw_surface_set_image_clip (cairo_ddraw_surface_t *surface)
+{
+    if (surface->image_clip_invalid) {
+	surface->image_clip_invalid = FALSE;
+	if (surface->has_clip_region) {
+	    unsigned int serial =
+		_cairo_surface_allocate_clip_serial (surface->image);
+	    surface->has_image_clip = TRUE;
+	    return _cairo_surface_set_clip_region (surface->image,
+						   &surface->clip_region,
+						   serial);
+	} else {
+	    surface->has_image_clip = FALSE;
+	    return _cairo_surface_set_clip_region (surface->image,
+						   NULL, 0);
+	}
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
 _cairo_ddraw_surface_set_clip_list (cairo_ddraw_surface_t * surface)
 {
     DWORD stack_data[CAIRO_STACK_BUFFER_SIZE / sizeof (DWORD)];
     cairo_rectangle_int_t extents;
     int num_rects;
     RGNDATA * rgn;
     DWORD size;
     cairo_status_t status;
@@ -344,17 +366,20 @@ static cairo_status_t
 						 surface->data_offset,
 						 surface->format,
 						 surface->extents.width,
 						 surface->extents.height,
 						 root_img->stride);
 	if (surface->image->status)
 	    return surface->image->status;
 
-	return CAIRO_STATUS_SUCCESS;
+	surface->has_image_clip = FALSE;
+	surface->image_clip_invalid = surface->has_clip_region;
+
+	return _cairo_ddraw_surface_set_image_clip (surface);
     }
 
     if (surface->locked)
 	return CAIRO_STATUS_SUCCESS;
 
     ddsd.dwSize = sizeof (ddsd);
     START_TIMER(lock);
     if (FAILED(hr = IDDSLock (surface->lpdds, NULL, &ddsd,
@@ -378,17 +403,20 @@ static cairo_status_t
 					     surface->format,
 					     ddsd.dwWidth,
 					     ddsd.dwHeight,
 					     ddsd.lPitch);
 
     if (surface->image->status)
 	return surface->image->status;
 
-    return CAIRO_STATUS_SUCCESS;
+    surface->has_image_clip = FALSE;
+    surface->image_clip_invalid = surface->has_clip_region;
+
+    return _cairo_ddraw_surface_set_image_clip (surface);
 }
 
 static inline cairo_status_t
 _cairo_ddraw_surface_unlock (cairo_ddraw_surface_t *surface)
 {
     cairo_ddraw_surface_t * root = surface->root;
     HRESULT hr;
 
@@ -431,18 +459,16 @@ static inline cairo_status_t
 	HRESULT hr;
 	if (FAILED(hr = IDDSSetClipper(root->lpdds, NULL)))
 	    return _cairo_ddraw_print_ddraw_error ("_reset_clipper", hr);
 	root->installed_clipper = NULL;
     }
 
     return CAIRO_STATUS_SUCCESS;
 }
-
-
 #ifdef CAIRO_DDRAW_USE_GL
 #define CAIRO_DDRAW_API_ENTRY_STATUS                                  \
     do {                                                              \
 	int status;                                                   \
 	if (status = _cairo_ddraw_ogl_make_current())		      \
 	    return (status);					      \
     } while (0)
 #define CAIRO_DDRAW_API_ENTRY_VOID do {                               \
@@ -541,17 +567,17 @@ static cairo_status_t
     END_TIMER(flush);
  
     return status;
 }
 
 cairo_status_t
 _cairo_ddraw_surface_reset (cairo_surface_t *surface)
 {
-    return _cairo_ddraw_surface_set_clip_region (surface, NULL);
+    return _cairo_surface_reset_clip (surface);
 }
 
 static cairo_surface_t *
 _cairo_ddraw_surface_create_similar (void * abstract_surface,
 				     cairo_content_t content,
 				     int width,
 				     int height)
 {
@@ -2446,18 +2472,18 @@ static cairo_int_status_t
 
 static cairo_int_status_t
 _cairo_ddraw_surface_show_glyphs (void		         *abstract_dst,
 				  cairo_operator_t	 op,
 				  const cairo_pattern_t  *pattern,
 				  cairo_glyph_t	         *glyphs,
 				  int		         num_glyphs,
 				  cairo_scaled_font_t    *scaled_font,
-				  cairo_clip_t           *clip,
-				  int		         *remaining_glyphs)
+				  int		         *remaining_glyphs,
+				  cairo_rectangle_int_t  *extents)
 { 
     cairo_ddraw_surface_t * dst = (cairo_ddraw_surface_t *) abstract_dst;
     cairo_color_t * color;
     cairo_ddraw_ogl_font_t * font = scaled_font->surface_private;
     GLuint vbo;
     cairo_ddraw_ogl_glyph_quad_t * verts;
     cairo_ddraw_ogl_glyph_idx_t * indices;
     cairo_status_t status = CAIRO_STATUS_SUCCESS;
@@ -2471,27 +2497,20 @@ static cairo_int_status_t
 
     CAIRO_DDRAW_API_ENTRY_STATUS;
 
     assert (num_glyphs);
 
     if (pattern->type != CAIRO_PATTERN_TYPE_SOLID)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    if (clip != NULL) {
-	cairo_region_t *clip_region;
-	cairo_status_t status;
-
-	status = _cairo_clip_get_region (clip, &clip_region);
-	assert (status != CAIRO_INT_STATUS_NOTHING_TO_DO);
-	if (status)
-	    return status;
-
-	_cairo_ddraw_surface_set_clip_region (surface, clip_region);
-    }
+    if (dst->base.clip &&
+	(dst->base.clip->mode != CAIRO_CLIP_MODE_REGION ||
+	 dst->base.clip->surface != NULL))
+	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     color = &((cairo_solid_pattern_t *)pattern)->color;
 
     if (font == NULL) {
 	font = calloc (1, sizeof (cairo_ddraw_ogl_font_t));
 	if (font == NULL)
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -2687,18 +2706,17 @@ static cairo_int_status_t
 				void                    *abstract_dst,
 				int			src_x,
 				int			src_y,
 				int			mask_x,
 				int			mask_y,
 				int			dst_x,
 				int			dst_y,
 				unsigned int		width,
-				unsigned int		height,
-				cairo_regiont_t         *clip_region)
+				unsigned int		height)
 {
     cairo_ddraw