[cairo-commit] 2 commits - src/cairo-analysis-surface.c src/cairo-bentley-ottmann-rectangular.c src/cairo-bentley-ottmann-rectilinear.c src/cairo-boxes.c src/cairo-boxes-intersect.c src/cairo-boxes-private.h src/cairo-cff-subset.c src/cairo-clip-boxes.c src/cairo-clip.c src/cairo-clip-polygon.c src/cairo-clip-private.h src/cairo-clip-region.c src/cairo-clip-surface.c src/cairo-composite-rectangles.c src/cairo-composite-rectangles-private.h src/cairo-debug.c src/cairo-default-context.c src/cairo-error.c src/cairo-error-private.h src/cairo-fixed-private.h src/cairo-font-face-twin.c src/cairo-ft-font.c src/cairo-gl-glyphs.c src/cairo-gl-private.h src/cairo-gl-surface.c src/cairo-gl-surface-legacy.c src/cairo-gstate.c src/cairo-gstate-private.h src/cairo-image-info.c src/cairo-image-surface.c src/cairoint.h src/cairo-misc.c src/cairo-paginated-surface.c src/cairo-path-bounds.c src/cairo-path-fill.c src/cairo-path-stroke.c src/cairo-pattern.c src/cairo-pdf-operators.c src/cairo-pdf-oper ators-private.h src/cairo-pdf-surface.c src/cairo-png.c src/cairo-polygon.c src/cairo-polygon-intersect.c src/cairo-polygon-reduce.c src/cairo-ps-surface.c src/cairo-quartz-surface.c src/cairo-recording-surface.c src/cairo-recording-surface-private.h src/cairo-scaled-font.c src/cairo-scaled-font-subsets.c src/cairo-scaled-font-subsets-private.h src/cairo-script-surface.c src/cairo-spans.c src/cairo-surface.c src/cairo-surface-clipper.c src/cairo-surface-clipper-private.h src/cairo-surface-fallback.c src/cairo-surface-fallback-private.h src/cairo-surface-offset.c src/cairo-surface-offset-private.h src/cairo-surface-subsurface.c src/cairo-surface-wrapper.c src/cairo-surface-wrapper-private.h src/cairo-svg-surface.c src/cairo-tee.h src/cairo-tee-surface.c src/cairo-tor-scan-converter.c src/cairo-traps.c src/cairo-truetype-subset.c src/cairo-type1-fallback.c src/cairo-type3-glyph-surface.c src/cairo-types-private.h src/cairo-user-font.c src/cairo-win32-printing-surface.c src/cai ro-win32-surface.c src/cairo-xcb-private.h src/cairo-xcb-surface.c src/cairo-xcb-surface-cairo.c src/cairo-xcb-surface-render.c src/cairo-xlib-surface.c src/cairo-xml-surface.c src/Makefile.sources src/test-null-surface.c src/test-paginated-surface.c src/test-wrapping-surface.c test/clip-group-shapes-circles.ref.png test/clip-shape.ref.png test/clip-stroke.ref.png

Chris Wilson ickle at kemper.freedesktop.org
Tue Jul 19 13:15:50 PDT 2011


 src/Makefile.sources                     |    7 
 src/cairo-analysis-surface.c             |   98 --
 src/cairo-bentley-ottmann-rectangular.c  |    4 
 src/cairo-bentley-ottmann-rectilinear.c  |    2 
 src/cairo-boxes-intersect.c              |  666 +++++++++++++
 src/cairo-boxes-private.h                |   27 
 src/cairo-boxes.c                        |   78 +
 src/cairo-cff-subset.c                   |   14 
 src/cairo-clip-boxes.c                   |  559 +++++++++++
 src/cairo-clip-polygon.c                 |  127 ++
 src/cairo-clip-private.h                 |  149 +--
 src/cairo-clip-region.c                  |  117 ++
 src/cairo-clip-surface.c                 |  142 ++
 src/cairo-clip.c                         | 1414 +++--------------------------
 src/cairo-composite-rectangles-private.h |   19 
 src/cairo-composite-rectangles.c         |   54 -
 src/cairo-debug.c                        |   37 
 src/cairo-default-context.c              |    5 
 src/cairo-error-private.h                |   54 +
 src/cairo-error.c                        |    4 
 src/cairo-fixed-private.h                |    6 
 src/cairo-font-face-twin.c               |   31 
 src/cairo-ft-font.c                      |   52 -
 src/cairo-gl-glyphs.c                    |  134 +-
 src/cairo-gl-private.h                   |    2 
 src/cairo-gl-surface-legacy.c            |  601 ++++++++++++
 src/cairo-gl-surface.c                   |  126 --
 src/cairo-gstate-private.h               |    2 
 src/cairo-gstate.c                       |  206 +---
 src/cairo-image-info.c                   |    2 
 src/cairo-image-surface.c                |  507 +++-------
 src/cairo-misc.c                         |    2 
 src/cairo-paginated-surface.c            |   27 
 src/cairo-path-bounds.c                  |    1 
 src/cairo-path-fill.c                    |  112 ++
 src/cairo-path-stroke.c                  |   34 
 src/cairo-pattern.c                      |    4 
 src/cairo-pdf-operators-private.h        |   14 
 src/cairo-pdf-operators.c                |   12 
 src/cairo-pdf-surface.c                  |   82 -
 src/cairo-png.c                          |    2 
 src/cairo-polygon-intersect.c            | 1466 ++++++++++++++++++++++++++++++
 src/cairo-polygon-reduce.c               | 1491 +++++++++++++++++++++++++++++++
 src/cairo-polygon.c                      |  111 ++
 src/cairo-ps-surface.c                   |   61 -
 src/cairo-quartz-surface.c               |   28 
 src/cairo-recording-surface-private.h    |    5 
 src/cairo-recording-surface.c            |   82 -
 src/cairo-scaled-font-subsets-private.h  |    4 
 src/cairo-scaled-font-subsets.c          |    8 
 src/cairo-scaled-font.c                  |   14 
 src/cairo-script-surface.c               |   73 -
 src/cairo-spans.c                        |   29 
 src/cairo-surface-clipper-private.h      |    5 
 src/cairo-surface-clipper.c              |  122 +-
 src/cairo-surface-fallback-private.h     |   14 
 src/cairo-surface-fallback.c             |  259 +----
 src/cairo-surface-offset-private.h       |   14 
 src/cairo-surface-offset.c               |  102 --
 src/cairo-surface-subsurface.c           |   79 -
 src/cairo-surface-wrapper-private.h      |   16 
 src/cairo-surface-wrapper.c              |  228 +---
 src/cairo-surface.c                      |   82 -
 src/cairo-svg-surface.c                  |   42 
 src/cairo-tee-surface.c                  |   30 
 src/cairo-tee.h                          |    2 
 src/cairo-tor-scan-converter.c           |   22 
 src/cairo-traps.c                        |   95 +
 src/cairo-truetype-subset.c              |   11 
 src/cairo-type1-fallback.c               |    2 
 src/cairo-type3-glyph-surface.c          |   40 
 src/cairo-types-private.h                |   11 
 src/cairo-user-font.c                    |    9 
 src/cairo-win32-printing-surface.c       |   12 
 src/cairo-win32-surface.c                |    8 
 src/cairo-xcb-private.h                  |   38 
 src/cairo-xcb-surface-cairo.c            |   14 
 src/cairo-xcb-surface-render.c           |  615 ++++--------
 src/cairo-xcb-surface.c                  |   28 
 src/cairo-xlib-surface.c                 |   32 
 src/cairo-xml-surface.c                  |   27 
 src/cairoint.h                           |   79 +
 src/test-null-surface.c                  |   16 
 src/test-paginated-surface.c             |   14 
 src/test-wrapping-surface.c              |   14 
 test/clip-group-shapes-circles.ref.png   |binary
 test/clip-shape.ref.png                  |binary
 test/clip-stroke.ref.png                 |binary
 88 files changed, 7489 insertions(+), 3501 deletions(-)

New commits:
commit b132fae5e843c329d1414d1a65b2e8d66b99852f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 14 21:19:54 2011 +0100

    clip: Rudimentary support for clip-polygon extraction
    
    Step 1, fix the failings sighted recently by tracking clip-boxes as an
    explicit property of the clipping and of composition.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/Makefile.sources b/src/Makefile.sources
index 5371e81..97f452a 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -118,9 +118,14 @@ cairo_sources = \
 	cairo-bentley-ottmann-rectilinear.c \
 	cairo-botor-scan-converter.c \
 	cairo-boxes.c \
+	cairo-boxes-intersect.c \
 	cairo.c \
 	cairo-cache.c \
 	cairo-clip.c \
+	cairo-clip-boxes.c \
+	cairo-clip-polygon.c \
+	cairo-clip-region.c \
+	cairo-clip-surface.c \
 	cairo-color.c \
 	cairo-composite-rectangles.c \
 	cairo-debug.c \
@@ -156,6 +161,8 @@ cairo_sources = \
 	cairo-pattern.c \
 	cairo-pen.c \
 	cairo-polygon.c \
+	cairo-polygon-intersect.c \
+	cairo-polygon-reduce.c \
 	cairo-recording-surface.c \
 	cairo-rectangle.c \
 	cairo-rectangular-scan-converter.c \
diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index affa556..aa0977e 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -67,8 +67,8 @@ _cairo_analysis_surface_merge_status (cairo_int_status_t status_a,
 				      cairo_int_status_t status_b)
 {
     /* fatal errors should be checked and propagated at source */
-    assert (! _cairo_status_is_error (status_a));
-    assert (! _cairo_status_is_error (status_b));
+    assert (! _cairo_int_status_is_error (status_a));
+    assert (! _cairo_int_status_is_error (status_b));
 
     /* return the most important status */
     if (status_a == CAIRO_INT_STATUS_UNSUPPORTED ||
@@ -88,10 +88,10 @@ _cairo_analysis_surface_merge_status (cairo_int_status_t status_a,
 	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);
+    assert (status_a == CAIRO_INT_STATUS_SUCCESS &&
+	    status_b == CAIRO_INT_STATUS_SUCCESS);
 
-    return CAIRO_STATUS_SUCCESS;
+    return CAIRO_INT_STATUS_SUCCESS;
 }
 
 static cairo_int_status_t
@@ -144,10 +144,10 @@ _add_operation (cairo_analysis_surface_t *surface,
 	/* 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 ||
+	if (backend_status == CAIRO_INT_STATUS_SUCCESS ||
 	    backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
 	{
-	    return CAIRO_STATUS_SUCCESS;
+	    return CAIRO_INT_STATUS_SUCCESS;
 	}
 	else
 	{
@@ -172,10 +172,10 @@ _add_operation (cairo_analysis_surface_t *surface,
 		 * careful to not allow unsupported operations to be
 		 * replayed to the backend during
 		 * CAIRO_PAGINATED_MODE_RENDER */
-		if (backend_status == CAIRO_STATUS_SUCCESS ||
+		if (backend_status == CAIRO_INT_STATUS_SUCCESS ||
 		    backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
 		{
-		    return CAIRO_STATUS_SUCCESS;
+		    return CAIRO_INT_STATUS_SUCCESS;
 		}
 		else
 		{
@@ -217,10 +217,10 @@ _add_operation (cairo_analysis_surface_t *surface,
 	 * transparency into the white background.
 	 */
 	if (cairo_region_contains_rectangle (&surface->supported_region, rect) == CAIRO_REGION_OVERLAP_OUT)
-	    backend_status = CAIRO_STATUS_SUCCESS;
+	    backend_status = CAIRO_INT_STATUS_SUCCESS;
     }
 
-    if (backend_status == CAIRO_STATUS_SUCCESS) {
+    if (backend_status == CAIRO_INT_STATUS_SUCCESS) {
 	/* Add the operation to the supported region. Operations in
 	 * this region will be emitted as native operations.
 	 */
@@ -241,7 +241,7 @@ _add_operation (cairo_analysis_surface_t *surface,
      * invoke the cairo-surface-fallback path then return
      * CAIRO_STATUS_SUCCESS.
      */
-    if (status == CAIRO_STATUS_SUCCESS)
+    if (status == CAIRO_INT_STATUS_SUCCESS)
 	return CAIRO_INT_STATUS_IMAGE_FALLBACK;
     else
 	return status;
@@ -270,23 +270,17 @@ _cairo_analysis_surface_get_extents (void			*abstract_surface,
 }
 
 static void
-_rectangle_intersect_clip (cairo_rectangle_int_t *extents, cairo_clip_t *clip)
+_rectangle_intersect_clip (cairo_rectangle_int_t *extents, const cairo_clip_t *clip)
 {
-    const cairo_rectangle_int_t *clip_extents;
-
-    clip_extents = NULL;
     if (clip != NULL)
-	clip_extents = _cairo_clip_get_extents (clip);
-
-    if (clip_extents != NULL)
-	_cairo_rectangle_intersect (extents, clip_extents);
+	_cairo_rectangle_intersect (extents, _cairo_clip_get_extents (clip));
 }
 
 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,
+					   const cairo_clip_t *clip,
 					   cairo_rectangle_int_t *extents)
 {
     cairo_bool_t is_empty;
@@ -307,10 +301,10 @@ 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)
+			       const cairo_clip_t		*clip)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
-    cairo_status_t	     backend_status;
+    cairo_int_status_t	     backend_status;
     cairo_rectangle_int_t  extents;
 
     if (surface->target->backend->paint == NULL) {
@@ -319,7 +313,7 @@ _cairo_analysis_surface_paint (void			*abstract_surface,
 	backend_status =
 	    surface->target->backend->paint (surface->target,
 					     op, source, clip);
-	if (_cairo_status_is_error (backend_status))
+	if (_cairo_int_status_is_error (backend_status))
 	    return backend_status;
     }
 
@@ -338,7 +332,7 @@ _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)
+			      const cairo_clip_t		*clip)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
     cairo_int_status_t	      backend_status;
@@ -350,7 +344,7 @@ _cairo_analysis_surface_mask (void			*abstract_surface,
 	backend_status =
 	    surface->target->backend->mask (surface->target,
 					    op, source, mask, clip);
-	if (_cairo_status_is_error (backend_status))
+	if (_cairo_int_status_is_error (backend_status))
 	    return backend_status;
     }
 
@@ -363,7 +357,7 @@ _cairo_analysis_surface_mask (void			*abstract_surface,
 	    if (_cairo_surface_is_recording (surface_pattern->surface)) {
 		backend_source_status =
 		    _analyze_recording_surface_pattern (surface, source);
-		if (_cairo_status_is_error (backend_source_status))
+		if (_cairo_int_status_is_error (backend_source_status))
 		    return backend_source_status;
 	    }
 	}
@@ -373,7 +367,7 @@ _cairo_analysis_surface_mask (void			*abstract_surface,
 	    if (_cairo_surface_is_recording (surface_pattern->surface)) {
 		backend_mask_status =
 		    _analyze_recording_surface_pattern (surface, mask);
-		if (_cairo_status_is_error (backend_mask_status))
+		if (_cairo_int_status_is_error (backend_mask_status))
 		    return backend_mask_status;
 	    }
 	}
@@ -401,16 +395,16 @@ 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,
+				const cairo_path_fixed_t	*path,
 				const cairo_stroke_style_t	*style,
 				const cairo_matrix_t		*ctm,
 				const cairo_matrix_t		*ctm_inverse,
 				double			 tolerance,
 				cairo_antialias_t	 antialias,
-				cairo_clip_t		*clip)
+				const cairo_clip_t		*clip)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
-    cairo_status_t	     backend_status;
+    cairo_int_status_t	     backend_status;
     cairo_rectangle_int_t    extents;
 
     if (surface->target->backend->stroke == NULL) {
@@ -422,7 +416,7 @@ _cairo_analysis_surface_stroke (void			*abstract_surface,
 					      ctm, ctm_inverse,
 					      tolerance, antialias,
 					      clip);
-	if (_cairo_status_is_error (backend_status))
+	if (_cairo_int_status_is_error (backend_status))
 	    return backend_status;
     }
 
@@ -435,7 +429,7 @@ _cairo_analysis_surface_stroke (void			*abstract_surface,
 
     if (_cairo_operator_bounded_by_mask (op)) {
 	cairo_rectangle_int_t mask_extents;
-	cairo_status_t status;
+	cairo_int_status_t status;
 
 	status = _cairo_path_fixed_stroke_extents (path, style,
 						   ctm, ctm_inverse,
@@ -454,14 +448,14 @@ 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,
+			      const cairo_path_fixed_t	*path,
 			      cairo_fill_rule_t		 fill_rule,
 			      double			 tolerance,
 			      cairo_antialias_t		 antialias,
-			      cairo_clip_t		*clip)
+			      const cairo_clip_t		*clip)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
-    cairo_status_t	     backend_status;
+    cairo_int_status_t	     backend_status;
     cairo_rectangle_int_t    extents;
 
     if (surface->target->backend->fill == NULL) {
@@ -472,7 +466,7 @@ _cairo_analysis_surface_fill (void			*abstract_surface,
 					    source, path, fill_rule,
 					    tolerance, antialias,
 					    clip);
-	if (_cairo_status_is_error (backend_status))
+	if (_cairo_int_status_is_error (backend_status))
 	    return backend_status;
     }
 
@@ -502,11 +496,11 @@ _cairo_analysis_surface_show_glyphs (void		  *abstract_surface,
 				     cairo_glyph_t	  *glyphs,
 				     int		   num_glyphs,
 				     cairo_scaled_font_t  *scaled_font,
-				     cairo_clip_t         *clip,
+				     const cairo_clip_t         *clip,
 				     int                  *remaining_glyphs)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
-    cairo_status_t	     status, backend_status;
+    cairo_int_status_t	     status, backend_status;
     cairo_rectangle_int_t    extents, glyph_extents;
 
     /* Adapted from _cairo_surface_show_glyphs */
@@ -518,7 +512,7 @@ _cairo_analysis_surface_show_glyphs (void		  *abstract_surface,
 						   scaled_font,
 						   clip,
 						   remaining_glyphs);
-	if (_cairo_status_is_error (backend_status))
+	if (_cairo_int_status_is_error (backend_status))
 	    return backend_status;
     }
     else if (surface->target->backend->show_text_glyphs != NULL)
@@ -532,7 +526,7 @@ _cairo_analysis_surface_show_glyphs (void		  *abstract_surface,
 							FALSE,
 							scaled_font,
 							clip);
-	if (_cairo_status_is_error (backend_status))
+	if (_cairo_int_status_is_error (backend_status))
 	    return backend_status;
     }
     else
@@ -582,10 +576,10 @@ _cairo_analysis_surface_show_text_glyphs (void			    *abstract_surface,
 					  int			     num_clusters,
 					  cairo_text_cluster_flags_t cluster_flags,
 					  cairo_scaled_font_t	    *scaled_font,
-					  cairo_clip_t		    *clip)
+					  const cairo_clip_t		    *clip)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
-    cairo_status_t	     status, backend_status;
+    cairo_int_status_t	     status, backend_status;
     cairo_rectangle_int_t    extents, glyph_extents;
 
     /* Adapted from _cairo_surface_show_glyphs */
@@ -600,7 +594,7 @@ _cairo_analysis_surface_show_text_glyphs (void			    *abstract_surface,
 							cluster_flags,
 							scaled_font,
 							clip);
-	if (_cairo_status_is_error (backend_status))
+	if (_cairo_int_status_is_error (backend_status))
 	    return backend_status;
     }
     if (backend_status == CAIRO_INT_STATUS_UNSUPPORTED &&
@@ -614,7 +608,7 @@ _cairo_analysis_surface_show_text_glyphs (void			    *abstract_surface,
 						   scaled_font,
 						   clip,
 						   &remaining_glyphs);
-	if (_cairo_status_is_error (backend_status))
+	if (_cairo_int_status_is_error (backend_status))
 	    return backend_status;
 
 	glyphs += num_glyphs - remaining_glyphs;
@@ -803,36 +797,36 @@ typedef cairo_int_status_t
 (*_paint_func)			(void			*surface,
 			         cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
-				 cairo_clip_t		*clip);
+				 const cairo_clip_t		*clip);
 
 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);
+				 const cairo_clip_t		*clip);
 
 typedef cairo_int_status_t
 (*_stroke_func)			(void			*surface,
 			         cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
-				 cairo_path_fixed_t	*path,
+				 const cairo_path_fixed_t	*path,
 				 const cairo_stroke_style_t	*style,
 				 const cairo_matrix_t		*ctm,
 				 const cairo_matrix_t		*ctm_inverse,
 				 double			 tolerance,
 				 cairo_antialias_t	 antialias,
-				 cairo_clip_t		*clip);
+				 const cairo_clip_t		*clip);
 
 typedef cairo_int_status_t
 (*_fill_func)			(void			*surface,
 			         cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
-				 cairo_path_fixed_t	*path,
+				 const cairo_path_fixed_t	*path,
 				 cairo_fill_rule_t	 fill_rule,
 				 double			 tolerance,
 				 cairo_antialias_t	 antialias,
-				 cairo_clip_t		*clip);
+				 const cairo_clip_t		*clip);
 
 typedef cairo_int_status_t
 (*_show_glyphs_func)		(void			*surface,
@@ -841,7 +835,7 @@ typedef cairo_int_status_t
 				 cairo_glyph_t		*glyphs,
 				 int			 num_glyphs,
 				 cairo_scaled_font_t	*scaled_font,
-				 cairo_clip_t		*clip,
+				 const cairo_clip_t		*clip,
 				 int			*remaining_glyphs);
 
 static const cairo_surface_backend_t cairo_null_surface_backend = {
diff --git a/src/cairo-bentley-ottmann-rectangular.c b/src/cairo-bentley-ottmann-rectangular.c
index 9a4dcd9..ceeddd3 100644
--- a/src/cairo-bentley-ottmann-rectangular.c
+++ b/src/cairo-bentley-ottmann-rectangular.c
@@ -320,7 +320,7 @@ edge_end_box (sweep_line_t *sweep_line,
 	    box.p2.x = left->right->x;
 	    box.p2.y = bot;
 
-	    status = _cairo_boxes_add (container, &box);
+	    status = _cairo_boxes_add (container, CAIRO_ANTIALIAS_DEFAULT, &box);
 	}
     }
     if (unlikely (status))
@@ -746,7 +746,7 @@ _cairo_bentley_ottmann_tessellate_boxes (const cairo_boxes_t *in,
 	    box.p2.x = tmp;
 	}
 
-	status = _cairo_boxes_add (out, &box);
+	status = _cairo_boxes_add (out, CAIRO_ANTIALIAS_DEFAULT, &box);
 	assert (status == CAIRO_STATUS_SUCCESS);
 	return CAIRO_STATUS_SUCCESS;
     }
diff --git a/src/cairo-bentley-ottmann-rectilinear.c b/src/cairo-bentley-ottmann-rectilinear.c
index 1696d93..a3eb490 100644
--- a/src/cairo-bentley-ottmann-rectilinear.c
+++ b/src/cairo-bentley-ottmann-rectilinear.c
@@ -237,7 +237,7 @@ _cairo_bo_edge_end_trap (cairo_bo_edge_t	*left,
 	    box.p1.y = trap->top;
 	    box.p2.x = trap->right->edge.line.p1.x;
 	    box.p2.y = bot;
-	    status = _cairo_boxes_add (container, &box);
+	    status = _cairo_boxes_add (container, CAIRO_ANTIALIAS_DEFAULT, &box);
 	}
     }
 
diff --git a/src/cairo-boxes-intersect.c b/src/cairo-boxes-intersect.c
new file mode 100644
index 0000000..831abc1
--- /dev/null
+++ b/src/cairo-boxes-intersect.c
@@ -0,0 +1,666 @@
+/*
+ * Copyright © 2004 Carl Worth
+ * Copyright © 2006 Red Hat, Inc.
+ * Copyright © 2009 Chris Wilson
+ * Copyright © 2011 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Carl Worth
+ *
+ * Contributor(s):
+ *	Carl D. Worth <cworth at cworth.org>
+ *	Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+/* Provide definitions for standalone compilation */
+#include "cairoint.h"
+
+#include "cairo-boxes-private.h"
+#include "cairo-error-private.h"
+#include "cairo-combsort-private.h"
+#include "cairo-list-private.h"
+
+#include <setjmp.h>
+
+typedef struct _rectangle rectangle_t;
+typedef struct _edge edge_t;
+
+struct _edge {
+    edge_t *next, *prev;
+    edge_t *right;
+    cairo_fixed_t x, top;
+    int a_or_b;
+    int dir;
+};
+
+struct _rectangle {
+    edge_t left, right;
+    int32_t top, bottom;
+};
+
+#define UNROLL3(x) x x x
+
+/* the parent is always given by index/2 */
+#define PQ_PARENT_INDEX(i) ((i) >> 1)
+#define PQ_FIRST_ENTRY 1
+
+/* left and right children are index * 2 and (index * 2) +1 respectively */
+#define PQ_LEFT_CHILD_INDEX(i) ((i) << 1)
+
+typedef struct _pqueue {
+    int size, max_size;
+
+    rectangle_t **elements;
+    rectangle_t *elements_embedded[1024];
+} pqueue_t;
+
+typedef struct _sweep_line {
+    rectangle_t **rectangles;
+    pqueue_t pq;
+    edge_t head, tail;
+    edge_t *insert_left, *insert_right;
+    int32_t current_y;
+    int32_t last_y;
+
+    jmp_buf unwind;
+} sweep_line_t;
+
+#define DEBUG_TRAPS 0
+
+#if DEBUG_TRAPS
+static void
+dump_traps (cairo_traps_t *traps, const char *filename)
+{
+    FILE *file;
+    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
+rectangle_compare_start (const rectangle_t *a,
+			 const rectangle_t *b)
+{
+    return a->top - b->top;
+}
+
+static inline int
+rectangle_compare_stop (const rectangle_t *a,
+			 const 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_bool_t
+pqueue_grow (pqueue_t *pq)
+{
+    rectangle_t **new_elements;
+    pq->max_size *= 2;
+
+    if (pq->elements == pq->elements_embedded) {
+	new_elements = _cairo_malloc_ab (pq->max_size,
+					 sizeof (rectangle_t *));
+	if (unlikely (new_elements == NULL))
+	    return FALSE;
+
+	memcpy (new_elements, pq->elements_embedded,
+		sizeof (pq->elements_embedded));
+    } else {
+	new_elements = _cairo_realloc_ab (pq->elements,
+					  pq->max_size,
+					  sizeof (rectangle_t *));
+	if (unlikely (new_elements == NULL))
+	    return FALSE;
+    }
+
+    pq->elements = new_elements;
+    return TRUE;
+}
+
+static inline void
+pqueue_push (sweep_line_t *sweep, rectangle_t *rectangle)
+{
+    rectangle_t **elements;
+    int i, parent;
+
+    if (unlikely (sweep->pq.size + 1 == sweep->pq.max_size)) {
+	if (unlikely (! pqueue_grow (&sweep->pq))) {
+	    longjmp (sweep->unwind,
+		     _cairo_error (CAIRO_STATUS_NO_MEMORY));
+	}
+    }
+
+    elements = sweep->pq.elements;
+    for (i = ++sweep->pq.size;
+	 i != PQ_FIRST_ENTRY &&
+	 rectangle_compare_stop (rectangle,
+				 elements[parent = PQ_PARENT_INDEX (i)]) < 0;
+	 i = parent)
+    {
+	elements[i] = elements[parent];
+    }
+
+    elements[i] = rectangle;
+}
+
+static inline void
+pqueue_pop (pqueue_t *pq)
+{
+    rectangle_t **elements = pq->elements;
+    rectangle_t *tail;
+    int child, i;
+
+    tail = elements[pq->size--];
+    if (pq->size == 0) {
+	elements[PQ_FIRST_ENTRY] = NULL;
+	return;
+    }
+
+    for (i = PQ_FIRST_ENTRY;
+	 (child = PQ_LEFT_CHILD_INDEX (i)) <= pq->size;
+	 i = child)
+    {
+	if (child != pq->size &&
+	    rectangle_compare_stop (elements[child+1],
+				    elements[child]) < 0)
+	{
+	    child++;
+	}
+
+	if (rectangle_compare_stop (elements[child], tail) >= 0)
+	    break;
+
+	elements[i] = elements[child];
+    }
+    elements[i] = tail;
+}
+
+static inline rectangle_t *
+rectangle_pop_start (sweep_line_t *sweep_line)
+{
+    return *sweep_line->rectangles++;
+}
+
+static inline rectangle_t *
+rectangle_peek_stop (sweep_line_t *sweep_line)
+{
+    return sweep_line->pq.elements[PQ_FIRST_ENTRY];
+}
+
+CAIRO_COMBSORT_DECLARE (_rectangle_sort,
+			rectangle_t *,
+			rectangle_compare_start)
+
+static void
+sweep_line_init (sweep_line_t	 *sweep_line,
+		 rectangle_t	**rectangles,
+		 int		  num_rectangles)
+{
+    _rectangle_sort (rectangles, num_rectangles);
+    rectangles[num_rectangles] = NULL;
+    sweep_line->rectangles = rectangles;
+
+    sweep_line->head.x = INT32_MIN;
+    sweep_line->head.right = NULL;
+    sweep_line->head.dir = 0;
+    sweep_line->head.next = &sweep_line->tail;
+    sweep_line->tail.x = INT32_MAX;
+    sweep_line->tail.right = NULL;
+    sweep_line->tail.dir = 0;
+    sweep_line->tail.prev = &sweep_line->head;
+
+    sweep_line->insert_left = &sweep_line->tail;
+    sweep_line->insert_right = &sweep_line->tail;
+
+    sweep_line->current_y = INT32_MIN;
+    sweep_line->last_y = INT32_MIN;
+
+    pqueue_init (&sweep_line->pq);
+}
+
+static void
+sweep_line_fini (sweep_line_t *sweep_line)
+{
+    pqueue_fini (&sweep_line->pq);
+}
+
+static void
+end_box (sweep_line_t *sweep_line, edge_t *left, int32_t bot, cairo_boxes_t *out)
+{
+    if (likely (left->top < bot)) {
+	cairo_status_t status;
+	cairo_box_t box;
+
+	box.p1.x = left->x;
+	box.p1.y = left->top;
+	box.p2.x = left->right->x;
+	box.p2.y = bot;
+
+	status = _cairo_boxes_add (out, CAIRO_ANTIALIAS_DEFAULT, &box);
+	if (unlikely (status))
+	    longjmp (sweep_line->unwind, status);
+    }
+
+    left->right = NULL;
+}
+
+/* Start a new trapezoid at the given top y coordinate, whose edges
+ * are `edge' and `edge->next'. If `edge' already has a trapezoid,
+ * then either add it to the traps in `traps', if the trapezoid's
+ * right edge differs from `edge->next', or do nothing if the new
+ * trapezoid would be a continuation of the existing one. */
+static inline void
+start_or_continue_box (sweep_line_t *sweep_line,
+		       edge_t	*left,
+		       edge_t	*right,
+		       int		 top,
+		       cairo_boxes_t *out)
+{
+    if (left->right == right)
+	return;
+
+    if (left->right != NULL) {
+	if (right != NULL && left->right->x == right->x) {
+	    /* continuation on right, so just swap edges */
+	    left->right = right;
+	    return;
+	}
+
+	end_box (sweep_line, left, top, out);
+    }
+
+    if (right != NULL && left->x != right->x) {
+	left->top = top;
+	left->right = right;
+    }
+}
+
+static inline int is_zero(const int *winding)
+{
+    return winding[0] == 0 || winding[1] == 0;
+}
+
+static inline void
+active_edges (sweep_line_t *sweep, cairo_boxes_t *out)
+{
+    int top = sweep->current_y;
+    int winding[2] = { 0 };
+    edge_t *pos;
+
+    if (sweep->last_y == sweep->current_y)
+	return;
+
+    pos = sweep->head.next;
+    if (pos == &sweep->tail)
+	return;
+
+    do {
+	edge_t *left, *right;
+
+	left = pos;
+	do {
+	    winding[left->a_or_b] += left->dir;
+	    if (!is_zero (winding))
+		break;
+	    if (left->next == &sweep->tail)
+		goto out;
+
+	    if (unlikely (left->right != NULL))
+		end_box (sweep, left, top, out);
+
+	    left = left->next;
+	} while (1);
+
+	right = left->next;
+	do {
+	    if (unlikely (right->right != NULL))
+		end_box (sweep, right, top, out);
+
+	    winding[right->a_or_b] += right->dir;
+	    if (is_zero (winding)) {
+		/* skip co-linear edges */
+		if (likely (right->x != right->next->x))
+		    break;
+	    }
+
+	    right = right->next;
+	} while (TRUE);
+
+	start_or_continue_box (sweep, left, right, top, out);
+
+	pos = right->next;
+    } while (pos != &sweep->tail);
+
+out:
+    sweep->last_y = sweep->current_y;
+}
+
+static inline void
+sweep_line_delete_edge (sweep_line_t *sweep_line, edge_t *edge, cairo_boxes_t *out)
+{
+    if (edge->right != NULL) {
+	edge_t *next = edge->next;
+	if (next->x == edge->x) {
+	    next->top = edge->top;
+	    next->right = edge->right;
+	} else {
+	    end_box (sweep_line, edge, sweep_line->current_y, out);
+	}
+    }
+
+    if (sweep_line->insert_left == edge)
+	sweep_line->insert_left = edge->next;
+    if (sweep_line->insert_right == edge)
+	sweep_line->insert_right = edge->next;
+
+    edge->prev->next = edge->next;
+    edge->next->prev = edge->prev;
+}
+
+static inline void
+sweep_line_delete (sweep_line_t	*sweep,
+		   rectangle_t	*rectangle,
+		   cairo_boxes_t *out)
+{
+    sweep_line_delete_edge (sweep, &rectangle->left, out);
+    sweep_line_delete_edge (sweep, &rectangle->right, out);
+
+    pqueue_pop (&sweep->pq);
+}
+
+static inline void
+insert_edge (edge_t *edge, edge_t *pos)
+{
+    if (pos->x != edge->x) {
+	if (pos->x > edge->x) {
+	    do {
+		UNROLL3({
+		    if (pos->prev->x <= edge->x)
+			break;
+		    pos = pos->prev;
+		})
+	    } while (TRUE);
+	} else {
+	    do {
+		UNROLL3({
+		    pos = pos->next;
+		    if (pos->x >= edge->x)
+			break;
+		})
+	    } while (TRUE);
+	}
+    }
+
+    pos->prev->next = edge;
+    edge->prev = pos->prev;
+    edge->next = pos;
+    pos->prev = edge;
+}
+
+static inline void
+sweep_line_insert (sweep_line_t	*sweep, rectangle_t	*rectangle)
+{
+    edge_t *pos;
+
+    /* right edge */
+    pos = sweep->insert_right;
+    insert_edge (&rectangle->right, pos);
+    sweep->insert_right = &rectangle->right;
+
+    /* left edge */
+    pos = sweep->insert_left;
+    if (pos->x > sweep->insert_right->x)
+	pos = sweep->insert_right->prev;
+    insert_edge (&rectangle->left, pos);
+    sweep->insert_left = &rectangle->left;
+
+    pqueue_push (sweep, rectangle);
+}
+
+static cairo_status_t
+intersect (rectangle_t **rectangles, int num_rectangles, cairo_boxes_t *out)
+{
+    sweep_line_t sweep_line;
+    rectangle_t *rectangle;
+    cairo_status_t status;
+
+    sweep_line_init (&sweep_line, rectangles, num_rectangles);
+    if ((status = setjmp (sweep_line.unwind)))
+	goto unwind;
+
+    rectangle = rectangle_pop_start (&sweep_line);
+    do {
+	if (rectangle->top != sweep_line.current_y) {
+	    rectangle_t *stop;
+
+	    stop = rectangle_peek_stop (&sweep_line);
+	    while (stop != NULL && stop->bottom < rectangle->top) {
+		if (stop->bottom != sweep_line.current_y) {
+		    active_edges (&sweep_line, out);
+		    sweep_line.current_y = stop->bottom;
+		}
+
+		sweep_line_delete (&sweep_line, stop, out);
+
+		stop = rectangle_peek_stop (&sweep_line);
+	    }
+
+	    active_edges (&sweep_line, out);
+	    sweep_line.current_y = rectangle->top;
+	}
+
+	sweep_line_insert (&sweep_line, rectangle);
+    } while ((rectangle = rectangle_pop_start (&sweep_line)) != NULL);
+
+    while ((rectangle = rectangle_peek_stop (&sweep_line)) != NULL) {
+	if (rectangle->bottom != sweep_line.current_y) {
+	    active_edges (&sweep_line, out);
+	    sweep_line.current_y = rectangle->bottom;
+	}
+
+	sweep_line_delete (&sweep_line, rectangle, out);
+    }
+
+unwind:
+    sweep_line_fini (&sweep_line);
+    return status;
+}
+
+static cairo_status_t
+_cairo_boxes_intersect_with_box (const cairo_boxes_t *boxes,
+				 const cairo_box_t *box,
+				 cairo_boxes_t *out)
+{
+    const struct _cairo_boxes_chunk *chunk;
+    cairo_status_t status;
+    int i;
+
+    _cairo_boxes_clear (out);
+    _cairo_boxes_limit (out, box, 1);
+    for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
+	for (i = 0; i < chunk->count; i++) {
+	    status = _cairo_boxes_add (out,
+				       CAIRO_ANTIALIAS_DEFAULT,
+				       &chunk->base[i]);
+	    if (unlikely (status))
+		return status;
+	}
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_status_t
+_cairo_boxes_intersect (const cairo_boxes_t *a,
+			const cairo_boxes_t *b,
+			cairo_boxes_t *out)
+{
+    rectangle_t stack_rectangles[CAIRO_STACK_ARRAY_LENGTH (rectangle_t)];
+    rectangle_t *rectangles;
+    rectangle_t *stack_rectangles_ptrs[ARRAY_LENGTH (stack_rectangles) + 1];
+    rectangle_t **rectangles_ptrs;
+    const struct _cairo_boxes_chunk *chunk;
+    cairo_status_t status;
+    int i, j, count;
+
+    if (unlikely (a->num_boxes == 0 || b->num_boxes == 0)) {
+	_cairo_boxes_clear (out);
+	return CAIRO_STATUS_SUCCESS;
+    }
+
+    if (unlikely (a->num_boxes == 1)) {
+	cairo_box_t box = a->chunks.base[0];
+	return _cairo_boxes_intersect_with_box (b, &box, out);
+    }
+    if (unlikely (b->num_boxes == 1)) {
+	cairo_box_t box = b->chunks.base[0];
+	return _cairo_boxes_intersect_with_box (a, &box, out);
+	/* XXX */
+    }
+
+    rectangles = stack_rectangles;
+    rectangles_ptrs = stack_rectangles_ptrs;
+    count = a->num_boxes + b->num_boxes;
+    if (count > ARRAY_LENGTH (stack_rectangles)) {
+	rectangles = _cairo_malloc_ab_plus_c (count,
+					      sizeof (rectangle_t) +
+					      sizeof (rectangle_t *),
+					      sizeof (rectangle_t *));
+	if (unlikely (rectangles == NULL))
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+	rectangles_ptrs = (rectangle_t **) (rectangles + count);
+    }
+
+    j = 0;
+    for (chunk = &a->chunks; chunk != NULL; chunk = chunk->next) {
+	const cairo_box_t *box = chunk->base;
+	for (i = 0; i < chunk->count; i++) {
+	    if (box[i].p1.x < box[i].p2.x) {
+		rectangles[j].left.x = box[i].p1.x;
+		rectangles[j].left.dir = 1;
+
+		rectangles[j].right.x = box[i].p2.x;
+		rectangles[j].right.dir = -1;
+	    } else {
+		rectangles[j].right.x = box[i].p1.x;
+		rectangles[j].right.dir = 1;
+
+		rectangles[j].left.x = box[i].p2.x;
+		rectangles[j].left.dir = -1;
+	    }
+
+	    rectangles[j].left.a_or_b = 0;
+	    rectangles[j].left.right = NULL;
+	    rectangles[j].right.a_or_b = 0;
+	    rectangles[j].right.right = NULL;
+
+	    rectangles[j].top = box[i].p1.y;
+	    rectangles[j].bottom = box[i].p2.y;
+
+	    rectangles_ptrs[j] = &rectangles[j];
+	    j++;
+	}
+    }
+    for (chunk = &b->chunks; chunk != NULL; chunk = chunk->next) {
+	const cairo_box_t *box = chunk->base;
+	for (i = 0; i < chunk->count; i++) {
+	    if (box[i].p1.x < box[i].p2.x) {
+		rectangles[j].left.x = box[i].p1.x;
+		rectangles[j].left.dir = 1;
+
+		rectangles[j].right.x = box[i].p2.x;
+		rectangles[j].right.dir = -1;
+	    } else {
+		rectangles[j].right.x = box[i].p1.x;
+		rectangles[j].right.dir = 1;
+
+		rectangles[j].left.x = box[i].p2.x;
+		rectangles[j].left.dir = -1;
+	    }
+
+	    rectangles[j].left.a_or_b = 1;
+	    rectangles[j].left.right = NULL;
+	    rectangles[j].right.a_or_b = 1;
+	    rectangles[j].right.right = NULL;
+
+	    rectangles[j].top = box[i].p1.y;
+	    rectangles[j].bottom = box[i].p2.y;
+
+	    rectangles_ptrs[j] = &rectangles[j];
+	    j++;
+	}
+    }
+    assert (j == count);
+
+    _cairo_boxes_clear (out);
+    status = intersect (rectangles_ptrs, j, out);
+    if (rectangles != stack_rectangles)
+	free (rectangles);
+
+    return status;
+}
diff --git a/src/cairo-boxes-private.h b/src/cairo-boxes-private.h
index 3af0fbd..619545f 100644
--- a/src/cairo-boxes-private.h
+++ b/src/cairo-boxes-private.h
@@ -58,6 +58,10 @@ cairo_private void
 _cairo_boxes_init (cairo_boxes_t *boxes);
 
 cairo_private void
+_cairo_boxes_init_with_clip (cairo_boxes_t *boxes,
+			     cairo_clip_t *clip);
+
+cairo_private void
 _cairo_boxes_init_for_array (cairo_boxes_t *boxes,
 			     cairo_box_t *array,
 			     int num_boxes);
@@ -69,16 +73,39 @@ _cairo_boxes_limit (cairo_boxes_t	*boxes,
 
 cairo_private cairo_status_t
 _cairo_boxes_add (cairo_boxes_t *boxes,
+		  cairo_antialias_t antialias,
 		  const cairo_box_t *box);
 
 cairo_private void
 _cairo_boxes_extents (const cairo_boxes_t *boxes,
 		      cairo_rectangle_int_t *extents);
 
+cairo_private cairo_box_t *
+_cairo_boxes_to_array (const cairo_boxes_t *boxes,
+		       int *num_boxes,
+		       cairo_bool_t force_allocation);
+
+static inline void
+_cairo_boxes_free_array (const cairo_boxes_t *boxes,
+			 cairo_box_t *box)
+{
+    if (box != boxes->chunks.base)
+	free(box);
+}
+
+cairo_private cairo_status_t
+_cairo_boxes_intersect (const cairo_boxes_t *a,
+			const cairo_boxes_t *b,
+			cairo_boxes_t *out);
+
 cairo_private void
 _cairo_boxes_clear (cairo_boxes_t *boxes);
 
 cairo_private void
 _cairo_boxes_fini (cairo_boxes_t *boxes);
 
+cairo_private void
+_cairo_debug_print_boxes (FILE *stream,
+			  const cairo_boxes_t *boxes);
+
 #endif /* CAIRO_BOXES_H */
diff --git a/src/cairo-boxes.c b/src/cairo-boxes.c
index 31bfc0e..130a44c 100644
--- a/src/cairo-boxes.c
+++ b/src/cairo-boxes.c
@@ -53,6 +53,15 @@ _cairo_boxes_init (cairo_boxes_t *boxes)
 }
 
 void
+_cairo_boxes_init_with_clip (cairo_boxes_t *boxes,
+			     cairo_clip_t *clip)
+{
+    _cairo_boxes_init (boxes);
+    if (clip)
+	_cairo_boxes_limit (boxes, clip->boxes, clip->num_boxes);
+}
+
+void
 _cairo_boxes_init_for_array (cairo_boxes_t *boxes,
 			     cairo_box_t *array,
 			     int num_boxes)
@@ -156,8 +165,19 @@ _cairo_boxes_add_internal (cairo_boxes_t *boxes,
 
 cairo_status_t
 _cairo_boxes_add (cairo_boxes_t *boxes,
+		  cairo_antialias_t antialias,
 		  const cairo_box_t *box)
 {
+    cairo_box_t b;
+
+    if (antialias == CAIRO_ANTIALIAS_NONE) {
+	b.p1.x = _cairo_fixed_round_down (box->p1.x);
+	b.p1.y = _cairo_fixed_round_down (box->p1.y);
+	b.p2.x = _cairo_fixed_round_down (box->p2.x);
+	b.p2.y = _cairo_fixed_round_down (box->p2.y);
+	box = &b;
+    }
+
     if (box->p1.y == box->p2.y)
 	return CAIRO_STATUS_SUCCESS;
 
@@ -247,6 +267,11 @@ _cairo_boxes_extents (const cairo_boxes_t *boxes,
     cairo_box_t box;
     int i;
 
+    if (boxes->num_boxes == 0) {
+	extents->x = extents->y = extents->width = extents->height = 0;
+	return;
+    }
+
     box.p1.y = box.p1.x = INT_MAX;
     box.p2.y = box.p2.x = INT_MIN;
 
@@ -283,11 +308,41 @@ _cairo_boxes_clear (cairo_boxes_t *boxes)
     boxes->tail = &boxes->chunks;
     boxes->chunks.next = 0;
     boxes->chunks.count = 0;
+    boxes->chunks.base = boxes->boxes_embedded;
+    boxes->chunks.size = ARRAY_LENGTH (boxes->boxes_embedded);
     boxes->num_boxes = 0;
 
     boxes->is_pixel_aligned = TRUE;
 }
 
+cairo_box_t *
+_cairo_boxes_to_array (const cairo_boxes_t *boxes,
+		       int *num_boxes,
+		       cairo_bool_t force_allocation)
+{
+    const struct _cairo_boxes_chunk *chunk;
+    cairo_box_t *box;
+    int i, j;
+
+    *num_boxes = boxes->num_boxes;
+    if (boxes->chunks.next == NULL && ! force_allocation)
+	    return boxes->chunks.base;
+
+    box = _cairo_malloc_ab (boxes->num_boxes, sizeof (cairo_box_t));
+    if (box == NULL) {
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+	return NULL;
+    }
+
+    j = 0;
+    for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
+	for (i = 0; i < chunk->count; i++)
+	    box[j++] = chunk->base[i];
+    }
+
+    return box;
+}
+
 void
 _cairo_boxes_fini (cairo_boxes_t *boxes)
 {
@@ -298,3 +353,26 @@ _cairo_boxes_fini (cairo_boxes_t *boxes)
 	free (chunk);
     }
 }
+
+void
+_cairo_debug_print_boxes (FILE *stream, const cairo_boxes_t *boxes)
+{
+    cairo_rectangle_int_t extents;
+    const struct _cairo_boxes_chunk *chunk;
+    int i;
+
+    _cairo_boxes_extents (boxes, &extents);
+    fprintf (stream, "boxes x %d: (%d, %d) x (%d, %d)\n",
+	     boxes->num_boxes,
+	     extents.x, extents.y, extents.width, extents.height);
+
+    for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
+	for (i = 0; i < chunk->count; i++) {
+	    fprintf (stderr, "  box[%d]: (%f, %f), (%f, %f)\n", i,
+		     _cairo_fixed_to_double (chunk->base[i].p1.x),
+		     _cairo_fixed_to_double (chunk->base[i].p1.y),
+		     _cairo_fixed_to_double (chunk->base[i].p2.x),
+		     _cairo_fixed_to_double (chunk->base[i].p2.y));
+	}
+    }
+}
diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c
index 1a52ca2..02f2cba 100644
--- a/src/cairo-cff-subset.c
+++ b/src/cairo-cff-subset.c
@@ -1373,12 +1373,12 @@ cairo_cff_find_subroutines_used (cairo_cff_font_t  *font,
     return cairo_cff_parse_charstring (font, charstring, length, glyph_id);
 }
 
-static cairo_status_t
+static cairo_int_status_t
 cairo_cff_font_subset_charstrings_and_subroutines (cairo_cff_font_t  *font)
 {
     cff_index_element_t *element;
     unsigned int i;
-    cairo_status_t status;
+    cairo_int_status_t status;
     unsigned long glyph;
 
     font->subset_subroutines = TRUE;
@@ -1758,23 +1758,23 @@ cairo_cff_font_write_fdselect (cairo_cff_font_t  *font)
 
         byte = 3;
         status = _cairo_array_append (&font->output, &byte);
-        assert (status == CAIRO_STATUS_SUCCESS);
+        assert (status == CAIRO_INT_STATUS_SUCCESS);
 
         word = cpu_to_be16 (1);
         status = _cairo_array_append_multiple (&font->output, &word, 2);
-        assert (status == CAIRO_STATUS_SUCCESS);
+        assert (status == CAIRO_INT_STATUS_SUCCESS);
 
         word = cpu_to_be16 (0);
         status = _cairo_array_append_multiple (&font->output, &word, 2);
-        assert (status == CAIRO_STATUS_SUCCESS);
+        assert (status == CAIRO_INT_STATUS_SUCCESS);
 
         byte = 0;
         status = _cairo_array_append (&font->output, &byte);
-        assert (status == CAIRO_STATUS_SUCCESS);
+        assert (status == CAIRO_INT_STATUS_SUCCESS);
 
         word = cpu_to_be16 (font->scaled_font_subset->num_glyphs);
         status = _cairo_array_append_multiple (&font->output, &word, 2);
-        assert (status == CAIRO_STATUS_SUCCESS);
+        assert (status == CAIRO_INT_STATUS_SUCCESS);
     }
 
     return CAIRO_STATUS_SUCCESS;
diff --git a/src/cairo-clip-boxes.c b/src/cairo-clip-boxes.c
new file mode 100644
index 0000000..aa560ce
--- /dev/null
+++ b/src/cairo-clip-boxes.c
@@ -0,0 +1,559 @@
+/* -*- 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.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is University of Southern
+ * California.
+ *
+ * Contributor(s):
+ *	Carl D. Worth <cworth at cworth.org>
+ *	Kristian Høgsberg <krh at redhat.com>
+ *	Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#include "cairoint.h"
+#include "cairo-clip-private.h"
+#include "cairo-error-private.h"
+#include "cairo-freed-pool-private.h"
+#include "cairo-gstate-private.h"
+#include "cairo-path-fixed-private.h"
+#include "cairo-pattern-private.h"
+#include "cairo-composite-rectangles-private.h"
+#include "cairo-region-private.h"
+
+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;
+}
+
+
+static cairo_bool_t
+_cairo_clip_contains_rectangle_box (const cairo_clip_t *clip,
+				    const cairo_rectangle_int_t *rect,
+				    const cairo_box_t *box)
+{
+    int i;
+
+    /* clip == NULL means no clip, so the clip contains everything */
+    if (clip == NULL)
+	return TRUE;
+
+    if (_cairo_clip_is_all_clipped (clip))
+	return FALSE;
+
+    /* If we have a non-trivial path, just say no */
+    if (clip->path)
+	return FALSE;
+
+    if (clip->extents.x > rect->x ||
+	clip->extents.y > rect->y ||
+	clip->extents.x + clip->extents.width  < rect->x + rect->width ||
+	clip->extents.y + clip->extents.height < rect->y + rect->height)
+    {
+	return FALSE;
+    }
+
+    /* Check for a clip-box that wholly contains the rectangle */
+    assert (clip->num_boxes);
+    for (i = 0; i < clip->num_boxes; i++) {
+	if (box->p1.x >= clip->boxes[i].p1.x &&
+	    box->p1.y >= clip->boxes[i].p1.y &&
+	    box->p2.x <= clip->boxes[i].p2.x &&
+	    box->p2.y <= clip->boxes[i].p2.y)
+	{
+	    return TRUE;
+	}
+    }
+
+    return FALSE;
+}
+
+cairo_bool_t
+_cairo_clip_contains_box (const cairo_clip_t *clip,
+			  const cairo_box_t *box)
+{
+    cairo_rectangle_int_t rect;
+
+    _cairo_box_round_to_rectangle (box, &rect);
+    return _cairo_clip_contains_rectangle_box(clip, &rect, box);
+}
+
+cairo_bool_t
+_cairo_clip_contains_rectangle (const cairo_clip_t *clip,
+				const cairo_rectangle_int_t *rect)
+{
+    cairo_box_t box;
+
+    box.p1.x = _cairo_fixed_from_int (rect->x);
+    box.p1.y = _cairo_fixed_from_int (rect->y);
+    box.p2.x = _cairo_fixed_from_int (rect->x + rect->width);
+    box.p2.y = _cairo_fixed_from_int (rect->y + rect->height);
+
+    return _cairo_clip_contains_rectangle_box (clip, rect, &box);
+}
+
+cairo_clip_t *
+_cairo_clip_intersect_rectilinear_path (cairo_clip_t *clip,
+					const cairo_path_fixed_t *path,
+					cairo_fill_rule_t fill_rule,
+					cairo_antialias_t antialias)
+{
+    cairo_status_t status;
+    cairo_boxes_t boxes;
+
+    _cairo_boxes_init (&boxes);
+    status = _cairo_path_fixed_fill_rectilinear_to_boxes (path,
+							  fill_rule,
+							  antialias,
+							  &boxes);
+    if (likely (status == CAIRO_STATUS_SUCCESS))
+	clip = _cairo_clip_intersect_boxes (clip, &boxes);
+    else
+	clip = _cairo_clip_set_all_clipped (clip);
+    _cairo_boxes_fini (&boxes);
+
+    return clip;
+}
+
+static cairo_clip_t *
+_cairo_clip_intersect_rectangle_box (cairo_clip_t *clip,
+				     const cairo_rectangle_int_t *r,
+				     const cairo_box_t *box)
+{
+    cairo_box_t extents_box;
+    int i, j;
+
+    if (clip == NULL) {
+	clip = _cairo_clip_create ();
+	if (clip == NULL)
+	    return _cairo_clip_set_all_clipped (clip);
+
+	clip->boxes = _cairo_malloc (sizeof (cairo_box_t));
+	if (clip->boxes == NULL)
+	    return _cairo_clip_set_all_clipped (clip);
+
+	clip->extents = *r;
+	clip->num_boxes = 1;
+	clip->boxes[0] = *box;
+
+	return clip;
+    }
+
+    if (clip->num_boxes == 0) {
+	clip->boxes = _cairo_malloc (sizeof (cairo_box_t));
+	if (clip->boxes == NULL)
+	    return _cairo_clip_set_all_clipped (clip);
+
+	j = 1;
+	clip->boxes[0] = *box;
+    } else for (i = j = 0; i < clip->num_boxes; i++) {
+	cairo_box_t *b = &clip->boxes[j];
+
+	if (j != i)
+	    *b = clip->boxes[i];
+
+	if (box->p1.x > b->p1.x)
+	    b->p1.x = box->p1.x;
+	if (box->p2.x < b->p2.x)
+	    b->p2.x = box->p2.x;
+
+	if (box->p1.y > b->p1.y)
+	    b->p1.y = box->p1.y;
+	if (box->p2.y < b->p2.y)
+	    b->p2.y = box->p2.y;
+
+	j += b->p2.x > b->p1.x && b->p2.y > b->p1.y;
+    }
+    clip->num_boxes = j;
+
+    if (clip->num_boxes == 0)
+	return _cairo_clip_set_all_clipped (clip);
+
+    extents_box = clip->boxes[0];
+    for (i = 1; i < clip->num_boxes; i++) {
+	    if (clip->boxes[i].p1.x < extents_box.p1.x)
+		extents_box.p1.x = clip->boxes[i].p1.x;
+
+	    if (clip->boxes[i].p1.y < extents_box.p1.y)
+		extents_box.p1.y = clip->boxes[i].p1.y;
+
+	    if (clip->boxes[i].p2.x > extents_box.p2.x)
+		extents_box.p2.x = clip->boxes[i].p2.x;
+
+	    if (clip->boxes[i].p2.y > extents_box.p2.y)
+		extents_box.p2.y = clip->boxes[i].p2.y;
+    }
+
+    if (clip->path == NULL) {
+	_cairo_box_round_to_rectangle (&extents_box, &clip->extents);
+    } else {
+	cairo_rectangle_int_t extents_rect;
+
+	_cairo_box_round_to_rectangle (&extents_box, &extents_rect);
+	if (! _cairo_rectangle_intersect (&clip->extents, &extents_rect))
+	    return _cairo_clip_set_all_clipped (clip);
+    }
+
+    if (clip->region) {
+	cairo_region_destroy (clip->region);
+	clip->region = NULL;
+    }
+
+    clip->is_region = FALSE;
+    return clip;
+}
+
+cairo_clip_t *
+_cairo_clip_intersect_box (cairo_clip_t *clip,
+			   const cairo_box_t *box)
+{
+    cairo_rectangle_int_t r;
+
+    _cairo_box_round_to_rectangle (box, &r);
+    if (r.width == 0 || r.height == 0)
+	return _cairo_clip_set_all_clipped (clip);
+
+    return _cairo_clip_intersect_rectangle_box (clip, &r, box);
+}
+
+cairo_clip_t *
+_cairo_clip_intersect_boxes (cairo_clip_t *clip,
+			     const cairo_boxes_t *boxes)
+{
+    cairo_boxes_t clip_boxes;
+    cairo_rectangle_int_t extents;
+
+    if (boxes->num_boxes == 0)
+	return clip;
+
+    if (clip == NULL)
+	clip = _cairo_clip_create ();
+
+    if (clip->num_boxes == 0) {
+	clip->boxes = _cairo_boxes_to_array (boxes, &clip->num_boxes, TRUE);
+	_cairo_boxes_extents (boxes, &extents);
+    } else {
+	_cairo_boxes_init_for_array (&clip_boxes, clip->boxes, clip->num_boxes);
+	if (unlikely (_cairo_boxes_intersect (&clip_boxes, boxes, &clip_boxes)))
+	    return _cairo_clip_set_all_clipped (clip);
+
+	free (clip->boxes);
+	clip->boxes = _cairo_boxes_to_array (&clip_boxes, &clip->num_boxes, TRUE);
+	_cairo_boxes_extents (&clip_boxes, &extents);
+    }
+
+    if (clip->path == NULL)
+	clip->extents = extents;
+    else if (! _cairo_rectangle_intersect (&clip->extents, &extents))
+	clip = _cairo_clip_set_all_clipped (clip);
+
+    if (clip->region) {
+	cairo_region_destroy (clip->region);
+	clip->region = NULL;
+    }
+    clip->is_region = FALSE;
+
+    return clip;
+}
+
+cairo_clip_t *
+_cairo_clip_intersect_rectangle (cairo_clip_t       *clip,
+				 const cairo_rectangle_int_t *r)
+{
+    cairo_box_t box;
+
+    if (_cairo_clip_is_all_clipped (clip))
+	return clip;
+
+    if (r->width == 0 || r->height == 0)
+	return _cairo_clip_set_all_clipped (clip);
+
+    box.p1.x = _cairo_fixed_from_int (r->x);
+    box.p1.y = _cairo_fixed_from_int (r->y);
+    box.p2.x = _cairo_fixed_from_int (r->x + r->width);
+    box.p2.y = _cairo_fixed_from_int (r->y + r->height);
+
+    return _cairo_clip_intersect_rectangle_box (clip, r, &box);
+}
+
+struct reduce {
+    cairo_clip_t *clip;
+    cairo_box_t limit;
+    cairo_box_t extents;
+    cairo_bool_t inside;
+
+    cairo_point_t current_point;
+    cairo_point_t last_move_to;
+};
+
+static void
+_add_clipped_edge (struct reduce *r,
+		   const cairo_point_t *p1,
+		   const cairo_point_t *p2,
+		   int y1, int y2)
+{
+    cairo_fixed_t x;
+
+    x = _cairo_edge_compute_intersection_x_for_y (p1, p2, y1);
+    if (x < r->extents.p1.x)
+	r->extents.p1.x = x;
+
+    x = _cairo_edge_compute_intersection_x_for_y (p1, p2, y2);
+    if (x > r->extents.p2.x)
+	r->extents.p2.x = x;
+
+    if (y1 < r->extents.p1.y)
+	r->extents.p1.y = y1;
+
+    if (y2 > r->extents.p2.y)
+	r->extents.p2.y = y2;
+
+    r->inside = TRUE;
+}
+
+static void
+_add_edge (struct reduce *r,
+	   const cairo_point_t *p1,
+	   const cairo_point_t *p2)
+{
+    int top, bottom;
+    int top_y, bot_y;
+    int n;
+
+    if (p1->y < p2->y) {
+	top = p1->y;
+	bottom = p2->y;
+    } else {
+	top = p2->y;
+	bottom = p1->y;
+    }
+
+    if (bottom < r->limit.p1.y || top > r->limit.p2.y)
+	return;
+
+    if (p1->x > p2->x) {
+	const cairo_point_t *t = p1;
+	p1 = p2;
+	p2 = t;
+    }
+
+    if (p2->x <= r->limit.p1.x || p1->x >= r->limit.p2.x)
+	return;
+
+    for (n = 0; n < r->clip->num_boxes; n++) {
+	const cairo_box_t *limits = &r->clip->boxes[n];
+
+	if (bottom < limits->p1.y || top > limits->p2.y)
+	    continue;
+
+	if (p2->x <= limits->p1.x || p1->x >= limits->p2.x)
+	    continue;
+
+	if (p1->x >= limits->p1.x && p2->x <= limits->p1.x) {
+	    top_y = top;
+	    bot_y = bottom;
+	} else {
+	    int p1_y, p2_y;
+
+	    p1_y = _cairo_edge_compute_intersection_y_for_x (p1, p2,
+							     limits->p1.x);
+	    p2_y = _cairo_edge_compute_intersection_y_for_x (p1, p2,
+							     limits->p2.x);
+	    if (p1_y < p2_y) {
+		top_y = p1_y;
+		bot_y = p2_y;
+	    } else {
+		top_y = p2_y;
+		bot_y = p1_y;
+	    }
+
+	    if (top_y < top)
+		top_y = top;
+	    if (bot_y > bottom)
+		bot_y = bottom;
+	}
+
+	if (top_y < limits->p1.y)
+	    top_y = limits->p1.y;
+
+	if (bot_y > limits->p2.y)
+	    bot_y = limits->p2.y;
+	if (bot_y > top_y)
+	    _add_clipped_edge (r, p1, p2, top_y, bot_y);
+    }
+}
+
+static cairo_status_t
+_reduce_line_to (void *closure,
+		       const cairo_point_t *point)
+{
+    struct reduce *r = closure;
+
+    _add_edge (r, &r->current_point, point);
+    r->current_point = *point;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_reduce_close (void *closure)
+{
+    struct reduce *r = closure;
+
+    return _reduce_line_to (r, &r->last_move_to);
+}
+
+static cairo_status_t
+_reduce_move_to (void *closure,
+		 const cairo_point_t *point)
+{
+    struct reduce *r = closure;
+    cairo_status_t status;
+
+    /* close current subpath */
+    status = _reduce_close (closure);
+
+    /* make sure that the closure represents a degenerate path */
+    r->current_point = *point;
+    r->last_move_to = *point;
+
+    return status;
+}
+
+static cairo_clip_t *
+_cairo_clip_reduce_to_boxes (cairo_clip_t *clip)
+{
+    struct reduce r;
+    cairo_clip_path_t *clip_path;
+    cairo_status_t status;
+
+	return clip;
+    if (clip->path == NULL)
+	return clip;
+
+    r.clip = clip;
+    r.extents.p1.x = r.extents.p1.y = INT_MAX;
+    r.extents.p2.x = r.extents.p2.y = INT_MIN;
+    r.inside = FALSE;
+
+    r.limit.p1.x = _cairo_fixed_from_int (clip->extents.x);
+    r.limit.p1.y = _cairo_fixed_from_int (clip->extents.y);
+    r.limit.p2.x = _cairo_fixed_from_int (clip->extents.x + clip->extents.width);
+    r.limit.p2.y = _cairo_fixed_from_int (clip->extents.y + clip->extents.height);
+
+    clip_path = clip->path;
+    do {
+	r.current_point.x = 0;
+	r.current_point.y = 0;
+	r.last_move_to = r.current_point;
+
+	status = _cairo_path_fixed_interpret_flat (&clip_path->path,
+						   _reduce_move_to,
+						   _reduce_line_to,
+						   _reduce_close,
+						   &r,
+						   clip_path->tolerance);
+	assert (status == CAIRO_STATUS_SUCCESS);
+	_reduce_close (&r);
+    } while ((clip_path = clip_path->prev));
+
+    if (! r.inside) {
+	_cairo_clip_path_destroy (clip->path);
+	clip->path = NULL;
+    }
+
+    return _cairo_clip_intersect_box (clip, &r.extents);
+}
+
+cairo_clip_t *
+_cairo_clip_reduce_to_rectangle (const cairo_clip_t *clip,
+				 const cairo_rectangle_int_t *r)
+{
+    cairo_clip_t *copy;
+
+    if (_cairo_clip_is_all_clipped (clip))
+	return (cairo_clip_t *) clip;
+
+    if (_cairo_clip_contains_rectangle (clip, r))
+	return _cairo_clip_intersect_rectangle (NULL, r);
+
+    copy = _cairo_clip_copy_intersect_rectangle (clip, r);
+    if (_cairo_clip_is_all_clipped (copy))
+	return copy;
+
+    return _cairo_clip_reduce_to_boxes (copy);
+}
+
+cairo_clip_t *
+_cairo_clip_reduce_for_composite (const cairo_clip_t *clip,
+				  cairo_composite_rectangles_t *extents)
+{
+    const cairo_rectangle_int_t *r;
+
+    r = extents->is_bounded ? &extents->bounded : &extents->unbounded;
+    return _cairo_clip_reduce_to_rectangle (clip, r);
+}
+
+cairo_status_t
+_cairo_clip_to_boxes (cairo_clip_t *clip,
+		      cairo_boxes_t *boxes)
+{
+    _cairo_boxes_init_for_array (boxes, clip->boxes, clip->num_boxes);
+
+    if (clip->path == NULL) {
+	cairo_box_t *src = clip->boxes;
+	int i;
+
+	clip->boxes = _cairo_malloc_ab (clip->num_boxes, sizeof (cairo_box_t));
+	if (clip->boxes == NULL) {
+	    clip->boxes = src;
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	}
+
+	for (i = 0; i < clip->num_boxes; i++) {
+	    clip->boxes[i].p1.x = _cairo_fixed_floor (src[i].p1.x);
+	    clip->boxes[i].p1.y = _cairo_fixed_floor (src[i].p1.y);
+	    clip->boxes[i].p2.x = _cairo_fixed_ceil (src[i].p2.x);
+	    clip->boxes[i].p2.y = _cairo_fixed_ceil (src[i].p2.y);
+	}
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+
+}
diff --git a/src/cairo-clip-polygon.c b/src/cairo-clip-polygon.c
new file mode 100644
index 0000000..19da15d
--- /dev/null
+++ b/src/cairo-clip-polygon.c
@@ -0,0 +1,127 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2011 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is University of Southern
+ * California.
+ *
+ * Contributor(s):
+ *	Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#include "cairoint.h"
+#include "cairo-clip-private.h"
+#include "cairo-error-private.h"
+#include "cairo-freed-pool-private.h"
+#include "cairo-gstate-private.h"
+#include "cairo-path-fixed-private.h"
+#include "cairo-pattern-private.h"
+#include "cairo-composite-rectangles-private.h"
+#include "cairo-region-private.h"
+
+static cairo_bool_t
+can_convert_to_polygon (const cairo_clip_t *clip)
+{
+    cairo_clip_path_t *clip_path = clip->path;
+    cairo_antialias_t antialias = clip_path->antialias;
+
+    while ((clip_path = clip_path->prev) != NULL) {
+	if (clip_path->antialias != antialias)
+	    return FALSE;
+    }
+
+    return TRUE;
+}
+
+cairo_int_status_t
+_cairo_clip_get_polygon (const cairo_clip_t *clip,
+			 cairo_polygon_t *polygon,
+			 cairo_fill_rule_t *fill_rule,
+			 cairo_antialias_t *antialias)
+{
+    cairo_status_t status;
+    cairo_clip_path_t *clip_path;
+
+    if (_cairo_clip_is_all_clipped (clip)) {
+	_cairo_polygon_init (polygon, NULL, 0);
+	return CAIRO_INT_STATUS_SUCCESS;
+    }
+
+    /* If there is no clip, we need an infinite polygon */
+    assert (clip && (clip->path || clip->num_boxes));
+
+    if (clip->path == NULL) {
+	*fill_rule = CAIRO_FILL_RULE_WINDING;
+	*antialias = CAIRO_ANTIALIAS_DEFAULT;
+	return _cairo_polygon_init_box_array (polygon,
+					      clip->boxes,
+					      clip->num_boxes);
+    }
+
+    /* check that residual is all of the same type/tolerance */
+    if (! can_convert_to_polygon (clip))
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    _cairo_polygon_init_with_clip (polygon, clip);
+
+    clip_path = clip->path;
+    status = _cairo_path_fixed_fill_to_polygon (&clip_path->path,
+						clip_path->tolerance,
+						polygon);
+    if (unlikely (status)) {
+	_cairo_polygon_fini (polygon);
+	return status;
+    }
+
+    polygon->limits = NULL;
+    polygon->num_limits = 0;
+
+    *fill_rule = clip_path->fill_rule;
+    *antialias = clip_path->antialias;
+    while ((clip_path = clip_path->prev) != NULL) {
+	cairo_polygon_t next;
+
+	_cairo_polygon_init (&next, NULL, 0);
+	status = _cairo_path_fixed_fill_to_polygon (&clip_path->path,
+						    clip_path->tolerance,
+						    &next);
+	if (likely (status == CAIRO_STATUS_SUCCESS))
+		status = _cairo_polygon_intersect (polygon, *fill_rule,
+						   &next, clip_path->fill_rule);
+	_cairo_polygon_fini (&next);
+	if (unlikely (status)) {
+	    _cairo_polygon_fini (polygon);
+	    return status;
+	}
+
+	*fill_rule = CAIRO_FILL_RULE_WINDING;
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h
index bfbb539..861be63 100644
--- a/src/cairo-clip-private.h
+++ b/src/cairo-clip-private.h
@@ -31,24 +31,21 @@
  *
  * Contributor(s):
  *	Kristian Høgsberg <krh at redhat.com>
+ *	Chris Wilson <chris at chris-wilson.co.uk>
  */
 
 #ifndef CAIRO_CLIP_PRIVATE_H
 #define CAIRO_CLIP_PRIVATE_H
 
 #include "cairo-types-private.h"
+
+#include "cairo-boxes-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;
@@ -58,92 +55,124 @@ struct _cairo_clip_path {
     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_rectangle_int_t extents;
     cairo_clip_path_t *path;
 
-    cairo_bool_t all_clipped;
+    cairo_box_t *boxes;
+    int num_boxes;
 
+    cairo_region_t *region;
+    cairo_bool_t is_region;
 };
 
+cairo_private cairo_clip_t *
+_cairo_clip_create (void);
+
 cairo_private void
-_cairo_clip_init (cairo_clip_t *clip);
+_cairo_clip_path_destroy (cairo_clip_path_t *clip_path);
 
-cairo_private_no_warn cairo_clip_t *
-_cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other);
+cairo_private void
+_cairo_clip_destroy (cairo_clip_t *clip);
 
-cairo_private cairo_status_t
-_cairo_clip_init_copy_transformed (cairo_clip_t    *clip,
-				   cairo_clip_t    *other,
-				   const cairo_matrix_t *matrix);
+extern const cairo_clip_t __cairo_clip_all;
 
-cairo_private void
-_cairo_clip_reset (cairo_clip_t *clip);
+static inline cairo_bool_t _cairo_clip_is_all_clipped(const cairo_clip_t *clip)
+{
+    return clip == &__cairo_clip_all;
+}
 
-cairo_private cairo_bool_t
-_cairo_clip_equal (const cairo_clip_t *clip_a,
-		   const cairo_clip_t *clip_b);
+static inline cairo_clip_t *
+_cairo_clip_set_all_clipped (cairo_clip_t *clip)
+{
+    _cairo_clip_destroy (clip);
+    return (cairo_clip_t *) &__cairo_clip_all;
+}
 
-#define _cairo_clip_fini(clip) _cairo_clip_reset (clip)
+cairo_private cairo_clip_t *
+_cairo_clip_copy (const cairo_clip_t *clip);
 
-cairo_private cairo_status_t
-_cairo_clip_rectangle (cairo_clip_t       *clip,
-		       const cairo_rectangle_int_t *rectangle);
+cairo_private cairo_clip_t *
+_cairo_clip_copy_with_translation (const cairo_clip_t *clip, int tx, int ty);
 
-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_private cairo_bool_t
+_cairo_clip_equal (const cairo_clip_t *clip_a,
+		   const cairo_clip_t *clip_b);
 
-cairo_private cairo_status_t
-_cairo_clip_apply_clip (cairo_clip_t *clip,
-			const cairo_clip_t *other);
+cairo_private cairo_clip_t *
+_cairo_clip_intersect_rectangle (cairo_clip_t       *clip,
+				 const cairo_rectangle_int_t *rectangle);
+
+static inline cairo_clip_t *
+_cairo_clip_copy_intersect_rectangle (const cairo_clip_t       *clip,
+				      const cairo_rectangle_int_t *r)
+{
+    return _cairo_clip_intersect_rectangle (_cairo_clip_copy (clip), r);
+}
+
+cairo_private cairo_clip_t *
+_cairo_clip_intersect_box (cairo_clip_t       *clip,
+			   const cairo_box_t *box);
+
+cairo_private cairo_clip_t *
+_cairo_clip_intersect_boxes (cairo_clip_t *clip,
+			     const cairo_boxes_t *boxes);
+
+cairo_private cairo_clip_t *
+_cairo_clip_intersect_rectilinear_path (cairo_clip_t       *clip,
+					const cairo_path_fixed_t *path,
+					cairo_fill_rule_t   fill_rule,
+					cairo_antialias_t   antialias);
+
+cairo_private cairo_clip_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_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, int *tx, int *ty);
+_cairo_clip_get_surface (const cairo_clip_t *clip, cairo_surface_t *dst, int *tx, int *ty);
 
 cairo_private cairo_status_t
-_cairo_clip_combine_with_surface (cairo_clip_t *clip,
+_cairo_clip_combine_with_surface (const cairo_clip_t *clip,
 				  cairo_surface_t *dst,
 				  int dst_x, int dst_y);
 
-cairo_private cairo_int_status_t
-_cairo_clip_get_region (cairo_clip_t *clip,
-			cairo_region_t **region);
+cairo_private cairo_status_t
+_cairo_clip_to_boxes (cairo_clip_t *clip,
+		      cairo_boxes_t *boxes);
 
-cairo_private cairo_int_status_t
-_cairo_clip_get_boxes (cairo_clip_t *clip,
-		       cairo_box_t **boxes,
-		       int *count);
+cairo_private cairo_region_t *
+_cairo_clip_get_region (const cairo_clip_t *clip);
 
-cairo_private cairo_status_t
-_cairo_clip_to_boxes (cairo_clip_t **clip,
-		      cairo_composite_rectangles_t *extents,
-		      cairo_box_t **boxes,
-		      int *num_boxes);
+cairo_private cairo_bool_t
+_cairo_clip_is_region (const cairo_clip_t *clip);
+
+cairo_private cairo_clip_t *
+_cairo_clip_reduce_to_rectangle (const cairo_clip_t *clip,
+				 const cairo_rectangle_int_t *r);
+
+cairo_private cairo_clip_t *
+_cairo_clip_reduce_for_composite (const cairo_clip_t *clip,
+				  cairo_composite_rectangles_t *extents);
 
 cairo_private cairo_bool_t
-_cairo_clip_contains_rectangle (cairo_clip_t *clip,
+_cairo_clip_contains_rectangle (const cairo_clip_t *clip,
 				const cairo_rectangle_int_t *rect);
 
 cairo_private cairo_bool_t
-_cairo_clip_contains_extents (cairo_clip_t *clip,
-				const cairo_composite_rectangles_t *extents);
+_cairo_clip_contains_box (const cairo_clip_t *clip,
+			  const cairo_box_t *box);
 
-cairo_private void
-_cairo_clip_drop_cache (cairo_clip_t  *clip);
+cairo_private cairo_bool_t
+_cairo_clip_contains_extents (const cairo_clip_t *clip,
+			      const cairo_composite_rectangles_t *extents);
 
 cairo_private cairo_rectangle_list_t*
 _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate);
@@ -151,4 +180,10 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate);
 cairo_private cairo_rectangle_list_t *
 _cairo_rectangle_list_create_in_error (cairo_status_t status);
 
+cairo_private cairo_int_status_t
+_cairo_clip_get_polygon (const cairo_clip_t *clip,
+			 cairo_polygon_t *polygon,
+			 cairo_fill_rule_t *fill_rule,
+			 cairo_antialias_t *antialias);
+
 #endif /* CAIRO_CLIP_PRIVATE_H */
diff --git a/src/cairo-clip-region.c b/src/cairo-clip-region.c
new file mode 100644
index 0000000..28a0d4b
--- /dev/null
+++ b/src/cairo-clip-region.c
@@ -0,0 +1,117 @@
+/* -*- 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.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is University of Southern
+ * California.
+ *
+ * Contributor(s):
+ *	Carl D. Worth <cworth at cworth.org>
+ *	Kristian Høgsberg <krh at redhat.com>
+ *	Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#include "cairoint.h"
+#include "cairo-clip-private.h"
+#include "cairo-error-private.h"
+#include "cairo-freed-pool-private.h"
+#include "cairo-gstate-private.h"
+#include "cairo-path-fixed-private.h"
+#include "cairo-pattern-private.h"
+#include "cairo-composite-rectangles-private.h"
+#include "cairo-region-private.h"
+
+static void
+_cairo_clip_extract_region (cairo_clip_t *clip)
+{
+    cairo_rectangle_int_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (cairo_rectangle_int_t)];
+    cairo_rectangle_int_t *r = stack_rects;
+    cairo_bool_t is_region;
+    int i;
+
+    if (clip->num_boxes == 0)
+	return;
+
+    if (clip->num_boxes > ARRAY_LENGTH (stack_rects)) {
+	r = _cairo_malloc_ab (clip->num_boxes, sizeof (cairo_rectangle_int_t));
+	if (r == NULL){
+	    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+	    return;
+	}
+    }
+
+    is_region = clip->path == NULL;
+    for (i = 0; i < clip->num_boxes; i++) {
+	cairo_box_t *b = &clip->boxes[i];
+	if (is_region)
+	    is_region =
+		_cairo_fixed_is_integer (b->p1.x | b->p1.y |  b->p2.x | b->p2.y);
+	r[i].x = _cairo_fixed_integer_floor (b->p1.x);
+	r[i].y = _cairo_fixed_integer_floor (b->p1.y);
+	r[i].width  = _cairo_fixed_integer_ceil (b->p2.x) - r[i].x;
+	r[i].height = _cairo_fixed_integer_ceil (b->p2.y) - r[i].y;
+    }
+    clip->is_region = is_region;
+
+    clip->region = cairo_region_create_rectangles (r, i);
+
+    if (r != stack_rects)
+	free (r);
+}
+
+cairo_region_t *
+_cairo_clip_get_region (const cairo_clip_t *clip)
+{
+    if (clip == NULL)
+	return NULL;
+
+    if (clip->region == NULL)
+	_cairo_clip_extract_region ((cairo_clip_t *) clip);
+
+    return clip->region;
+}
+
+cairo_bool_t
+_cairo_clip_is_region (const cairo_clip_t *clip)
+{
+    if (clip == NULL)
+	return TRUE;
+
+    /* XXX Geometric reduction? */
+
+    if (clip->path)
+	    return FALSE;
+
+    if (clip->region == NULL)
+	_cairo_clip_extract_region ((cairo_clip_t *) clip);
+
+    return clip->is_region;
+}
diff --git a/src/cairo-clip-surface.c b/src/cairo-clip-surface.c
new file mode 100644
index 0000000..79e6a62
--- /dev/null
+++ b/src/cairo-clip-surface.c
@@ -0,0 +1,142 @@
+/* -*- 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.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is University of Southern
+ * California.
+ *
+ * Contributor(s):
+ *	Carl D. Worth <cworth at cworth.org>
+ *	Kristian Høgsberg <krh at redhat.com>
+ *	Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#include "cairoint.h"
+#include "cairo-clip-private.h"
+#include "cairo-error-private.h"
+#include "cairo-freed-pool-private.h"
+#include "cairo-gstate-private.h"
+#include "cairo-path-fixed-private.h"
+#include "cairo-pattern-private.h"
+#include "cairo-composite-rectangles-private.h"
+#include "cairo-region-private.h"
+
+cairo_status_t
+_cairo_clip_combine_with_surface (const cairo_clip_t *clip,
+				  cairo_surface_t *dst,
+				  int dst_x, int dst_y)
+{
+    cairo_clip_path_t *clip_path;
+    cairo_clip_path_t *copy_path;
+    cairo_clip_t *copy;
+    cairo_status_t status = CAIRO_STATUS_SUCCESS;
+
+    copy = _cairo_clip_copy_with_translation (clip, -dst_x, -dst_y);
+    copy_path = copy->path;
+    copy->path = NULL;
+
+    if (copy_path == NULL) {
+	assert (copy->num_boxes);
+	status = _cairo_surface_paint (dst,
+				       CAIRO_OPERATOR_IN,
+				       &_cairo_pattern_white.base,
+				       copy);
+    }
+
+    clip_path = copy_path;
+    while (status == CAIRO_STATUS_SUCCESS && clip_path) {
+	status = _cairo_surface_fill (dst,
+				      CAIRO_OPERATOR_IN,
+				      &_cairo_pattern_white.base,
+				      &clip_path->path,
+				      clip_path->fill_rule,
+				      clip_path->tolerance,
+				      clip_path->antialias,
+				      copy);
+	clip_path = clip_path->prev;
+    }
+
+    copy->path = copy_path;
+    _cairo_clip_destroy (copy);
+    return status;
+}
+
+cairo_surface_t *
+_cairo_clip_get_surface (const cairo_clip_t *clip,
+			 cairo_surface_t *target,
+			 int *tx, int *ty)
+{
+    cairo_surface_t *surface;
+    cairo_status_t status;
+    cairo_clip_t *copy;
+    cairo_clip_path_t *copy_path, *clip_path;
+
+    surface = _cairo_surface_create_similar_solid (target,
+						   CAIRO_CONTENT_ALPHA,
+						   clip->extents.width,
+						   clip->extents.height,
+						   CAIRO_COLOR_TRANSPARENT,
+						   TRUE);
+    if (unlikely (surface->status))
+	return surface;
+
+    copy = _cairo_clip_copy_with_translation (clip,
+					      -clip->extents.x,
+					      -clip->extents.y);
+    copy_path = copy->path;
+    copy->path = NULL;
+
+    assert (copy->num_boxes);
+    status = _cairo_surface_paint (surface,
+				   CAIRO_OPERATOR_ADD,
+				   &_cairo_pattern_white.base,
+				   copy);
+
+    clip_path = copy_path;
+    while (status == CAIRO_STATUS_SUCCESS && clip_path) {
+	status = _cairo_surface_fill (surface,
+				      CAIRO_OPERATOR_IN,
+				      &_cairo_pattern_white.base,
+				      &clip_path->path,
+				      clip_path->fill_rule,
+				      clip_path->tolerance,
+				      clip_path->antialias,
+				      copy);
+	clip_path = clip_path->prev;
+    }
+
+    copy->path = copy_path;
+    _cairo_clip_destroy (copy);
+
+    *tx = clip->extents.x;
+    *ty = clip->extents.y;
+    return surface;
+}
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index 9054b4e..99d7cd4 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -50,6 +50,16 @@
 #include "cairo-region-private.h"
 
 static freed_pool_t clip_path_pool;
+static freed_pool_t clip_pool;
+
+const cairo_clip_t __cairo_clip_all;
+
+static const cairo_rectangle_int_t _cairo_empty_rectangle = { 0, 0, 0, 0 };
+static const cairo_rectangle_int_t _cairo_unbounded_rectangle = {
+     CAIRO_RECT_INT_MIN, CAIRO_RECT_INT_MIN,
+     CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN,
+     CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN,
+};
 
 static cairo_clip_path_t *
 _cairo_clip_path_create (cairo_clip_t *clip)
@@ -65,10 +75,6 @@ _cairo_clip_path_create (cairo_clip_t *clip)
 
     CAIRO_REFERENCE_COUNT_INIT (&clip_path->ref_count, 1);
 
-    clip_path->flags = 0;
-    clip_path->region = NULL;
-    clip_path->surface = NULL;
-
     clip_path->prev = clip->path;
     clip->path = clip_path;
 
@@ -85,7 +91,7 @@ _cairo_clip_path_reference (cairo_clip_path_t *clip_path)
     return clip_path;
 }
 
-static void
+void
 _cairo_clip_path_destroy (cairo_clip_path_t *clip_path)
 {
     assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&clip_path->ref_count));
@@ -94,10 +100,6 @@ _cairo_clip_path_destroy (cairo_clip_path_t *clip_path)
 	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);
@@ -105,115 +107,75 @@ _cairo_clip_path_destroy (cairo_clip_path_t *clip_path)
     _freed_pool_put (&clip_path_pool, clip_path);
 }
 
-void
-_cairo_clip_init (cairo_clip_t *clip)
+cairo_clip_t *
+_cairo_clip_create (void)
 {
-    clip->all_clipped = FALSE;
+    cairo_clip_t *clip;
+
+    clip = _freed_pool_get (&clip_pool);
+    if (unlikely (clip == NULL)) {
+	clip = malloc (sizeof (cairo_clip_t));
+	if (unlikely (clip == NULL))
+	    return NULL;
+    }
+
+    clip->extents = _cairo_unbounded_rectangle;
+
     clip->path = NULL;
+    clip->boxes = NULL;
+    clip->num_boxes = 0;
+    clip->region = NULL;
+    clip->is_region = FALSE;
+
+    return clip;
 }
 
-static void
-_cairo_clip_set_all_clipped (cairo_clip_t *clip)
+void
+_cairo_clip_destroy (cairo_clip_t *clip)
 {
-    clip->all_clipped = TRUE;
-    if (clip->path != NULL) {
+    if (clip == NULL || _cairo_clip_is_all_clipped (clip))
+	return;
+
+    if (clip->path != NULL)
 	_cairo_clip_path_destroy (clip->path);
-	clip->path = NULL;
-    }
+
+    free (clip->boxes);
+    cairo_region_destroy (clip->region);
+
+    _freed_pool_put (&clip_pool, clip);
 }
 
-static cairo_status_t
-_cairo_clip_intersect_rectangle (cairo_clip_t *clip,
-				 const cairo_rectangle_int_t *rect)
+cairo_clip_t *
+_cairo_clip_copy (const cairo_clip_t *clip)
 {
-    cairo_clip_path_t *clip_path;
-    cairo_status_t status;
+    cairo_clip_t *copy;
 
-    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 == NULL || _cairo_clip_is_all_clipped (clip))
+	return (cairo_clip_t *) clip;
 
-    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->fill_rule = CAIRO_FILL_RULE_WINDING;
-    clip_path->tolerance = 1;
-    clip_path->antialias = CAIRO_ANTIALIAS_DEFAULT;
-    clip_path->flags |= CAIRO_CLIP_PATH_IS_BOX;
-
-    clip_path->extents = *rect;
-    if (clip_path->prev != NULL) {
-	if (! _cairo_rectangle_intersect (&clip_path->extents,
-					  &clip_path->prev->extents))
-	{
-	    _cairo_clip_set_all_clipped (clip);
-	}
-    }
+    copy = _cairo_clip_create ();
 
-    /* could preallocate the region if it proves worthwhile */
+    if (clip->path)
+	copy->path = _cairo_clip_path_reference (clip->path);
 
-    return CAIRO_STATUS_SUCCESS;
-}
+    if (clip->num_boxes) {
+	copy->boxes = _cairo_malloc_ab (clip->num_boxes, sizeof (cairo_box_t));
+	if (unlikely (copy->boxes == NULL))
+	    return _cairo_clip_set_all_clipped (copy);
 
-cairo_clip_t *
-_cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
-{
-    if (other != NULL) {
-	clip->all_clipped = other->all_clipped;
-	if (other->path == NULL) {
-	    clip->path = NULL;
-	    if (! clip->all_clipped)
-		clip = NULL;
-	} else {
-	    clip->path = _cairo_clip_path_reference (other->path);
-	}
-    } else {
-	_cairo_clip_init (clip);
-	clip = NULL;
+	memcpy (copy->boxes, clip->boxes,
+		clip->num_boxes * sizeof (cairo_box_t));
+	copy->num_boxes = clip->num_boxes;
     }
 
-    return clip;
-}
+    copy->extents = clip->extents;
+    copy->region = cairo_region_reference (clip->region);
+    copy->is_region = clip->is_region;
 
-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;
-    }
+    return copy;
 }
 
-static cairo_status_t
+cairo_clip_t *
 _cairo_clip_intersect_path (cairo_clip_t       *clip,
 			    const cairo_path_fixed_t *path,
 			    cairo_fill_rule_t   fill_rule,
@@ -224,928 +186,147 @@ _cairo_clip_intersect_path (cairo_clip_t       *clip,
     cairo_status_t status;
     cairo_rectangle_int_t extents;
     cairo_box_t box;
-    cairo_bool_t is_box = FALSE;
-
-    if (clip->path != NULL) {
-	if (clip->path->fill_rule == fill_rule &&
-	    (_cairo_path_fixed_fill_is_rectilinear (path) || tolerance == clip->path->tolerance) &&
-	    antialias == clip->path->antialias &&
-	    _cairo_path_fixed_equal (&clip->path->path, path))
-	{
-	    return CAIRO_STATUS_SUCCESS;
+
+    if (_cairo_clip_is_all_clipped (clip))
+	return clip;
+
+    /* catch the empty clip path */
+    if (_cairo_path_fixed_fill_is_empty (path))
+	return _cairo_clip_set_all_clipped (clip);
+
+    if (_cairo_path_fixed_is_box (path, &box)) {
+	if (antialias == CAIRO_ANTIALIAS_NONE) {
+	    box.p1.x = _cairo_fixed_round_down (box.p1.x);
+	    box.p1.y = _cairo_fixed_round_down (box.p1.y);
+	    box.p2.x = _cairo_fixed_round_down (box.p2.x);
+	    box.p2.y = _cairo_fixed_round_down (box.p2.y);
 	}
+
+	return _cairo_clip_intersect_box (clip, &box);
     }
+    if (_cairo_path_fixed_fill_is_rectilinear (path))
+	return _cairo_clip_intersect_rectilinear_path (clip, path,
+						       fill_rule, antialias);
 
     _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;
-    }
+    if (extents.width == 0 || extents.height == 0)
+	return _cairo_clip_set_all_clipped (clip);
 
-    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;
-	}
+    if (clip && ! _cairo_rectangle_intersect (&clip->extents, &extents))
+	return _cairo_clip_set_all_clipped (clip);
 
-	/* 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;
-	}
+    if (clip == NULL) {
+	clip = _cairo_clip_create ();
+	if (unlikely (clip == NULL))
+		return _cairo_clip_set_all_clipped (clip);
+
+	clip->extents = extents;
     }
 
     clip_path = _cairo_clip_path_create (clip);
     if (unlikely (clip_path == NULL))
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    return _cairo_clip_set_all_clipped (clip);
 
     status = _cairo_path_fixed_init_copy (&clip_path->path, path);
-    if (unlikely (status)) {
-	clip->path = clip->path->prev;
-	_cairo_clip_path_destroy (clip_path);
-	return status;
-    }
+    if (unlikely (status))
+	    return _cairo_clip_set_all_clipped (clip);
 
-    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;
+    clip->is_region = FALSE;
+    return clip;
 }
 
 cairo_bool_t
 _cairo_clip_equal (const cairo_clip_t *clip_a,
 		   const cairo_clip_t *clip_b)
 {
-    const cairo_clip_path_t *clip_path_a, *clip_path_b;
-
-    clip_path_a = clip_a->path;
-    clip_path_b = clip_b->path;
-
-    while (clip_path_a && clip_path_b) {
-	if (clip_path_a == clip_path_b)
-	    return TRUE;
-
-	if (clip_path_a->fill_rule != clip_path_b->fill_rule)
-	    return FALSE;
-
-	if (clip_path_a->tolerance != clip_path_b->tolerance)
-	    return FALSE;
-
-	if (clip_path_a->antialias != clip_path_b->antialias)
-	    return FALSE;
-
-	if (! _cairo_path_fixed_equal (&clip_path_a->path, &clip_path_b->path))
-	    return FALSE;
-
-	clip_path_a = clip_path_a->prev;
-	clip_path_b = clip_path_b->prev;
-    }
-
-    return clip_path_a == clip_path_b; /* ie both NULL */
-}
-
-cairo_status_t
-_cairo_clip_clip (cairo_clip_t       *clip,
-		  const cairo_path_fixed_t *path,
-		  cairo_fill_rule_t   fill_rule,
-		  double              tolerance,
-		  cairo_antialias_t   antialias)
-{
-    if (clip->all_clipped)
-	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;
-    }
-
-    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;
-
-    if (rectangle->width == 0 || rectangle->height == 0) {
-	_cairo_clip_set_all_clipped (clip);
-	return CAIRO_STATUS_SUCCESS;
-    }
-
-    /* if a smaller clip has already been set, ignore the new path */
-    if (clip->path != NULL) {
-	if (rectangle->x <= clip->path->extents.x &&
-	    rectangle->y <= clip->path->extents.y &&
-	    rectangle->x + rectangle->width  >= clip->path->extents.x + clip->path->extents.width &&
-	    rectangle->y + rectangle->height >= clip->path->extents.y + clip->path->extents.height)
-	{
-	    return CAIRO_STATUS_SUCCESS;
-	}
-    }
-
-    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;
-
-    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)) {
-	clip->path = clip->path->prev;
-	_cairo_clip_path_destroy (clip_path);
-	return status;
-    }
-
-    _cairo_path_fixed_transform (&clip_path->path, matrix);
-    _cairo_path_fixed_approximate_clip_extents (&clip_path->path,
-						&clip_path->extents);
-    if (clip_path->prev != NULL) {
-	_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;
+    /* are both all-clipped or no-clip? */
+    if (clip_a == clip_b)
+	return TRUE;
 
-    return CAIRO_STATUS_SUCCESS;
+    return FALSE;
 }
 
-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)
+static cairo_clip_t *
+_cairo_clip_path_copy_with_translation (cairo_clip_t      *clip,
+					cairo_clip_path_t *other_path,
+					int fx, int fy)
 {
     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;
-    }
+    if (other_path->prev != NULL)
+	clip = _cairo_clip_path_copy_with_translation (clip, other_path->prev,
+						       fx, fy);
+    if (_cairo_clip_is_all_clipped (clip))
+	return clip;
 
     clip_path = _cairo_clip_path_create (clip);
     if (unlikely (clip_path == NULL))
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	return _cairo_clip_set_all_clipped (clip);
 
     status = _cairo_path_fixed_init_copy (&clip_path->path,
 					  &other_path->path);
-    if (unlikely (status)) {
-	clip->path = clip->path->prev;
-	_cairo_clip_path_destroy (clip_path);
-	return status;
-    }
+    if (unlikely (status))
+	return _cairo_clip_set_all_clipped (clip);
 
-    _cairo_path_fixed_translate (&clip_path->path,
-				 _cairo_fixed_from_int (tx),
-				 _cairo_fixed_from_int (ty));
+    _cairo_path_fixed_translate (&clip_path->path, fx, fy);
 
     clip_path->fill_rule = other_path->fill_rule;
     clip_path->tolerance = other_path->tolerance;
     clip_path->antialias = other_path->antialias;
 
-    clip_path->flags = other_path->flags;
-    if (other_path->region != NULL) {
-	clip_path->region = cairo_region_copy (other_path->region);
-	status = clip_path->region->status;
-	if (unlikely (status)) {
-	    clip->path = clip->path->prev;
-	    _cairo_clip_path_destroy (clip_path);
-	    return status;
-	}
-
-	cairo_region_translate (clip_path->region, tx, ty);
-    }
-    clip_path->surface = cairo_surface_reference (other_path->surface);
-
-    clip_path->extents = other_path->extents;
-    clip_path->extents.x += tx;
-    clip_path->extents.y += ty;
-
-    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);
-	    }
-	}
-    }
-
-    return status;
-}
-
-static cairo_status_t
-_cairo_clip_apply_clip_path (cairo_clip_t *clip,
-			     const cairo_clip_path_t *path)
-{
-    if (path->prev != NULL) {
-	cairo_status_t status;
-
-	status = _cairo_clip_apply_clip_path (clip, path->prev);
-	if (unlikely (status))
-	    return status;
-    }
-
-    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;
-
-    if (clip->all_clipped)
-	return CAIRO_STATUS_SUCCESS;
-
-    if (other->all_clipped) {
-	_cairo_clip_set_all_clipped (clip);
-	return CAIRO_STATUS_SUCCESS;
-    }
-
-    status = CAIRO_STATUS_SUCCESS;
-    if (other->path != NULL)
-	status = _cairo_clip_apply_clip_path (clip, other->path);
-
-    return status;
-}
-
-static inline cairo_bool_t
-_clip_paths_are_rectilinear (cairo_clip_path_t *clip_path)
-{
-    while (clip_path != NULL) {
-	if (! _cairo_path_fixed_fill_is_rectilinear (&clip_path->path))
-	    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_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;
-
-    /* Start simple... Intersect some boxes with an arbitrary path. */
-    if (! _cairo_path_fixed_fill_is_rectilinear (&clip_path->path))
-	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);
-
-    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;
-    }
-
-    _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);
-
-    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))
-	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))
-    {
-	return clip_path->flags & CAIRO_CLIP_PATH_REGION_IS_UNSUPPORTED ?
-	    CAIRO_INT_STATUS_UNSUPPORTED :
-	    CAIRO_STATUS_SUCCESS;
-    }
-
-    if (! _cairo_path_fixed_fill_maybe_region (&clip_path->path))
-	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))
-	    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;
-    }
-
-    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, *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;
-	    }
-
-	    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;
-	}
-    }
-
-  CLEANUP:
-    _cairo_polygon_fini (&polygon);
-    _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)
-{
-    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;
-
-	    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;
-    }
-
-    /* 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;
-    }
-
-    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 (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;
-	    }
-
-	    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;
-	}
-    }
-
-    *count = num_boxes;
-    return CAIRO_STATUS_SUCCESS;
+    return clip;
 }
 
-static cairo_surface_t *
-_cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
-			      cairo_surface_t *target,
-			      int *tx, int *ty)
+cairo_clip_t *
+_cairo_clip_copy_with_translation (const cairo_clip_t *clip, int tx, int ty)
 {
-    const cairo_rectangle_int_t *clip_extents = &clip_path->extents;
-    cairo_bool_t need_translate;
-    cairo_surface_t *surface;
-    cairo_clip_path_t *prev;
-    cairo_status_t status;
+    cairo_clip_t *copy;
+    int fx, fy, i;
 
-    while (clip_path->prev != NULL &&
-	   clip_path->flags & CAIRO_CLIP_PATH_IS_BOX &&
-	   _cairo_path_fixed_fill_maybe_region (&clip_path->path))
-    {
-	clip_path = clip_path->prev;
-    }
+    if (clip == NULL || _cairo_clip_is_all_clipped (clip))
+	return (cairo_clip_t *)clip;
 
-    clip_extents = &clip_path->extents;
-    if (clip_path->surface != NULL &&
-	clip_path->surface->backend == target->backend)
-    {
-	*tx = clip_extents->x;
-	*ty = clip_extents->y;
-	return clip_path->surface;
-    }
+    if (tx == 0 && ty == 0)
+	return _cairo_clip_copy (clip);
 
-    surface = _cairo_surface_create_similar_scratch (target,
-						     CAIRO_CONTENT_ALPHA,
-						     clip_extents->width,
-						     clip_extents->height);
-    if (surface == NULL) {
-	surface = cairo_image_surface_create (CAIRO_FORMAT_A8,
-					      clip_extents->width,
-					      clip_extents->height);
-    }
-    if (unlikely (surface->status))
-	return surface;
-
-    need_translate = clip_extents->x | clip_extents->y;
-    if (clip_path->flags & CAIRO_CLIP_PATH_IS_BOX &&
-	_cairo_path_fixed_fill_maybe_region (&clip_path->path))
-    {
-	status = _cairo_surface_paint (surface,
-				       CAIRO_OPERATOR_SOURCE,
-				       &_cairo_pattern_white.base,
-				       NULL);
-	if (unlikely (status))
-	    goto BAIL;
-    }
-    else
-    {
-	status = _cairo_surface_paint (surface,
-				       CAIRO_OPERATOR_CLEAR,
-				       &_cairo_pattern_clear.base,
-				       NULL);
-	if (unlikely (status))
-	    goto BAIL;
-
-	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_ADD,
-				      &_cairo_pattern_white.base,
-				      &clip_path->path,
-				      clip_path->fill_rule,
-				      clip_path->tolerance,
-				      clip_path->antialias,
-				      NULL);
-	if (need_translate) {
-	    _cairo_path_fixed_translate (&clip_path->path,
-					 _cairo_fixed_from_int (clip_extents->x),
-					 _cairo_fixed_from_int (clip_extents->y));
-	}
+    copy = _cairo_clip_create ();
+    if (copy == NULL)
+	    return _cairo_clip_set_all_clipped (copy);
 
-	if (unlikely (status))
-	    goto BAIL;
-    }
+    fx = _cairo_fixed_from_int (tx);
+    fy = _cairo_fixed_from_int (ty);
 
-    prev = clip_path->prev;
-    while (prev != NULL) {
-	if (prev->flags & CAIRO_CLIP_PATH_IS_BOX &&
-	    _cairo_path_fixed_fill_maybe_region (&prev->path))
-	{
-	    /* a simple box only affects the extents */
-	}
-	else if (_cairo_path_fixed_fill_is_rectilinear (&prev->path) ||
-		prev->surface == NULL ||
-		prev->surface->backend != target->backend)
-	{
-	    if (need_translate) {
-		_cairo_path_fixed_translate (&prev->path,
-					     _cairo_fixed_from_int (-clip_extents->x),
-					     _cairo_fixed_from_int (-clip_extents->y));
-	    }
-	    status = _cairo_surface_fill (surface,
-					  CAIRO_OPERATOR_IN,
-					  &_cairo_pattern_white.base,
-					  &prev->path,
-					  prev->fill_rule,
-					  prev->tolerance,
-					  prev->antialias,
-					  NULL);
-	    if (need_translate) {
-		_cairo_path_fixed_translate (&prev->path,
-					     _cairo_fixed_from_int (clip_extents->x),
-					     _cairo_fixed_from_int (clip_extents->y));
-	    }
+    if (clip->num_boxes) {
+	copy->boxes = _cairo_malloc_ab (clip->num_boxes, sizeof (cairo_box_t));
+	if (unlikely (copy->boxes == NULL))
+	    return _cairo_clip_set_all_clipped (copy);
 
-	    if (unlikely (status))
-		goto BAIL;
-	}
-	else
-	{
-	    cairo_surface_pattern_t pattern;
-	    cairo_surface_t *prev_surface;
-	    int prev_tx, prev_ty;
-
-	    prev_surface = _cairo_clip_path_get_surface (prev, target, &prev_tx, &prev_ty);
-	    status = prev_surface->status;
-	    if (unlikely (status))
-		goto BAIL;
-
-	    _cairo_pattern_init_for_surface (&pattern, prev_surface);
-	    pattern.base.filter = CAIRO_FILTER_NEAREST;
-	    cairo_matrix_init_translate (&pattern.base.matrix,
-					 clip_extents->x - prev_tx,
-					 clip_extents->y - prev_ty);
-	    status = _cairo_surface_paint (surface,
-					   CAIRO_OPERATOR_IN,
-					   &pattern.base,
-					   NULL);
-	    _cairo_pattern_fini (&pattern.base);
-
-	    if (unlikely (status))
-		goto BAIL;
-
-	    break;
+	for (i = 0; i < clip->num_boxes; i++) {
+	    copy->boxes[i].p1.x = clip->boxes[i].p1.x + fx;
+	    copy->boxes[i].p2.x = clip->boxes[i].p2.x + fx;
+	    copy->boxes[i].p1.y = clip->boxes[i].p1.y + fy;
+	    copy->boxes[i].p2.y = clip->boxes[i].p2.y + fy;
 	}
-
-	prev = prev->prev;
+	copy->num_boxes = clip->num_boxes;
     }
 
-    *tx = clip_extents->x;
-    *ty = clip_extents->y;
-    cairo_surface_destroy (clip_path->surface);
-    return clip_path->surface = surface;
-
-  BAIL:
-    cairo_surface_destroy (surface);
-    return _cairo_surface_create_in_error (status);
-}
-
-cairo_bool_t
-_cairo_clip_contains_rectangle (cairo_clip_t *clip,
-				const cairo_rectangle_int_t *rect)
-{
-    cairo_clip_path_t *clip_path;
-
-    /* clip == NULL means no clip, so the clip contains everything */
-    if (clip == NULL)
-	return TRUE;
-
-    clip_path = clip->path;
-    if (clip_path->extents.x > rect->x ||
-	clip_path->extents.y > rect->y ||
-	clip_path->extents.x + clip_path->extents.width  < rect->x + rect->width ||
-	clip_path->extents.y + clip_path->extents.height < rect->y + rect->height)
-    {
-	return FALSE;
-    }
+    copy->extents = clip->extents;
+    copy->extents.x += tx;
+    copy->extents.y += ty;
 
-    do {
-	cairo_box_t box;
-
-	if ((clip_path->flags & CAIRO_CLIP_PATH_IS_BOX) == 0)
-	    return FALSE;
-
-	if (! _cairo_path_fixed_is_box (&clip_path->path, &box))
-	    return FALSE;
-
-	if (box.p1.x > _cairo_fixed_from_int (rect->x) ||
-	    box.p1.y > _cairo_fixed_from_int (rect->y) ||
-	    box.p2.x < _cairo_fixed_from_int (rect->x + rect->width) ||
-	    box.p2.y < _cairo_fixed_from_int (rect->y + rect->height))
-	{
-	    return FALSE;
-	}
-    } while ((clip_path = clip_path->prev) != NULL);
+    if (clip->path == NULL)
+	return copy;
 
-    return TRUE;
+    return _cairo_clip_path_copy_with_translation (copy, clip->path, fx, fy);
 }
 
 cairo_bool_t
-_cairo_clip_contains_extents (cairo_clip_t *clip,
+_cairo_clip_contains_extents (const cairo_clip_t *clip,
 			      const cairo_composite_rectangles_t *extents)
 {
     const cairo_rectangle_int_t *rect;
@@ -1155,149 +336,57 @@ _cairo_clip_contains_extents (cairo_clip_t *clip,
 }
 
 void
-_cairo_debug_print_clip (FILE *stream, cairo_clip_t *clip)
+_cairo_debug_print_clip (FILE *stream, const cairo_clip_t *clip)
 {
-    cairo_clip_path_t *clip_path;
+    int i;
 
     if (clip == NULL) {
 	fprintf (stream, "no clip\n");
 	return;
     }
 
-    if (clip->all_clipped) {
+    if (_cairo_clip_is_all_clipped (clip)) {
 	fprintf (stream, "clip: all-clipped\n");
 	return;
     }
 
-    if (clip->path == NULL) {
-	fprintf (stream, "clip: empty\n");
-	return;
-    }
-
     fprintf (stream, "clip:\n");
+    fprintf (stream, "  extents: (%d, %d) x (%d, %d)",
+	     clip->extents.x, clip->extents.y,
+	     clip->extents.width, clip->extents.height);
 
-    clip_path = clip->path;
-    do {
-	fprintf (stream, "path: has region? %s, has surface? %s, aa=%d, tolerance=%f, rule=%d: ",
-		 clip_path->region == NULL ? "no" : "yes",
-		 clip_path->surface == NULL ? "no" : "yes",
-		 clip_path->antialias,
-		 clip_path->tolerance,
-		 clip_path->fill_rule);
-	_cairo_debug_print_path (stream, &clip_path->path);
-	fprintf (stream, "\n");
-    } while ((clip_path = clip_path->prev) != NULL);
-}
-
-cairo_surface_t *
-_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *target, int *tx, int *ty)
-{
-    /* XXX is_clear -> all_clipped */
-    assert (clip->path != NULL);
-    return _cairo_clip_path_get_surface (clip->path, target, tx, ty);
-}
-
-cairo_status_t
-_cairo_clip_combine_with_surface (cairo_clip_t *clip,
-				  cairo_surface_t *dst,
-				  int dst_x, int dst_y)
-{
-    cairo_clip_path_t *clip_path = clip->path;
-    cairo_bool_t need_translate;
-    cairo_status_t status;
-
-    assert (clip_path != NULL);
-
-    need_translate = dst_x | dst_y;
-    do {
-	if (clip_path->surface != NULL &&
-	    clip_path->surface->backend == dst->backend)
-	{
-	    cairo_surface_pattern_t pattern;
-
-	    _cairo_pattern_init_for_surface (&pattern, clip_path->surface);
-	    cairo_matrix_init_translate (&pattern.base.matrix,
-					 dst_x - clip_path->extents.x,
-					 dst_y - clip_path->extents.y);
-	    pattern.base.filter = CAIRO_FILTER_NEAREST;
-	    status = _cairo_surface_paint (dst,
-					   CAIRO_OPERATOR_IN,
-					   &pattern.base,
-					   NULL);
-
-	    _cairo_pattern_fini (&pattern.base);
-
-	    return status;
-	}
-
-	if (clip_path->flags & CAIRO_CLIP_PATH_IS_BOX &&
-	    _cairo_path_fixed_fill_maybe_region (&clip_path->path))
-	{
-	    continue;
-	}
-
-	if (need_translate) {
-	    _cairo_path_fixed_translate (&clip_path->path,
-					 _cairo_fixed_from_int (-dst_x),
-					 _cairo_fixed_from_int (-dst_y));
-	}
-	status = _cairo_surface_fill (dst,
-				      CAIRO_OPERATOR_IN,
-				      &_cairo_pattern_white.base,
-				      &clip_path->path,
-				      clip_path->fill_rule,
-				      clip_path->tolerance,
-				      clip_path->antialias,
-				      NULL);
-	if (need_translate) {
-	    _cairo_path_fixed_translate (&clip_path->path,
-					 _cairo_fixed_from_int (dst_x),
-					 _cairo_fixed_from_int (dst_y));
-	}
-
-	if (unlikely (status))
-	    return status;
-    } while ((clip_path = clip_path->prev) != NULL);
+    fprintf (stream, "  num_boxes = %d\n", clip->num_boxes);
+    for (i = 0; i < clip->num_boxes; i++) {
+	fprintf (stream, "  [%d] = (%f, %f), (%f, %f)\n", i,
+		 _cairo_fixed_to_double (clip->boxes[i].p1.x),
+		 _cairo_fixed_to_double (clip->boxes[i].p1.y),
+		 _cairo_fixed_to_double (clip->boxes[i].p2.x),
+		 _cairo_fixed_to_double (clip->boxes[i].p2.y));
+    }
 
-    return CAIRO_STATUS_SUCCESS;
+    if (clip->path) {
+	cairo_clip_path_t *clip_path = clip->path;
+	do {
+	    fprintf (stream, "path: aa=%d, tolerance=%f, rule=%d: ",
+		     clip_path->antialias,
+		     clip_path->tolerance,
+		     clip_path->fill_rule);
+	    _cairo_debug_print_path (stream, &clip_path->path);
+	    fprintf (stream, "\n");
+	} while ((clip_path = clip_path->prev) != NULL);
+    }
 }
 
-static const cairo_rectangle_int_t _cairo_empty_rectangle_int = { 0, 0, 0, 0 };
-
 const cairo_rectangle_int_t *
 _cairo_clip_get_extents (const cairo_clip_t *clip)
 {
-    if (clip->all_clipped)
-	return &_cairo_empty_rectangle_int;
-
-    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;
+    if (clip == NULL)
+	return &_cairo_unbounded_rectangle;
 
-    clip_path = clip->path;
-    do {
-	if (clip_path->region != NULL) {
-	    cairo_region_destroy (clip_path->region);
-	    clip_path->region = NULL;
-	}
+    if (_cairo_clip_is_all_clipped (clip))
+	return &_cairo_empty_rectangle;
 
-	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 &clip->extents;
 }
 
 const cairo_rectangle_list_t _cairo_rectangles_nil =
@@ -1329,145 +418,6 @@ _cairo_clip_int_rect_to_user (cairo_gstate_t *gstate,
     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_bool_t
-box_is_aligned (const cairo_box_t *box)
-{
-    return
-	_cairo_fixed_is_integer (box->p1.x) &&
-	_cairo_fixed_is_integer (box->p1.y) &&
-	_cairo_fixed_is_integer (box->p2.x) &&
-	_cairo_fixed_is_integer (box->p2.y);
-}
-
-static void
-intersect_with_boxes (cairo_composite_rectangles_t *extents,
-		      cairo_box_t *boxes,
-		      int num_boxes)
-{
-    cairo_rectangle_int_t rect;
-    cairo_box_t box;
-    int i;
-
-    assert (num_boxes > 0);
-
-    /* Find the extents over all the clip boxes */
-    box = boxes[0];
-    for (i = 1; i < num_boxes; i++) {
-	if (boxes[i].p1.x < box.p1.x)
-	    box.p1.x = boxes[i].p1.x;
-	if (boxes[i].p1.y < box.p1.y)
-	    box.p1.y = boxes[i].p1.y;
-
-	if (boxes[i].p2.x > box.p2.x)
-	    box.p2.x = boxes[i].p2.x;
-	if (boxes[i].p2.y > box.p2.y)
-	    box.p2.y = boxes[i].p2.y;
-    }
-
-    _cairo_box_round_to_rectangle (&box, &rect);
-    _cairo_rectangle_intersect (&extents->bounded, &rect);
-    _cairo_rectangle_intersect (&extents->unbounded, &rect);
-}
-
-cairo_status_t
-_cairo_clip_to_boxes (cairo_clip_t **clip,
-		      cairo_composite_rectangles_t *extents,
-		      cairo_box_t **boxes,
-		      int *num_boxes)
-{
-    cairo_status_t status;
-    const cairo_rectangle_int_t *rect;
-
-    rect = extents->is_bounded ? &extents->bounded : &extents->unbounded;
-
-    if (*clip == NULL)
-	goto EXTENTS;
-
-    status = _cairo_clip_rectangle (*clip, rect);
-    if (unlikely (status))
-	return status;
-
-    status = _cairo_clip_get_boxes (*clip, boxes, num_boxes);
-    switch ((int) status) {
-    case CAIRO_STATUS_SUCCESS:
-	intersect_with_boxes (extents, *boxes, *num_boxes);
-	if (rect->width == 0 || rect->height == 0 ||
-	    extents->is_bounded ||
-	    (*num_boxes == 1 && box_is_aligned (*boxes)))
-	{
-	    *clip = NULL;
-	}
-	goto DONE;
-
-    case CAIRO_INT_STATUS_UNSUPPORTED:
-	goto EXTENTS;
-
-    default:
-	return status;
-    }
-
-  EXTENTS:
-    status = CAIRO_STATUS_SUCCESS;
-    _cairo_box_from_rectangle (&(*boxes)[0], rect);
-    *num_boxes = 1;
-  DONE:
-    return status;
-}
-
 cairo_rectangle_list_t *
 _cairo_rectangle_list_create_in_error (cairo_status_t status)
 {
@@ -1499,24 +449,18 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
     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->all_clipped)
-	goto DONE;
-
-    if (!clip->path)
+    if (clip == NULL)
 	return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
 
-    status = _cairo_clip_get_region (clip, &region);
-    if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
+    if (_cairo_clip_is_all_clipped (clip))
 	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);
-    }
+
+    region = _cairo_clip_get_region (clip);
+    if (region == NULL)
+	return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
 
     n_rects = cairo_region_num_rectangles (region);
     if (n_rects) {
diff --git a/src/cairo-composite-rectangles-private.h b/src/cairo-composite-rectangles-private.h
index a0f7c1a..2b4bdba 100644
--- a/src/cairo-composite-rectangles-private.h
+++ b/src/cairo-composite-rectangles-private.h
@@ -56,6 +56,8 @@ struct _cairo_composite_rectangles {
     cairo_rectangle_int_t bounded; /* dst */
     cairo_rectangle_int_t unbounded; /* clip */
     uint32_t is_bounded;
+
+    cairo_clip_t *clip;
 };
 
 cairo_private cairo_int_status_t
@@ -63,7 +65,7 @@ _cairo_composite_rectangles_init_for_paint (cairo_composite_rectangles_t *extent
 					 int surface_width, int surface_height,
 					 cairo_operator_t	 op,
 					 const cairo_pattern_t	*source,
-					 cairo_clip_t		*clip);
+					 const cairo_clip_t		*clip);
 
 cairo_private cairo_int_status_t
 _cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents,
@@ -71,25 +73,25 @@ _cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents
 					cairo_operator_t	 op,
 					const cairo_pattern_t	*source,
 					const cairo_pattern_t	*mask,
-					cairo_clip_t		*clip);
+					const cairo_clip_t		*clip);
 
 cairo_private cairo_int_status_t
 _cairo_composite_rectangles_init_for_stroke (cairo_composite_rectangles_t *extents,
 					     int surface_width, int surface_height,
 					     cairo_operator_t	 op,
 					     const cairo_pattern_t	*source,
-					     cairo_path_fixed_t	*path,
+					     const cairo_path_fixed_t	*path,
 					     const cairo_stroke_style_t	*style,
 					     const cairo_matrix_t	*ctm,
-					     cairo_clip_t		*clip);
+					     const cairo_clip_t		*clip);
 
 cairo_private cairo_int_status_t
 _cairo_composite_rectangles_init_for_fill (cairo_composite_rectangles_t *extents,
 					   int surface_width, int surface_height,
 					   cairo_operator_t	 op,
 					   const cairo_pattern_t	*source,
-					   cairo_path_fixed_t	*path,
-					   cairo_clip_t		*clip);
+					   const cairo_path_fixed_t	*path,
+					   const cairo_clip_t		*clip);
 
 cairo_private cairo_int_status_t
 _cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *extents,
@@ -99,7 +101,10 @@ _cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *exten
 					     cairo_scaled_font_t	*scaled_font,
 					     cairo_glyph_t		*glyphs,
 					     int			 num_glyphs,
-					     cairo_clip_t		*clip,
+					     const cairo_clip_t		*clip,
 					     cairo_bool_t		*overlap);
 
+cairo_private void
+_cairo_composite_rectangles_fini (cairo_composite_rectangles_t *extents);
+
 #endif /* CAIRO_COMPOSITE_RECTANGLES_PRIVATE_H */
diff --git a/src/cairo-composite-rectangles.c b/src/cairo-composite-rectangles.c
index 4240de3..cab7c0c 100644
--- a/src/cairo-composite-rectangles.c
+++ b/src/cairo-composite-rectangles.c
@@ -41,25 +41,29 @@
 
 /* A collection of routines to facilitate writing compositors. */
 
+void _cairo_composite_rectangles_fini (cairo_composite_rectangles_t *extents)
+{
+    _cairo_clip_destroy (extents->clip);
+}
+
 static inline cairo_bool_t
 _cairo_composite_rectangles_init (cairo_composite_rectangles_t *extents,
 				  int width, int height,
 				  cairo_operator_t op,
 				  const cairo_pattern_t *source,
-				  cairo_clip_t *clip)
+				  const cairo_clip_t *clip)
 {
     extents->unbounded.x = extents->unbounded.y = 0;
     extents->unbounded.width  = width;
     extents->unbounded.height = height;
+    extents->clip = NULL;
 
-    if (clip != NULL) {
-	const cairo_rectangle_int_t *clip_extents;
-
-	clip_extents = _cairo_clip_get_extents (clip);
-	if (clip_extents == NULL)
-	    return FALSE;
+    if (_cairo_clip_is_all_clipped (clip))
+	return FALSE;
 
-	if (! _cairo_rectangle_intersect (&extents->unbounded, clip_extents))
+    if (clip != NULL) {
+	if (! _cairo_rectangle_intersect (&extents->unbounded,
+					  _cairo_clip_get_extents (clip)))
 	    return FALSE;
     }
 
@@ -80,7 +84,7 @@ _cairo_composite_rectangles_init_for_paint (cairo_composite_rectangles_t *extent
 					    int surface_width, int surface_height,
 					    cairo_operator_t		 op,
 					    const cairo_pattern_t	*source,
-					    cairo_clip_t		*clip)
+					    const cairo_clip_t		*clip)
 {
     if (! _cairo_composite_rectangles_init (extents,
 					    surface_width, surface_height,
@@ -90,11 +94,17 @@ _cairo_composite_rectangles_init_for_paint (cairo_composite_rectangles_t *extent
     }
 
     extents->mask = extents->bounded;
+
+    extents->clip = _cairo_clip_reduce_for_composite (clip, extents);
+    if (_cairo_clip_is_all_clipped (extents->clip))
+	return CAIRO_INT_STATUS_NOTHING_TO_DO;
+
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_int_status_t
-_cairo_composite_rectangles_intersect (cairo_composite_rectangles_t *extents)
+_cairo_composite_rectangles_intersect (cairo_composite_rectangles_t *extents,
+				       const cairo_clip_t *clip)
 {
     cairo_bool_t ret;
 
@@ -102,6 +112,10 @@ _cairo_composite_rectangles_intersect (cairo_composite_rectangles_t *extents)
     if (! ret && extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK)
 	return CAIRO_INT_STATUS_NOTHING_TO_DO;
 
+    extents->clip = _cairo_clip_reduce_for_composite (clip, extents);
+    if (_cairo_clip_is_all_clipped (extents->clip))
+	return CAIRO_INT_STATUS_NOTHING_TO_DO;
+
     return CAIRO_STATUS_SUCCESS;
 }
 
@@ -111,7 +125,7 @@ _cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents
 					   cairo_operator_t		 op,
 					   const cairo_pattern_t	*source,
 					   const cairo_pattern_t	*mask,
-					   cairo_clip_t			*clip)
+					   const cairo_clip_t		*clip)
 {
     if (! _cairo_composite_rectangles_init (extents,
 					    surface_width, surface_height,
@@ -122,7 +136,7 @@ _cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents
 
     _cairo_pattern_get_extents (mask, &extents->mask);
 
-    return _cairo_composite_rectangles_intersect (extents);
+    return _cairo_composite_rectangles_intersect (extents, clip);
 }
 
 cairo_int_status_t
@@ -130,10 +144,10 @@ _cairo_composite_rectangles_init_for_stroke (cairo_composite_rectangles_t *exten
 					     int surface_width, int surface_height,
 					     cairo_operator_t		 op,
 					     const cairo_pattern_t	*source,
-					     cairo_path_fixed_t		*path,
+					     const cairo_path_fixed_t		*path,
 					     const cairo_stroke_style_t	*style,
 					     const cairo_matrix_t	*ctm,
-					     cairo_clip_t		*clip)
+					     const cairo_clip_t		*clip)
 {
     if (! _cairo_composite_rectangles_init (extents,
 					    surface_width, surface_height,
@@ -144,7 +158,7 @@ _cairo_composite_rectangles_init_for_stroke (cairo_composite_rectangles_t *exten
 
     _cairo_path_fixed_approximate_stroke_extents (path, style, ctm, &extents->mask);
 
-    return _cairo_composite_rectangles_intersect (extents);
+    return _cairo_composite_rectangles_intersect (extents, clip);
 }
 
 cairo_int_status_t
@@ -152,8 +166,8 @@ _cairo_composite_rectangles_init_for_fill (cairo_composite_rectangles_t *extents
 					   int surface_width, int surface_height,
 					   cairo_operator_t		 op,
 					   const cairo_pattern_t	*source,
-					   cairo_path_fixed_t		*path,
-					   cairo_clip_t			*clip)
+					   const cairo_path_fixed_t		*path,
+					   const cairo_clip_t		*clip)
 {
     if (! _cairo_composite_rectangles_init (extents,
 					    surface_width, surface_height,
@@ -164,7 +178,7 @@ _cairo_composite_rectangles_init_for_fill (cairo_composite_rectangles_t *extents
 
     _cairo_path_fixed_approximate_fill_extents (path, &extents->mask);
 
-    return _cairo_composite_rectangles_intersect (extents);
+    return _cairo_composite_rectangles_intersect (extents, clip);
 }
 
 cairo_int_status_t
@@ -175,7 +189,7 @@ _cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *exten
 					     cairo_scaled_font_t	*scaled_font,
 					     cairo_glyph_t		*glyphs,
 					     int			 num_glyphs,
-					     cairo_clip_t		*clip,
+					     const cairo_clip_t		*clip,
 					     cairo_bool_t		*overlap)
 {
     cairo_status_t status;
@@ -194,5 +208,5 @@ _cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *exten
     if (unlikely (status))
 	return status;
 
-    return _cairo_composite_rectangles_intersect (extents);
+    return _cairo_composite_rectangles_intersect (extents, clip);
 }
diff --git a/src/cairo-debug.c b/src/cairo-debug.c
index 9b16de8..99289e3 100644
--- a/src/cairo-debug.c
+++ b/src/cairo-debug.c
@@ -35,7 +35,6 @@
 
 #include "cairoint.h"
 
-
 /**
  * cairo_debug_reset_static_data:
  *
@@ -234,8 +233,10 @@ void
 _cairo_debug_print_path (FILE *stream, cairo_path_fixed_t *path)
 {
     cairo_status_t status;
+    cairo_box_t box;
 
-    printf ("path: extents=(%f, %f), (%f, %f)\n",
+    fprintf (stream,
+	     "path: extents=(%f, %f), (%f, %f)\n",
 	    _cairo_fixed_to_double (path->extents.p1.x),
 	    _cairo_fixed_to_double (path->extents.p1.y),
 	    _cairo_fixed_to_double (path->extents.p2.x),
@@ -249,5 +250,37 @@ _cairo_debug_print_path (FILE *stream, cairo_path_fixed_t *path)
 					  stream);
     assert (status == CAIRO_STATUS_SUCCESS);
 
+    if (_cairo_path_fixed_is_box (path, &box)) {
+	fprintf (stream, "[box (%d, %d), (%d, %d)]",
+		 box.p1.x, box.p1.y, box.p2.x, box.p2.y);
+    }
+
     printf ("\n");
 }
+
+void
+_cairo_debug_print_polygon (FILE *stream, cairo_polygon_t *polygon)
+{
+    int n;
+
+    fprintf (stream,
+	     "polygon: extents=(%f, %f), (%f, %f)\n",
+	    _cairo_fixed_to_double (polygon->extents.p1.x),
+	    _cairo_fixed_to_double (polygon->extents.p1.y),
+	    _cairo_fixed_to_double (polygon->extents.p2.x),
+	    _cairo_fixed_to_double (polygon->extents.p2.y));
+    for (n = 0; n < polygon->num_edges; n++) {
+	cairo_edge_t *edge = &polygon->edges[n];
+
+	fprintf (stream,
+		 "  (%f, %f) -> (%f, %f), top=%f, bottom=%f, dir=%d\n",
+		 _cairo_fixed_to_double (edge->line.p1.x),
+		 _cairo_fixed_to_double (edge->line.p1.y),
+		 _cairo_fixed_to_double (edge->line.p2.x),
+		 _cairo_fixed_to_double (edge->line.p2.y),
+		 _cairo_fixed_to_double (edge->top),
+		 _cairo_fixed_to_double (edge->bottom),
+		 edge->dir);
+
+    }
+}
diff --git a/src/cairo-default-context.c b/src/cairo-default-context.c
index cec8016..1798e5c 100644
--- a/src/cairo-default-context.c
+++ b/src/cairo-default-context.c
@@ -131,7 +131,7 @@ _cairo_default_context_push_group (void *abstract_cr, cairo_content_t content)
     cairo_status_t status;
 
     clip = _cairo_gstate_get_clip (cr->gstate);
-    if (clip->all_clipped) {
+    if (_cairo_clip_is_all_clipped (clip)) {
 	group_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
 	status = group_surface->status;
 	if (unlikely (status))
@@ -276,7 +276,8 @@ _cairo_default_context_set_source_rgba (void *abstract_cr, double red, double gr
     cairo_pattern_t *pattern;
     cairo_status_t status;
 
-    if (_current_source_matches_solid (cr->gstate->source, red, green, blue, 1.))
+    if (_current_source_matches_solid (cr->gstate->source,
+				       red, green, blue, alpha))
 	return CAIRO_STATUS_SUCCESS;
 
     /* push the current pattern to the freed lists */
diff --git a/src/cairo-error-private.h b/src/cairo-error-private.h
index fc0c564..953e8af 100644
--- a/src/cairo-error-private.h
+++ b/src/cairo-error-private.h
@@ -43,9 +43,63 @@
 
 CAIRO_BEGIN_DECLS
 
+enum _cairo_int_status {
+    CAIRO_INT_STATUS_SUCCESS = 0,
+
+    CAIRO_INT_STATUS_NO_MEMORY,
+    CAIRO_INT_STATUS_INVALID_RESTORE,
+    CAIRO_INT_STATUS_INVALID_POP_GROUP,
+    CAIRO_INT_STATUS_NO_CURRENT_POINT,
+    CAIRO_INT_STATUS_INVALID_MATRIX,
+    CAIRO_INT_STATUS_INVALID_STATUS,
+    CAIRO_INT_STATUS_NULL_POINTER,
+    CAIRO_INT_STATUS_INVALID_STRING,
+    CAIRO_INT_STATUS_INVALID_PATH_DATA,
+    CAIRO_INT_STATUS_READ_ERROR,
+    CAIRO_INT_STATUS_WRITE_ERROR,
+    CAIRO_INT_STATUS_SURFACE_FINISHED,
+    CAIRO_INT_STATUS_SURFACE_TYPE_MISMATCH,
+    CAIRO_INT_STATUS_PATTERN_TYPE_MISMATCH,
+    CAIRO_INT_STATUS_INVALID_CONTENT,
+    CAIRO_INT_STATUS_INVALID_FORMAT,
+    CAIRO_INT_STATUS_INVALID_VISUAL,
+    CAIRO_INT_STATUS_FILE_NOT_FOUND,
+    CAIRO_INT_STATUS_INVALID_DASH,
+    CAIRO_INT_STATUS_INVALID_DSC_COMMENT,
+    CAIRO_INT_STATUS_INVALID_INDEX,
+    CAIRO_INT_STATUS_CLIP_NOT_REPRESENTABLE,
+    CAIRO_INT_STATUS_TEMP_FILE_ERROR,
+    CAIRO_INT_STATUS_INVALID_STRIDE,
+    CAIRO_INT_STATUS_FONT_TYPE_MISMATCH,
+    CAIRO_INT_STATUS_USER_FONT_IMMUTABLE,
+    CAIRO_INT_STATUS_USER_FONT_ERROR,
+    CAIRO_INT_STATUS_NEGATIVE_COUNT,
+    CAIRO_INT_STATUS_INVALID_CLUSTERS,
+    CAIRO_INT_STATUS_INVALID_SLANT,
+    CAIRO_INT_STATUS_INVALID_WEIGHT,
+    CAIRO_INT_STATUS_INVALID_SIZE,
+    CAIRO_INT_STATUS_USER_FONT_NOT_IMPLEMENTED,
+    CAIRO_INT_STATUS_DEVICE_TYPE_MISMATCH,
+    CAIRO_INT_STATUS_DEVICE_ERROR,
+    CAIRO_INT_STATUS_INVALID_MESH_CONSTRUCTION,
+    CAIRO_INT_STATUS_DEVICE_FINISHED,
+
+    CAIRO_INT_STATUS_LAST_STATUS,
+
+    CAIRO_INT_STATUS_UNSUPPORTED = 100,
+    CAIRO_INT_STATUS_DEGENERATE,
+    CAIRO_INT_STATUS_NOTHING_TO_DO,
+    CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY,
+    CAIRO_INT_STATUS_IMAGE_FALLBACK,
+    CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN,
+};
+
 #define _cairo_status_is_error(status) \
     (status != CAIRO_STATUS_SUCCESS && status <= CAIRO_STATUS_LAST_STATUS)
 
+#define _cairo_int_status_is_error(status) \
+    (status != CAIRO_INT_STATUS_SUCCESS && status <= CAIRO_INT_STATUS_LAST_STATUS)
+
 cairo_private cairo_status_t
 _cairo_error (cairo_status_t status);
 
diff --git a/src/cairo-error.c b/src/cairo-error.c
index a3fc197..1b9bd76 100644
--- a/src/cairo-error.c
+++ b/src/cairo-error.c
@@ -39,7 +39,9 @@
 #include "cairoint.h"
 #include "cairo-private.h"
 
+#include "cairo-compiler-private.h"
 #include "cairo-error-private.h"
+
 #include <assert.h>
 
 /**
@@ -67,3 +69,5 @@ _cairo_error (cairo_status_t status)
 
     return status;
 }
+
+COMPILE_TIME_ASSERT ((int)CAIRO_INT_STATUS_LAST_STATUS == (int)CAIRO_STATUS_LAST_STATUS);
diff --git a/src/cairo-fixed-private.h b/src/cairo-fixed-private.h
index 6cecc8d..9a16a03 100644
--- a/src/cairo-fixed-private.h
+++ b/src/cairo-fixed-private.h
@@ -164,6 +164,12 @@ _cairo_fixed_floor (cairo_fixed_t f)
 }
 
 static inline cairo_fixed_t
+_cairo_fixed_ceil (cairo_fixed_t f)
+{
+    return _cairo_fixed_floor (f + CAIRO_FIXED_FRAC_MASK);
+}
+
+static inline cairo_fixed_t
 _cairo_fixed_round (cairo_fixed_t f)
 {
     return _cairo_fixed_floor (f + (CAIRO_FIXED_FRAC_MASK+1)/2);
diff --git a/src/cairo-font-face-twin.c b/src/cairo-font-face-twin.c
index 98c6dd8..2ad2630 100644
--- a/src/cairo-font-face-twin.c
+++ b/src/cairo-font-face-twin.c
@@ -283,16 +283,14 @@ face_props_parse (twin_face_properties_t *props,
 	    parse_field (props, start, end - start);
 }
 
-static cairo_status_t
-twin_font_face_create_properties (cairo_font_face_t *twin_face,
-				  twin_face_properties_t **props_out)
+static twin_face_properties_t *
+twin_font_face_create_properties (cairo_font_face_t *twin_face)
 {
     twin_face_properties_t *props;
-    cairo_status_t status;
 
     props = malloc (sizeof (twin_face_properties_t));
     if (unlikely (props == NULL))
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	return NULL;
 
     props->stretch  = TWIN_STRETCH_NORMAL;
     props->slant = CAIRO_FONT_SLANT_NORMAL;
@@ -300,30 +298,25 @@ twin_font_face_create_properties (cairo_font_face_t *twin_face,
     props->monospace = FALSE;
     props->smallcaps = FALSE;
 
-    status = cairo_font_face_set_user_data (twin_face,
+    if (unlikely (cairo_font_face_set_user_data (twin_face,
 					    &twin_properties_key,
-					    props, free);
-    if (unlikely (status)) {
+					    props, free))) {
 	free (props);
-	return status;
+	return NULL;
     }
 
-    if (props_out)
-	*props_out = props;
-
-    return CAIRO_STATUS_SUCCESS;
+    return props;
 }
 
 static cairo_status_t
 twin_font_face_set_properties_from_toy (cairo_font_face_t *twin_face,
 					cairo_toy_font_face_t *toy_face)
 {
-    cairo_status_t status;
     twin_face_properties_t *props;
 
-    status = twin_font_face_create_properties (twin_face, &props);
-    if (unlikely (status))
-	return status;
+    props = twin_font_face_create_properties (twin_face);
+    if (unlikely (props == NULL))
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     props->slant = toy_face->slant;
     props->weight = toy_face->weight == CAIRO_FONT_WEIGHT_NORMAL ?
@@ -729,11 +722,9 @@ cairo_font_face_t *
 _cairo_font_face_twin_create_fallback (void)
 {
     cairo_font_face_t *twin_font_face;
-    cairo_status_t status;
 
     twin_font_face = _cairo_font_face_twin_create_internal ();
-    status = twin_font_face_create_properties (twin_font_face, NULL);
-    if (status) {
+    if (! twin_font_face_create_properties (twin_font_face)) {
 	cairo_font_face_destroy (twin_font_face);
 	return (cairo_font_face_t *) &_cairo_font_face_nil;
     }
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 6389200..ff737a3 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -2573,27 +2573,28 @@ static const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend = {
 /* #cairo_ft_font_face_t */
 
 #if CAIRO_HAS_FC_FONT
-static cairo_status_t
-_cairo_ft_font_face_create_for_pattern (FcPattern *pattern,
-					cairo_font_face_t **out);
+static cairo_font_face_t *
+_cairo_ft_font_face_create_for_pattern (FcPattern *pattern);
 
 static cairo_status_t
-_cairo_ft_font_face_create_for_toy (cairo_toy_font_face_t   *toy_face,
-				    cairo_font_face_t      **font_face)
+_cairo_ft_font_face_create_for_toy (cairo_toy_font_face_t *toy_face,
+				    cairo_font_face_t **font_face_out)
 {
+    cairo_font_face_t *font_face = (cairo_font_face_t *) &_cairo_font_face_nil;
     FcPattern *pattern;
     int fcslant;
     int fcweight;
-    cairo_status_t status = CAIRO_STATUS_SUCCESS;
 
     pattern = FcPatternCreate ();
-    if (!pattern)
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    if (!pattern) {
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+	return font_face->status;
+    }
 
     if (!FcPatternAddString (pattern,
 		             FC_FAMILY, (unsigned char *) toy_face->family))
     {
-	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	goto FREE_PATTERN;
     }
 
@@ -2612,7 +2613,7 @@ _cairo_ft_font_face_create_for_toy (cairo_toy_font_face_t   *toy_face,
     }
 
     if (!FcPatternAddInteger (pattern, FC_SLANT, fcslant)) {
-	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	goto FREE_PATTERN;
     }
 
@@ -2628,16 +2629,17 @@ _cairo_ft_font_face_create_for_toy (cairo_toy_font_face_t   *toy_face,
     }
 
     if (!FcPatternAddInteger (pattern, FC_WEIGHT, fcweight)) {
-	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	goto FREE_PATTERN;
     }
 
-    status = _cairo_ft_font_face_create_for_pattern (pattern, font_face);
+    font_face = _cairo_ft_font_face_create_for_pattern (pattern);
 
  FREE_PATTERN:
     FcPatternDestroy (pattern);
 
-    return status;
+    *font_face_out = font_face;
+    return font_face->status;
 }
 #endif
 
@@ -2776,15 +2778,16 @@ const cairo_font_face_backend_t _cairo_ft_font_face_backend = {
 };
 
 #if CAIRO_HAS_FC_FONT
-static cairo_status_t
-_cairo_ft_font_face_create_for_pattern (FcPattern *pattern,
-					cairo_font_face_t **out)
+static cairo_font_face_t *
+_cairo_ft_font_face_create_for_pattern (FcPattern *pattern)
 {
     cairo_ft_font_face_t *font_face;
 
     font_face = malloc (sizeof (cairo_ft_font_face_t));
-    if (unlikely (font_face == NULL))
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    if (unlikely (font_face == NULL)) {
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+	return (cairo_font_face_t *) &_cairo_font_face_nil;
+    }
 
     font_face->unscaled = NULL;
     font_face->next = NULL;
@@ -2792,7 +2795,8 @@ _cairo_ft_font_face_create_for_pattern (FcPattern *pattern,
     font_face->pattern = FcPatternDuplicate (pattern);
     if (unlikely (font_face->pattern == NULL)) {
 	free (font_face);
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+	return (cairo_font_face_t *) &_cairo_font_face_nil;
     }
 
     font_face->resolved_font_face = NULL;
@@ -2800,8 +2804,7 @@ _cairo_ft_font_face_create_for_pattern (FcPattern *pattern,
 
     _cairo_font_face_init (&font_face->base, &_cairo_ft_font_face_backend);
 
-    *out = &font_face->base;
-    return CAIRO_STATUS_SUCCESS;
+    return &font_face->base;
 }
 #endif
 
@@ -3156,12 +3159,7 @@ cairo_ft_font_face_create_for_pattern (FcPattern *pattern)
     if (unlikely (unscaled == NULL)) {
 	/* Store the pattern.  We will resolve it and create unscaled
 	 * font when creating scaled fonts */
-	status = _cairo_ft_font_face_create_for_pattern (pattern,
-							 &font_face);
-	if (unlikely (status))
-	    return (cairo_font_face_t *) &_cairo_font_face_nil;
-
-	return font_face;
+	return _cairo_ft_font_face_create_for_pattern (pattern);
     }
 
     _get_pattern_ft_options (pattern, &ft_options);
diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
index f09cf41..81efbbb 100644
--- a/src/cairo-gl-glyphs.c
+++ b/src/cairo-gl-glyphs.c
@@ -40,6 +40,7 @@
 
 #include "cairo-gl-private.h"
 
+#include "cairo-composite-rectangles-private.h"
 #include "cairo-error-private.h"
 #include "cairo-rtree-private.h"
 
@@ -54,7 +55,7 @@ typedef struct _cairo_gl_glyph_private {
     struct { float x, y; } p1, p2;
 } cairo_gl_glyph_private_t;
 
-static cairo_status_t
+static cairo_int_status_t
 _cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
 				 cairo_gl_glyph_cache_t *cache,
 				 cairo_scaled_glyph_t  *scaled_glyph)
@@ -63,7 +64,7 @@ _cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
     cairo_gl_surface_t *cache_surface;
     cairo_gl_glyph_private_t *glyph_private;
     cairo_rtree_node_t *node = NULL;
-    cairo_status_t status;
+    cairo_int_status_t status;
     int width, height;
 
     width = glyph_surface->width;
@@ -79,7 +80,7 @@ _cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
     if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
 	status = _cairo_rtree_evict_random (&cache->rtree,
 				            width, height, &node);
-	if (status == CAIRO_STATUS_SUCCESS) {
+	if (status == CAIRO_INT_STATUS_SUCCESS) {
 	    status = _cairo_rtree_node_insert (&cache->rtree,
 		                               node, width, height, &node);
 	}
@@ -148,6 +149,7 @@ cairo_gl_context_get_glyph_cache (cairo_gl_context_t *ctx,
 	cache = &ctx->glyph_cache[1];
         content = CAIRO_CONTENT_ALPHA;
 	break;
+    default:
     case CAIRO_FORMAT_INVALID:
 	ASSERT_NOT_REACHED;
 	return _cairo_error (CAIRO_STATUS_INVALID_FORMAT);
@@ -227,10 +229,9 @@ _render_glyphs (cairo_gl_surface_t	*dst,
 		const cairo_pattern_t	*source,
 		cairo_glyph_t		*glyphs,
 		int			 num_glyphs,
-		const cairo_rectangle_int_t *glyph_extents,
 		cairo_scaled_font_t	*scaled_font,
+		const cairo_composite_rectangles_t *extents,
 		cairo_bool_t		*has_component_alpha,
-		cairo_region_t		*clip_region,
 		int			*remaining_glyphs)
 {
     cairo_format_t last_format = CAIRO_FORMAT_INVALID;
@@ -249,7 +250,7 @@ _render_glyphs (cairo_gl_surface_t	*dst,
     _cairo_scaled_font_freeze_cache (scaled_font);
 
     status = _cairo_gl_composite_init (&setup, op, dst,
-                                       TRUE, glyph_extents);
+                                       TRUE, &extents->bounded);
 
     if (unlikely (status))
 	goto FINISH;
@@ -260,10 +261,11 @@ _render_glyphs (cairo_gl_surface_t	*dst,
     }
 
     status = _cairo_gl_composite_set_source (&setup, source,
-                                             glyph_extents->x, glyph_extents->y,
+                                             extents->bounded.x,
+					     extents->bounded.y,
                                              dst_x, dst_y,
-                                             glyph_extents->width,
-                                             glyph_extents->height);
+                                             extents->bounded.width,
+                                             extents->bounded.height);
     if (unlikely (status))
 	goto FINISH;
 
@@ -273,7 +275,8 @@ _render_glyphs (cairo_gl_surface_t	*dst,
 	cairo_list_add (&scaled_font->link, &ctx->fonts);
     }
 
-    _cairo_gl_composite_set_clip_region (&setup, clip_region);
+    _cairo_gl_composite_set_clip_region (&setup,
+					 _cairo_clip_get_region (extents->clip));
 
     for (i = 0; i < num_glyphs; i++) {
 	cairo_scaled_glyph_t *scaled_glyph;
@@ -374,35 +377,41 @@ _cairo_gl_surface_show_glyphs_via_mask (cairo_gl_surface_t	*dst,
 					const cairo_pattern_t	*source,
 					cairo_glyph_t		*glyphs,
 					int			 num_glyphs,
-					const cairo_rectangle_int_t *glyph_extents,
 					cairo_scaled_font_t	*scaled_font,
-					cairo_clip_t		*clip,
+					cairo_composite_rectangles_t *extents,
 					int			*remaining_glyphs)
 {
     cairo_surface_t *mask;
     cairo_status_t status;
     cairo_bool_t has_component_alpha;
+    cairo_clip_t *saved_clip;
     int i;
 
     /* XXX: For non-CA, this should be CAIRO_CONTENT_ALPHA to save memory */
     mask = cairo_gl_surface_create (dst->base.device,
                                     CAIRO_CONTENT_COLOR_ALPHA,
-                                    glyph_extents->width,
-                                    glyph_extents->height);
+                                    extents->bounded.width,
+                                    extents->bounded.height);
     if (unlikely (mask->status))
         return mask->status;
 
     for (i = 0; i < num_glyphs; i++) {
-	glyphs[i].x -= glyph_extents->x;
-	glyphs[i].y -= glyph_extents->y;
+	glyphs[i].x -= extents->bounded.x;
+	glyphs[i].y -= extents->bounded.y;
     }
 
+
+    saved_clip = extents->clip;
+    extents->clip = NULL;
     status = _render_glyphs ((cairo_gl_surface_t *) mask, 0, 0,
 	                     CAIRO_OPERATOR_ADD,
 			     &_cairo_pattern_white.base,
-	                     glyphs, num_glyphs, glyph_extents,
-			     scaled_font, &has_component_alpha,
-			     NULL, remaining_glyphs);
+	                     glyphs, num_glyphs, scaled_font,
+			     extents,
+			     &has_component_alpha,
+			     remaining_glyphs);
+    extents->clip = saved_clip;
+
     if (likely (status == CAIRO_STATUS_SUCCESS)) {
 	cairo_surface_pattern_t mask_pattern;
 
@@ -410,14 +419,15 @@ _cairo_gl_surface_show_glyphs_via_mask (cairo_gl_surface_t	*dst,
 	_cairo_pattern_init_for_surface (&mask_pattern, mask);
 	mask_pattern.base.has_component_alpha = has_component_alpha;
 	cairo_matrix_init_translate (&mask_pattern.base.matrix,
-		                     -glyph_extents->x, -glyph_extents->y);
+		                     -extents->bounded.x, -extents->bounded.y);
 	status = _cairo_surface_mask (&dst->base, op,
-		                      source, &mask_pattern.base, clip);
+		                      source, &mask_pattern.base,
+				      extents->clip);
 	_cairo_pattern_fini (&mask_pattern.base);
     } else {
 	for (i = 0; i < num_glyphs; i++) {
-	    glyphs[i].x += glyph_extents->x;
-	    glyphs[i].y += glyph_extents->y;
+	    glyphs[i].x += extents->bounded.x;
+	    glyphs[i].y += extents->bounded.y;
 	}
 	*remaining_glyphs = num_glyphs;
     }
@@ -434,13 +444,11 @@ _cairo_gl_surface_show_glyphs (void			*abstract_dst,
 			       cairo_glyph_t		*glyphs,
 			       int			 num_glyphs,
 			       cairo_scaled_font_t	*scaled_font,
-			       cairo_clip_t		*clip,
+			       const cairo_clip_t	*clip,
 			       int			*remaining_glyphs)
 {
     cairo_gl_surface_t *dst = abstract_dst;
-    cairo_rectangle_int_t surface_extents;
-    cairo_rectangle_int_t extents;
-    cairo_region_t *clip_region = NULL;
+    cairo_composite_rectangles_t extents;
     cairo_bool_t overlap, use_mask = FALSE;
     cairo_bool_t has_component_alpha;
     cairo_status_t status;
@@ -526,60 +534,40 @@ _cairo_gl_surface_show_glyphs (void			*abstract_dst,
     if (! _cairo_gl_surface_owns_font (dst, scaled_font))
 	return UNSUPPORTED ("do not control font");
 
-    /* If the glyphs overlap, we need to build an intermediate mask rather
-     * then perform the compositing directly.
-     */
-    status = _cairo_scaled_font_glyph_device_extents (scaled_font,
-						      glyphs, num_glyphs,
-						      &extents,
-						      &overlap);
+    status = _cairo_composite_rectangles_init_for_glyphs (&extents,
+							  dst->width,
+							  dst->height,
+							  op, source,
+							  scaled_font,
+							  glyphs, num_glyphs,
+							  clip, &overlap);
     if (unlikely (status))
 	return status;
 
+    /* If the glyphs overlap, we need to build an intermediate mask rather
+     * then perform the compositing directly.
+     */
     use_mask |= overlap;
-
-    if (clip != NULL) {
-	status = _cairo_clip_get_region (clip, &clip_region);
-	/* the empty clip should never be propagated this far */
-	assert (status != CAIRO_INT_STATUS_NOTHING_TO_DO);
-	if (unlikely (_cairo_status_is_error (status)))
-	    return status;
-
-	use_mask |= status == CAIRO_INT_STATUS_UNSUPPORTED;
-
-	if (! _cairo_rectangle_intersect (&extents,
-		                          _cairo_clip_get_extents (clip)))
-	    goto EMPTY;
-    }
-
-    surface_extents.x = surface_extents.y = 0;
-    surface_extents.width = dst->width;
-    surface_extents.height = dst->height;
-    if (! _cairo_rectangle_intersect (&extents, &surface_extents))
-	goto EMPTY;
+    use_mask |= ! _cairo_clip_is_region (extents.clip);
 
     if (use_mask) {
-	return _cairo_gl_surface_show_glyphs_via_mask (dst, op,
-			                               source,
-			                               glyphs, num_glyphs,
-						       &extents,
-						       scaled_font,
-						       clip,
-						       remaining_glyphs);
+	status = _cairo_gl_surface_show_glyphs_via_mask (dst, op,
+							 source,
+							 glyphs, num_glyphs,
+							 scaled_font,
+							 &extents,
+							 remaining_glyphs);
+    } else {
+	status = _render_glyphs (dst, extents.bounded.x, extents.bounded.y,
+				 op, source,
+				 glyphs, num_glyphs, scaled_font,
+				 &extents,
+				 &has_component_alpha,
+				 remaining_glyphs);
     }
 
-    return _render_glyphs (dst, extents.x, extents.y,
-	                   op, source,
-			   glyphs, num_glyphs, &extents,
-			   scaled_font, &has_component_alpha,
-			   clip_region, remaining_glyphs);
-
-EMPTY:
-    *remaining_glyphs = 0;
-    if (! _cairo_operator_bounded_by_mask (op))
-	return _cairo_surface_paint (&dst->base, op, source, clip);
-    else
-	return CAIRO_STATUS_SUCCESS;
+    _cairo_composite_rectangles_fini (&extents);
+    return status;
 }
 
 void
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index edd1355..c83d78f 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -501,7 +501,7 @@ _cairo_gl_surface_show_glyphs (void			*abstract_dst,
 			       cairo_glyph_t		*glyphs,
 			       int			 num_glyphs,
 			       cairo_scaled_font_t	*scaled_font,
-			       cairo_clip_t		*clip,
+			       const cairo_clip_t	*clip,
 			       int			*remaining_glyphs);
 
 static inline int
diff --git a/src/cairo-gl-surface-legacy.c b/src/cairo-gl-surface-legacy.c
new file mode 100644
index 0000000..0ba356e
--- /dev/null
+++ b/src/cairo-gl-surface-legacy.c
@@ -0,0 +1,601 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2009 Eric Anholt
+ * Copyright © 2009 Chris Wilson
+ * Copyright © 2005,2010 Red Hat, Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Red Hat, Inc.
+ *
+ * Contributor(s):
+ *	Benjamin Otte <otte at gnome.org>
+ *	Carl Worth <cworth at cworth.org>
+ *	Chris Wilson <chris at chris-wilson.co.uk>
+ *	Eric Anholt <eric at anholt.net>
+ */
+
+#include "cairoint.h"
+
+#include "cairo-composite-rectangles-private.h"
+#include "cairo-default-context-private.h"
+#include "cairo-error-private.h"
+#include "cairo-gl-private.h"
+
+cairo_status_t
+_cairo_gl_surface_acquire_dest_image (void		      *abstract_surface,
+				      cairo_rectangle_int_t   *interest_rect,
+				      cairo_image_surface_t  **image_out,
+				      cairo_rectangle_int_t   *image_rect_out,
+				      void		     **image_extra)
+{
+    cairo_gl_surface_t *surface = abstract_surface;
+    cairo_int_status_t status;
+
+    status = _cairo_gl_surface_deferred_clear (surface);
+    if (unlikely (status))
+	return status;
+
+    *image_extra = NULL;
+    return _cairo_gl_surface_get_image (surface, interest_rect, image_out,
+					image_rect_out);
+}
+
+void
+_cairo_gl_surface_release_dest_image (void		      *abstract_surface,
+				      cairo_rectangle_int_t   *interest_rect,
+				      cairo_image_surface_t   *image,
+				      cairo_rectangle_int_t   *image_rect,
+				      void		      *image_extra)
+{
+    cairo_status_t status;
+
+    status = _cairo_gl_surface_draw_image (abstract_surface, image,
+					   0, 0,
+					   image->width, image->height,
+					   image_rect->x, image_rect->y);
+    /* as we created the image, its format should be directly applicable */
+    assert (status == CAIRO_STATUS_SUCCESS);
+
+    cairo_surface_destroy (&image->base);
+}
+
+cairo_status_t
+_cairo_gl_surface_clone_similar (void		     *abstract_surface,
+				 cairo_surface_t     *src,
+				 int                  src_x,
+				 int                  src_y,
+				 int                  width,
+				 int                  height,
+				 int                 *clone_offset_x,
+				 int                 *clone_offset_y,
+				 cairo_surface_t    **clone_out)
+{
+    cairo_gl_surface_t *surface = abstract_surface;
+    cairo_int_status_t status;
+
+    /* XXX: Use GLCopyTexImage2D to clone non-texture-surfaces */
+    if (src->device == surface->base.device &&
+        _cairo_gl_surface_is_texture ((cairo_gl_surface_t *) src)) {
+	status = _cairo_gl_surface_deferred_clear ((cairo_gl_surface_t *)src);
+	if (unlikely (status))
+	    return status;
+
+	*clone_offset_x = 0;
+	*clone_offset_y = 0;
+	*clone_out = cairo_surface_reference (src);
+
+	return CAIRO_STATUS_SUCCESS;
+    } else if (_cairo_surface_is_image (src)) {
+	cairo_image_surface_t *image_src = (cairo_image_surface_t *)src;
+	cairo_gl_surface_t *clone;
+
+	clone = (cairo_gl_surface_t *)
+		_cairo_gl_surface_create_similar (&surface->base,
+						  src->content,
+						  width, height);
+	if (clone == NULL)
+	    return UNSUPPORTED ("create_similar failed");
+	if (clone->base.status)
+	    return clone->base.status;
+
+	status = _cairo_gl_surface_draw_image (clone, image_src,
+					       src_x, src_y,
+					       width, height,
+					       0, 0);
+	if (status) {
+	    cairo_surface_destroy (&clone->base);
+	    return status;
+	}
+
+	*clone_out = &clone->base;
+	*clone_offset_x = src_x;
+	*clone_offset_y = src_y;
+
+	return CAIRO_STATUS_SUCCESS;
+    }
+
+    return UNSUPPORTED ("unknown src surface type in clone_similar");
+}
+
+/** Creates a cairo-gl pattern surface for the given trapezoids */
+static cairo_status_t
+_cairo_gl_get_traps_pattern (cairo_gl_surface_t *dst,
+			     int dst_x, int dst_y,
+			     int width, int height,
+			     cairo_trapezoid_t *traps,
+			     int num_traps,
+			     cairo_antialias_t antialias,
+			     cairo_surface_pattern_t *pattern)
+{
+    pixman_format_code_t pixman_format;
+    pixman_image_t *image;
+    cairo_surface_t *surface;
+    int i;
+
+    pixman_format = antialias != CAIRO_ANTIALIAS_NONE ? PIXMAN_a8 : PIXMAN_a1,
+    image = pixman_image_create_bits (pixman_format, width, height, NULL, 0);
+    if (unlikely (image == NULL))
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    for (i = 0; i < num_traps; i++) {
+	pixman_trapezoid_t trap;
+
+	trap.top = _cairo_fixed_to_16_16 (traps[i].top);
+	trap.bottom = _cairo_fixed_to_16_16 (traps[i].bottom);
+
+	trap.left.p1.x = _cairo_fixed_to_16_16 (traps[i].left.p1.x);
+	trap.left.p1.y = _cairo_fixed_to_16_16 (traps[i].left.p1.y);
+	trap.left.p2.x = _cairo_fixed_to_16_16 (traps[i].left.p2.x);
+	trap.left.p2.y = _cairo_fixed_to_16_16 (traps[i].left.p2.y);
+
+	trap.right.p1.x = _cairo_fixed_to_16_16 (traps[i].right.p1.x);
+	trap.right.p1.y = _cairo_fixed_to_16_16 (traps[i].right.p1.y);
+	trap.right.p2.x = _cairo_fixed_to_16_16 (traps[i].right.p2.x);
+	trap.right.p2.y = _cairo_fixed_to_16_16 (traps[i].right.p2.y);
+
+	pixman_rasterize_trapezoid (image, &trap, -dst_x, -dst_y);
+    }
+
+    surface = _cairo_image_surface_create_for_pixman_image (image,
+							    pixman_format);
+    if (unlikely (surface->status)) {
+	pixman_image_unref (image);
+	return surface->status;
+    }
+
+    _cairo_pattern_init_for_surface (pattern, surface);
+    cairo_surface_destroy (surface);
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_int_status_t
+_cairo_gl_surface_composite (cairo_operator_t		  op,
+			     const cairo_pattern_t	 *src,
+			     const cairo_pattern_t	 *mask,
+			     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_region_t		 *clip_region)
+{
+    cairo_gl_surface_t *dst = abstract_dst;
+    cairo_gl_context_t *ctx;
+    cairo_status_t status;
+    cairo_gl_composite_t setup;
+    cairo_rectangle_int_t rect = { dst_x, dst_y, width, height };
+    int dx, dy;
+
+    status = _cairo_gl_surface_deferred_clear (dst);
+    if (unlikely (status))
+	    return status;
+
+    if (op == CAIRO_OPERATOR_SOURCE &&
+        mask == NULL &&
+        src->type == CAIRO_PATTERN_TYPE_SURFACE &&
+        _cairo_surface_is_image (((cairo_surface_pattern_t *) src)->surface) &&
+        _cairo_matrix_is_integer_translation (&src->matrix, &dx, &dy)) {
+        cairo_image_surface_t *image = (cairo_image_surface_t *)
+            ((cairo_surface_pattern_t *) src)->surface;
+        dx += src_x;
+        dy += src_y;
+        if (dx >= 0 &&
+            dy >= 0 &&
+            dx + width <= (unsigned int) image->width &&
+            dy + height <= (unsigned int) image->height) {
+            status = _cairo_gl_surface_draw_image (dst, image,
+                                                   dx, dy,
+                                                   width, height,
+                                                   dst_x, dst_y);
+            if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+                return status;
+        }
+    }
+
+    status = _cairo_gl_composite_init (&setup, op, dst,
+                                       mask && mask->has_component_alpha,
+                                       &rect);
+    if (unlikely (status))
+        goto CLEANUP;
+
+    status = _cairo_gl_composite_set_source (&setup, src,
+                                             src_x, src_y,
+                                             dst_x, dst_y,
+                                             width, height);
+    if (unlikely (status))
+        goto CLEANUP;
+
+    status = _cairo_gl_composite_set_mask (&setup, mask,
+                                           mask_x, mask_y,
+                                           dst_x, dst_y,
+                                           width, height);
+    if (unlikely (status))
+        goto CLEANUP;
+
+    status = _cairo_gl_composite_begin (&setup, &ctx);
+    if (unlikely (status))
+	goto CLEANUP;
+
+    if (clip_region != NULL) {
+        int i, num_rectangles;
+
+        num_rectangles = cairo_region_num_rectangles (clip_region);
+
+	for (i = 0; i < num_rectangles; i++) {
+	    cairo_rectangle_int_t rect;
+
+	    cairo_region_get_rectangle (clip_region, i, &rect);
+            _cairo_gl_composite_emit_rect (ctx,
+                                           rect.x,              rect.y,
+                                           rect.x + rect.width, rect.y + rect.height,
+                                           0);
+	}
+    } else {
+        _cairo_gl_composite_emit_rect (ctx,
+                                       dst_x,         dst_y,
+                                       dst_x + width, dst_y + height,
+                                       0);
+    }
+
+    status = _cairo_gl_context_release (ctx, status);
+
+  CLEANUP:
+    _cairo_gl_composite_fini (&setup);
+
+    return status;
+}
+
+cairo_int_status_t
+_cairo_gl_surface_composite_trapezoids (cairo_operator_t op,
+					const cairo_pattern_t *pattern,
+					void *abstract_dst,
+					cairo_antialias_t antialias,
+					int src_x, int src_y,
+					int dst_x, int dst_y,
+					unsigned int width,
+					unsigned int height,
+					cairo_trapezoid_t *traps,
+					int num_traps,
+					cairo_region_t *clip_region)
+{
+    cairo_gl_surface_t *dst = abstract_dst;
+    cairo_surface_pattern_t traps_pattern;
+    cairo_int_status_t status;
+
+    if (! _cairo_gl_operator_is_supported (op))
+	return UNSUPPORTED ("unsupported operator");
+
+    status = _cairo_gl_surface_deferred_clear (dst);
+    if (unlikely (status))
+	    return status;
+
+    status = _cairo_gl_get_traps_pattern (dst,
+					  dst_x, dst_y, width, height,
+					  traps, num_traps, antialias,
+					  &traps_pattern);
+    if (unlikely (status))
+	return status;
+
+    status = _cairo_gl_surface_composite (op,
+					  pattern, &traps_pattern.base, dst,
+					  src_x, src_y,
+					  0, 0,
+					  dst_x, dst_y,
+					  width, height,
+					  clip_region);
+
+    _cairo_pattern_fini (&traps_pattern.base);
+
+    assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
+    return status;
+}
+
+cairo_int_status_t
+_cairo_gl_surface_fill_rectangles (void			   *abstract_dst,
+				   cairo_operator_t	    op,
+				   const cairo_color_t     *color,
+				   cairo_rectangle_int_t   *rects,
+				   int			    num_rects)
+{
+    cairo_gl_surface_t *dst = abstract_dst;
+    cairo_solid_pattern_t solid;
+    cairo_gl_context_t *ctx;
+    cairo_status_t status;
+    cairo_gl_composite_t setup;
+    int i;
+
+    status = _cairo_gl_surface_deferred_clear (dst);
+    if (unlikely (status))
+	    return status;
+
+    status = _cairo_gl_composite_init (&setup, op, dst,
+                                       FALSE,
+                                       /* XXX */ NULL);
+    if (unlikely (status))
+        goto CLEANUP;
+
+    _cairo_pattern_init_solid (&solid, color);
+    status = _cairo_gl_composite_set_source (&setup, &solid.base,
+                                             0, 0,
+                                             0, 0,
+                                             0, 0);
+    if (unlikely (status))
+        goto CLEANUP;
+
+    status = _cairo_gl_composite_set_mask (&setup, NULL,
+                                           0, 0,
+                                           0, 0,
+                                           0, 0);
+    if (unlikely (status))
+        goto CLEANUP;
+
+    status = _cairo_gl_composite_begin (&setup, &ctx);
+    if (unlikely (status))
+        goto CLEANUP;
+
+    for (i = 0; i < num_rects; i++) {
+        _cairo_gl_composite_emit_rect (ctx,
+                                       rects[i].x,
+                                       rects[i].y,
+                                       rects[i].x + rects[i].width,
+                                       rects[i].y + rects[i].height,
+                                       0);
+    }
+
+    status = _cairo_gl_context_release (ctx, status);
+
+  CLEANUP:
+    _cairo_gl_composite_fini (&setup);
+
+    return status;
+}
+
+typedef struct _cairo_gl_surface_span_renderer {
+    cairo_span_renderer_t base;
+
+    cairo_gl_composite_t setup;
+
+    int xmin, xmax;
+    int ymin, ymax;
+
+    cairo_gl_context_t *ctx;
+} cairo_gl_surface_span_renderer_t;
+
+static cairo_status_t
+_cairo_gl_render_bounded_spans (void *abstract_renderer,
+				int y, int height,
+				const cairo_half_open_span_t *spans,
+				unsigned num_spans)
+{
+    cairo_gl_surface_span_renderer_t *renderer = abstract_renderer;
+
+    if (num_spans == 0)
+	return CAIRO_STATUS_SUCCESS;
+
+    do {
+	if (spans[0].coverage) {
+            _cairo_gl_composite_emit_rect (renderer->ctx,
+                                           spans[0].x, y,
+                                           spans[1].x, y + height,
+                                           spans[0].coverage);
+	}
+
+	spans++;
+    } while (--num_spans > 1);
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_cairo_gl_render_unbounded_spans (void *abstract_renderer,
+				  int y, int height,
+				  const cairo_half_open_span_t *spans,
+				  unsigned num_spans)
+{
+    cairo_gl_surface_span_renderer_t *renderer = abstract_renderer;
+
+    if (y > renderer->ymin) {
+        _cairo_gl_composite_emit_rect (renderer->ctx,
+                                       renderer->xmin, renderer->ymin,
+                                       renderer->xmax, y,
+                                       0);
+    }
+
+    if (num_spans == 0) {
+        _cairo_gl_composite_emit_rect (renderer->ctx,
+                                       renderer->xmin, y,
+                                       renderer->xmax, y + height,
+                                       0);
+    } else {
+        if (spans[0].x != renderer->xmin) {
+            _cairo_gl_composite_emit_rect (renderer->ctx,
+                                           renderer->xmin, y,
+                                           spans[0].x,     y + height,
+                                           0);
+        }
+
+        do {
+            _cairo_gl_composite_emit_rect (renderer->ctx,
+                                           spans[0].x, y,
+                                           spans[1].x, y + height,
+                                           spans[0].coverage);
+            spans++;
+        } while (--num_spans > 1);
+
+        if (spans[0].x != renderer->xmax) {
+            _cairo_gl_composite_emit_rect (renderer->ctx,
+                                           spans[0].x,     y,
+                                           renderer->xmax, y + height,
+                                           0);
+        }
+    }
+
+    renderer->ymin = y + height;
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_cairo_gl_finish_unbounded_spans (void *abstract_renderer)
+{
+    cairo_gl_surface_span_renderer_t *renderer = abstract_renderer;
+
+    if (renderer->ymax > renderer->ymin) {
+        _cairo_gl_composite_emit_rect (renderer->ctx,
+                                       renderer->xmin, renderer->ymin,
+                                       renderer->xmax, renderer->ymax,
+                                       0);
+    }
+
+    return _cairo_gl_context_release (renderer->ctx, CAIRO_STATUS_SUCCESS);
+}
+
+static cairo_status_t
+_cairo_gl_finish_bounded_spans (void *abstract_renderer)
+{
+    cairo_gl_surface_span_renderer_t *renderer = abstract_renderer;
+
+    return _cairo_gl_context_release (renderer->ctx, CAIRO_STATUS_SUCCESS);
+}
+
+static void
+_cairo_gl_surface_span_renderer_destroy (void *abstract_renderer)
+{
+    cairo_gl_surface_span_renderer_t *renderer = abstract_renderer;
+
+    if (!renderer)
+	return;
+
+    _cairo_gl_composite_fini (&renderer->setup);
+
+    free (renderer);
+}
+
+cairo_bool_t
+_cairo_gl_surface_check_span_renderer (cairo_operator_t	       op,
+				       const cairo_pattern_t  *pattern,
+				       void		      *abstract_dst,
+				       cairo_antialias_t       antialias)
+{
+    if (! _cairo_gl_operator_is_supported (op))
+	return FALSE;
+
+    return TRUE;
+
+    (void) pattern;
+    (void) abstract_dst;
+    (void) antialias;
+}
+
+cairo_span_renderer_t *
+_cairo_gl_surface_create_span_renderer (cairo_operator_t	 op,
+					const cairo_pattern_t	*src,
+					void			*abstract_dst,
+					cairo_antialias_t	 antialias,
+					const cairo_composite_rectangles_t *rects)
+{
+    cairo_gl_surface_t *dst = abstract_dst;
+    cairo_gl_surface_span_renderer_t *renderer;
+    cairo_status_t status;
+    const cairo_rectangle_int_t *extents;
+
+    status = _cairo_gl_surface_deferred_clear (dst);
+    if (unlikely (status))
+	return _cairo_span_renderer_create_in_error (status);
+
+    renderer = calloc (1, sizeof (*renderer));
+    if (unlikely (renderer == NULL))
+	return _cairo_span_renderer_create_in_error (CAIRO_STATUS_NO_MEMORY);
+
+    renderer->base.destroy = _cairo_gl_surface_span_renderer_destroy;
+    if (rects->is_bounded) {
+	renderer->base.render_rows = _cairo_gl_render_bounded_spans;
+        renderer->base.finish =      _cairo_gl_finish_bounded_spans;
+	extents = &rects->bounded;
+    } else {
+	renderer->base.render_rows = _cairo_gl_render_unbounded_spans;
+        renderer->base.finish =      _cairo_gl_finish_unbounded_spans;
+	extents = &rects->unbounded;
+    }
+    renderer->xmin = extents->x;
+    renderer->xmax = extents->x + extents->width;
+    renderer->ymin = extents->y;
+    renderer->ymax = extents->y + extents->height;
+
+    status = _cairo_gl_composite_init (&renderer->setup,
+                                       op, dst,
+                                       FALSE, extents);
+    if (unlikely (status))
+        goto FAIL;
+
+    status = _cairo_gl_composite_set_source (&renderer->setup, src,
+                                             extents->x, extents->y,
+                                             extents->x, extents->y,
+                                             extents->width, extents->height);
+    if (unlikely (status))
+        goto FAIL;
+
+    _cairo_gl_composite_set_spans (&renderer->setup);
+    _cairo_gl_composite_set_clip_region (&renderer->setup,
+					 _cairo_clip_get_region (rects->clip));
+
+    status = _cairo_gl_composite_begin (&renderer->setup, &renderer->ctx);
+    if (unlikely (status))
+        goto FAIL;
+
+    return &renderer->base;
+
+FAIL:
+    _cairo_gl_composite_fini (&renderer->setup);
+    free (renderer);
+    return _cairo_span_renderer_create_in_error (status);
+}
+
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index eb317f0..1b001b6 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -745,7 +745,7 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
     cairo_image_surface_t *clone = NULL;
     cairo_gl_context_t *ctx;
     int cpp;
-    cairo_status_t status = CAIRO_STATUS_SUCCESS;
+    cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
 
     status = _cairo_gl_context_acquire (dst->base.device, &ctx);
     if (unlikely (status))
@@ -851,7 +851,7 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
 	}
     } else {
         cairo_surface_t *tmp;
-        
+
         tmp = _cairo_gl_surface_create_scratch (ctx,
                                                 dst->base.content,
                                                 width, height);
@@ -864,7 +864,7 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
                                                src_x, src_y,
                                                width, height,
                                                0, 0);
-        if (status == CAIRO_STATUS_SUCCESS) {
+        if (status == CAIRO_INT_STATUS_SUCCESS) {
             cairo_surface_pattern_t tmp_pattern;
 
             _cairo_pattern_init_for_surface (&tmp_pattern, tmp);
@@ -1212,7 +1212,7 @@ _cairo_gl_surface_composite (cairo_operator_t		  op,
 {
     cairo_gl_surface_t *dst = abstract_dst;
     cairo_gl_context_t *ctx;
-    cairo_status_t status;
+    cairo_int_status_t status;
     cairo_gl_composite_t setup;
     cairo_rectangle_int_t rect = { dst_x, dst_y, width, height };
     int dx, dy;
@@ -1634,7 +1634,7 @@ static cairo_int_status_t
 _cairo_gl_surface_paint (void *abstract_surface,
 			 cairo_operator_t	 op,
 			 const cairo_pattern_t *source,
-			 cairo_clip_t	    *clip)
+			 const cairo_clip_t    *clip)
 {
     /* simplify the common case of clearing the surface */
     if (clip == NULL) {
@@ -1658,22 +1658,12 @@ _cairo_gl_surface_polygon (cairo_gl_surface_t *dst,
                            cairo_polygon_t *polygon,
                            cairo_fill_rule_t fill_rule,
                            cairo_antialias_t antialias,
-                           const cairo_composite_rectangles_t *extents,
-                           cairo_clip_t *clip)
+                           const cairo_composite_rectangles_t *extents)
 {
-    cairo_status_t status;
-    cairo_region_t *clip_region = NULL;
+    cairo_region_t *clip_region = _cairo_clip_get_region (extents->clip);
 
-    if (clip != NULL) {
-	status = _cairo_clip_get_region (clip, &clip_region);
-	if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
-	    return CAIRO_STATUS_SUCCESS;
-	if (unlikely (_cairo_status_is_error (status)))
-	    return status;
-
-	if (status == CAIRO_INT_STATUS_UNSUPPORTED)
-            return UNSUPPORTED ("a clip surface would be required");
-    }
+    if (! _cairo_clip_is_region (extents->clip))
+	return UNSUPPORTED ("a clip surface would be required");
 
     if (! _cairo_surface_check_span_renderer (op, src, &dst->base, antialias))
         return UNSUPPORTED ("no span renderer");
@@ -1685,35 +1675,30 @@ _cairo_gl_surface_polygon (cairo_gl_surface_t *dst,
         src = &_cairo_pattern_white.base;
     }
 
-    status = _cairo_surface_composite_polygon (&dst->base,
-                                               op,
-                                               src,
-                                               fill_rule,
-                                               antialias,
-                                               extents,
-                                               polygon,
-                                               clip_region);
-    return status;
+    return _cairo_surface_composite_polygon (&dst->base,
+					     op,
+					     src,
+					     fill_rule,
+					     antialias,
+					     extents,
+					     polygon,
+					     clip_region);
 }
 
 static cairo_int_status_t
 _cairo_gl_surface_stroke (void			        *abstract_surface,
                           cairo_operator_t		 op,
                           const cairo_pattern_t	        *source,
-                          cairo_path_fixed_t		*path,
+                          const cairo_path_fixed_t		*path,
                           const cairo_stroke_style_t	*style,
                           const cairo_matrix_t	        *ctm,
                           const cairo_matrix_t	        *ctm_inverse,
                           double			 tolerance,
                           cairo_antialias_t		 antialias,
-                          cairo_clip_t		        *clip)
+                          const cairo_clip_t		        *clip)
 {
     cairo_gl_surface_t *surface = abstract_surface;
     cairo_composite_rectangles_t extents;
-    cairo_box_t boxes_stack[32], *clip_boxes = boxes_stack;
-    int num_boxes = ARRAY_LENGTH (boxes_stack);
-    cairo_clip_t local_clip;
-    cairo_bool_t have_clip = FALSE;
     cairo_polygon_t polygon;
     cairo_status_t status;
 
@@ -1726,24 +1711,7 @@ _cairo_gl_surface_stroke (void			        *abstract_surface,
     if (unlikely (status))
 	return status;
 
-    if (_cairo_clip_contains_extents (clip, &extents))
-	clip = NULL;
-
-    if (clip != NULL) {
-	clip = _cairo_clip_init_copy (&local_clip, clip);
-	have_clip = TRUE;
-    }
-
-    status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
-    if (unlikely (status)) {
-	if (have_clip)
-	    _cairo_clip_fini (&local_clip);
-
-	return status;
-    }
-
-    _cairo_polygon_init (&polygon, clip_boxes, num_boxes);
-
+    _cairo_polygon_init_with_clip (&polygon, extents.clip);
     status = _cairo_path_fixed_stroke_to_polygon (path,
                                                   style,
                                                   ctm, ctm_inverse,
@@ -1752,13 +1720,11 @@ _cairo_gl_surface_stroke (void			        *abstract_surface,
     if (likely (status == CAIRO_STATUS_SUCCESS)) {
         status = _cairo_gl_surface_polygon (surface, op, source, &polygon,
                                             CAIRO_FILL_RULE_WINDING, antialias,
-                                            &extents, clip);
+                                            &extents);
     }
-
     _cairo_polygon_fini (&polygon);
 
-    if (have_clip)
-	_cairo_clip_fini (&local_clip);
+    _cairo_composite_rectangles_fini (&extents);
 
     return status;
 }
@@ -1767,18 +1733,14 @@ static cairo_int_status_t
 _cairo_gl_surface_fill (void			*abstract_surface,
                         cairo_operator_t	 op,
                         const cairo_pattern_t	*source,
-                        cairo_path_fixed_t	*path,
+                        const cairo_path_fixed_t*path,
                         cairo_fill_rule_t	 fill_rule,
                         double			 tolerance,
                         cairo_antialias_t	 antialias,
-                        cairo_clip_t		*clip)
+                        const cairo_clip_t	*clip)
 {
     cairo_gl_surface_t *surface = abstract_surface;
     cairo_composite_rectangles_t extents;
-    cairo_box_t boxes_stack[32], *clip_boxes = boxes_stack;
-    cairo_clip_t local_clip;
-    cairo_bool_t have_clip = FALSE;
-    int num_boxes = ARRAY_LENGTH (boxes_stack);
     cairo_polygon_t polygon;
     cairo_status_t status;
 
@@ -1790,50 +1752,16 @@ _cairo_gl_surface_fill (void			*abstract_surface,
     if (unlikely (status))
 	return status;
 
-    if (_cairo_clip_contains_extents (clip, &extents))
-	clip = NULL;
-
-#if 0
-    if (extents.is_bounded && clip != NULL) {
-	cairo_clip_path_t *clip_path;
-
-	if (((clip_path = _clip_get_single_path (clip)) != NULL) &&
-	    _cairo_path_fixed_equal (&clip_path->path, path))
-	{
-	    clip = NULL;
-	}
-    }
-#endif
-
-    if (clip != NULL) {
-	clip = _cairo_clip_init_copy (&local_clip, clip);
-	have_clip = TRUE;
-    }
-
-    status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
-    if (unlikely (status)) {
-	if (have_clip)
-	    _cairo_clip_fini (&local_clip);
-
-	return status;
-    }
-
-    _cairo_polygon_init (&polygon, clip_boxes, num_boxes);
-
+    _cairo_polygon_init_with_clip (&polygon, extents.clip);
     status = _cairo_path_fixed_fill_to_polygon (path, tolerance, &polygon);
     if (likely (status == CAIRO_STATUS_SUCCESS)) {
         status = _cairo_gl_surface_polygon (surface, op, source, &polygon,
                                             fill_rule, antialias,
-                                            &extents, clip);
+                                            &extents);
     }
-
     _cairo_polygon_fini (&polygon);
 
-    if (clip_boxes != boxes_stack)
-	free (clip_boxes);
-
-    if (have_clip)
-	_cairo_clip_fini (&local_clip);
+    _cairo_composite_rectangles_fini (&extents);
 
     return status;
 }
diff --git a/src/cairo-gstate-private.h b/src/cairo-gstate-private.h
index 9e823fa..38f11c7 100644
--- a/src/cairo-gstate-private.h
+++ b/src/cairo-gstate-private.h
@@ -55,7 +55,7 @@ struct _cairo_gstate {
     cairo_matrix_t font_matrix;
     cairo_font_options_t font_options;
 
-    cairo_clip_t clip;
+    cairo_clip_t *clip;
 
     cairo_surface_t *target;		/* The target to which all rendering is directed */
     cairo_surface_t *parent_target;	/* The previous target which was receiving rendering */
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index a7eced6..b6252de 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -111,7 +111,7 @@ _cairo_gstate_init (cairo_gstate_t  *gstate,
 
     _cairo_font_options_init_default (&gstate->font_options);
 
-    _cairo_clip_init (&gstate->clip);
+    gstate->clip = NULL;
 
     gstate->target = cairo_surface_reference (target);
     gstate->parent_target = NULL;
@@ -169,7 +169,7 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other)
 
     _cairo_font_options_init_copy (&gstate->font_options , &other->font_options);
 
-    _cairo_clip_init_copy (&gstate->clip, &other->clip);
+    gstate->clip = _cairo_clip_copy (other->clip);
 
     gstate->target = cairo_surface_reference (other->target);
     /* parent_target is always set to NULL; it's only ever set by redirect_target */
@@ -206,7 +206,7 @@ _cairo_gstate_fini (cairo_gstate_t *gstate)
     cairo_scaled_font_destroy (gstate->scaled_font);
     gstate->scaled_font = NULL;
 
-    _cairo_clip_reset (&gstate->clip);
+    _cairo_clip_destroy (gstate->clip);
 
     cairo_list_del (&gstate->device_transform_observer.link);
 
@@ -300,8 +300,6 @@ _cairo_gstate_restore (cairo_gstate_t **gstate, cairo_gstate_t **freelist)
 cairo_status_t
 _cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child)
 {
-    cairo_matrix_t matrix;
-
     /* If this gstate is already redirected, this is an error; we need a
      * new gstate to be able to redirect */
     assert (gstate->parent_target == NULL);
@@ -320,13 +318,11 @@ _cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child)
 
     /* The clip is in surface backend coordinates for the previous target;
      * translate it into the child's backend coordinates. */
-    cairo_matrix_init_translate (&matrix,
-				 child->device_transform.x0 - gstate->parent_target->device_transform.x0,
-				 child->device_transform.y0 - gstate->parent_target->device_transform.y0);
-    _cairo_clip_reset (&gstate->clip);
-    return _cairo_clip_init_copy_transformed (&gstate->clip,
-					      &gstate->next->clip,
-					      &matrix);
+    gstate->clip = _cairo_clip_copy_with_translation (gstate->next->clip,
+						      child->device_transform.x0 - gstate->parent_target->device_transform.x0,
+						      child->device_transform.y0 - gstate->parent_target->device_transform.y0);
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 /**
@@ -388,7 +384,7 @@ _cairo_gstate_get_original_target (cairo_gstate_t *gstate)
 cairo_clip_t *
 _cairo_gstate_get_clip (cairo_gstate_t *gstate)
 {
-    return &gstate->clip;
+    return gstate->clip;
 }
 
 cairo_status_t
@@ -938,39 +934,6 @@ _cairo_gstate_copy_transformed_mask (cairo_gstate_t   *gstate,
 					    &gstate->ctm_inverse);
 }
 
-/* We need to take a copy of the clip so that the lower layers may modify it
- * by, perhaps, intersecting it with the operation extents and other paths.
- */
-#define _gstate_get_clip(G, C) _cairo_clip_init_copy ((C), &(G)->clip)
-
-static cairo_bool_t
-_clipped (cairo_gstate_t *gstate)
-{
-    cairo_rectangle_int_t extents;
-
-    if (gstate->clip.all_clipped)
-	return TRUE;
-
-    /* XXX consider applying a surface clip? */
-
-    if (gstate->clip.path == NULL)
-	return FALSE;
-
-    if (_cairo_surface_get_extents (gstate->target, &extents)) {
-	if (extents.width == 0 || extents.height == 0)
-	    return TRUE;
-
-	if (! _cairo_rectangle_intersect (&extents,
-					  &gstate->clip.path->extents))
-	{
-	    return TRUE;
-	}
-    }
-
-    /* perform a simple query to exclude trivial all-clipped cases */
-    return _cairo_clip_get_region (&gstate->clip, NULL) == CAIRO_INT_STATUS_NOTHING_TO_DO;
-}
-
 static cairo_operator_t
 _reduce_op (cairo_gstate_t *gstate)
 {
@@ -1029,7 +992,6 @@ _cairo_gstate_paint (cairo_gstate_t *gstate)
 {
     cairo_pattern_union_t source_pattern;
     const cairo_pattern_t *pattern;
-    cairo_clip_t clip;
     cairo_status_t status;
     cairo_operator_t op;
 
@@ -1040,7 +1002,7 @@ _cairo_gstate_paint (cairo_gstate_t *gstate)
     if (gstate->op == CAIRO_OPERATOR_DEST)
 	return CAIRO_STATUS_SUCCESS;
 
-    if (_clipped (gstate))
+    if (_cairo_clip_is_all_clipped (gstate->clip))
 	return CAIRO_STATUS_SUCCESS;
 
     op = _reduce_op (gstate);
@@ -1051,12 +1013,9 @@ _cairo_gstate_paint (cairo_gstate_t *gstate)
 	pattern = &source_pattern.base;
     }
 
-    status = _cairo_surface_paint (gstate->target,
-				   op, pattern,
-				   _gstate_get_clip (gstate, &clip));
-    _cairo_clip_fini (&clip);
-
-    return status;
+    return _cairo_surface_paint (gstate->target,
+				 op, pattern,
+				 gstate->clip);
 }
 
 cairo_status_t
@@ -1066,7 +1025,6 @@ _cairo_gstate_mask (cairo_gstate_t  *gstate,
     cairo_pattern_union_t source_pattern, mask_pattern;
     const cairo_pattern_t *source;
     cairo_operator_t op;
-    cairo_clip_t clip;
     cairo_status_t status;
 
     status = _cairo_gstate_get_pattern_status (mask);
@@ -1080,7 +1038,7 @@ _cairo_gstate_mask (cairo_gstate_t  *gstate,
     if (gstate->op == CAIRO_OPERATOR_DEST)
 	return CAIRO_STATUS_SUCCESS;
 
-    if (_clipped (gstate))
+    if (_cairo_clip_is_all_clipped (gstate->clip))
 	return CAIRO_STATUS_SUCCESS;
 
     assert (gstate->opacity == 1.0);
@@ -1126,16 +1084,15 @@ _cairo_gstate_mask (cairo_gstate_t  *gstate,
 
 	status = _cairo_surface_paint (gstate->target, op,
 				       &source_pattern.base,
-				       _gstate_get_clip (gstate, &clip));
+				       gstate->clip);
     }
     else
     {
 	status = _cairo_surface_mask (gstate->target, op,
 				      source,
 				      &mask_pattern.base,
-				      _gstate_get_clip (gstate, &clip));
+				      gstate->clip);
     }
-    _cairo_clip_fini (&clip);
 
     return status;
 }
@@ -1146,7 +1103,6 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
     cairo_pattern_union_t source_pattern;
     cairo_stroke_style_t style;
     double dash[2];
-    cairo_clip_t clip;
     cairo_status_t status;
 
     status = _cairo_gstate_get_pattern_status (gstate->source);
@@ -1159,7 +1115,7 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
     if (gstate->stroke_style.line_width <= 0.0)
 	return CAIRO_STATUS_SUCCESS;
 
-    if (_clipped (gstate))
+    if (_cairo_clip_is_all_clipped (gstate->clip))
 	return CAIRO_STATUS_SUCCESS;
 
     assert (gstate->opacity == 1.0);
@@ -1175,19 +1131,16 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
 
     _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
 
-    status = _cairo_surface_stroke (gstate->target,
-				    gstate->op,
-				    &source_pattern.base,
-				    path,
-				    &style,
-				    &gstate->ctm,
-				    &gstate->ctm_inverse,
-				    gstate->tolerance,
-				    gstate->antialias,
-				    _gstate_get_clip (gstate, &clip));
-    _cairo_clip_fini (&clip);
-
-    return status;
+    return _cairo_surface_stroke (gstate->target,
+				  gstate->op,
+				  &source_pattern.base,
+				  path,
+				  &style,
+				  &gstate->ctm,
+				  &gstate->ctm_inverse,
+				  gstate->tolerance,
+				  gstate->antialias,
+				  gstate->clip);
 }
 
 cairo_status_t
@@ -1251,7 +1204,6 @@ BAIL:
 cairo_status_t
 _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
 {
-    cairo_clip_t clip;
     cairo_status_t status;
 
     status = _cairo_gstate_get_pattern_status (gstate->source);
@@ -1261,7 +1213,7 @@ _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
     if (gstate->op == CAIRO_OPERATOR_DEST)
 	return CAIRO_STATUS_SUCCESS;
 
-    if (_clipped (gstate))
+    if (_cairo_clip_is_all_clipped (gstate->clip))
 	return CAIRO_STATUS_SUCCESS;
 
     assert (gstate->opacity == 1.0);
@@ -1273,7 +1225,7 @@ _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
 	status = _cairo_surface_paint (gstate->target,
 				       CAIRO_OPERATOR_CLEAR,
 				       &_cairo_pattern_clear.base,
-				       _gstate_get_clip (gstate, &clip));
+				       gstate->clip);
     } else {
 	cairo_pattern_union_t source_pattern;
 	const cairo_pattern_t *pattern;
@@ -1298,7 +1250,7 @@ _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
 	    box.p2.y >= _cairo_fixed_from_int (extents.y + extents.height))
 	{
 	    status = _cairo_surface_paint (gstate->target, op, pattern,
-					   _gstate_get_clip (gstate, &clip));
+					   gstate->clip);
 	}
 	else
 	{
@@ -1307,12 +1259,10 @@ _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
 					  gstate->fill_rule,
 					  gstate->tolerance,
 					  gstate->antialias,
-					  _gstate_get_clip (gstate, &clip));
+					  gstate->clip);
 	}
     }
 
-    _cairo_clip_fini (&clip);
-
     return status;
 }
 
@@ -1335,32 +1285,46 @@ _cairo_gstate_in_clip (cairo_gstate_t	  *gstate,
 		       double		   x,
 		       double		   y)
 {
-    cairo_clip_path_t *clip_path;
+    cairo_clip_t *clip = gstate->clip;
+    int i;
 
-    if (gstate->clip.all_clipped)
+    if (_cairo_clip_is_all_clipped (clip))
 	return FALSE;
 
-    clip_path = gstate->clip.path;
-    if (clip_path == NULL)
-	return TRUE;
-
     _cairo_gstate_user_to_backend (gstate, &x, &y);
 
-    if (x <  clip_path->extents.x ||
-	x >= clip_path->extents.x + clip_path->extents.width ||
-	y <  clip_path->extents.y ||
-	y >= clip_path->extents.y + clip_path->extents.height)
+    if (x <  clip->extents.x ||
+	x >= clip->extents.x + clip->extents.width ||
+	y <  clip->extents.y ||
+	y >= clip->extents.y + clip->extents.height)
     {
 	return FALSE;
     }
 
-    do {
-	if (! _cairo_path_fixed_in_fill (&clip_path->path,
-					 clip_path->fill_rule,
-					 clip_path->tolerance,
-					 x, y))
+    if (clip->num_boxes) {
+	int fx, fy;
+
+	fx = _cairo_fixed_from_double (x);
+	fy = _cairo_fixed_from_double (y);
+	for (i = 0; i < clip->num_boxes; i++) {
+	    if (fx >= clip->boxes[i].p1.x && fx <= clip->boxes[i].p2.x &&
+		fy >= clip->boxes[i].p1.y && fy <= clip->boxes[i].p2.y)
+		break;
+	}
+	if (i == clip->num_boxes)
 	    return FALSE;
-    } while ((clip_path = clip_path->prev) != NULL);
+    }
+
+    if (clip->path) {
+	cairo_clip_path_t *clip_path = clip->path;
+	do {
+	    if (! _cairo_path_fixed_in_fill (&clip_path->path,
+					     clip_path->fill_rule,
+					     clip_path->tolerance,
+					     x, y))
+		return FALSE;
+	} while ((clip_path = clip_path->prev) != NULL);
+    }
 
     return TRUE;
 }
@@ -1500,7 +1464,8 @@ _cairo_gstate_fill_extents (cairo_gstate_t     *gstate,
 cairo_status_t
 _cairo_gstate_reset_clip (cairo_gstate_t *gstate)
 {
-    _cairo_clip_reset (&gstate->clip);
+    _cairo_clip_destroy (gstate->clip);
+    gstate->clip = NULL;
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -1508,23 +1473,27 @@ _cairo_gstate_reset_clip (cairo_gstate_t *gstate)
 cairo_status_t
 _cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
 {
-    return _cairo_clip_clip (&gstate->clip,
-			     path, gstate->fill_rule,
-			     gstate->tolerance, gstate->antialias);
+    gstate->clip =
+	_cairo_clip_intersect_path (gstate->clip,
+				    path,
+				    gstate->fill_rule,
+				    gstate->tolerance,
+				    gstate->antialias);
+    /* XXX */
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_bool_t
 _cairo_gstate_int_clip_extents (cairo_gstate_t        *gstate,
 				cairo_rectangle_int_t *extents)
 {
-    const cairo_rectangle_int_t *clip_extents;
     cairo_bool_t is_bounded;
 
     is_bounded = _cairo_surface_get_extents (gstate->target, extents);
 
-    clip_extents = _cairo_clip_get_extents (&gstate->clip);
-    if (clip_extents != NULL) {
-	_cairo_rectangle_intersect (extents, clip_extents);
+    if (gstate->clip) {
+	_cairo_rectangle_intersect (extents,
+				    _cairo_clip_get_extents (gstate->clip));
 	is_bounded = TRUE;
     }
 
@@ -1568,23 +1537,19 @@ _cairo_gstate_clip_extents (cairo_gstate_t *gstate,
 cairo_rectangle_list_t*
 _cairo_gstate_copy_clip_rectangle_list (cairo_gstate_t *gstate)
 {
-    cairo_clip_t clip;
     cairo_rectangle_int_t extents;
     cairo_rectangle_list_t *list;
-    cairo_status_t status;
-
-    _cairo_clip_init_copy (&clip, &gstate->clip);
+    cairo_clip_t *clip;
 
     if (_cairo_surface_get_extents (gstate->target, &extents))
-	status = _cairo_clip_rectangle (&clip, &extents);
+	clip = _cairo_clip_copy_intersect_rectangle (gstate->clip, &extents);
     else
-	status = CAIRO_STATUS_SUCCESS;
+	clip = gstate->clip;
 
-    if (unlikely (status))
-	return _cairo_rectangle_list_create_in_error (status);
+    list = _cairo_clip_copy_rectangle_list (clip, gstate);
 
-    list = _cairo_clip_copy_rectangle_list (&clip, gstate);
-    _cairo_clip_fini (&clip);
+    if (clip != gstate->clip)
+	_cairo_clip_destroy (clip);
 
     return list;
 }
@@ -1875,7 +1840,6 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t		   *gstate,
     cairo_text_cluster_t *transformed_clusters = NULL;
     cairo_operator_t op;
     cairo_status_t status;
-    cairo_clip_t clip;
 
     status = _cairo_gstate_get_pattern_status (gstate->source);
     if (unlikely (status))
@@ -1884,7 +1848,7 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t		   *gstate,
     if (gstate->op == CAIRO_OPERATOR_DEST)
 	return CAIRO_STATUS_SUCCESS;
 
-    if (_clipped (gstate))
+    if (_cairo_clip_is_all_clipped (gstate->clip))
 	return CAIRO_STATUS_SUCCESS;
 
     status = _cairo_gstate_ensure_scaled_font (gstate);
@@ -1958,14 +1922,14 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t		   *gstate,
 						      transformed_clusters, info->num_clusters,
 						      info->cluster_flags,
 						      gstate->scaled_font,
-						      _gstate_get_clip (gstate, &clip));
+						      gstate->clip);
 	} else {
 	    status = _cairo_surface_show_text_glyphs (gstate->target, op, pattern,
 						      NULL, 0,
 						      transformed_glyphs, num_glyphs,
 						      NULL, 0, 0,
 						      gstate->scaled_font,
-						      _gstate_get_clip (gstate, &clip));
+						      gstate->clip);
 	}
     }
     else
@@ -1984,14 +1948,12 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t		   *gstate,
 					  CAIRO_FILL_RULE_WINDING,
 					  gstate->tolerance,
 					  gstate->scaled_font->options.antialias,
-					  _gstate_get_clip (gstate, &clip));
+					  gstate->clip);
 	}
 
 	_cairo_path_fixed_fini (&path);
     }
 
-    _cairo_clip_fini (&clip);
-
 CLEANUP_GLYPHS:
     if (transformed_glyphs != stack_transformed_glyphs)
       cairo_glyph_free (transformed_glyphs);
diff --git a/src/cairo-image-info.c b/src/cairo-image-info.c
index 63201e6..4489698 100644
--- a/src/cairo-image-info.c
+++ b/src/cairo-image-info.c
@@ -34,6 +34,8 @@
  */
 
 #include "cairoint.h"
+
+#include "cairo-error-private.h"
 #include "cairo-image-info-private.h"
 
 static uint32_t
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index be42724..d7e8b82 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -77,16 +77,6 @@
  * @Since: 1.8
  */
 
-static cairo_int_status_t
-_cairo_image_surface_fill (void *dst,
-			   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);
-
 static pixman_image_t *
 _pixman_image_for_solid (const cairo_solid_pattern_t *pattern);
 
@@ -113,6 +103,7 @@ _cairo_format_from_pixman_format (pixman_format_code_t pixman_format)
 	return CAIRO_FORMAT_A1;
     case PIXMAN_r5g6b5:
 	return CAIRO_FORMAT_RGB16_565;
+    case PIXMAN_r8g8b8a8: case PIXMAN_r8g8b8x8:
     case PIXMAN_a8b8g8r8: case PIXMAN_x8b8g8r8: case PIXMAN_r8g8b8:
     case PIXMAN_b8g8r8:   case PIXMAN_b5g6r5:
     case PIXMAN_a1r5g5b5: case PIXMAN_x1r5g5b5: case PIXMAN_a1b5g5r5:
@@ -181,6 +172,8 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t		*pixman_image,
     surface->stride = pixman_image_get_stride (pixman_image);
     surface->depth = pixman_image_get_depth (pixman_image);
 
+    surface->base.is_clear = width == 0 || height == 0;
+
     return &surface->base;
 }
 
@@ -1099,7 +1092,7 @@ _pixman_image_for_gradient (const cairo_gradient_pattern_t *pattern,
     cairo_circle_double_t extremes[2];
     pixman_point_fixed_t p1, p2;
     unsigned int i;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     if (pattern->n_stops > ARRAY_LENGTH(pixman_stops_static)) {
 	pixman_stops = _cairo_malloc_ab (pattern->n_stops,
@@ -1150,7 +1143,7 @@ _pixman_image_for_gradient (const cairo_gradient_pattern_t *pattern,
 						    extents->y + extents->height/2.,
 						    &pixman_transform, ix, iy);
     if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
-	if (unlikely (status != CAIRO_STATUS_SUCCESS) ||
+	if (unlikely (status != CAIRO_INT_STATUS_SUCCESS) ||
 	    ! pixman_image_set_transform (pixman_image, &pixman_transform))
 	{
 	    pixman_image_unref (pixman_image);
@@ -1328,7 +1321,7 @@ _pixman_image_for_surface (const cairo_surface_pattern_t *pattern,
     cairo_rectangle_int_t sample;
     cairo_extend_t extend;
     cairo_filter_t filter;
-    cairo_status_t status;
+    cairo_int_status_t status;
     cairo_bool_t undo_src_transform = FALSE;
 
     extend = pattern->base.extend;
@@ -1529,7 +1522,7 @@ _pixman_image_for_surface (const cairo_surface_pattern_t *pattern,
 	 * and we can use any filtering, so choose the fastest one. */
 	pixman_image_set_filter (pixman_image, PIXMAN_FILTER_NEAREST, NULL, 0);
     }
-    else if (unlikely (status != CAIRO_STATUS_SUCCESS ||
+    else if (unlikely (status != CAIRO_INT_STATUS_SUCCESS ||
 		       ! pixman_image_set_transform (pixman_image,
 						     &pixman_transform)))
     {
@@ -1795,7 +1788,7 @@ _cairo_image_surface_fixup_unbounded_boxes (cairo_image_surface_t *dst,
 
 	_cairo_boxes_init (&tmp);
 
-	status = _cairo_boxes_add (&tmp, &box);
+	status = _cairo_boxes_add (&tmp, CAIRO_ANTIALIAS_DEFAULT, &box);
 	assert (status == CAIRO_STATUS_SUCCESS);
 
 	tmp.chunks.next = &boxes->chunks;
@@ -1812,12 +1805,14 @@ _cairo_image_surface_fixup_unbounded_boxes (cairo_image_surface_t *dst,
 	pbox = pixman_region32_rectangles (&clip_region->rgn, &i);
 	_cairo_boxes_limit (&clear, (cairo_box_t *) pbox, i);
 
-	status = _cairo_boxes_add (&clear, &box);
+	status = _cairo_boxes_add (&clear, CAIRO_ANTIALIAS_DEFAULT, &box);
 	assert (status == CAIRO_STATUS_SUCCESS);
 
 	for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
 	    for (i = 0; i < chunk->count; i++) {
-		status = _cairo_boxes_add (&clear, &chunk->base[i]);
+		status = _cairo_boxes_add (&clear,
+					   CAIRO_ANTIALIAS_DEFAULT,
+					   &chunk->base[i]);
 		if (unlikely (status)) {
 		    _cairo_boxes_fini (&clear);
 		    return status;
@@ -1885,7 +1880,7 @@ typedef cairo_status_t
 		      const cairo_pattern_t		*src,
 		      int				 dst_x,
 		      int				 dst_y,
-		      cairo_matrix_t 			*dst_device_transform,
+		      cairo_matrix_t			*dst_device_transform,
 		      const cairo_rectangle_int_t	*extents,
 		      cairo_region_t			*clip_region);
 
@@ -1896,23 +1891,13 @@ _create_composite_mask_pattern (cairo_clip_t                  *clip,
 				cairo_image_surface_t         *dst,
 				const cairo_rectangle_int_t   *extents)
 {
-    cairo_region_t *clip_region = NULL;
+    cairo_region_t *clip_region = _cairo_clip_get_region (clip);
+    cairo_bool_t need_clip_surface = ! _cairo_clip_is_region (clip);
     pixman_image_t *mask;
     cairo_status_t status;
-    cairo_bool_t need_clip_surface = FALSE;
-
-    if (clip != NULL) {
-	status = _cairo_clip_get_region (clip, &clip_region);
-	assert (! _cairo_status_is_error (status));
-
-	/* The all-clipped state should never propagate this far. */
-	assert (status != CAIRO_INT_STATUS_NOTHING_TO_DO);
-
-	need_clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED;
 
-	if (clip_region != NULL && cairo_region_num_rectangles (clip_region) == 1)
-	    clip_region = NULL;
-    }
+    if (clip_region != NULL && cairo_region_num_rectangles (clip_region) == 1)
+	clip_region = NULL;
 
     mask = pixman_image_create_bits (PIXMAN_a8, extents->width, extents->height,
 				     NULL, 0);
@@ -1955,7 +1940,8 @@ _create_composite_mask_pattern (cairo_clip_t                  *clip,
 
 	pixman_image_ref (mask);
 
-	status = _cairo_clip_combine_with_surface (clip, tmp, extents->x, extents->y);
+	status = _cairo_clip_combine_with_surface (clip, tmp,
+						   extents->x, extents->y);
 	cairo_surface_destroy (tmp);
 	if (unlikely (status)) {
 	    pixman_image_unref (mask);
@@ -2014,7 +2000,9 @@ _clip_and_composite_with_mask (cairo_clip_t                  *clip,
 	pixman_image_t *src;
 	int src_x, src_y;
 
-	src = _pixman_image_for_pattern (pattern, FALSE, extents, &dst->base.device_transform, &src_x, &src_y);
+	src = _pixman_image_for_pattern (pattern, FALSE, extents,
+					 &dst->base.device_transform,
+					 &src_x, &src_y);
 	if (unlikely (src == NULL)) {
 	    pixman_image_unref (mask);
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -2085,7 +2073,6 @@ _clip_and_composite_combine (cairo_clip_t                  *clip,
     if (unlikely (status))
 	goto CLEANUP_SURFACE;
 
-    assert (clip->path != NULL);
     clip_surface = _cairo_clip_get_surface (clip, &dst->base, &clip_x, &clip_y);
     if (unlikely (clip_surface->status))
 	goto CLEANUP_SURFACE;
@@ -2156,7 +2143,6 @@ _clip_and_composite_source (cairo_clip_t                  *clip,
     int src_x, src_y;
 
     if (pattern == NULL) {
-	cairo_region_t *clip_region;
 	cairo_status_t status;
 
 	status = draw_func (draw_closure,
@@ -2168,7 +2154,7 @@ _clip_and_composite_source (cairo_clip_t                  *clip,
 	if (unlikely (status))
 	    return status;
 
-	if (_cairo_clip_get_region (clip, &clip_region) == CAIRO_INT_STATUS_UNSUPPORTED)
+	if (! _cairo_clip_is_region (clip))
 	    status = _cairo_clip_combine_with_surface (clip, &dst->base, 0, 0);
 
 	return status;
@@ -2179,7 +2165,9 @@ _clip_and_composite_source (cairo_clip_t                  *clip,
     if (unlikely (mask == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
-    src = _pixman_image_for_pattern (pattern, FALSE, extents, &dst->base.device_transform, &src_x, &src_y);
+    src = _pixman_image_for_pattern (pattern, FALSE, extents,
+				     &dst->base.device_transform,
+				     &src_x, &src_y);
     if (unlikely (src == NULL)) {
 	pixman_image_unref (mask);
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -2230,39 +2218,14 @@ _clip_and_composite (cairo_image_surface_t	*dst,
 		     const cairo_pattern_t	*src,
 		     image_draw_func_t		 draw_func,
 		     void			*draw_closure,
-		     cairo_composite_rectangles_t*extents,
-		     cairo_clip_t		*clip)
+		     cairo_composite_rectangles_t*extents)
 {
+    cairo_region_t *clip_region = _cairo_clip_get_region (extents->clip);
+    cairo_bool_t need_clip_surface = ! _cairo_clip_is_region (extents->clip);
     cairo_status_t status;
-    cairo_region_t *clip_region = NULL;
-    cairo_bool_t need_clip_surface = FALSE;
-
-    if (clip != NULL) {
-	status = _cairo_clip_get_region (clip, &clip_region);
-	if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
-	    return CAIRO_STATUS_SUCCESS;
-	if (unlikely (_cairo_status_is_error (status)))
-	    return status;
-
-	need_clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED;
-
-	if (clip_region != NULL) {
-	    cairo_rectangle_int_t rect;
-	    cairo_bool_t is_empty;
-
-	    cairo_region_get_extents (clip_region, &rect);
-	    is_empty = ! _cairo_rectangle_intersect (&extents->unbounded, &rect);
-	    if (unlikely (is_empty))
-		return CAIRO_STATUS_SUCCESS;
 
-	    is_empty = ! _cairo_rectangle_intersect (&extents->bounded, &rect);
-	    if (unlikely (is_empty && extents->is_bounded))
-		return CAIRO_STATUS_SUCCESS;
-
-	    if (cairo_region_num_rectangles (clip_region) == 1)
-		clip_region = NULL;
-	}
-    }
+    if (cairo_region_num_rectangles (clip_region) == 1)
+	clip_region = NULL;
 
     if (clip_region != NULL) {
 	status = _cairo_image_surface_set_clip_region (dst, clip_region);
@@ -2276,7 +2239,7 @@ _clip_and_composite (cairo_image_surface_t	*dst,
     }
 
     if (op == CAIRO_OPERATOR_SOURCE) {
-	status = _clip_and_composite_source (clip, src,
+	status = _clip_and_composite_source (extents->clip, src,
 					     draw_func, draw_closure,
 					     dst, &extents->bounded);
     } else {
@@ -2287,11 +2250,11 @@ _clip_and_composite (cairo_image_surface_t	*dst,
 
 	if (need_clip_surface) {
 	    if (extents->is_bounded) {
-		status = _clip_and_composite_with_mask (clip, op, src,
+		status = _clip_and_composite_with_mask (extents->clip, op, src,
 							draw_func, draw_closure,
 							dst, &extents->bounded);
 	    } else {
-		status = _clip_and_composite_combine (clip, op, src,
+		status = _clip_and_composite_combine (extents->clip, op, src,
 						      draw_func, draw_closure,
 						      dst, &extents->bounded);
 	    }
@@ -2308,7 +2271,7 @@ _clip_and_composite (cairo_image_surface_t	*dst,
 
     if (status == CAIRO_STATUS_SUCCESS && ! extents->is_bounded) {
 	status = _cairo_image_surface_fixup_unbounded (dst, extents,
-						       need_clip_surface ? clip : NULL);
+						       need_clip_surface ? extents->clip : NULL);
     }
 
     if (clip_region != NULL)
@@ -2444,7 +2407,9 @@ _composite_traps (void                          *closure,
 	return CAIRO_STATUS_SUCCESS;
     }
 
-    src = _pixman_image_for_pattern (pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
+    src = _pixman_image_for_pattern (pattern, FALSE, extents,
+				     dst_device_transform,
+				     &src_x, &src_y);
     if (unlikely (src == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -2856,7 +2821,9 @@ _composite_unaligned_boxes (cairo_image_surface_t *dst,
     if (unlikely (status))
 	goto CLEANUP;
 
-    src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded, &dst->base.device_transform, &src_x, &src_y);
+    src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded,
+				     &dst->base.device_transform,
+				     &src_x, &src_y);
     if (unlikely (src == NULL)) {
 	status =  _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto CLEANUP;
@@ -2882,44 +2849,36 @@ _composite_boxes (cairo_image_surface_t *dst,
 		  cairo_operator_t op,
 		  const cairo_pattern_t *pattern,
 		  cairo_boxes_t *boxes,
-		  cairo_antialias_t antialias,
-		  cairo_clip_t *clip,
 		  const cairo_composite_rectangles_t *extents)
 {
-    cairo_region_t *clip_region = NULL;
-    cairo_bool_t need_clip_mask = FALSE;
+    cairo_region_t *clip_region = _cairo_clip_get_region (extents->clip);
+    cairo_bool_t need_clip_mask = extents->clip->path != NULL;
     cairo_status_t status;
     struct _cairo_boxes_chunk *chunk;
     uint32_t pixel;
     int i;
 
-    if (clip != NULL) {
-	status = _cairo_clip_get_region (clip, &clip_region);
-	need_clip_mask = status == CAIRO_INT_STATUS_UNSUPPORTED;
-	if (need_clip_mask &&
-	    (op == CAIRO_OPERATOR_SOURCE || ! extents->is_bounded))
-	{
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-	}
-
-	if (clip_region != NULL && cairo_region_num_rectangles (clip_region) == 1)
-	    clip_region = NULL;
+    if (need_clip_mask &&
+	(op == CAIRO_OPERATOR_SOURCE || ! extents->is_bounded))
+    {
+	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
-    if (antialias != CAIRO_ANTIALIAS_NONE) {
-	if (! boxes->is_pixel_aligned) {
-	    if (need_clip_mask)
-		return CAIRO_INT_STATUS_UNSUPPORTED;
+    if (clip_region != NULL && cairo_region_num_rectangles (clip_region) == 1)
+	clip_region = NULL;
 
-	    if (pattern_to_pixel ((cairo_solid_pattern_t *) pattern, op,
-				  dst->pixman_format, &pixel))
-	    {
-		return _fill_unaligned_boxes (dst, pattern, pixel, boxes, extents);
-	    }
-	    else
-	    {
-		return _composite_unaligned_boxes (dst, op, pattern, boxes, extents);
-	    }
+    if (! boxes->is_pixel_aligned) {
+	if (need_clip_mask)
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+
+	if (pattern_to_pixel ((cairo_solid_pattern_t *) pattern, op,
+			      dst->pixman_format, &pixel))
+	{
+	    return _fill_unaligned_boxes (dst, pattern, pixel, boxes, extents);
+	}
+	else
+	{
+	    return _composite_unaligned_boxes (dst, op, pattern, boxes, extents);
 	}
     }
 
@@ -2957,7 +2916,9 @@ _composite_boxes (cairo_image_surface_t *dst,
 	    cairo_surface_t *clip_surface;
 	    int clip_x, clip_y;
 
-	    clip_surface = _cairo_clip_get_surface (clip, &dst->base, &clip_x, &clip_y);
+	    clip_surface = _cairo_clip_get_surface (extents->clip,
+						    &dst->base,
+						    &clip_x, &clip_y);
 	    if (unlikely (clip_surface->status))
 		return clip_surface->status;
 
@@ -2970,10 +2931,14 @@ _composite_boxes (cairo_image_surface_t *dst,
 	    }
 
 	    mask = ((cairo_image_surface_t *) clip_surface)->pixman_image;
+	    pixman_image_ref (mask);
+	    cairo_surface_destroy (clip_surface);
 	}
 
 	if (pattern != NULL) {
-	    src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded, &dst->base.device_transform, &src_x, &src_y);
+	    src = _pixman_image_for_pattern (pattern, FALSE, &extents->bounded,
+					     &dst->base.device_transform,
+					     &src_x, &src_y);
 	    if (unlikely (src == NULL))
 		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	} else {
@@ -3022,19 +2987,17 @@ _clip_and_composite_boxes (cairo_image_surface_t *dst,
 			   cairo_operator_t op,
 			   const cairo_pattern_t *src,
 			   cairo_boxes_t *boxes,
-			   cairo_antialias_t antialias,
-			   cairo_composite_rectangles_t *extents,
-			   cairo_clip_t *clip)
+			   cairo_composite_rectangles_t *extents)
 {
     cairo_traps_t traps;
-    cairo_status_t status;
+    cairo_int_status_t status;
     composite_traps_info_t info;
 
     if (boxes->num_boxes == 0 && extents->is_bounded)
 	return CAIRO_STATUS_SUCCESS;
 
     /* Use a fast path if the boxes are pixel aligned */
-    status = _composite_boxes (dst, op, src, boxes, antialias, clip, extents);
+    status = _composite_boxes (dst, op, src, boxes, extents);
     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
 	return status;
 
@@ -3045,10 +3008,10 @@ _clip_and_composite_boxes (cairo_image_surface_t *dst,
 
     info.num_traps = traps.num_traps;
     info.traps = traps.traps;
-    info.antialias = antialias;
+    info.antialias = CAIRO_ANTIALIAS_DEFAULT;
     status = _clip_and_composite (dst, op, src,
 				  _composite_traps, &info,
-				  extents, clip);
+				  extents);
 
     _cairo_traps_fini (&traps);
     return status;
@@ -3151,8 +3114,7 @@ _clip_and_composite_trapezoids (cairo_image_surface_t *dst,
 				const cairo_pattern_t *src,
 				cairo_traps_t *traps,
 				cairo_antialias_t antialias,
-				cairo_composite_rectangles_t *extents,
-				cairo_clip_t *clip)
+				cairo_composite_rectangles_t *extents)
 {
     composite_traps_info_t info;
     cairo_bool_t need_clip_surface = FALSE;
@@ -3161,12 +3123,7 @@ _clip_and_composite_trapezoids (cairo_image_surface_t *dst,
     if (traps->num_traps == 0 && extents->is_bounded)
 	return CAIRO_STATUS_SUCCESS;
 
-    if (clip != NULL) {
-	cairo_region_t *clip_region;
-
-	status = _cairo_clip_get_region (clip, &clip_region);
-	need_clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED;
-    }
+    need_clip_surface = ! _cairo_clip_is_region (extents->clip);
 
     if (traps->has_intersections) {
 	if (traps->is_rectangular)
@@ -3191,8 +3148,7 @@ _clip_and_composite_trapezoids (cairo_image_surface_t *dst,
 
 	_boxes_for_traps (&boxes, traps, antialias);
 	return _clip_and_composite_boxes (dst, op, src,
-					  &boxes, antialias,
-					  extents, clip);
+					  &boxes, extents);
     }
 
     /* No fast path, exclude self-intersections and clip trapezoids. */
@@ -3204,27 +3160,7 @@ _clip_and_composite_trapezoids (cairo_image_surface_t *dst,
     info.antialias = antialias;
     return _clip_and_composite (dst, op, src,
 				_composite_traps, &info,
-				extents, clip);
-}
-
-static cairo_clip_path_t *
-_clip_get_single_path (cairo_clip_t *clip)
-{
-    cairo_clip_path_t *iter = clip->path;
-    cairo_clip_path_t *path = NULL;
-
-    /* Boxes only effect the extents, so discard any outer boxes. */
-    do {
-	if (path != NULL)
-	    return FALSE;
-
-	if ((iter->flags & CAIRO_CLIP_PATH_IS_BOX) == 0)
-	    path = iter;
-
-	iter = iter->prev;
-    } while (iter != NULL);
-
-    return path;
+				extents);
 }
 
 /* high level image interface */
@@ -3233,16 +3169,12 @@ static cairo_int_status_t
 _cairo_image_surface_paint (void			*abstract_surface,
 			    cairo_operator_t		 op,
 			    const cairo_pattern_t	*source,
-			    cairo_clip_t		*clip)
+			    const cairo_clip_t		*clip)
 {
     cairo_image_surface_t *surface = abstract_surface;
     cairo_composite_rectangles_t extents;
-    cairo_clip_path_t *clip_path;
-    cairo_clip_t local_clip;
-    cairo_bool_t have_clip = FALSE;
-    cairo_box_t boxes_stack[32], *clip_boxes = boxes_stack;
-    int num_boxes = ARRAY_LENGTH (boxes_stack);
     cairo_status_t status;
+    cairo_boxes_t boxes;
 
     status = _cairo_composite_rectangles_init_for_paint (&extents,
 							 surface->width,
@@ -3252,53 +3184,20 @@ _cairo_image_surface_paint (void			*abstract_surface,
     if (unlikely (status))
 	return status;
 
-    if (_cairo_clip_contains_extents (clip, &extents))
-	clip = NULL;
-
-    if (clip != NULL) {
-	clip = _cairo_clip_init_copy (&local_clip, clip);
-	have_clip = TRUE;
-    }
-
-    status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
-    if (unlikely (status)) {
-	if (have_clip)
-	    _cairo_clip_fini (&local_clip);
-
-	return status;
-    }
-
     /* If the clip cannot be reduced to a set of boxes, we will need to
      * use a clipmask. Paint is special as it is the only operation that
      * does not implicitly use a mask, so we may be able to reduce this
      * operation to a fill...
      */
-    if (clip != NULL &&
-	extents.is_bounded &&
-	(clip_path = _clip_get_single_path (clip)) != NULL)
-    {
-	status = _cairo_image_surface_fill (surface, op, source,
-					    &clip_path->path,
-					    clip_path->fill_rule,
-					    clip_path->tolerance,
-					    clip_path->antialias,
-					    NULL);
-    }
-    else
-    {
-	cairo_boxes_t boxes;
 
-	_cairo_boxes_init_for_array (&boxes, clip_boxes, num_boxes);
+    status = _cairo_clip_to_boxes (extents.clip, &boxes);
+    if (likely (status == CAIRO_STATUS_SUCCESS)) {
 	status = _clip_and_composite_boxes (surface, op, source,
-					    &boxes, CAIRO_ANTIALIAS_DEFAULT,
-					    &extents, clip);
+					    &boxes, &extents);
+	_cairo_boxes_fini (&boxes);
     }
 
-    if (clip_boxes != boxes_stack)
-	free (clip_boxes);
-
-    if (have_clip)
-	_cairo_clip_fini (&local_clip);
+    _cairo_composite_rectangles_fini (&extents);
 
     return status;
 }
@@ -3311,7 +3210,7 @@ _composite_mask (void				*closure,
 		 const cairo_pattern_t		*src_pattern,
 		 int				 dst_x,
 		 int				 dst_y,
-		 cairo_matrix_t 		*dst_device_transform,
+		 cairo_matrix_t			*dst_device_transform,
 		 const cairo_rectangle_int_t	*extents,
 		 cairo_region_t			*clip_region)
 {
@@ -3321,11 +3220,15 @@ _composite_mask (void				*closure,
     int mask_x = 0, mask_y = 0;
 
     if (src_pattern != NULL) {
-	src = _pixman_image_for_pattern (src_pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
+	src = _pixman_image_for_pattern (src_pattern, FALSE, extents,
+					 dst_device_transform,
+					 &src_x, &src_y);
 	if (unlikely (src == NULL))
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
-	mask = _pixman_image_for_pattern (mask_pattern, TRUE, extents, dst_device_transform, &mask_x, &mask_y);
+	mask = _pixman_image_for_pattern (mask_pattern, TRUE, extents,
+					  dst_device_transform,
+					  &mask_x, &mask_y);
 	if (unlikely (mask == NULL)) {
 	    pixman_image_unref (src);
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -3334,7 +3237,9 @@ _composite_mask (void				*closure,
 	if (mask_pattern->has_component_alpha)
 	    pixman_image_set_component_alpha (mask, TRUE);
     } else {
-	src = _pixman_image_for_pattern (mask_pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
+	src = _pixman_image_for_pattern (mask_pattern, FALSE, extents,
+					 dst_device_transform,
+					 &src_x, &src_y);
 	if (unlikely (src == NULL))
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
@@ -3357,12 +3262,10 @@ _cairo_image_surface_mask (void				*abstract_surface,
 			   cairo_operator_t		 op,
 			   const cairo_pattern_t	*source,
 			   const cairo_pattern_t	*mask,
-			   cairo_clip_t			*clip)
+			   const cairo_clip_t		*clip)
 {
     cairo_image_surface_t *surface = abstract_surface;
     cairo_composite_rectangles_t extents;
-    cairo_clip_t local_clip;
-    cairo_bool_t have_clip = FALSE;
     cairo_status_t status;
 
     status = _cairo_composite_rectangles_init_for_mask (&extents,
@@ -3371,26 +3274,11 @@ _cairo_image_surface_mask (void				*abstract_surface,
     if (unlikely (status))
 	return status;
 
-    if (_cairo_clip_contains_extents (clip, &extents))
-	clip = NULL;
-
-    if (clip != NULL && extents.is_bounded) {
-	clip = _cairo_clip_init_copy (&local_clip, clip);
-	status = _cairo_clip_rectangle (clip, &extents.bounded);
-	if (unlikely (status)) {
-	    _cairo_clip_fini (&local_clip);
-	    return status;
-	}
-
-	have_clip = TRUE;
-    }
-
     status = _clip_and_composite (surface, op, source,
 				  _composite_mask, (void *) mask,
-				  &extents, clip);
+				  &extents);
 
-    if (have_clip)
-	_cairo_clip_fini (&local_clip);
+    _cairo_composite_rectangles_fini (&extents);
 
     return status;
 }
@@ -3410,7 +3298,7 @@ _composite_spans (void                          *closure,
 		  const cairo_pattern_t         *pattern,
 		  int                            dst_x,
 		  int                            dst_y,
-		  cairo_matrix_t 		*dst_device_transform,
+		  cairo_matrix_t		*dst_device_transform,
 		  const cairo_rectangle_int_t   *extents,
 		  cairo_region_t		*clip_region)
 {
@@ -3494,7 +3382,9 @@ _composite_spans (void                          *closure,
 	pixman_image_t *src;
 	int src_x, src_y;
 
-	src = _pixman_image_for_pattern (pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
+	src = _pixman_image_for_pattern (pattern, FALSE, extents,
+					 dst_device_transform,
+					 &src_x, &src_y);
 	if (unlikely (src == NULL)) {
 	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto CLEANUP_RENDERER;
@@ -3527,8 +3417,7 @@ _clip_and_composite_polygon (cairo_image_surface_t *dst,
 			     cairo_polygon_t *polygon,
 			     cairo_fill_rule_t fill_rule,
 			     cairo_antialias_t antialias,
-			     cairo_composite_rectangles_t *extents,
-			     cairo_clip_t *clip)
+			     cairo_composite_rectangles_t *extents)
 {
     cairo_status_t status;
 
@@ -3541,7 +3430,7 @@ _clip_and_composite_polygon (cairo_image_surface_t *dst,
 	_cairo_traps_init (&traps);
 	status = _clip_and_composite_trapezoids (dst, op, src,
 						 &traps, antialias,
-						 extents, clip);
+						 extents);
 	_cairo_traps_fini (&traps);
 
 	return status;
@@ -3560,7 +3449,7 @@ _clip_and_composite_polygon (cairo_image_surface_t *dst,
 
 	status = _clip_and_composite (dst, op, src,
 				      _composite_spans, &info,
-				      extents, clip);
+				      extents);
     } else {
 	cairo_traps_t traps;
 
@@ -3573,7 +3462,7 @@ _clip_and_composite_polygon (cairo_image_surface_t *dst,
 	if (likely (status == CAIRO_STATUS_SUCCESS)) {
 	    status = _clip_and_composite_trapezoids (dst, op, src,
 						     &traps, antialias,
-						     extents, clip);
+						     extents);
 	}
 
 	_cairo_traps_fini (&traps);
@@ -3586,21 +3475,17 @@ static cairo_int_status_t
 _cairo_image_surface_stroke (void			*abstract_surface,
 			     cairo_operator_t		 op,
 			     const cairo_pattern_t	*source,
-			     cairo_path_fixed_t		*path,
+			     const cairo_path_fixed_t	*path,
 			     const cairo_stroke_style_t	*style,
 			     const cairo_matrix_t	*ctm,
 			     const cairo_matrix_t	*ctm_inverse,
 			     double			 tolerance,
 			     cairo_antialias_t		 antialias,
-			     cairo_clip_t		*clip)
+			     const cairo_clip_t		*clip)
 {
     cairo_image_surface_t *surface = abstract_surface;
     cairo_composite_rectangles_t extents;
-    cairo_box_t boxes_stack[32], *clip_boxes = boxes_stack;
-    int num_boxes = ARRAY_LENGTH (boxes_stack);
-    cairo_clip_t local_clip;
-    cairo_bool_t have_clip = FALSE;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     status = _cairo_composite_rectangles_init_for_stroke (&extents,
 							  surface->width,
@@ -3611,80 +3496,42 @@ _cairo_image_surface_stroke (void			*abstract_surface,
     if (unlikely (status))
 	return status;
 
-    if (_cairo_clip_contains_extents (clip, &extents))
-	clip = NULL;
-
-    if (clip != NULL) {
-	clip = _cairo_clip_init_copy (&local_clip, clip);
-	have_clip = TRUE;
-    }
-
-    status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
-    if (unlikely (status)) {
-	if (have_clip)
-	    _cairo_clip_fini (&local_clip);
-
-	return status;
-    }
-
     status = CAIRO_INT_STATUS_UNSUPPORTED;
     if (_cairo_path_fixed_stroke_is_rectilinear (path)) {
 	cairo_boxes_t boxes;
 
-	_cairo_boxes_init (&boxes);
-	if (num_boxes == 0) {
-		/* When compositing with the span renderer, we limit the mask
-		 * to the bounded area, and so we must also constrain the path
-		 * appropriately. (Unlike the other compositing paths
-		 * where the operation itself is limited to extents.)
-		 */
-		boxes_stack[0].p1.x = extents.bounded.x;
-		boxes_stack[0].p1.y = extents.bounded.y;
-		boxes_stack[0].p2.x = extents.bounded.x + extents.bounded.width;
-		boxes_stack[0].p2.y = extents.bounded.y + extents.bounded.height;
-
-		clip_boxes = boxes_stack;
-		num_boxes = 1;
-	}
-	_cairo_boxes_limit (&boxes, clip_boxes, num_boxes);
-
+	_cairo_boxes_init_with_clip (&boxes, extents.clip);
 	status = _cairo_path_fixed_stroke_rectilinear_to_boxes (path,
 								style,
 								ctm,
+								antialias,
 								&boxes);
-	if (likely (status == CAIRO_STATUS_SUCCESS)) {
+	if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
 	    status = _clip_and_composite_boxes (surface, op, source,
-						&boxes, antialias,
-						&extents, clip);
+						&boxes, &extents);
 	}
-
 	_cairo_boxes_fini (&boxes);
     }
 
     if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
 	cairo_polygon_t polygon;
 
-	_cairo_polygon_init (&polygon, clip_boxes, num_boxes);
-
+	_cairo_polygon_init_with_clip (&polygon, extents.clip);
 	status = _cairo_path_fixed_stroke_to_polygon (path,
 						      style,
 						      ctm, ctm_inverse,
 						      tolerance,
 						      &polygon);
-	if (likely (status == CAIRO_STATUS_SUCCESS)) {
+	if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
 	    status = _clip_and_composite_polygon (surface, op, source, &polygon,
-						  CAIRO_FILL_RULE_WINDING, antialias,
-						  &extents, clip);
+						  CAIRO_FILL_RULE_WINDING,
+						  antialias,
+						  &extents);
 	}
-
 	_cairo_polygon_fini (&polygon);
     }
 
-    if (clip_boxes != boxes_stack)
-	free (clip_boxes);
-
-    if (have_clip)
-	_cairo_clip_fini (&local_clip);
+    _cairo_composite_rectangles_fini (&extents);
 
     return status;
 }
@@ -3693,18 +3540,14 @@ static cairo_int_status_t
 _cairo_image_surface_fill (void				*abstract_surface,
 			   cairo_operator_t		 op,
 			   const cairo_pattern_t	*source,
-			   cairo_path_fixed_t		*path,
+			   const cairo_path_fixed_t	*path,
 			   cairo_fill_rule_t		 fill_rule,
 			   double			 tolerance,
 			   cairo_antialias_t		 antialias,
-			   cairo_clip_t			*clip)
+			   const cairo_clip_t		*clip)
 {
     cairo_image_surface_t *surface = abstract_surface;
     cairo_composite_rectangles_t extents;
-    cairo_box_t boxes_stack[32], *clip_boxes = boxes_stack;
-    cairo_clip_t local_clip;
-    cairo_bool_t have_clip = FALSE;
-    int num_boxes = ARRAY_LENGTH (boxes_stack);
     cairo_status_t status;
 
     status = _cairo_composite_rectangles_init_for_fill (&extents,
@@ -3715,84 +3558,35 @@ _cairo_image_surface_fill (void				*abstract_surface,
     if (unlikely (status))
 	return status;
 
-    if (_cairo_clip_contains_extents (clip, &extents))
-	clip = NULL;
-
-    if (extents.is_bounded && clip != NULL) {
-	cairo_clip_path_t *clip_path;
-
-	if (((clip_path = _clip_get_single_path (clip)) != NULL) &&
-	    _cairo_path_fixed_equal (&clip_path->path, path))
-	{
-	    clip = NULL;
-	}
-    }
-
-    if (clip != NULL) {
-	clip = _cairo_clip_init_copy (&local_clip, clip);
-	have_clip = TRUE;
-    }
-
-    status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
-    if (unlikely (status)) {
-	if (have_clip)
-	    _cairo_clip_fini (&local_clip);
-
-	return status;
-    }
-
     if (_cairo_path_fixed_fill_is_rectilinear (path)) {
 	cairo_boxes_t boxes;
 
-	_cairo_boxes_init (&boxes);
-	if (num_boxes == 0) {
-		/* When compositing with the span renderer, we limit the mask
-		 * to the bounded area, and so we must also constrain the path
-		 * appropriately. (Unlike the other compositing paths
-		 * where the operation itself is limited to extents.)
-		 */
-		boxes_stack[0].p1.x = extents.bounded.x;
-		boxes_stack[0].p1.y = extents.bounded.y;
-		boxes_stack[0].p2.x = extents.bounded.x + extents.bounded.width;
-		boxes_stack[0].p2.y = extents.bounded.y + extents.bounded.height;
-
-		clip_boxes = boxes_stack;
-		num_boxes = 1;
-	}
-	_cairo_boxes_limit (&boxes, clip_boxes, num_boxes);
-
+	_cairo_boxes_init_with_clip (&boxes, extents.clip);
 	status = _cairo_path_fixed_fill_rectilinear_to_boxes (path,
 							      fill_rule,
+							      antialias,
 							      &boxes);
 	if (likely (status == CAIRO_STATUS_SUCCESS)) {
 	    status = _clip_and_composite_boxes (surface, op, source,
-						&boxes, antialias,
-						&extents, clip);
+						&boxes, &extents);
 	}
-
 	_cairo_boxes_fini (&boxes);
     } else {
 	cairo_polygon_t polygon;
 
 	assert (! _cairo_path_fixed_fill_is_empty (path));
 
-	_cairo_polygon_init (&polygon, clip_boxes, num_boxes);
-
+	_cairo_polygon_init_with_clip (&polygon, extents.clip);
 	status = _cairo_path_fixed_fill_to_polygon (path, tolerance, &polygon);
 	if (likely (status == CAIRO_STATUS_SUCCESS)) {
 	    status = _clip_and_composite_polygon (surface, op, source, &polygon,
 						  fill_rule, antialias,
-						  &extents, clip);
+						  &extents);
 	}
-
 	_cairo_polygon_fini (&polygon);
     }
 
-    if (clip_boxes != boxes_stack)
-	free (clip_boxes);
-
-    if (have_clip)
-	_cairo_clip_fini (&local_clip);
+    _cairo_composite_rectangles_fini (&extents);
 
     return status;
 }
@@ -3811,7 +3605,7 @@ _composite_glyphs_via_mask (void			*closure,
 			    const cairo_pattern_t	*pattern,
 			    int				 dst_x,
 			    int				 dst_y,
-			    cairo_matrix_t 		*dst_device_transform,
+			    cairo_matrix_t		*dst_device_transform,
 			    const cairo_rectangle_int_t	*extents,
 			    cairo_region_t		*clip_region)
 {
@@ -3827,7 +3621,9 @@ _composite_glyphs_via_mask (void			*closure,
     int src_x, src_y;
     int i;
 
-    src = _pixman_image_for_pattern (pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
+    src = _pixman_image_for_pattern (pattern, FALSE, extents,
+				     dst_device_transform,
+				     &src_x, &src_y);
     if (unlikely (src == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -3961,7 +3757,9 @@ _composite_glyphs (void				*closure,
     int i;
 
     if (pattern != NULL) {
-	src = _pixman_image_for_pattern (pattern, FALSE, extents, dst_device_transform, &src_x, &src_y);
+	src = _pixman_image_for_pattern (pattern, FALSE, extents,
+					 dst_device_transform,
+					 &src_x, &src_y);
 	src_x -= dst_x;
 	src_y -= dst_y;
     } else {
@@ -4042,16 +3840,14 @@ _cairo_image_surface_glyphs (void			*abstract_surface,
 			     cairo_glyph_t		*glyphs,
 			     int			 num_glyphs,
 			     cairo_scaled_font_t	*scaled_font,
-			     cairo_clip_t		*clip,
+			     const cairo_clip_t		*clip,
 			     int *num_remaining)
 {
     cairo_image_surface_t *surface = abstract_surface;
     cairo_composite_rectangles_t extents;
     composite_glyphs_info_t glyph_info;
-    cairo_clip_t local_clip;
-    cairo_bool_t have_clip = FALSE;
-    cairo_bool_t overlap;
     cairo_status_t status;
+    cairo_bool_t overlap;
 
     status = _cairo_composite_rectangles_init_for_glyphs (&extents,
 							  surface->width,
@@ -4064,20 +3860,6 @@ _cairo_image_surface_glyphs (void			*abstract_surface,
     if (unlikely (status))
 	return status;
 
-    if (_cairo_clip_contains_rectangle (clip, &extents.mask))
-	clip = NULL;
-
-    if (clip != NULL && extents.is_bounded) {
-	clip = _cairo_clip_init_copy (&local_clip, clip);
-	status = _cairo_clip_rectangle (clip, &extents.bounded);
-	if (unlikely (status)) {
-	    _cairo_clip_fini (&local_clip);
-	    return status;
-	}
-
-	have_clip = TRUE;
-    }
-
     glyph_info.font = scaled_font;
     glyph_info.glyphs = glyphs;
     glyph_info.num_glyphs = num_glyphs;
@@ -4085,10 +3867,9 @@ _cairo_image_surface_glyphs (void			*abstract_surface,
     status = _clip_and_composite (surface, op, source,
 				  overlap || extents.is_bounded == 0 ? _composite_glyphs_via_mask : _composite_glyphs,
 				  &glyph_info,
-				  &extents, clip);
+				  &extents);
 
-    if (have_clip)
-	_cairo_clip_fini (&local_clip);
+    _cairo_composite_rectangles_fini (&extents);
 
     *num_remaining = 0;
     return status;
@@ -4228,7 +4009,9 @@ _cairo_image_surface_composite (cairo_operator_t	 op,
 
     extents.is_bounded = _cairo_operator_bounded_by_either (op);
 
-    src = _pixman_image_for_pattern (src_pattern, FALSE, &extents.source, &dst->base.device_transform, &src_offset_x, &src_offset_y);
+    src = _pixman_image_for_pattern (src_pattern, FALSE, &extents.source,
+				     &dst->base.device_transform,
+				     &src_offset_x, &src_offset_y);
     if (unlikely (src == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -4237,7 +4020,9 @@ _cairo_image_surface_composite (cairo_operator_t	 op,
 	pixman_image_t *mask;
 	int mask_offset_x, mask_offset_y;
 
-	mask = _pixman_image_for_pattern (mask_pattern, TRUE, &extents.mask, &dst->base.device_transform, &mask_offset_x, &mask_offset_y);
+	mask = _pixman_image_for_pattern (mask_pattern, TRUE, &extents.mask,
+					  &dst->base.device_transform,
+					  &mask_offset_x, &mask_offset_y);
 	if (unlikely (mask == NULL)) {
 	    pixman_image_unref (src);
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -4507,7 +4292,9 @@ _cairo_image_surface_span_renderer_finish (void *abstract_renderer)
 	    return status;
     }
 
-    src = _pixman_image_for_pattern (renderer->pattern, FALSE, &rects->bounded, &renderer->dst->base.device_transform, &src_x, &src_y);
+    src = _pixman_image_for_pattern (renderer->pattern, FALSE, &rects->bounded,
+				     &renderer->dst->base.device_transform,
+				     &src_x, &src_y);
     if (src == NULL)
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
diff --git a/src/cairo-misc.c b/src/cairo-misc.c
index 926d3aa..c04fe11 100644
--- a/src/cairo-misc.c
+++ b/src/cairo-misc.c
@@ -41,7 +41,7 @@
 #include "cairoint.h"
 #include "cairo-error-private.h"
 
-COMPILE_TIME_ASSERT (CAIRO_STATUS_LAST_STATUS < CAIRO_INT_STATUS_UNSUPPORTED);
+COMPILE_TIME_ASSERT ((int)CAIRO_STATUS_LAST_STATUS < (int)CAIRO_INT_STATUS_UNSUPPORTED);
 COMPILE_TIME_ASSERT (CAIRO_INT_STATUS_LAST_STATUS <= 127);
 
 /**
diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index 74c8468..e876127 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -279,7 +279,7 @@ _paint_fallback_image (cairo_paginated_surface_t *surface,
     cairo_status_t status;
     cairo_surface_t *image;
     cairo_surface_pattern_t pattern;
-    cairo_clip_t clip;
+    cairo_clip_t *clip;
 
     x = rect->x;
     y = rect->y;
@@ -304,15 +304,14 @@ _paint_fallback_image (cairo_paginated_surface_t *surface,
      * filtering (if possible) to avoid introducing potential artifacts. */
     pattern.base.filter = CAIRO_FILTER_NEAREST;
 
-    _cairo_clip_init (&clip);
-    status = _cairo_clip_rectangle (&clip, rect);
+    clip = _cairo_clip_intersect_rectangle (NULL, rect);
     if (likely (status == CAIRO_STATUS_SUCCESS)) {
 	status = _cairo_surface_paint (surface->target,
 				       CAIRO_OPERATOR_SOURCE,
-				       &pattern.base, &clip);
+				       &pattern.base, clip);
     }
 
-    _cairo_clip_fini (&clip);
+    _cairo_clip_destroy (clip);
     _cairo_pattern_fini (&pattern.base);
 
 CLEANUP_IMAGE:
@@ -325,7 +324,7 @@ static cairo_int_status_t
 _paint_page (cairo_paginated_surface_t *surface)
 {
     cairo_surface_t *analysis;
-    cairo_status_t status;
+    cairo_int_status_t status;
     cairo_bool_t has_supported, has_page_fallback, has_finegrained_fallback;
 
     if (unlikely (surface->target->status))
@@ -340,7 +339,7 @@ _paint_page (cairo_paginated_surface_t *surface)
     status = _cairo_recording_surface_replay_and_create_regions (surface->recording_surface,
 								 analysis);
     if (status || analysis->status) {
-	if (status == CAIRO_STATUS_SUCCESS)
+	if (status == CAIRO_INT_STATUS_SUCCESS)
 	    status = analysis->status;
 	goto FAIL;
     }
@@ -542,7 +541,7 @@ static cairo_int_status_t
 _cairo_paginated_surface_paint (void			*abstract_surface,
 				cairo_operator_t	 op,
 				const cairo_pattern_t	*source,
-				cairo_clip_t		*clip)
+				const cairo_clip_t	*clip)
 {
     cairo_paginated_surface_t *surface = abstract_surface;
 
@@ -554,7 +553,7 @@ _cairo_paginated_surface_mask (void		*abstract_surface,
 			       cairo_operator_t	 op,
 			       const cairo_pattern_t	*source,
 			       const cairo_pattern_t	*mask,
-			       cairo_clip_t		*clip)
+			       const cairo_clip_t		*clip)
 {
     cairo_paginated_surface_t *surface = abstract_surface;
 
@@ -565,13 +564,13 @@ static cairo_int_status_t
 _cairo_paginated_surface_stroke (void			*abstract_surface,
 				 cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
-				 cairo_path_fixed_t	*path,
+				 const cairo_path_fixed_t	*path,
 				 const cairo_stroke_style_t	*style,
 				 const cairo_matrix_t		*ctm,
 				 const cairo_matrix_t		*ctm_inverse,
 				 double			 tolerance,
 				 cairo_antialias_t	 antialias,
-				 cairo_clip_t		*clip)
+				 const cairo_clip_t		*clip)
 {
     cairo_paginated_surface_t *surface = abstract_surface;
 
@@ -586,11 +585,11 @@ static cairo_int_status_t
 _cairo_paginated_surface_fill (void			*abstract_surface,
 			       cairo_operator_t		 op,
 			       const cairo_pattern_t	*source,
-			       cairo_path_fixed_t	*path,
+			       const cairo_path_fixed_t	*path,
 			       cairo_fill_rule_t	 fill_rule,
 			       double			 tolerance,
 			       cairo_antialias_t	 antialias,
-			       cairo_clip_t		*clip)
+			       const cairo_clip_t		*clip)
 {
     cairo_paginated_surface_t *surface = abstract_surface;
 
@@ -620,7 +619,7 @@ _cairo_paginated_surface_show_text_glyphs (void			      *abstract_surface,
 					   int			       num_clusters,
 					   cairo_text_cluster_flags_t  cluster_flags,
 					   cairo_scaled_font_t	      *scaled_font,
-					   cairo_clip_t		      *clip)
+					   const cairo_clip_t		      *clip)
 {
     cairo_paginated_surface_t *surface = abstract_surface;
 
diff --git a/src/cairo-path-bounds.c b/src/cairo-path-bounds.c
index 204b982..1fc9a06 100644
--- a/src/cairo-path-bounds.c
+++ b/src/cairo-path-bounds.c
@@ -37,6 +37,7 @@
 
 #include "cairoint.h"
 #include "cairo-box-private.h"
+#include "cairo-error-private.h"
 #include "cairo-path-fixed-private.h"
 
 
diff --git a/src/cairo-path-fill.c b/src/cairo-path-fill.c
index 6074a52..b15b1a4 100644
--- a/src/cairo-path-fill.c
+++ b/src/cairo-path-fill.c
@@ -120,6 +120,86 @@ _cairo_path_fixed_fill_to_polygon (const cairo_path_fixed_t *path,
     return _cairo_filler_close (&filler);
 }
 
+typedef struct cairo_filler_rectilinear_aligned {
+    cairo_polygon_t *polygon;
+
+    cairo_point_t current_point;
+    cairo_point_t last_move_to;
+} cairo_filler_ra_t;
+
+static cairo_status_t
+_cairo_filler_ra_line_to (void *closure,
+			  const cairo_point_t *point)
+{
+    cairo_filler_ra_t *filler = closure;
+    cairo_status_t status;
+    cairo_point_t p;
+
+    p.x = _cairo_fixed_round_down (point->x);
+    p.y = _cairo_fixed_round_down (point->y);
+
+    status = _cairo_polygon_add_external_edge (filler->polygon,
+					       &filler->current_point,
+					       &p);
+
+    filler->current_point = p;
+
+    return status;
+}
+
+static cairo_status_t
+_cairo_filler_ra_move_to (void *closure,
+			  const cairo_point_t *point)
+{
+    cairo_filler_t *filler = closure;
+    cairo_status_t status;
+    cairo_point_t p;
+
+    /* close current subpath */
+    status = _cairo_filler_close (closure);
+    if (unlikely (status))
+	return status;
+
+    p.x = _cairo_fixed_round_down (point->x);
+    p.y = _cairo_fixed_round_down (point->y);
+
+    /* make sure that the closure represents a degenerate path */
+    filler->current_point = p;
+    filler->last_move_to = p;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_status_t
+_cairo_path_fixed_fill_rectilinear_to_polygon (const cairo_path_fixed_t *path,
+					       cairo_antialias_t antialias,
+					       cairo_polygon_t *polygon)
+{
+    cairo_filler_ra_t filler;
+    cairo_status_t status;
+
+    if (antialias != CAIRO_ANTIALIAS_NONE)
+	    return _cairo_path_fixed_fill_to_polygon (path, 0., polygon);
+
+    filler.polygon = polygon;
+
+    /* make sure that the closure represents a degenerate path */
+    filler.current_point.x = 0;
+    filler.current_point.y = 0;
+    filler.last_move_to = filler.current_point;
+
+    status = _cairo_path_fixed_interpret_flat (path,
+					       _cairo_filler_ra_move_to,
+					       _cairo_filler_ra_line_to,
+					       _cairo_filler_close,
+					       &filler,
+					       0.);
+    if (unlikely (status))
+	return status;
+
+    return _cairo_filler_close (&filler);
+}
+
 cairo_status_t
 _cairo_path_fixed_fill_to_traps (const cairo_path_fixed_t *path,
 				 cairo_fill_rule_t fill_rule,
@@ -170,12 +250,15 @@ _cairo_path_fixed_fill_rectilinear_tessellate_to_region (const cairo_path_fixed_
     _cairo_traps_init (&traps);
     status = _cairo_path_fixed_fill_rectilinear_to_traps (path,
 							  fill_rule,
+							  CAIRO_ANTIALIAS_NONE,
 							  &traps);
     if (_cairo_status_is_error (status))
 	goto CLEANUP_TRAPS;
 
     if (status == CAIRO_STATUS_SUCCESS) {
-	status = _cairo_traps_extract_region (&traps, &region);
+	status = _cairo_traps_extract_region (&traps,
+					      CAIRO_ANTIALIAS_NONE,
+					      &region);
 	goto CLEANUP_TRAPS;
     }
 
@@ -200,7 +283,9 @@ _cairo_path_fixed_fill_rectilinear_tessellate_to_region (const cairo_path_fixed_
 								   &polygon,
 								   fill_rule);
 	if (likely (status == CAIRO_STATUS_SUCCESS))
-	    status = _cairo_traps_extract_region (&traps, &region);
+	    status = _cairo_traps_extract_region (&traps,
+						  CAIRO_ANTIALIAS_NONE,
+						  &region);
     }
 
   CLEANUP_POLYGON:
@@ -338,6 +423,7 @@ TESSELLATE:
 cairo_int_status_t
 _cairo_path_fixed_fill_rectilinear_to_traps (const cairo_path_fixed_t *path,
 					     cairo_fill_rule_t fill_rule,
+					     cairo_antialias_t antialias,
 					     cairo_traps_t *traps)
 {
     cairo_box_t box;
@@ -347,6 +433,12 @@ _cairo_path_fixed_fill_rectilinear_to_traps (const cairo_path_fixed_t *path,
     traps->is_rectangular = TRUE;
 
     if (_cairo_path_fixed_is_box (path, &box)) {
+	if (antialias == CAIRO_ANTIALIAS_NONE) {
+	    box.p1.x = _cairo_fixed_round_down (box.p1.x);
+	    box.p1.y = _cairo_fixed_round_down (box.p1.y);
+	    box.p2.x = _cairo_fixed_round_down (box.p2.x);
+	    box.p2.y = _cairo_fixed_round_down (box.p2.y);
+	}
 	return _cairo_traps_tessellate_rectangle (traps, &box.p1, &box.p2);
     } else {
 	cairo_path_fixed_iter_t iter;
@@ -365,6 +457,13 @@ _cairo_path_fixed_fill_rectilinear_to_traps (const cairo_path_fixed_t *path,
 		box.p2.x = t;
 	    }
 
+	    if (antialias == CAIRO_ANTIALIAS_NONE) {
+		box.p1.x = _cairo_fixed_round_down (box.p1.x);
+		box.p1.y = _cairo_fixed_round_down (box.p1.y);
+		box.p2.x = _cairo_fixed_round_down (box.p2.x);
+		box.p2.y = _cairo_fixed_round_down (box.p2.y);
+	    }
+
 	    status = _cairo_traps_tessellate_rectangle (traps,
 							&box.p1, &box.p2);
 	    if (unlikely (status)) {
@@ -384,6 +483,7 @@ _cairo_path_fixed_fill_rectilinear_to_traps (const cairo_path_fixed_t *path,
 static cairo_status_t
 _cairo_path_fixed_fill_rectilinear_tessellate_to_boxes (const cairo_path_fixed_t *path,
 							cairo_fill_rule_t fill_rule,
+							cairo_antialias_t antialias,
 							cairo_boxes_t *boxes)
 {
     cairo_polygon_t polygon;
@@ -393,7 +493,7 @@ _cairo_path_fixed_fill_rectilinear_tessellate_to_boxes (const cairo_path_fixed_t
     boxes->num_limits = 0;
 
     /* tolerance will be ignored as the path is rectilinear */
-    status = _cairo_path_fixed_fill_to_polygon (path, 0., &polygon);
+    status = _cairo_path_fixed_fill_rectilinear_to_polygon (path, antialias, &polygon);
     if (likely (status == CAIRO_STATUS_SUCCESS)) {
 	status =
 	    _cairo_bentley_ottmann_tessellate_rectilinear_polygon_to_boxes (&polygon,
@@ -409,6 +509,7 @@ _cairo_path_fixed_fill_rectilinear_tessellate_to_boxes (const cairo_path_fixed_t
 cairo_status_t
 _cairo_path_fixed_fill_rectilinear_to_boxes (const cairo_path_fixed_t *path,
 					     cairo_fill_rule_t fill_rule,
+					     cairo_antialias_t antialias,
 					     cairo_boxes_t *boxes)
 {
     cairo_path_fixed_iter_t iter;
@@ -416,7 +517,7 @@ _cairo_path_fixed_fill_rectilinear_to_boxes (const cairo_path_fixed_t *path,
     cairo_box_t box;
 
     if (_cairo_path_fixed_is_box (path, &box))
-	return _cairo_boxes_add (boxes, &box);
+	return _cairo_boxes_add (boxes, antialias, &box);
 
     _cairo_path_fixed_iter_init (&iter, path);
     while (_cairo_path_fixed_iter_is_fill_box (&iter, &box)) {
@@ -435,7 +536,7 @@ _cairo_path_fixed_fill_rectilinear_to_boxes (const cairo_path_fixed_t *path,
 	    box.p2.x = t;
 	}
 
-	status = _cairo_boxes_add (boxes, &box);
+	status = _cairo_boxes_add (boxes, antialias, &box);
 	if (unlikely (status))
 	    return status;
     }
@@ -447,5 +548,6 @@ _cairo_path_fixed_fill_rectilinear_to_boxes (const cairo_path_fixed_t *path,
     _cairo_boxes_clear (boxes);
     return _cairo_path_fixed_fill_rectilinear_tessellate_to_boxes (path,
 								   fill_rule,
+								   antialias,
 								   boxes);
 }
diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c
index 6b0df9c..31ce1ac 100644
--- a/src/cairo-path-stroke.c
+++ b/src/cairo-path-stroke.c
@@ -1402,6 +1402,7 @@ _cairo_path_fixed_stroke_to_traps (const cairo_path_fixed_t	*path,
 	status = _cairo_path_fixed_stroke_rectilinear_to_traps (path,
 								stroke_style,
 								ctm,
+								CAIRO_ANTIALIAS_DEFAULT,
 								traps);
 	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
 	    return status;
@@ -1440,6 +1441,7 @@ typedef struct _segment_t {
 typedef struct _cairo_rectilinear_stroker {
     const cairo_stroke_style_t *stroke_style;
     const cairo_matrix_t *ctm;
+    cairo_antialias_t antialias;
 
     cairo_fixed_t half_line_width;
     cairo_bool_t do_traps;
@@ -1478,6 +1480,7 @@ static cairo_bool_t
 _cairo_rectilinear_stroker_init (cairo_rectilinear_stroker_t	*stroker,
 				 const cairo_stroke_style_t	*stroke_style,
 				 const cairo_matrix_t		*ctm,
+				 cairo_antialias_t		 antialias,
 				 cairo_bool_t			 do_traps,
 				 void				*container)
 {
@@ -1512,6 +1515,7 @@ _cairo_rectilinear_stroker_init (cairo_rectilinear_stroker_t	*stroker,
 
     stroker->stroke_style = stroke_style;
     stroker->ctm = ctm;
+    stroker->antialias = antialias;
 
     stroker->half_line_width =
 	_cairo_fixed_from_double (stroke_style->line_width / 2.0);
@@ -1687,6 +1691,12 @@ _cairo_rectilinear_stroker_emit_segments (cairo_rectilinear_stroker_t *stroker)
 	}
 
 	if (stroker->do_traps) {
+	    if (stroker->antialias == CAIRO_ANTIALIAS_NONE) {
+		a->x = _cairo_fixed_round_down (a->x);
+		a->y = _cairo_fixed_round_down (a->y);
+		b->x = _cairo_fixed_round_down (b->x);
+		b->y = _cairo_fixed_round_down (b->y);
+	    }
 	    status = _cairo_traps_tessellate_rectangle (stroker->container, a, b);
 	} else {
 	    cairo_box_t box;
@@ -1694,7 +1704,7 @@ _cairo_rectilinear_stroker_emit_segments (cairo_rectilinear_stroker_t *stroker)
 	    box.p1 = *a;
 	    box.p2 = *b;
 
-	    status = _cairo_boxes_add (stroker->container, &box);
+	    status = _cairo_boxes_add (stroker->container, stroker->antialias, &box);
 	}
 	if (unlikely (status))
 	    return status;
@@ -1762,6 +1772,12 @@ _cairo_rectilinear_stroker_emit_segments_dashed (cairo_rectilinear_stroker_t *st
 	    }
 
 	    if (stroker->do_traps) {
+		if (stroker->antialias == CAIRO_ANTIALIAS_NONE) {
+		    p1.x = _cairo_fixed_round_down (p1.x);
+		    p1.y = _cairo_fixed_round_down (p1.y);
+		    p2.x = _cairo_fixed_round_down (p2.x);
+		    p2.y = _cairo_fixed_round_down (p2.y);
+		}
 		status = _cairo_traps_tessellate_rectangle (stroker->container, &p1, &p2);
 	    } else {
 		cairo_box_t box;
@@ -1769,7 +1785,7 @@ _cairo_rectilinear_stroker_emit_segments_dashed (cairo_rectilinear_stroker_t *st
 		box.p1 = p1;
 		box.p2 = p2;
 
-		status = _cairo_boxes_add (stroker->container, &box);
+		status = _cairo_boxes_add (stroker->container, stroker->antialias, &box);
 	    }
 	    if (unlikely (status))
 		return status;
@@ -1824,6 +1840,12 @@ _cairo_rectilinear_stroker_emit_segments_dashed (cairo_rectilinear_stroker_t *st
 	    continue;
 
 	if (stroker->do_traps) {
+	    if (stroker->antialias == CAIRO_ANTIALIAS_NONE) {
+		a->x = _cairo_fixed_round_down (a->x);
+		a->y = _cairo_fixed_round_down (a->y);
+		b->x = _cairo_fixed_round_down (b->x);
+		b->y = _cairo_fixed_round_down (b->y);
+	    }
 	    status = _cairo_traps_tessellate_rectangle (stroker->container, a, b);
 	} else {
 	    cairo_box_t box;
@@ -1831,7 +1853,7 @@ _cairo_rectilinear_stroker_emit_segments_dashed (cairo_rectilinear_stroker_t *st
 	    box.p1 = *a;
 	    box.p2 = *b;
 
-	    status = _cairo_boxes_add (stroker->container, &box);
+	    status = _cairo_boxes_add (stroker->container, stroker->antialias, &box);
 	}
 	if (unlikely (status))
 	    return status;
@@ -2029,6 +2051,7 @@ cairo_int_status_t
 _cairo_path_fixed_stroke_rectilinear_to_traps (const cairo_path_fixed_t	*path,
 					       const cairo_stroke_style_t	*stroke_style,
 					       const cairo_matrix_t	*ctm,
+					       cairo_antialias_t	 antialias,
 					       cairo_traps_t		*traps)
 {
     cairo_rectilinear_stroker_t rectilinear_stroker;
@@ -2037,7 +2060,7 @@ _cairo_path_fixed_stroke_rectilinear_to_traps (const cairo_path_fixed_t	*path,
     assert (_cairo_path_fixed_stroke_is_rectilinear (path));
 
     if (! _cairo_rectilinear_stroker_init (&rectilinear_stroker,
-					   stroke_style, ctm,
+					   stroke_style, ctm, antialias,
 					   TRUE, traps))
     {
 	return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -2082,6 +2105,7 @@ cairo_int_status_t
 _cairo_path_fixed_stroke_rectilinear_to_boxes (const cairo_path_fixed_t	*path,
 					       const cairo_stroke_style_t	*stroke_style,
 					       const cairo_matrix_t	*ctm,
+					       cairo_antialias_t	 antialias,
 					       cairo_boxes_t		*boxes)
 {
     cairo_rectilinear_stroker_t rectilinear_stroker;
@@ -2090,7 +2114,7 @@ _cairo_path_fixed_stroke_rectilinear_to_boxes (const cairo_path_fixed_t	*path,
     assert (_cairo_path_fixed_stroke_is_rectilinear (path));
 
     if (! _cairo_rectilinear_stroker_init (&rectilinear_stroker,
-					   stroke_style, ctm,
+					   stroke_style, ctm, antialias,
 					   FALSE, boxes))
     {
 	return CAIRO_INT_STATUS_UNSUPPORTED;
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index b14a5f8..bb4c643 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -2118,7 +2118,7 @@ _cairo_pattern_acquire_surface_for_gradient (const cairo_gradient_pattern_t *pat
     pixman_transform_t	  pixman_transform;
     cairo_circle_double_t extremes[2];
     pixman_point_fixed_t  p1, p2;
-    cairo_status_t	  status;
+    cairo_int_status_t	  status;
     cairo_bool_t	  repeat = FALSE;
     int                   ix, iy;
     pixman_gradient_stop_t pixman_stops_static[2];
@@ -2241,7 +2241,7 @@ _cairo_pattern_acquire_surface_for_gradient (const cairo_gradient_pattern_t *pat
 						    &pixman_transform,
 						    &ix, &iy);
     if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
-	if (unlikely (status != CAIRO_STATUS_SUCCESS) ||
+	if (unlikely (status != CAIRO_INT_STATUS_SUCCESS) ||
 	    ! pixman_image_set_transform (pixman_image, &pixman_transform))
 	{
 	    cairo_surface_destroy (&image->base);
diff --git a/src/cairo-pdf-operators-private.h b/src/cairo-pdf-operators-private.h
index 14d60b6..48ae6b5 100644
--- a/src/cairo-pdf-operators-private.h
+++ b/src/cairo-pdf-operators-private.h
@@ -129,8 +129,8 @@ cairo_private void
 _cairo_pdf_operators_reset (cairo_pdf_operators_t	 *pdf_operators);
 
 cairo_private cairo_int_status_t
-_cairo_pdf_operators_clip (cairo_pdf_operators_t 	*pdf_operators,
-			   cairo_path_fixed_t		*path,
+_cairo_pdf_operators_clip (cairo_pdf_operators_t	*pdf_operators,
+			   const cairo_path_fixed_t	*path,
 			   cairo_fill_rule_t		 fill_rule);
 
 cairo_private cairo_int_status_t
@@ -140,19 +140,19 @@ _cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t		*pdf_operators,
 
 cairo_private cairo_int_status_t
 _cairo_pdf_operators_stroke (cairo_pdf_operators_t	*pdf_operators,
-			     cairo_path_fixed_t		*path,
+			     const cairo_path_fixed_t	*path,
 			     const cairo_stroke_style_t	*style,
 			     const cairo_matrix_t	*ctm,
 			     const cairo_matrix_t	*ctm_inverse);
 
 cairo_private cairo_int_status_t
-_cairo_pdf_operators_fill (cairo_pdf_operators_t 	*pdf_operators,
-			   cairo_path_fixed_t		*path,
-			   cairo_fill_rule_t	 	fill_rule);
+_cairo_pdf_operators_fill (cairo_pdf_operators_t	*pdf_operators,
+			   const cairo_path_fixed_t	*path,
+			   cairo_fill_rule_t		fill_rule);
 
 cairo_private cairo_int_status_t
 _cairo_pdf_operators_fill_stroke (cairo_pdf_operators_t		*pdf_operators,
-				  cairo_path_fixed_t		*path,
+				  const cairo_path_fixed_t	*path,
 				  cairo_fill_rule_t		 fill_rule,
 				  const cairo_stroke_style_t	*style,
 				  const cairo_matrix_t		*ctm,
diff --git a/src/cairo-pdf-operators.c b/src/cairo-pdf-operators.c
index 0f2500e..58c6472 100644
--- a/src/cairo-pdf-operators.c
+++ b/src/cairo-pdf-operators.c
@@ -493,7 +493,7 @@ _cairo_pdf_path_rectangle (pdf_path_info_t *info, cairo_box_t *box)
  */
 static cairo_status_t
 _cairo_pdf_operators_emit_path (cairo_pdf_operators_t	*pdf_operators,
-				cairo_path_fixed_t      *path,
+				const cairo_path_fixed_t*path,
 				cairo_matrix_t          *path_transform,
 				cairo_line_cap_t         line_cap)
 {
@@ -530,7 +530,7 @@ _cairo_pdf_operators_emit_path (cairo_pdf_operators_t	*pdf_operators,
 
 cairo_int_status_t
 _cairo_pdf_operators_clip (cairo_pdf_operators_t	*pdf_operators,
-			   cairo_path_fixed_t		*path,
+			   const cairo_path_fixed_t	*path,
 			   cairo_fill_rule_t		 fill_rule)
 {
     const char *pdf_operator;
@@ -763,7 +763,7 @@ _cairo_matrix_factor_out_scale (cairo_matrix_t *m, double *scale)
 
 static cairo_int_status_t
 _cairo_pdf_operators_emit_stroke (cairo_pdf_operators_t		*pdf_operators,
-				  cairo_path_fixed_t		*path,
+				  const cairo_path_fixed_t	*path,
 				  const cairo_stroke_style_t	*style,
 				  const cairo_matrix_t		*ctm,
 				  const cairo_matrix_t		*ctm_inverse,
@@ -854,7 +854,7 @@ _cairo_pdf_operators_emit_stroke (cairo_pdf_operators_t		*pdf_operators,
 
 cairo_int_status_t
 _cairo_pdf_operators_stroke (cairo_pdf_operators_t		*pdf_operators,
-			     cairo_path_fixed_t			*path,
+			     const cairo_path_fixed_t		*path,
 			     const cairo_stroke_style_t		*style,
 			     const cairo_matrix_t		*ctm,
 			     const cairo_matrix_t		*ctm_inverse)
@@ -869,7 +869,7 @@ _cairo_pdf_operators_stroke (cairo_pdf_operators_t		*pdf_operators,
 
 cairo_int_status_t
 _cairo_pdf_operators_fill (cairo_pdf_operators_t	*pdf_operators,
-			   cairo_path_fixed_t		*path,
+			   const cairo_path_fixed_t	*path,
 			   cairo_fill_rule_t		fill_rule)
 {
     const char *pdf_operator;
@@ -908,7 +908,7 @@ _cairo_pdf_operators_fill (cairo_pdf_operators_t	*pdf_operators,
 
 cairo_int_status_t
 _cairo_pdf_operators_fill_stroke (cairo_pdf_operators_t		*pdf_operators,
-				  cairo_path_fixed_t		*path,
+				  const cairo_path_fixed_t	*path,
 				  cairo_fill_rule_t		 fill_rule,
 				  const cairo_stroke_style_t	*style,
 				  const cairo_matrix_t		*ctm,
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index dbb7228..8bfa556 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -1089,12 +1089,12 @@ _get_jpeg_image_info (cairo_surface_t		 *source,
     return _cairo_image_info_get_jpeg_info (info, *mime_data, *mime_data_length);
 }
 
-static cairo_status_t
+static cairo_int_status_t
 _get_source_surface_size (cairo_surface_t         *source,
 			  int                     *width,
 			  int                     *height)
 {
-    cairo_status_t status;
+    cairo_int_status_t status;
     cairo_rectangle_int_t extents;
     cairo_image_info_t info;
     const unsigned char *mime_data;
@@ -2184,12 +2184,12 @@ static cairo_status_t
 _cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t     *surface,
 				       cairo_surface_t         *source,
 				       cairo_pdf_resource_t     resource,
-				       cairo_bool_t 		interpolate,
+				       cairo_bool_t		interpolate,
 				       cairo_bool_t             mask)
 {
     cairo_image_surface_t *image;
     void *image_extra;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     status = _cairo_pdf_surface_emit_jpx_image (surface, source, resource);
     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
@@ -2226,7 +2226,7 @@ _cairo_pdf_surface_emit_padded_image_surface (cairo_pdf_surface_t     *surface,
     cairo_image_surface_t *image;
     cairo_surface_t *pad_image;
     void *image_extra;
-    cairo_status_t status;
+    cairo_int_status_t status;
     cairo_surface_pattern_t *pattern = (cairo_surface_pattern_t *) pdf_pattern->pattern;
     int x = 0;
     int y = 0;
@@ -2276,6 +2276,7 @@ _cairo_pdf_surface_emit_padded_image_surface (cairo_pdf_surface_t     *surface,
     }
 
     switch (pdf_pattern->pattern->filter) {
+    default:
     case CAIRO_FILTER_GOOD:
     case CAIRO_FILTER_BEST:
     case CAIRO_FILTER_BILINEAR:
@@ -2323,7 +2324,7 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t  *surface,
     cairo_paginated_mode_t old_paginated_mode;
     cairo_rectangle_int_t recording_extents;
     cairo_bool_t is_bounded;
-    cairo_status_t status;
+    cairo_int_status_t status;
     int alpha = 0;
 
     is_bounded = _cairo_surface_get_extents (recording_surface, &recording_extents);
@@ -2384,7 +2385,7 @@ _cairo_pdf_surface_emit_recording_subsurface (cairo_pdf_surface_t  *surface,
 {
     double old_width, old_height;
     cairo_paginated_mode_t old_paginated_mode;
-    cairo_status_t status;
+    cairo_int_status_t status;
     int alpha = 0;
 
     old_width = surface->width;
@@ -4351,6 +4352,7 @@ _cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t		*surface,
     if (_cairo_status_is_error (status))
 	return status;
 
+    last_glyph = font_subset->num_glyphs - 1;
     if (font_subset->is_latin) {
 	/* find last glyph used */
 	for (i = 255; i >= 32; i--)
@@ -4404,7 +4406,7 @@ _cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t		*surface,
 				 tag,
 				 subset->base_font,
 				 font_subset->is_latin ? 32 : 0,
-				 font_subset->is_latin ? last_glyph : font_subset->num_glyphs - 1,
+				 last_glyph,
 				 descriptor.id);
 
     if (font_subset->is_latin)
@@ -4741,7 +4743,7 @@ _cairo_pdf_emit_imagemask (cairo_image_surface_t *image,
     return _cairo_output_stream_get_status (stream);
 }
 
-static cairo_status_t
+static cairo_int_status_t
 _cairo_pdf_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_subset,
 					     void		        *closure)
 {
@@ -4781,7 +4783,7 @@ _cairo_pdf_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_su
     return status;
 }
 
-static cairo_status_t
+static cairo_int_status_t
 _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t		*surface,
 					   cairo_scaled_font_subset_t	*font_subset)
 {
@@ -4966,12 +4968,12 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t		*surface,
     return _cairo_array_append (&surface->fonts, &font);
 }
 
-static cairo_status_t
+static cairo_int_status_t
 _cairo_pdf_surface_emit_unscaled_font_subset (cairo_scaled_font_subset_t *font_subset,
                                               void			 *closure)
 {
     cairo_pdf_surface_t *surface = closure;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     status = _cairo_pdf_surface_emit_cff_font_subset (surface, font_subset);
     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
@@ -4994,22 +4996,22 @@ _cairo_pdf_surface_emit_unscaled_font_subset (cairo_scaled_font_subset_t *font_s
 	return status;
 
     ASSERT_NOT_REACHED;
-    return CAIRO_STATUS_SUCCESS;
+    return CAIRO_INT_STATUS_SUCCESS;
 }
 
-static cairo_status_t
+static cairo_int_status_t
 _cairo_pdf_surface_emit_scaled_font_subset (cairo_scaled_font_subset_t *font_subset,
                                             void		       *closure)
 {
     cairo_pdf_surface_t *surface = closure;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     status = _cairo_pdf_surface_emit_type3_font_subset (surface, font_subset);
     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
 	return status;
 
     ASSERT_NOT_REACHED;
-    return CAIRO_STATUS_SUCCESS;
+    return CAIRO_INT_STATUS_SUCCESS;
 }
 
 static cairo_status_t
@@ -5742,20 +5744,20 @@ static cairo_int_status_t
 _cairo_pdf_surface_paint (void			*abstract_surface,
 			  cairo_operator_t	 op,
 			  const cairo_pattern_t	*source,
-			  cairo_clip_t		*clip)
+			  const cairo_clip_t	*clip)
 {
     cairo_pdf_surface_t *surface = abstract_surface;
-    cairo_status_t status;
     cairo_pdf_smask_group_t *group;
     cairo_pdf_resource_t pattern_res, gstate_res;
     cairo_composite_rectangles_t extents;
+    cairo_int_status_t status;
 
     status = _cairo_composite_rectangles_init_for_paint (&extents,
 							 surface->width, surface->height,
 							 op, source, clip);
     if (unlikely (status)) {
 	if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
-	    return CAIRO_STATUS_SUCCESS;
+	    return CAIRO_INT_STATUS_SUCCESS;
 
 	return status;
     }
@@ -5859,12 +5861,12 @@ _cairo_pdf_surface_mask (void			*abstract_surface,
 			 cairo_operator_t	 op,
 			 const cairo_pattern_t	*source,
 			 const cairo_pattern_t	*mask,
-			 cairo_clip_t		*clip)
+			 const cairo_clip_t	*clip)
 {
     cairo_pdf_surface_t *surface = abstract_surface;
     cairo_pdf_smask_group_t *group;
-    cairo_status_t status;
     cairo_composite_rectangles_t extents;
+    cairo_int_status_t status;
 
     status = _cairo_composite_rectangles_init_for_mask (&extents,
 							surface->width, surface->height,
@@ -5966,19 +5968,19 @@ static cairo_int_status_t
 _cairo_pdf_surface_stroke (void			*abstract_surface,
 			   cairo_operator_t	 op,
 			   const cairo_pattern_t *source,
-			   cairo_path_fixed_t	*path,
+			   const cairo_path_fixed_t	*path,
 			   const cairo_stroke_style_t	*style,
 			   const cairo_matrix_t	*ctm,
 			   const cairo_matrix_t	*ctm_inverse,
 			   double		 tolerance,
 			   cairo_antialias_t	 antialias,
-			   cairo_clip_t		*clip)
+			   const cairo_clip_t	*clip)
 {
     cairo_pdf_surface_t *surface = abstract_surface;
     cairo_pdf_smask_group_t *group;
     cairo_pdf_resource_t pattern_res, gstate_res;
     cairo_composite_rectangles_t extents;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     status = _cairo_composite_rectangles_init_for_stroke (&extents,
 							  surface->width,
@@ -5988,7 +5990,7 @@ _cairo_pdf_surface_stroke (void			*abstract_surface,
 							  clip);
     if (unlikely (status)) {
 	if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
-	    return CAIRO_STATUS_SUCCESS;
+	    return CAIRO_INT_STATUS_SUCCESS;
 
 	return status;
     }
@@ -6003,7 +6005,7 @@ _cairo_pdf_surface_stroke (void			*abstract_surface,
 	    return status;
 
 	if (! _cairo_rectangle_intersect (&extents.bounded, &extents.mask))
-	    return CAIRO_STATUS_SUCCESS;
+	    return CAIRO_INT_STATUS_SUCCESS;
     }
 
     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
@@ -6021,7 +6023,7 @@ _cairo_pdf_surface_stroke (void			*abstract_surface,
 						 &extents.bounded,
 						 &pattern_res, &gstate_res);
     if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
-	return CAIRO_STATUS_SUCCESS;
+	return CAIRO_INT_STATUS_SUCCESS;
     if (unlikely (status))
 	return status;
 
@@ -6097,14 +6099,14 @@ static cairo_int_status_t
 _cairo_pdf_surface_fill (void			*abstract_surface,
 			 cairo_operator_t	 op,
 			 const cairo_pattern_t	*source,
-			 cairo_path_fixed_t	*path,
+			 const cairo_path_fixed_t*path,
 			 cairo_fill_rule_t	 fill_rule,
 			 double			 tolerance,
 			 cairo_antialias_t	 antialias,
-			 cairo_clip_t		*clip)
+			 const cairo_clip_t	*clip)
 {
     cairo_pdf_surface_t *surface = abstract_surface;
-    cairo_status_t status;
+    cairo_int_status_t status;
     cairo_pdf_smask_group_t *group;
     cairo_pdf_resource_t pattern_res, gstate_res;
     cairo_composite_rectangles_t extents;
@@ -6116,7 +6118,7 @@ _cairo_pdf_surface_fill (void			*abstract_surface,
 							clip);
     if (unlikely (status)) {
 	if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
-	    return CAIRO_STATUS_SUCCESS;
+	    return CAIRO_INT_STATUS_SUCCESS;
 
 	return status;
     }
@@ -6129,7 +6131,7 @@ _cairo_pdf_surface_fill (void			*abstract_surface,
 					&extents.mask);
 
 	if (! _cairo_rectangle_intersect (&extents.bounded, &extents.mask))
-	    return CAIRO_STATUS_SUCCESS;
+	    return CAIRO_INT_STATUS_SUCCESS;
     }
 
     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
@@ -6180,7 +6182,7 @@ _cairo_pdf_surface_fill (void			*abstract_surface,
 						 &extents.bounded,
 						 &pattern_res, &gstate_res);
     if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
-	return CAIRO_STATUS_SUCCESS;
+	return CAIRO_INT_STATUS_SUCCESS;
     if (unlikely (status))
 	return status;
 
@@ -6251,7 +6253,7 @@ _cairo_pdf_surface_fill_stroke (void			*abstract_surface,
 				cairo_fill_rule_t	 fill_rule,
 				double			 fill_tolerance,
 				cairo_antialias_t	 fill_antialias,
-				cairo_path_fixed_t	*path,
+				const cairo_path_fixed_t*path,
 				cairo_operator_t	 stroke_op,
 				const cairo_pattern_t	*stroke_source,
 				const cairo_stroke_style_t *stroke_style,
@@ -6259,10 +6261,10 @@ _cairo_pdf_surface_fill_stroke (void			*abstract_surface,
 				const cairo_matrix_t	*stroke_ctm_inverse,
 				double			 stroke_tolerance,
 				cairo_antialias_t	 stroke_antialias,
-				cairo_clip_t		*clip)
+				const cairo_clip_t	*clip)
 {
     cairo_pdf_surface_t *surface = abstract_surface;
-    cairo_status_t status;
+    cairo_int_status_t status;
     cairo_pdf_resource_t fill_pattern_res, stroke_pattern_res, gstate_res;
     cairo_composite_rectangles_t extents;
 
@@ -6408,14 +6410,14 @@ _cairo_pdf_surface_show_text_glyphs (void			*abstract_surface,
 				     int                         num_clusters,
 				     cairo_text_cluster_flags_t  cluster_flags,
 				     cairo_scaled_font_t	*scaled_font,
-				     cairo_clip_t		*clip)
+				     const cairo_clip_t		*clip)
 {
     cairo_pdf_surface_t *surface = abstract_surface;
     cairo_pdf_smask_group_t *group;
     cairo_pdf_resource_t pattern_res, gstate_res;
     cairo_composite_rectangles_t extents;
     cairo_bool_t overlap;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     status = _cairo_composite_rectangles_init_for_glyphs (&extents,
 							  surface->width,
@@ -6427,7 +6429,7 @@ _cairo_pdf_surface_show_text_glyphs (void			*abstract_surface,
 							  &overlap);
     if (unlikely (status)) {
 	if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
-	    return CAIRO_STATUS_SUCCESS;
+	    return CAIRO_INT_STATUS_SUCCESS;
 
 	return status;
     }
@@ -6447,7 +6449,7 @@ _cairo_pdf_surface_show_text_glyphs (void			*abstract_surface,
 						 &extents.bounded,
 						 &pattern_res, &gstate_res);
     if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
-	return CAIRO_STATUS_SUCCESS;
+	return CAIRO_INT_STATUS_SUCCESS;
     if (unlikely (status))
 	return status;
 
diff --git a/src/cairo-png.c b/src/cairo-png.c
index 5cb132e..5468096 100644
--- a/src/cairo-png.c
+++ b/src/cairo-png.c
@@ -169,7 +169,7 @@ write_png (cairo_surface_t	*surface,
 	   void			*closure)
 {
     int i;
-    cairo_status_t status;
+    cairo_int_status_t status;
     cairo_image_surface_t *image;
     cairo_image_surface_t * volatile clone;
     void *image_extra;
diff --git a/src/cairo-polygon-intersect.c b/src/cairo-polygon-intersect.c
new file mode 100644
index 0000000..e2ed6e9
--- /dev/null
+++ b/src/cairo-polygon-intersect.c
@@ -0,0 +1,1466 @@
+/*
+ * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Carl Worth
+ *
+ * Contributor(s):
+ *	Carl D. Worth <cworth at cworth.org>
+ *	Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+/* Provide definitions for standalone compilation */
+#include "cairoint.h"
+
+#include "cairo-error-private.h"
+#include "cairo-freelist-private.h"
+#include "cairo-combsort-private.h"
+
+typedef cairo_point_t cairo_bo_point32_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 _cairo_bo_deferred {
+    cairo_bo_edge_t *other;
+    int32_t top;
+    int dir;
+} cairo_bo_deferred_t;
+
+struct _cairo_bo_edge {
+    int a_or_b;
+    cairo_edge_t edge;
+    cairo_bo_edge_t *prev;
+    cairo_bo_edge_t *next;
+    cairo_bo_deferred_t deferred;
+};
+
+/* the parent is always given by index/2 */
+#define PQ_PARENT_INDEX(i) ((i) >> 1)
+#define PQ_FIRST_ENTRY 1
+
+/* left and right children are index * 2 and (index * 2) +1 respectively */
+#define PQ_LEFT_CHILD_INDEX(i) ((i) << 1)
+
+typedef enum {
+    CAIRO_BO_EVENT_TYPE_STOP,
+    CAIRO_BO_EVENT_TYPE_INTERSECTION,
+    CAIRO_BO_EVENT_TYPE_START
+} 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;
+
+typedef struct _pqueue {
+    int size, max_size;
+
+    cairo_bo_event_t **elements;
+    cairo_bo_event_t *elements_embedded[1024];
+} pqueue_t;
+
+typedef struct _cairo_bo_event_queue {
+    cairo_freepool_t pool;
+    pqueue_t pqueue;
+    cairo_bo_event_t **start_events;
+} cairo_bo_event_queue_t;
+
+typedef struct _cairo_bo_sweep_line {
+    cairo_bo_edge_t *head;
+    int32_t current_y;
+    cairo_bo_edge_t *current_edge;
+} cairo_bo_sweep_line_t;
+
+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;
+
+    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)
+ *
+ * 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)
+ * 2.	    adx/ady ? bdx/bdy
+ * 3.	(adx * bdy) ? (bdx * ady)
+ *
+ * Note that from step 2 to step 3 there is no change needed in the
+ * sign of the result since both ady and bdy are guaranteed to be
+ * greater than or equal to 0.
+ *
+ * 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)
+{
+    /* 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;
+
+    /* 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;
+    if (bdx == 0)
+	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;
+	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);
+    }
+}
+
+/*
+ * We need to compare the x-coordinates of a pair of lines for a particular y,
+ * without loss of precision.
+ *
+ * The x-coordinate along an edge for a given y is:
+ *   X = A_x + (Y - A_y) * A_dx / A_dy
+ *
+ * So the inequality we wish to test is:
+ *   A_x + (Y - A_y) * A_dx / A_dy ∘ B_x + (Y - B_y) * B_dx / B_dy,
+ * where ∘ is our inequality operator.
+ *
+ * By construction, we know that A_dy and B_dy (and (Y - A_y), (Y - B_y)) are
+ * all positive, so we can rearrange it thus without causing a sign change:
+ *   A_dy * B_dy * (A_x - B_x) ∘ (Y - B_y) * B_dx * A_dy
+ *                                 - (Y - A_y) * A_dx * B_dy
+ *
+ * Given the assumption that all the deltas fit within 32 bits, we can compute
+ * this comparison directly using 128 bit arithmetic. For certain, but common,
+ * input we can reduce this down to a single 32 bit compare by inspecting the
+ * deltas.
+ *
+ * (And put the burden of the work on developing fast 128 bit ops, which are
+ * required throughout the tessellator.)
+ *
+ * See the similar discussion for _slope_compare().
+ */
+static int
+edges_compare_x_for_y_general (const cairo_bo_edge_t *a,
+			       const cairo_bo_edge_t *b,
+			       int32_t y)
+{
+    /* XXX: We're assuming here that dx and dy will still fit in 32
+     * bits. That's not true in general as there could be overflow. We
+     * should prevent that before the tessellation algorithm
+     * begins.
+     */
+    int32_t dx;
+    int32_t adx, ady;
+    int32_t bdx, bdy;
+    enum {
+       HAVE_NONE    = 0x0,
+       HAVE_DX      = 0x1,
+       HAVE_ADX     = 0x2,
+       HAVE_DX_ADX  = HAVE_DX | HAVE_ADX,
+       HAVE_BDX     = 0x4,
+       HAVE_DX_BDX  = HAVE_DX | HAVE_BDX,
+       HAVE_ADX_BDX = HAVE_ADX | HAVE_BDX,
+       HAVE_ALL     = HAVE_DX | HAVE_ADX | HAVE_BDX
+    } have_dx_adx_bdx = HAVE_ALL;
+
+    /* don't bother solving for abscissa if the edges' bounding boxes
+     * can be used to order them. */
+    {
+           int32_t amin, amax;
+           int32_t bmin, bmax;
+           if (a->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;
+    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;
+    if (bdx == 0)
+	have_dx_adx_bdx &= ~HAVE_BDX;
+
+    dx = a->edge.line.p1.x - b->edge.line.p1.x;
+    if (dx == 0)
+	have_dx_adx_bdx &= ~HAVE_DX;
+
+#define L _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (ady, bdy), dx)
+#define A _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (adx, bdy), y - a->edge.line.p1.y)
+#define B _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (bdx, ady), y - b->edge.line.p1.y)
+    switch (have_dx_adx_bdx) {
+    default:
+    case HAVE_NONE:
+	return 0;
+    case HAVE_DX:
+	/* A_dy * B_dy * (A_x - B_x) ∘ 0 */
+	return dx; /* ady * bdy is positive definite */
+    case HAVE_ADX:
+	/* 0 ∘  - (Y - A_y) * A_dx * B_dy */
+	return adx; /* bdy * (y - a->top.y) is positive definite */
+    case HAVE_BDX:
+	/* 0 ∘ (Y - B_y) * B_dx * A_dy */
+	return -bdx; /* ady * (y - b->top.y) is positive definite */
+    case HAVE_ADX_BDX:
+	/*  0 ∘ (Y - B_y) * B_dx * A_dy - (Y - A_y) * A_dx * B_dy */
+	if ((adx ^ bdx) < 0) {
+	    return adx;
+	} else if (a->edge.line.p1.y == b->edge.line.p1.y) { /* common origin */
+	    cairo_int64_t adx_bdy, bdx_ady;
+
+	    /* ∴ A_dx * B_dy ∘ B_dx * A_dy */
+
+	    adx_bdy = _cairo_int32x32_64_mul (adx, bdy);
+	    bdx_ady = _cairo_int32x32_64_mul (bdx, ady);
+
+	    return _cairo_int64_cmp (adx_bdy, bdx_ady);
+	} else
+	    return _cairo_int128_cmp (A, B);
+    case HAVE_DX_ADX:
+	/* A_dy * (A_x - B_x) ∘ - (Y - A_y) * A_dx */
+	if ((-adx ^ dx) < 0) {
+	    return dx;
+	} else {
+	    cairo_int64_t ady_dx, dy_adx;
+
+	    ady_dx = _cairo_int32x32_64_mul (ady, dx);
+	    dy_adx = _cairo_int32x32_64_mul (a->edge.line.p1.y - y, adx);
+
+	    return _cairo_int64_cmp (ady_dx, dy_adx);
+	}
+    case HAVE_DX_BDX:
+	/* B_dy * (A_x - B_x) ∘ (Y - B_y) * B_dx */
+	if ((bdx ^ dx) < 0) {
+	    return dx;
+	} else {
+	    cairo_int64_t bdy_dx, dy_bdx;
+
+	    bdy_dx = _cairo_int32x32_64_mul (bdy, dx);
+	    dy_bdx = _cairo_int32x32_64_mul (y - b->edge.line.p1.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
+}
+
+/*
+ * We need to compare the x-coordinate of a line for a particular y wrt to a
+ * given x, without loss of precision.
+ *
+ * The x-coordinate along an edge for a given y is:
+ *   X = A_x + (Y - A_y) * A_dx / A_dy
+ *
+ * So the inequality we wish to test is:
+ *   A_x + (Y - A_y) * A_dx / A_dy ∘ X
+ * where ∘ is our inequality operator.
+ *
+ * By construction, we know that A_dy (and (Y - A_y)) are
+ * all positive, so we can rearrange it thus without causing a sign change:
+ *   (Y - A_y) * A_dx ∘ (X - A_x) * A_dy
+ *
+ * Given the assumption that all the deltas fit within 32 bits, we can compute
+ * this comparison directly using 64 bit arithmetic.
+ *
+ * See the similar discussion for _slope_compare() and
+ * edges_compare_x_for_y_general().
+ */
+static int
+edge_compare_for_y_against_x (const cairo_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;
+
+    if (adx == 0)
+	return -dx;
+    if (dx == 0 || (adx ^ dx) < 0)
+	return adx;
+
+    dy = y - a->edge.line.p1.y;
+    ady = a->edge.line.p2.y - a->edge.line.p1.y;
+
+    L = _cairo_int32x32_64_mul (dy, adx);
+    R = _cairo_int32x32_64_mul (dx, ady);
+
+    return _cairo_int64_cmp (L, R);
+}
+
+static int
+edges_compare_x_for_y (const cairo_bo_edge_t *a,
+		       const cairo_bo_edge_t *b,
+		       int32_t y)
+{
+    /* If the sweep-line is currently on an end-point of a line,
+     * then we know its precise x value (and considering that we often need to
+     * compare events at end-points, this happens frequently enough to warrant
+     * special casing).
+     */
+    enum {
+       HAVE_NEITHER = 0x0,
+       HAVE_AX      = 0x1,
+       HAVE_BX      = 0x2,
+       HAVE_BOTH    = HAVE_AX | HAVE_BX
+    } have_ax_bx = HAVE_BOTH;
+    int32_t ax, bx;
+
+    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;
+    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;
+    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)
+{
+    return a->p1.x == b->p1.x && a->p1.y == b->p1.y &&
+           a->p2.x == b->p2.x && a->p2.y == b->p2.y;
+}
+
+static 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)
+{
+    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);
+	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. */
+    return b->edge.bottom - a->edge.bottom;
+}
+
+static inline cairo_int64_t
+det32_64 (int32_t a, int32_t b,
+	  int32_t c, int32_t d)
+{
+    /* det = a * d - b * c */
+    return _cairo_int64_sub (_cairo_int32x32_64_mul (a, d),
+			     _cairo_int32x32_64_mul (b, c));
+}
+
+static inline cairo_int128_t
+det64x32_128 (cairo_int64_t a, int32_t       b,
+	      cairo_int64_t c, int32_t       d)
+{
+    /* det = a * d - b * c */
+    return _cairo_int128_sub (_cairo_int64x32_128_mul (a, d),
+			      _cairo_int64x32_128_mul (c, b));
+}
+
+/* Compute the intersection of two lines as defined by two edges. The
+ * result is provided as a coordinate pair of 128-bit integers.
+ *
+ * Returns %CAIRO_BO_STATUS_INTERSECTION if there is an intersection or
+ * %CAIRO_BO_STATUS_PARALLEL if the two lines are exactly parallel.
+ */
+static cairo_bool_t
+intersect_lines (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 dx2 = b->edge.line.p1.x - b->edge.line.p2.x;
+    int32_t dy2 = b->edge.line.p1.y - b->edge.line.p2.y;
+
+    cairo_int64_t den_det;
+    cairo_int64_t R;
+    cairo_quorem64_t qr;
+
+    den_det = det32_64 (dx1, dy1, dx2, dy2);
+
+     /* Q: Can we determine that the lines do not intersect (within range)
+      * much more cheaply than computing the intersection point i.e. by
+      * avoiding the division?
+      *
+      *   X = ax + t * adx = bx + s * bdx;
+      *   Y = ay + t * ady = by + s * bdy;
+      *   ∴ t * (ady*bdx - bdy*adx) = bdx * (by - ay) + bdy * (ax - bx)
+      *   => t * L = R
+      *
+      * Therefore we can reject any intersection (under the criteria for
+      * valid intersection events) if:
+      *   L^R < 0 => t < 0, or
+      *   L<R => t > 1
+      *
+      * (where top/bottom must at least extend to the line endpoints).
+      *
+      * A similar substitution can be performed for s, yielding:
+      *   s * (ady*bdx - bdy*adx) = ady * (ax - bx) - adx * (ay - by)
+      */
+    R = det32_64 (dx2, dy2,
+		  b->edge.line.p1.x - a->edge.line.p1.x,
+		  b->edge.line.p1.y - a->edge.line.p1.y);
+    if (_cairo_int64_negative (den_det)) {
+	if (_cairo_int64_ge (den_det, R))
+	    return FALSE;
+    } else {
+	if (_cairo_int64_le (den_det, R))
+	    return FALSE;
+    }
+
+    R = det32_64 (dy1, dx1,
+		  a->edge.line.p1.y - b->edge.line.p1.y,
+		  a->edge.line.p1.x - b->edge.line.p1.x);
+    if (_cairo_int64_negative (den_det)) {
+	if (_cairo_int64_ge (den_det, R))
+	    return FALSE;
+    } else {
+	if (_cairo_int64_le (den_det, R))
+	    return FALSE;
+    }
+
+    /* We now know that the two lines should intersect within range. */
+
+    a_det = det32_64 (a->edge.line.p1.x, a->edge.line.p1.y,
+		      a->edge.line.p2.x, a->edge.line.p2.y);
+    b_det = det32_64 (b->edge.line.p1.x, b->edge.line.p1.y,
+		      b->edge.line.p2.x, b->edge.line.p2.y);
+
+    /* x = det (a_det, dx1, b_det, dx2) / den_det */
+    qr = _cairo_int_96by64_32x64_divrem (det64x32_128 (a_det, dx1,
+						       b_det, dx2),
+					 den_det);
+    if (_cairo_int64_eq (qr.rem, den_det))
+	return FALSE;
+#if 0
+    intersection->x.exactness = _cairo_int64_is_zero (qr.rem) ? EXACT : INEXACT;
+#else
+    intersection->x.exactness = EXACT;
+    if (! _cairo_int64_is_zero (qr.rem)) {
+	if (_cairo_int64_negative (den_det) ^ _cairo_int64_negative (qr.rem))
+	    qr.rem = _cairo_int64_negate (qr.rem);
+	qr.rem = _cairo_int64_mul (qr.rem, _cairo_int32_to_int64 (2));
+	if (_cairo_int64_ge (qr.rem, den_det)) {
+	    qr.quo = _cairo_int64_add (qr.quo,
+				       _cairo_int32_to_int64 (_cairo_int64_negative (qr.quo) ? -1 : 1));
+	} else
+	    intersection->x.exactness = INEXACT;
+    }
+#endif
+    intersection->x.ordinate = _cairo_int64_to_int32 (qr.quo);
+
+    /* y = det (a_det, dy1, b_det, dy2) / den_det */
+    qr = _cairo_int_96by64_32x64_divrem (det64x32_128 (a_det, dy1,
+						       b_det, dy2),
+					 den_det);
+    if (_cairo_int64_eq (qr.rem, den_det))
+	return FALSE;
+#if 0
+    intersection->y.exactness = _cairo_int64_is_zero (qr.rem) ? EXACT : INEXACT;
+#else
+    intersection->y.exactness = EXACT;
+    if (! _cairo_int64_is_zero (qr.rem)) {
+	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;
+}
+
+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)
+	return +1;
+    if (a.ordinate < b)
+	return -1;
+    /* With quotient identical, if remainder is 0 then compare equal */
+    /* Otherwise, the non-zero remainder makes a > b */
+    return INEXACT == a.exactness;
+}
+
+/* Does the given edge contain the given point. The point must already
+ * be known to be contained within the line determined by the edge,
+ * (most likely the point results from an intersection of this edge
+ * with another).
+ *
+ * If we had exact arithmetic, then this function would simply be a
+ * matter of examining whether the y value of the point lies within
+ * the range of y values of the edge. But since intersection points
+ * are not exact due to being rounded to the nearest integer within
+ * the available precision, we must also examine the x value of the
+ * point.
+ *
+ * The definition of "contains" here is that the given intersection
+ * point will be seen by the sweep line after the start event for the
+ * given edge and before the stop event for the edge. See the comments
+ * in the implementation for more details.
+ */
+static cairo_bool_t
+_cairo_bo_edge_contains_intersect_point (cairo_bo_edge_t		*edge,
+					 cairo_bo_intersect_point_t	*point)
+{
+    int cmp_top, cmp_bottom;
+
+    /* XXX: When running the actual algorithm, we don't actually need to
+     * compare against edge->top at all here, since any intersection above
+     * top is eliminated early via a slope comparison. We're leaving these
+     * here for now only for the sake of the quadratic-time intersection
+     * finder which needs them.
+     */
+
+    cmp_top = _cairo_bo_intersect_ordinate_32_compare (point->y,
+						       edge->edge.top);
+    cmp_bottom = _cairo_bo_intersect_ordinate_32_compare (point->y,
+							  edge->edge.bottom);
+
+    if (cmp_top < 0 || cmp_bottom > 0)
+    {
+	return FALSE;
+    }
+
+    if (cmp_top > 0 && cmp_bottom < 0)
+    {
+	return TRUE;
+    }
+
+    /* At this stage, the point lies on the same y value as either
+     * edge->top or edge->bottom, so we have to examine the x value in
+     * order to properly determine containment. */
+
+    /* If the y value of the point is the same as the y value of the
+     * top of the edge, then the x value of the point must be greater
+     * to be considered as inside the edge. Similarly, if the y value
+     * of the point is the same as the y value of the bottom of the
+     * edge, then the x value of the point must be less to be
+     * considered as inside. */
+
+    if (cmp_top == 0) {
+	cairo_fixed_t top_x;
+
+	top_x = _line_compute_intersection_x_for_y (&edge->edge.line,
+						    edge->edge.top);
+	return _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;
+    }
+}
+
+/* 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
+ * one or both edges, and %CAIRO_BO_STATUS_PARALLEL if the two edges
+ * are exactly parallel.
+ *
+ * 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
+_cairo_bo_edge_intersect (cairo_bo_edge_t	*a,
+			  cairo_bo_edge_t	*b,
+			  cairo_bo_point32_t	*intersection)
+{
+    cairo_bo_intersect_point_t quorem;
+
+    if (! intersect_lines (a, b, &quorem))
+	return FALSE;
+
+    if (! _cairo_bo_edge_contains_intersect_point (a, &quorem))
+	return FALSE;
+
+    if (! _cairo_bo_edge_contains_intersect_point (b, &quorem))
+	return FALSE;
+
+    /* Now that we've correctly compared the intersection point and
+     * determined that it lies within the edge, then we know that we
+     * no longer need any more bits of storage for the intersection
+     * than we do for our edge coordinates. We also no longer need the
+     * remainder from the division. */
+    intersection->x = quorem.x.ordinate;
+    intersection->y = quorem.y.ordinate;
+
+    return TRUE;
+}
+
+static inline int
+cairo_bo_event_compare (const cairo_bo_event_t *a,
+			const cairo_bo_event_t *b)
+{
+    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);
+}
+
+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_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);
+}
+
+static void
+_cairo_bo_event_queue_delete (cairo_bo_event_queue_t *queue,
+			      cairo_bo_event_t	     *event)
+{
+    _cairo_freepool_free (&queue->pool, event);
+}
+
+static cairo_bo_event_t *
+_cairo_bo_event_dequeue (cairo_bo_event_queue_t *event_queue)
+{
+    cairo_bo_event_t *event, *cmp;
+
+    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))
+    {
+	event = cmp;
+	event_queue->start_events++;
+    }
+    else
+    {
+	_pqueue_pop (&event_queue->pqueue);
+    }
+
+    return event;
+}
+
+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;
+}
+
+static cairo_status_t
+event_queue_insert_stop (cairo_bo_event_queue_t	*event_queue,
+			 cairo_bo_edge_t		*edge)
+{
+    cairo_bo_point32_t point;
+
+    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);
+}
+
+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);
+}
+
+static inline cairo_status_t
+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_point32_t intersection;
+
+    if (_line_equal (&left->edge.line, &right->edge.line))
+	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
+     * occurred before the current sweep line position. */
+    if (_slope_compare (left, right) <= 0)
+	return CAIRO_STATUS_SUCCESS;
+
+    if (! _cairo_bo_edge_intersect (left, right, &intersection))
+	return CAIRO_STATUS_SUCCESS;
+
+    return _cairo_bo_event_queue_insert (event_queue,
+					 CAIRO_BO_EVENT_TYPE_INTERSECTION,
+					 left, right,
+					 &intersection);
+}
+
+static void
+_cairo_bo_sweep_line_init (cairo_bo_sweep_line_t *sweep_line)
+{
+    sweep_line->head = NULL;
+    sweep_line->current_y = INT32_MIN;
+    sweep_line->current_edge = NULL;
+}
+
+static cairo_status_t
+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_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;
+	    }
+
+	    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->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;
+
+    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;
+
+    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 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;
+
+    if (right->next != NULL)
+	right->next->prev = left;
+
+    left->next = right->next;
+    right->next = left;
+
+    right->prev = left->prev;
+    left->prev = right;
+}
+
+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;
+    }
+}
+
+static void
+edges_end (cairo_bo_edge_t	*left,
+	   int32_t		 bot,
+	   cairo_polygon_t	*polygon)
+{
+    cairo_bo_deferred_t *l = &left->deferred;
+    cairo_bo_edge_t *right = l->other;
+    cairo_bo_deferred_t *r = &right->deferred;
+
+    if (likely (l->top < bot)) {
+	_cairo_polygon_add_line (polygon, &left->edge.line,
+				 l->top, bot, l->dir);
+	_cairo_polygon_add_line (polygon, &right->edge.line,
+				 l->top, bot, r->dir);
+    }
+
+    l->other = NULL;
+    r->other = NULL;
+}
+
+
+static inline void
+edges_start_or_continue (cairo_bo_edge_t	*left,
+			 cairo_bo_edge_t	*right,
+			 int			 top,
+			 cairo_polygon_t	*polygon)
+{
+    if (left->deferred.other == right) {
+	assert (right->deferred.other == left);
+	assert (left->deferred.dir == 1);
+	assert (right->deferred.dir == -1);
+	return;
+    }
+
+    if (left->deferred.other != NULL) {
+	assert (left->deferred.dir == 1);
+	if (right != NULL && edges_colinear (left->deferred.other, right)) {
+	    /* continuation on right, so just swap edges */
+	    left->deferred.other->deferred.other = NULL;
+	    left->deferred.other = right;
+	    right->deferred.other = left;
+	    right->deferred.dir = -1;
+	    return;
+	}
+
+	edges_end (left, top, polygon);
+    }
+
+    if (right != NULL && ! edges_colinear (left, right)) {
+	left->deferred.top = top;
+	left->deferred.dir = 1;
+	left->deferred.other = right;
+
+	right->deferred.top = top;
+	right->deferred.dir = -1;
+	right->deferred.other = left;
+    }
+}
+
+#define is_zero(w) ((w)[0] == 0 || (w)[1] == 0)
+
+static inline void
+active_edges (cairo_bo_edge_t		*left,
+	      int32_t			 top,
+	      cairo_polygon_t	        *polygon)
+{
+	cairo_bo_edge_t *right;
+	int winding[2] = {0, 0};
+
+	/* Yes, this is naive. Consider this a placeholder. */
+
+	while (left != NULL) {
+	    assert (is_zero (winding));
+
+	    do {
+		winding[left->a_or_b] += left->edge.dir;
+		if (! is_zero (winding))
+		    break;
+
+		if unlikely ((left->deferred.other))
+		    edges_end (left, top, polygon);
+
+		left = left->next;
+		if (! left)
+		    return;
+	    } while (1);
+
+	    right = left->next;
+	    do {
+		if unlikely ((right->deferred.other))
+		    edges_end (right, top, polygon);
+
+		winding[right->a_or_b] += right->edge.dir;
+		if (is_zero (winding)) {
+		    if (right->next == NULL ||
+			! edges_colinear (right, right->next))
+			break;
+		}
+
+		right = right->next;
+	    } while (right);
+
+	    edges_start_or_continue (left, right, top, polygon);
+
+	    left = right;
+	    if (left != NULL)
+		left = left->next;
+	}
+}
+
+
+static cairo_status_t
+intersection_sweep (cairo_bo_event_t   **start_events,
+		    int			 num_events,
+		    cairo_polygon_t	*polygon)
+{
+    cairo_status_t status = CAIRO_STATUS_SUCCESS; /* silence compiler */
+    cairo_bo_event_queue_t event_queue;
+    cairo_bo_sweep_line_t sweep_line;
+    cairo_bo_event_t *event;
+    cairo_bo_edge_t *left, *right;
+    cairo_bo_edge_t *e1, *e2;
+
+    _cairo_bo_event_queue_init (&event_queue, start_events, num_events);
+    _cairo_bo_sweep_line_init (&sweep_line);
+
+    while ((event = _cairo_bo_event_dequeue (&event_queue))) {
+	if (event->point.y != sweep_line.current_y) {
+	    active_edges (sweep_line.head,
+			  sweep_line.current_y,
+			  polygon);
+	    sweep_line.current_y = event->point.y;
+	}
+
+	switch (event->type) {
+	case CAIRO_BO_EVENT_TYPE_START:
+	    e1 = &((cairo_bo_start_event_t *) event)->edge;
+
+	    status = sweep_line_insert (&sweep_line, e1);
+	    if (unlikely (status))
+		goto unwind;
+
+	    status = event_queue_insert_stop (&event_queue, e1);
+	    if (unlikely (status))
+		goto unwind;
+
+	    left = e1->prev;
+	    right = e1->next;
+
+	    if (left != NULL) {
+		status = event_queue_insert_if_intersect_below_current_y (&event_queue, left, e1);
+		if (unlikely (status))
+		    goto unwind;
+	    }
+
+	    if (right != NULL) {
+		status = event_queue_insert_if_intersect_below_current_y (&event_queue, e1, right);
+		if (unlikely (status))
+		    goto unwind;
+	    }
+
+	    break;
+
+	case CAIRO_BO_EVENT_TYPE_STOP:
+	    e1 = ((cairo_bo_queue_event_t *) event)->e1;
+	    _cairo_bo_event_queue_delete (&event_queue, event);
+
+	    if (e1->deferred.other)
+		edges_end (e1, sweep_line.current_y, polygon);
+
+	    left = e1->prev;
+	    right = e1->next;
+
+	    _cairo_bo_sweep_line_delete (&sweep_line, e1);
+
+	    if (left != NULL && right != NULL) {
+		status = event_queue_insert_if_intersect_below_current_y (&event_queue, left, right);
+		if (unlikely (status))
+		    goto unwind;
+	    }
+
+	    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);
+
+	    /* skip this intersection if its edges are not adjacent */
+	    if (e2 != e1->next)
+		break;
+
+	    left = e1->prev;
+	    right = e2->next;
+
+	    _cairo_bo_sweep_line_swap (&sweep_line, e1, e2);
+
+	    /* after the swap e2 is left of e1 */
+
+	    if (left != NULL) {
+		status = event_queue_insert_if_intersect_below_current_y (&event_queue, left, e2);
+		if (unlikely (status))
+		    goto unwind;
+	    }
+
+	    if (right != NULL) {
+		status = event_queue_insert_if_intersect_below_current_y (&event_queue, e1, right);
+		if (unlikely (status))
+		    goto unwind;
+	    }
+
+	    break;
+	}
+    }
+
+ unwind:
+    _cairo_bo_event_queue_fini (&event_queue);
+
+    return status;
+}
+
+cairo_status_t
+_cairo_polygon_intersect (cairo_polygon_t *a, int winding_a,
+			  cairo_polygon_t *b, int winding_b)
+{
+    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;
+    int i, j;
+
+    /* XXX lazy */
+    if (winding_a != CAIRO_FILL_RULE_WINDING) {
+	status = _cairo_polygon_reduce (a, winding_a);
+	if (unlikely (status))
+	    return status;
+    }
+
+    if (winding_b != CAIRO_FILL_RULE_WINDING) {
+	status = _cairo_polygon_reduce (b, winding_b);
+	if (unlikely (status))
+	    return status;
+    }
+
+    if (unlikely (0 == a->num_edges))
+	return CAIRO_STATUS_SUCCESS;
+
+    if (unlikely (b->num_edges == 0)) {
+	a->num_edges = 0;
+	return CAIRO_STATUS_SUCCESS;
+    }
+
+    events = stack_events;
+    event_ptrs = stack_event_ptrs;
+    num_events = a->num_edges + b->num_edges;
+    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))
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+	event_ptrs = (cairo_bo_event_t **) (events + num_events);
+    }
+
+    j = 0;
+    for (i = 0; i < a->num_edges; i++) {
+	event_ptrs[j] = (cairo_bo_event_t *) &events[j];
+
+	events[j].type = CAIRO_BO_EVENT_TYPE_START;
+	events[j].point.y = a->edges[i].top;
+	events[j].point.x =
+	    _line_compute_intersection_x_for_y (&a->edges[i].line,
+						events[j].point.y);
+
+	events[j].edge.a_or_b = 0;
+	events[j].edge.edge = a->edges[i];
+	events[j].edge.deferred.other = NULL;
+	events[j].edge.prev = NULL;
+	events[j].edge.next = NULL;
+	j++;
+    }
+
+    for (i = 0; i < b->num_edges; i++) {
+	event_ptrs[j] = (cairo_bo_event_t *) &events[j];
+
+	events[j].type = CAIRO_BO_EVENT_TYPE_START;
+	events[j].point.y = b->edges[i].top;
+	events[j].point.x =
+	    _line_compute_intersection_x_for_y (&b->edges[i].line,
+						events[j].point.y);
+
+	events[j].edge.a_or_b = 1;
+	events[j].edge.edge = b->edges[i];
+	events[j].edge.deferred.other = NULL;
+	events[j].edge.prev = NULL;
+	events[j].edge.next = NULL;
+	j++;
+    }
+    assert (j == num_events);
+
+    //fprintf(stderr, "a "); _cairo_debug_print_polygon(stderr,a);
+    //fprintf(stderr, "b "); _cairo_debug_print_polygon(stderr,b);
+
+    a->num_edges = 0;
+    status = intersection_sweep (event_ptrs, num_events, a);
+    if (events != stack_events)
+	free (events);
+
+    return status;
+}
diff --git a/src/cairo-polygon-reduce.c b/src/cairo-polygon-reduce.c
new file mode 100644
index 0000000..f18e234
--- /dev/null
+++ b/src/cairo-polygon-reduce.c
@@ -0,0 +1,1491 @@
+/*
+ * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Carl Worth
+ *
+ * Contributor(s):
+ *	Carl D. Worth <cworth at cworth.org>
+ *	Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+/* Provide definitions for standalone compilation */
+#include "cairoint.h"
+
+#include "cairo-error-private.h"
+#include "cairo-freelist-private.h"
+#include "cairo-combsort-private.h"
+
+typedef cairo_point_t cairo_bo_point32_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 _cairo_bo_deferred {
+    cairo_bo_edge_t *right;
+    int32_t top;
+} cairo_bo_deferred_t;
+
+struct _cairo_bo_edge {
+    cairo_edge_t edge;
+    cairo_bo_edge_t *prev;
+    cairo_bo_edge_t *next;
+    cairo_bo_deferred_t deferred;
+};
+
+/* the parent is always given by index/2 */
+#define PQ_PARENT_INDEX(i) ((i) >> 1)
+#define PQ_FIRST_ENTRY 1
+
+/* left and right children are index * 2 and (index * 2) +1 respectively */
+#define PQ_LEFT_CHILD_INDEX(i) ((i) << 1)
+
+typedef enum {
+    CAIRO_BO_EVENT_TYPE_STOP,
+    CAIRO_BO_EVENT_TYPE_INTERSECTION,
+    CAIRO_BO_EVENT_TYPE_START
+} 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;
+
+typedef struct _pqueue {
+    int size, max_size;
+
+    cairo_bo_event_t **elements;
+    cairo_bo_event_t *elements_embedded[1024];
+} pqueue_t;
+
+typedef struct _cairo_bo_event_queue {
+    cairo_freepool_t pool;
+    pqueue_t pqueue;
+    cairo_bo_event_t **start_events;
+} cairo_bo_event_queue_t;
+
+typedef struct _cairo_bo_sweep_line {
+    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 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;
+
+    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)
+ *
+ * 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)
+ * 2.	    adx/ady ? bdx/bdy
+ * 3.	(adx * bdy) ? (bdx * ady)
+ *
+ * Note that from step 2 to step 3 there is no change needed in the
+ * sign of the result since both ady and bdy are guaranteed to be
+ * greater than or equal to 0.
+ *
+ * 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)
+{
+    /* 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;
+
+    /* 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;
+    if (bdx == 0)
+	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;
+	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);
+    }
+}
+
+/*
+ * We need to compare the x-coordinates of a pair of lines for a particular y,
+ * without loss of precision.
+ *
+ * The x-coordinate along an edge for a given y is:
+ *   X = A_x + (Y - A_y) * A_dx / A_dy
+ *
+ * So the inequality we wish to test is:
+ *   A_x + (Y - A_y) * A_dx / A_dy ∘ B_x + (Y - B_y) * B_dx / B_dy,
+ * where ∘ is our inequality operator.
+ *
+ * By construction, we know that A_dy and B_dy (and (Y - A_y), (Y - B_y)) are
+ * all positive, so we can rearrange it thus without causing a sign change:
+ *   A_dy * B_dy * (A_x - B_x) ∘ (Y - B_y) * B_dx * A_dy
+ *                                 - (Y - A_y) * A_dx * B_dy
+ *
+ * Given the assumption that all the deltas fit within 32 bits, we can compute
+ * this comparison directly using 128 bit arithmetic. For certain, but common,
+ * input we can reduce this down to a single 32 bit compare by inspecting the
+ * deltas.
+ *
+ * (And put the burden of the work on developing fast 128 bit ops, which are
+ * required throughout the tessellator.)
+ *
+ * See the similar discussion for _slope_compare().
+ */
+static int
+edges_compare_x_for_y_general (const cairo_bo_edge_t *a,
+			       const cairo_bo_edge_t *b,
+			       int32_t y)
+{
+    /* XXX: We're assuming here that dx and dy will still fit in 32
+     * bits. That's not true in general as there could be overflow. We
+     * should prevent that before the tessellation algorithm
+     * begins.
+     */
+    int32_t dx;
+    int32_t adx, ady;
+    int32_t bdx, bdy;
+    enum {
+       HAVE_NONE    = 0x0,
+       HAVE_DX      = 0x1,
+       HAVE_ADX     = 0x2,
+       HAVE_DX_ADX  = HAVE_DX | HAVE_ADX,
+       HAVE_BDX     = 0x4,
+       HAVE_DX_BDX  = HAVE_DX | HAVE_BDX,
+       HAVE_ADX_BDX = HAVE_ADX | HAVE_BDX,
+       HAVE_ALL     = HAVE_DX | HAVE_ADX | HAVE_BDX
+    } have_dx_adx_bdx = HAVE_ALL;
+
+    /* don't bother solving for abscissa if the edges' bounding boxes
+     * can be used to order them. */
+    {
+           int32_t amin, amax;
+           int32_t bmin, bmax;
+           if (a->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;
+    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;
+    if (bdx == 0)
+	have_dx_adx_bdx &= ~HAVE_BDX;
+
+    dx = a->edge.line.p1.x - b->edge.line.p1.x;
+    if (dx == 0)
+	have_dx_adx_bdx &= ~HAVE_DX;
+
+#define L _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (ady, bdy), dx)
+#define A _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (adx, bdy), y - a->edge.line.p1.y)
+#define B _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (bdx, ady), y - b->edge.line.p1.y)
+    switch (have_dx_adx_bdx) {
+    default:
+    case HAVE_NONE:
+	return 0;
+    case HAVE_DX:
+	/* A_dy * B_dy * (A_x - B_x) ∘ 0 */
+	return dx; /* ady * bdy is positive definite */
+    case HAVE_ADX:
+	/* 0 ∘  - (Y - A_y) * A_dx * B_dy */
+	return adx; /* bdy * (y - a->top.y) is positive definite */
+    case HAVE_BDX:
+	/* 0 ∘ (Y - B_y) * B_dx * A_dy */
+	return -bdx; /* ady * (y - b->top.y) is positive definite */
+    case HAVE_ADX_BDX:
+	/*  0 ∘ (Y - B_y) * B_dx * A_dy - (Y - A_y) * A_dx * B_dy */
+	if ((adx ^ bdx) < 0) {
+	    return adx;
+	} else if (a->edge.line.p1.y == b->edge.line.p1.y) { /* common origin */
+	    cairo_int64_t adx_bdy, bdx_ady;
+
+	    /* ∴ A_dx * B_dy ∘ B_dx * A_dy */
+
+	    adx_bdy = _cairo_int32x32_64_mul (adx, bdy);
+	    bdx_ady = _cairo_int32x32_64_mul (bdx, ady);
+
+	    return _cairo_int64_cmp (adx_bdy, bdx_ady);
+	} else
+	    return _cairo_int128_cmp (A, B);
+    case HAVE_DX_ADX:
+	/* A_dy * (A_x - B_x) ∘ - (Y - A_y) * A_dx */
+	if ((-adx ^ dx) < 0) {
+	    return dx;
+	} else {
+	    cairo_int64_t ady_dx, dy_adx;
+
+	    ady_dx = _cairo_int32x32_64_mul (ady, dx);
+	    dy_adx = _cairo_int32x32_64_mul (a->edge.line.p1.y - y, adx);
+
+	    return _cairo_int64_cmp (ady_dx, dy_adx);
+	}
+    case HAVE_DX_BDX:
+	/* B_dy * (A_x - B_x) ∘ (Y - B_y) * B_dx */
+	if ((bdx ^ dx) < 0) {
+	    return dx;
+	} else {
+	    cairo_int64_t bdy_dx, dy_bdx;
+
+	    bdy_dx = _cairo_int32x32_64_mul (bdy, dx);
+	    dy_bdx = _cairo_int32x32_64_mul (y - b->edge.line.p1.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
+}
+
+/*
+ * We need to compare the x-coordinate of a line for a particular y wrt to a
+ * given x, without loss of precision.
+ *
+ * The x-coordinate along an edge for a given y is:
+ *   X = A_x + (Y - A_y) * A_dx / A_dy
+ *
+ * So the inequality we wish to test is:
+ *   A_x + (Y - A_y) * A_dx / A_dy ∘ X
+ * where ∘ is our inequality operator.
+ *
+ * By construction, we know that A_dy (and (Y - A_y)) are
+ * all positive, so we can rearrange it thus without causing a sign change:
+ *   (Y - A_y) * A_dx ∘ (X - A_x) * A_dy
+ *
+ * Given the assumption that all the deltas fit within 32 bits, we can compute
+ * this comparison directly using 64 bit arithmetic.
+ *
+ * See the similar discussion for _slope_compare() and
+ * edges_compare_x_for_y_general().
+ */
+static int
+edge_compare_for_y_against_x (const cairo_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;
+
+    if (adx == 0)
+	return -dx;
+    if (dx == 0 || (adx ^ dx) < 0)
+	return adx;
+
+    dy = y - a->edge.line.p1.y;
+    ady = a->edge.line.p2.y - a->edge.line.p1.y;
+
+    L = _cairo_int32x32_64_mul (dy, adx);
+    R = _cairo_int32x32_64_mul (dx, ady);
+
+    return _cairo_int64_cmp (L, R);
+}
+
+static int
+edges_compare_x_for_y (const cairo_bo_edge_t *a,
+		       const cairo_bo_edge_t *b,
+		       int32_t y)
+{
+    /* If the sweep-line is currently on an end-point of a line,
+     * then we know its precise x value (and considering that we often need to
+     * compare events at end-points, this happens frequently enough to warrant
+     * special casing).
+     */
+    enum {
+       HAVE_NEITHER = 0x0,
+       HAVE_AX      = 0x1,
+       HAVE_BX      = 0x2,
+       HAVE_BOTH    = HAVE_AX | HAVE_BX
+    } have_ax_bx = HAVE_BOTH;
+    int32_t ax, bx;
+
+    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;
+    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;
+    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)
+{
+    return a->p1.x == b->p1.x && a->p1.y == b->p1.y &&
+           a->p2.x == b->p2.x && a->p2.y == b->p2.y;
+}
+
+static 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)
+{
+    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);
+	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. */
+    return b->edge.bottom - a->edge.bottom;
+}
+
+static inline cairo_int64_t
+det32_64 (int32_t a, int32_t b,
+	  int32_t c, int32_t d)
+{
+    /* det = a * d - b * c */
+    return _cairo_int64_sub (_cairo_int32x32_64_mul (a, d),
+			     _cairo_int32x32_64_mul (b, c));
+}
+
+static inline cairo_int128_t
+det64x32_128 (cairo_int64_t a, int32_t       b,
+	      cairo_int64_t c, int32_t       d)
+{
+    /* det = a * d - b * c */
+    return _cairo_int128_sub (_cairo_int64x32_128_mul (a, d),
+			      _cairo_int64x32_128_mul (c, b));
+}
+
+/* Compute the intersection of two lines as defined by two edges. The
+ * result is provided as a coordinate pair of 128-bit integers.
+ *
+ * Returns %CAIRO_BO_STATUS_INTERSECTION if there is an intersection or
+ * %CAIRO_BO_STATUS_PARALLEL if the two lines are exactly parallel.
+ */
+static cairo_bool_t
+intersect_lines (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 dx2 = b->edge.line.p1.x - b->edge.line.p2.x;
+    int32_t dy2 = b->edge.line.p1.y - b->edge.line.p2.y;
+
+    cairo_int64_t den_det;
+    cairo_int64_t R;
+    cairo_quorem64_t qr;
+
+    den_det = det32_64 (dx1, dy1, dx2, dy2);
+
+     /* Q: Can we determine that the lines do not intersect (within range)
+      * much more cheaply than computing the intersection point i.e. by
+      * avoiding the division?
+      *
+      *   X = ax + t * adx = bx + s * bdx;
+      *   Y = ay + t * ady = by + s * bdy;
+      *   ∴ t * (ady*bdx - bdy*adx) = bdx * (by - ay) + bdy * (ax - bx)
+      *   => t * L = R
+      *
+      * Therefore we can reject any intersection (under the criteria for
+      * valid intersection events) if:
+      *   L^R < 0 => t < 0, or
+      *   L<R => t > 1
+      *
+      * (where top/bottom must at least extend to the line endpoints).
+      *
+      * A similar substitution can be performed for s, yielding:
+      *   s * (ady*bdx - bdy*adx) = ady * (ax - bx) - adx * (ay - by)
+      */
+    R = det32_64 (dx2, dy2,
+		  b->edge.line.p1.x - a->edge.line.p1.x,
+		  b->edge.line.p1.y - a->edge.line.p1.y);
+    if (_cairo_int64_negative (den_det)) {
+	if (_cairo_int64_ge (den_det, R))
+	    return FALSE;
+    } else {
+	if (_cairo_int64_le (den_det, R))
+	    return FALSE;
+    }
+
+    R = det32_64 (dy1, dx1,
+		  a->edge.line.p1.y - b->edge.line.p1.y,
+		  a->edge.line.p1.x - b->edge.line.p1.x);
+    if (_cairo_int64_negative (den_det)) {
+	if (_cairo_int64_ge (den_det, R))
+	    return FALSE;
+    } else {
+	if (_cairo_int64_le (den_det, R))
+	    return FALSE;
+    }
+
+    /* We now know that the two lines should intersect within range. */
+
+    a_det = det32_64 (a->edge.line.p1.x, a->edge.line.p1.y,
+		      a->edge.line.p2.x, a->edge.line.p2.y);
+    b_det = det32_64 (b->edge.line.p1.x, b->edge.line.p1.y,
+		      b->edge.line.p2.x, b->edge.line.p2.y);
+
+    /* x = det (a_det, dx1, b_det, dx2) / den_det */
+    qr = _cairo_int_96by64_32x64_divrem (det64x32_128 (a_det, dx1,
+						       b_det, dx2),
+					 den_det);
+    if (_cairo_int64_eq (qr.rem, den_det))
+	return FALSE;
+#if 0
+    intersection->x.exactness = _cairo_int64_is_zero (qr.rem) ? EXACT : INEXACT;
+#else
+    intersection->x.exactness = EXACT;
+    if (! _cairo_int64_is_zero (qr.rem)) {
+	if (_cairo_int64_negative (den_det) ^ _cairo_int64_negative (qr.rem))
+	    qr.rem = _cairo_int64_negate (qr.rem);
+	qr.rem = _cairo_int64_mul (qr.rem, _cairo_int32_to_int64 (2));
+	if (_cairo_int64_ge (qr.rem, den_det)) {
+	    qr.quo = _cairo_int64_add (qr.quo,
+				       _cairo_int32_to_int64 (_cairo_int64_negative (qr.quo) ? -1 : 1));
+	} else
+	    intersection->x.exactness = INEXACT;
+    }
+#endif
+    intersection->x.ordinate = _cairo_int64_to_int32 (qr.quo);
+
+    /* y = det (a_det, dy1, b_det, dy2) / den_det */
+    qr = _cairo_int_96by64_32x64_divrem (det64x32_128 (a_det, dy1,
+						       b_det, dy2),
+					 den_det);
+    if (_cairo_int64_eq (qr.rem, den_det))
+	return FALSE;
+#if 0
+    intersection->y.exactness = _cairo_int64_is_zero (qr.rem) ? EXACT : INEXACT;
+#else
+    intersection->y.exactness = EXACT;
+    if (! _cairo_int64_is_zero (qr.rem)) {
+	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;
+}
+
+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)
+	return +1;
+    if (a.ordinate < b)
+	return -1;
+    /* With quotient identical, if remainder is 0 then compare equal */
+    /* Otherwise, the non-zero remainder makes a > b */
+    return INEXACT == a.exactness;
+}
+
+/* Does the given edge contain the given point. The point must already
+ * be known to be contained within the line determined by the edge,
+ * (most likely the point results from an intersection of this edge
+ * with another).
+ *
+ * If we had exact arithmetic, then this function would simply be a
+ * matter of examining whether the y value of the point lies within
+ * the range of y values of the edge. But since intersection points
+ * are not exact due to being rounded to the nearest integer within
+ * the available precision, we must also examine the x value of the
+ * point.
+ *
+ * The definition of "contains" here is that the given intersection
+ * point will be seen by the sweep line after the start event for the
+ * given edge and before the stop event for the edge. See the comments
+ * in the implementation for more details.
+ */
+static cairo_bool_t
+_cairo_bo_edge_contains_intersect_point (cairo_bo_edge_t		*edge,
+					 cairo_bo_intersect_point_t	*point)
+{
+    int cmp_top, cmp_bottom;
+
+    /* XXX: When running the actual algorithm, we don't actually need to
+     * compare against edge->top at all here, since any intersection above
+     * top is eliminated early via a slope comparison. We're leaving these
+     * here for now only for the sake of the quadratic-time intersection
+     * finder which needs them.
+     */
+
+    cmp_top = _cairo_bo_intersect_ordinate_32_compare (point->y,
+						       edge->edge.top);
+    cmp_bottom = _cairo_bo_intersect_ordinate_32_compare (point->y,
+							  edge->edge.bottom);
+
+    if (cmp_top < 0 || cmp_bottom > 0)
+    {
+	return FALSE;
+    }
+
+    if (cmp_top > 0 && cmp_bottom < 0)
+    {
+	return TRUE;
+    }
+
+    /* At this stage, the point lies on the same y value as either
+     * edge->top or edge->bottom, so we have to examine the x value in
+     * order to properly determine containment. */
+
+    /* If the y value of the point is the same as the y value of the
+     * top of the edge, then the x value of the point must be greater
+     * to be considered as inside the edge. Similarly, if the y value
+     * of the point is the same as the y value of the bottom of the
+     * edge, then the x value of the point must be less to be
+     * considered as inside. */
+
+    if (cmp_top == 0) {
+	cairo_fixed_t top_x;
+
+	top_x = _line_compute_intersection_x_for_y (&edge->edge.line,
+						    edge->edge.top);
+	return _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;
+    }
+}
+
+/* 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
+ * one or both edges, and %CAIRO_BO_STATUS_PARALLEL if the two edges
+ * are exactly parallel.
+ *
+ * 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
+_cairo_bo_edge_intersect (cairo_bo_edge_t	*a,
+			  cairo_bo_edge_t	*b,
+			  cairo_bo_point32_t	*intersection)
+{
+    cairo_bo_intersect_point_t quorem;
+
+    if (! intersect_lines (a, b, &quorem))
+	return FALSE;
+
+    if (! _cairo_bo_edge_contains_intersect_point (a, &quorem))
+	return FALSE;
+
+    if (! _cairo_bo_edge_contains_intersect_point (b, &quorem))
+	return FALSE;
+
+    /* Now that we've correctly compared the intersection point and
+     * determined that it lies within the edge, then we know that we
+     * no longer need any more bits of storage for the intersection
+     * than we do for our edge coordinates. We also no longer need the
+     * remainder from the division. */
+    intersection->x = quorem.x.ordinate;
+    intersection->y = quorem.y.ordinate;
+
+    return TRUE;
+}
+
+static inline int
+cairo_bo_event_compare (const cairo_bo_event_t *a,
+			const cairo_bo_event_t *b)
+{
+    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);
+}
+
+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_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);
+}
+
+static void
+_cairo_bo_event_queue_delete (cairo_bo_event_queue_t *queue,
+			      cairo_bo_event_t	     *event)
+{
+    _cairo_freepool_free (&queue->pool, event);
+}
+
+static cairo_bo_event_t *
+_cairo_bo_event_dequeue (cairo_bo_event_queue_t *event_queue)
+{
+    cairo_bo_event_t *event, *cmp;
+
+    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))
+    {
+	event = cmp;
+	event_queue->start_events++;
+    }
+    else
+    {
+	_pqueue_pop (&event_queue->pqueue);
+    }
+
+    return event;
+}
+
+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;
+}
+
+static cairo_status_t
+_cairo_bo_event_queue_insert_stop (cairo_bo_event_queue_t	*event_queue,
+				   cairo_bo_edge_t		*edge)
+{
+    cairo_bo_point32_t point;
+
+    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);
+}
+
+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);
+}
+
+static inline 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_point32_t intersection;
+
+    if (_line_equal (&left->edge.line, &right->edge.line))
+	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
+     * occurred before the current sweep line position. */
+    if (_slope_compare (left, right) <= 0)
+	return CAIRO_STATUS_SUCCESS;
+
+    if (! _cairo_bo_edge_intersect (left, right, &intersection))
+	return CAIRO_STATUS_SUCCESS;
+
+    return _cairo_bo_event_queue_insert (event_queue,
+					 CAIRO_BO_EVENT_TYPE_INTERSECTION,
+					 left, right,
+					 &intersection);
+}
+
+static void
+_cairo_bo_sweep_line_init (cairo_bo_sweep_line_t *sweep_line)
+{
+    sweep_line->head = NULL;
+    sweep_line->stopped = NULL;
+    sweep_line->current_y = INT32_MIN;
+    sweep_line->current_edge = NULL;
+}
+
+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;
+
+	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;
+	    }
+
+	    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->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;
+
+    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;
+
+    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 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;
+
+    if (right->next != NULL)
+	right->next->prev = left;
+
+    left->next = right->next;
+    right->next = left;
+
+    right->prev = left->prev;
+    left->prev = right;
+}
+
+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;
+    }
+}
+
+static void
+_cairo_bo_edge_end (cairo_bo_edge_t	*left,
+		    int32_t		 bot,
+		    cairo_polygon_t	*polygon)
+{
+    cairo_bo_deferred_t *d = &left->deferred;
+
+    if (likely (d->top < bot)) {
+	_cairo_polygon_add_line (polygon,
+				 &left->edge.line,
+				 d->top, bot,
+				 1);
+	_cairo_polygon_add_line (polygon,
+				 &d->right->edge.line,
+				 d->top, bot,
+				 -1);
+    }
+
+    d->right = NULL;
+}
+
+
+static inline void
+_cairo_bo_edge_start_or_continue (cairo_bo_edge_t	*left,
+				  cairo_bo_edge_t	*right,
+				  int			 top,
+				  cairo_polygon_t	*polygon)
+{
+    if (left->deferred.right == right)
+	return;
+
+    if (left->deferred.right != NULL) {
+	if (right != NULL && edges_colinear (left->deferred.right, right))
+	{
+	    /* continuation on right, so just swap edges */
+	    left->deferred.right = right;
+	    return;
+	}
+
+	_cairo_bo_edge_end (left, top, polygon);
+    }
+
+    if (right != NULL && ! edges_colinear (left, right)) {
+	left->deferred.top = top;
+	left->deferred.right = right;
+    }
+}
+
+static inline void
+_active_edges_to_polygon (cairo_bo_edge_t		*left,
+			  int32_t			 top,
+			  cairo_fill_rule_t		 fill_rule,
+			  cairo_polygon_t	        *polygon)
+{
+    cairo_bo_edge_t *right;
+
+    if (fill_rule == CAIRO_FILL_RULE_WINDING) {
+	while (left != NULL) {
+	    int in_out = left->edge.dir;
+
+	    right = left->next;
+	    if (left->deferred.right == NULL) {
+		while (right != NULL && right->deferred.right == NULL)
+		    right = right->next;
+
+		if (right != NULL && edges_colinear (left, right)) {
+		    /* continuation on left */
+		    left->deferred = right->deferred;
+		    right->deferred.right = NULL;
+		}
+	    }
+
+	    right = left->next;
+	    while (right != NULL) {
+		if (right->deferred.right != NULL)
+		    _cairo_bo_edge_end (right, top, polygon);
+
+		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;
+	    }
+
+	    _cairo_bo_edge_start_or_continue (left, right, top, polygon);
+
+	    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.right != NULL)
+		    _cairo_bo_edge_end (right, top, polygon);
+
+		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;
+	    }
+
+	    _cairo_bo_edge_start_or_continue (left, right, top, polygon);
+
+	    left = right;
+	    if (left != NULL)
+		left = left->next;
+	}
+    }
+}
+
+
+static cairo_status_t
+_cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_event_t   **start_events,
+					    int			 num_events,
+					    cairo_fill_rule_t	 fill_rule,
+					    cairo_polygon_t	*polygon)
+{
+    cairo_status_t status = CAIRO_STATUS_SUCCESS; /* silence compiler */
+    cairo_bo_event_queue_t event_queue;
+    cairo_bo_sweep_line_t sweep_line;
+    cairo_bo_event_t *event;
+    cairo_bo_edge_t *left, *right;
+    cairo_bo_edge_t *e1, *e2;
+
+    _cairo_bo_event_queue_init (&event_queue, start_events, num_events);
+    _cairo_bo_sweep_line_init (&sweep_line);
+
+    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.right != NULL)
+		     _cairo_bo_edge_end (e1, e1->edge.bottom, polygon);
+	    }
+	    sweep_line.stopped = NULL;
+
+	    _active_edges_to_polygon (sweep_line.head,
+				      sweep_line.current_y,
+				      fill_rule, polygon);
+
+	    sweep_line.current_y = event->point.y;
+	}
+
+	switch (event->type) {
+	case CAIRO_BO_EVENT_TYPE_START:
+	    e1 = &((cairo_bo_start_event_t *) event)->edge;
+
+	    status = _cairo_bo_sweep_line_insert (&sweep_line, e1);
+	    if (unlikely (status))
+		goto unwind;
+
+	    status = _cairo_bo_event_queue_insert_stop (&event_queue, e1);
+	    if (unlikely (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 = left->deferred;
+		    if (left->prev != NULL)
+			left->prev = left->next;
+		    else
+			sweep_line.stopped = left->next;
+		    if (left->next != NULL)
+			left->next->prev = left->prev;
+		    break;
+		}
+	    }
+
+	    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;
+	    }
+
+	    break;
+
+	case CAIRO_BO_EVENT_TYPE_STOP:
+	    e1 = ((cairo_bo_queue_event_t *) event)->e1;
+	    _cairo_bo_event_queue_delete (&event_queue, event);
+
+	    left = e1->prev;
+	    right = e1->next;
+
+	    _cairo_bo_sweep_line_delete (&sweep_line, e1);
+
+	    /* first, check to see if we have a continuation via a fresh edge */
+	    if (e1->deferred.right != NULL) {
+		e1->next = sweep_line.stopped;
+		if (sweep_line.stopped != NULL)
+		    sweep_line.stopped->prev = e1;
+		sweep_line.stopped = e1;
+		e1->prev = NULL;
+	    }
+
+	    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;
+	    }
+
+	    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);
+
+	    /* skip this intersection if its edges are not adjacent */
+	    if (e2 != e1->next)
+		break;
+
+	    left = e1->prev;
+	    right = e2->next;
+
+	    _cairo_bo_sweep_line_swap (&sweep_line, e1, e2);
+
+	    /* 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;
+	    }
+
+	    if (right != NULL) {
+		status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, e1, right);
+		if (unlikely (status))
+		    goto unwind;
+	    }
+
+	    break;
+	}
+    }
+
+    for (e1 = sweep_line.stopped; e1; e1 = e1->next) {
+	if (e1->deferred.right != NULL)
+	    _cairo_bo_edge_end (e1, e1->edge.bottom, polygon);
+    }
+ unwind:
+    _cairo_bo_event_queue_fini (&event_queue);
+
+    return status;
+}
+
+cairo_status_t
+_cairo_polygon_reduce (cairo_polygon_t *polygon,
+		       cairo_fill_rule_t fill_rule)
+{
+    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_limits;
+    int num_events;
+    int i;
+
+    num_events = polygon->num_edges;
+    if (unlikely (0 == num_events))
+	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))
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+	event_ptrs = (cairo_bo_event_t **) (events + num_events);
+    }
+
+    for (i = 0; i < num_events; i++) {
+	event_ptrs[i] = (cairo_bo_event_t *) &events[i];
+
+	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);
+
+	events[i].edge.edge = polygon->edges[i];
+	events[i].edge.deferred.right = NULL;
+	events[i].edge.prev = NULL;
+	events[i].edge.next = NULL;
+    }
+
+    num_limits = polygon->num_limits; polygon->num_limits = 0;
+    polygon->num_edges = 0;
+
+    status = _cairo_bentley_ottmann_tessellate_bo_edges (event_ptrs,
+							 num_events,
+							 fill_rule,
+							 polygon);
+     polygon->num_limits = num_limits;
+
+    if (events != stack_events)
+	free (events);
+
+    return status;
+}
diff --git a/src/cairo-polygon.c b/src/cairo-polygon.c
index c3f3631..cc9faae 100644
--- a/src/cairo-polygon.c
+++ b/src/cairo-polygon.c
@@ -37,8 +37,14 @@
 
 #include "cairoint.h"
 
+#include "cairo-boxes-private.h"
 #include "cairo-error-private.h"
 
+static void
+_cairo_polygon_add_edge (cairo_polygon_t *polygon,
+			 const cairo_point_t *p1,
+			 const cairo_point_t *p2);
+
 void
 _cairo_polygon_init (cairo_polygon_t *polygon,
 		     const cairo_box_t *limits,
@@ -80,6 +86,111 @@ _cairo_polygon_init (cairo_polygon_t *polygon,
 }
 
 void
+_cairo_polygon_init_with_clip (cairo_polygon_t *polygon,
+			       const cairo_clip_t *clip)
+{
+    if (clip)
+	_cairo_polygon_init (polygon, clip->boxes, clip->num_boxes);
+    else
+	_cairo_polygon_init (polygon, 0, 0);
+}
+
+cairo_status_t
+_cairo_polygon_init_boxes (cairo_polygon_t *polygon,
+			   const cairo_boxes_t *boxes)
+{
+    const struct _cairo_boxes_chunk *chunk;
+    int i;
+
+    VG (VALGRIND_MAKE_MEM_UNDEFINED (polygon, sizeof (cairo_polygon_t)));
+
+    polygon->status = CAIRO_STATUS_SUCCESS;
+
+    polygon->num_edges = 0;
+
+    polygon->edges = polygon->edges_embedded;
+    polygon->edges_size = ARRAY_LENGTH (polygon->edges_embedded);
+    if (boxes->num_boxes > ARRAY_LENGTH (polygon->edges_embedded)/2) {
+	polygon->edges_size = 2 * boxes->num_boxes;
+	polygon->edges = _cairo_malloc_ab (polygon->edges_size,
+					   2*sizeof(cairo_edge_t));
+	if (unlikely (polygon->edges == NULL))
+	    return polygon->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    }
+
+    polygon->extents.p1.x = polygon->extents.p1.y = INT32_MAX;
+    polygon->extents.p2.x = polygon->extents.p2.y = INT32_MIN;
+
+    polygon->limits = NULL;
+    polygon->num_limits = 0;
+
+    for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
+	    for (i = 0; i < chunk->count; i++) {
+		    cairo_point_t p1, p2;
+
+		    p1 = chunk->base[i].p1;
+		    p2.x = p1.x;
+		    p2.y = chunk->base[i].p2.y;
+		    _cairo_polygon_add_edge (polygon, &p1, &p2);
+
+		    p1 = chunk->base[i].p2;
+		    p2.x = p1.x;
+		    p2.y = chunk->base[i].p1.y;
+		    _cairo_polygon_add_edge (polygon, &p1, &p2);
+	    }
+    }
+
+    return polygon->status;
+}
+
+cairo_status_t
+_cairo_polygon_init_box_array (cairo_polygon_t *polygon,
+			       cairo_box_t *boxes,
+			       int num_boxes)
+{
+    int i;
+
+    VG (VALGRIND_MAKE_MEM_UNDEFINED (polygon, sizeof (cairo_polygon_t)));
+
+    polygon->status = CAIRO_STATUS_SUCCESS;
+
+    polygon->num_edges = 0;
+
+    polygon->edges = polygon->edges_embedded;
+    polygon->edges_size = ARRAY_LENGTH (polygon->edges_embedded);
+    if (num_boxes > ARRAY_LENGTH (polygon->edges_embedded)/2) {
+	polygon->edges_size = 2 * num_boxes;
+	polygon->edges = _cairo_malloc_ab (polygon->edges_size,
+					   2*sizeof(cairo_edge_t));
+	if (unlikely (polygon->edges == NULL))
+	    return polygon->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    }
+
+    polygon->extents.p1.x = polygon->extents.p1.y = INT32_MAX;
+    polygon->extents.p2.x = polygon->extents.p2.y = INT32_MIN;
+
+    polygon->limits = NULL;
+    polygon->num_limits = 0;
+
+    for (i = 0; i < num_boxes; i++) {
+	cairo_point_t p1, p2;
+
+	p1 = boxes[i].p1;
+	p2.x = p1.x;
+	p2.y = boxes[i].p2.y;
+	_cairo_polygon_add_edge (polygon, &p1, &p2);
+
+	p1 = boxes[i].p2;
+	p2.x = p1.x;
+	p2.y = boxes[i].p1.y;
+	_cairo_polygon_add_edge (polygon, &p1, &p2);
+    }
+
+    return polygon->status;
+}
+
+
+void
 _cairo_polygon_fini (cairo_polygon_t *polygon)
 {
     if (polygon->edges != polygon->edges_embedded)
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 0b5f8e9..80ad474 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -572,7 +572,7 @@ _cairo_ps_emit_imagemask (cairo_image_surface_t *image,
     return _cairo_output_stream_get_status (stream);
 }
 
-static cairo_status_t
+static cairo_int_status_t
 _cairo_ps_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_subset,
 					    void		       *closure)
 {
@@ -704,16 +704,15 @@ _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t		*surface,
     return CAIRO_STATUS_SUCCESS;
 }
 
-static cairo_status_t
+static cairo_int_status_t
 _cairo_ps_surface_emit_unscaled_font_subset (cairo_scaled_font_subset_t	*font_subset,
 				            void			*closure)
 {
     cairo_ps_surface_t *surface = closure;
-    cairo_status_t status;
-
+    cairo_int_status_t status;
 
     status = _cairo_scaled_font_subset_create_glyph_names (font_subset);
-    if (_cairo_status_is_error (status))
+    if (_cairo_int_status_is_error (status))
 	return status;
 
     status = _cairo_ps_surface_emit_type1_font_subset (surface, font_subset);
@@ -732,15 +731,15 @@ _cairo_ps_surface_emit_unscaled_font_subset (cairo_scaled_font_subset_t	*font_su
     return CAIRO_STATUS_SUCCESS;
 }
 
-static cairo_status_t
+static cairo_int_status_t
 _cairo_ps_surface_emit_scaled_font_subset (cairo_scaled_font_subset_t *font_subset,
                                            void			      *closure)
 {
     cairo_ps_surface_t *surface = closure;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     status = _cairo_scaled_font_subset_create_glyph_names (font_subset);
-    if (_cairo_status_is_error (status))
+    if (_cairo_int_status_is_error (status))
 	return status;
 
     status = _cairo_ps_surface_emit_type3_font_subset (surface, font_subset);
@@ -748,7 +747,7 @@ _cairo_ps_surface_emit_scaled_font_subset (cairo_scaled_font_subset_t *font_subs
 	return status;
 
     ASSERT_NOT_REACHED;
-    return CAIRO_STATUS_SUCCESS;
+    return CAIRO_INT_STATUS_SUCCESS;
 }
 
 static cairo_status_t
@@ -1640,7 +1639,7 @@ _cairo_ps_surface_end_page (cairo_ps_surface_t *surface)
     if (unlikely (status))
 	return status;
 
-    if (surface->clipper.clip.path != NULL) {
+    if (surface->clipper.clip != NULL) {
 	_cairo_output_stream_printf (surface->stream, "Q Q\n");
 	_cairo_surface_clipper_reset (&surface->clipper);
     } else
@@ -2444,7 +2443,7 @@ _cairo_ps_surface_emit_recording_surface (cairo_ps_surface_t *surface,
     cairo_content_t old_content;
     cairo_rectangle_int_t old_page_bbox;
     cairo_box_t bbox;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     old_content = surface->content;
     old_width = surface->width;
@@ -2516,7 +2515,7 @@ _cairo_ps_surface_emit_recording_surface (cairo_ps_surface_t *surface,
     return CAIRO_STATUS_SUCCESS;
 }
 
-static cairo_status_t
+static cairo_int_status_t
 _cairo_ps_surface_emit_recording_subsurface (cairo_ps_surface_t *surface,
 					     cairo_surface_t    *recording_surface,
 					     const cairo_rectangle_int_t *extents)
@@ -2525,7 +2524,7 @@ _cairo_ps_surface_emit_recording_subsurface (cairo_ps_surface_t *surface,
     cairo_matrix_t old_cairo_to_ps;
     cairo_content_t old_content;
     cairo_rectangle_int_t old_page_bbox;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     old_content = surface->content;
     old_width = surface->width;
@@ -2733,7 +2732,7 @@ _cairo_ps_surface_emit_surface (cairo_ps_surface_t      *surface,
 				int                      width,
 				int                      height)
 {
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     if (pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
 	cairo_surface_t *source = pattern->surface;
@@ -3576,7 +3575,7 @@ static cairo_int_status_t
 _cairo_ps_surface_paint (void			*abstract_surface,
 			 cairo_operator_t	 op,
 			 const cairo_pattern_t	*source,
-			 cairo_clip_t		*clip)
+			 const cairo_clip_t		*clip)
 {
     cairo_ps_surface_t *surface = abstract_surface;
     cairo_output_stream_t *stream = surface->stream;
@@ -3635,13 +3634,13 @@ static cairo_int_status_t
 _cairo_ps_surface_stroke (void			*abstract_surface,
 			  cairo_operator_t	 op,
 			  const cairo_pattern_t	*source,
-			  cairo_path_fixed_t	*path,
+			  const cairo_path_fixed_t	*path,
 			  const cairo_stroke_style_t	*style,
 			  const cairo_matrix_t	*ctm,
 			  const cairo_matrix_t	*ctm_inverse,
 			  double		 tolerance,
 			  cairo_antialias_t	 antialias,
-			  cairo_clip_t		*clip)
+			  const cairo_clip_t		*clip)
 {
     cairo_ps_surface_t *surface = abstract_surface;
     cairo_composite_rectangles_t extents;
@@ -3699,11 +3698,11 @@ static cairo_int_status_t
 _cairo_ps_surface_fill (void		*abstract_surface,
 			cairo_operator_t	 op,
 			const cairo_pattern_t	*source,
-			cairo_path_fixed_t	*path,
+			const cairo_path_fixed_t*path,
 			cairo_fill_rule_t	 fill_rule,
 			double			 tolerance,
 			cairo_antialias_t	 antialias,
-			cairo_clip_t		*clip)
+			const cairo_clip_t		*clip)
 {
     cairo_ps_surface_t *surface = abstract_surface;
     cairo_composite_rectangles_t extents;
@@ -3786,7 +3785,7 @@ _cairo_ps_surface_show_glyphs (void		     *abstract_surface,
 			       cairo_glyph_t         *glyphs,
 			       int		      num_glyphs,
 			       cairo_scaled_font_t   *scaled_font,
-			       cairo_clip_t	     *clip,
+			       const cairo_clip_t    *clip,
 			       int		     *remaining_glyphs)
 {
     cairo_ps_surface_t *surface = abstract_surface;
@@ -3840,7 +3839,7 @@ _cairo_ps_surface_set_paginated_mode (void			*abstract_surface,
 
     surface->paginated_mode = paginated_mode;
 
-    if (surface->clipper.clip.path != NULL) {
+    if (surface->clipper.clip != NULL) {
 	status = _cairo_pdf_operators_flush (&surface->pdf_operators);
 
 	_cairo_output_stream_printf (surface->stream, "Q q\n");
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 9628c87..5b99680 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -1725,7 +1725,7 @@ static cairo_int_status_t
 _cairo_quartz_surface_paint_cg (cairo_quartz_surface_t *surface,
 				cairo_operator_t op,
 				const cairo_pattern_t *source,
-				cairo_clip_t *clip)
+				const cairo_clip_t *clip)
 {
     cairo_quartz_drawing_state_t state;
     cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
@@ -1752,7 +1752,7 @@ static cairo_int_status_t
 _cairo_quartz_surface_paint (void *abstract_surface,
 			     cairo_operator_t op,
 			     const cairo_pattern_t *source,
-			     cairo_clip_t *clip)
+			     const cairo_clip_t *clip)
 {
     cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
     cairo_int_status_t rv;
@@ -1779,11 +1779,11 @@ static cairo_int_status_t
 _cairo_quartz_surface_fill_cg (cairo_quartz_surface_t *surface,
 			       cairo_operator_t op,
 			       const cairo_pattern_t *source,
-			       cairo_path_fixed_t *path,
+			       const cairo_path_fixed_t *path,
 			       cairo_fill_rule_t fill_rule,
 			       double tolerance,
 			       cairo_antialias_t antialias,
-			       cairo_clip_t *clip)
+			       const cairo_clip_t *clip)
 {
     cairo_quartz_drawing_state_t state;
     cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
@@ -1827,11 +1827,11 @@ static cairo_int_status_t
 _cairo_quartz_surface_fill (void *abstract_surface,
 			    cairo_operator_t op,
 			    const cairo_pattern_t *source,
-			    cairo_path_fixed_t *path,
+			    const cairo_path_fixed_t *path,
 			    cairo_fill_rule_t fill_rule,
 			    double tolerance,
 			    cairo_antialias_t antialias,
-			    cairo_clip_t *clip)
+			    const cairo_clip_t *clip)
 {
     cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
     cairo_int_status_t rv;
@@ -1864,13 +1864,13 @@ static cairo_int_status_t
 _cairo_quartz_surface_stroke_cg (cairo_quartz_surface_t *surface,
 				 cairo_operator_t op,
 				 const cairo_pattern_t *source,
-				 cairo_path_fixed_t *path,
+				 const cairo_path_fixed_t *path,
 				 const cairo_stroke_style_t *style,
 				 const cairo_matrix_t *ctm,
 				 const cairo_matrix_t *ctm_inverse,
 				 double tolerance,
 				 cairo_antialias_t antialias,
-				 cairo_clip_t *clip)
+				 const cairo_clip_t *clip)
 {
     cairo_quartz_drawing_state_t state;
     cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
@@ -1947,13 +1947,13 @@ static cairo_int_status_t
 _cairo_quartz_surface_stroke (void *abstract_surface,
 			      cairo_operator_t op,
 			      const cairo_pattern_t *source,
-			      cairo_path_fixed_t *path,
+			      const cairo_path_fixed_t *path,
 			      const cairo_stroke_style_t *style,
 			      const cairo_matrix_t *ctm,
 			      const cairo_matrix_t *ctm_inverse,
 			      double tolerance,
 			      cairo_antialias_t antialias,
-			      cairo_clip_t *clip)
+			      const cairo_clip_t *clip)
 {
     cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
     cairo_int_status_t rv;
@@ -1987,7 +1987,7 @@ _cairo_quartz_surface_show_glyphs_cg (cairo_quartz_surface_t *surface,
 				      cairo_glyph_t *glyphs,
 				      int num_glyphs,
 				      cairo_scaled_font_t *scaled_font,
-				      cairo_clip_t *clip,
+				      const cairo_clip_t *clip,
 				      int *remaining_glyphs)
 {
     CGAffineTransform textTransform, invTextTransform;
@@ -2131,7 +2131,7 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface,
 				   cairo_glyph_t *glyphs,
 				   int num_glyphs,
 				   cairo_scaled_font_t *scaled_font,
-				   cairo_clip_t *clip,
+				   const cairo_clip_t *clip,
 				   int *remaining_glyphs)
 {
     cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
@@ -2248,7 +2248,7 @@ _cairo_quartz_surface_mask_cg (cairo_quartz_surface_t *surface,
 			       cairo_operator_t op,
 			       const cairo_pattern_t *source,
 			       const cairo_pattern_t *mask,
-			       cairo_clip_t *clip)
+			       const cairo_clip_t *clip)
 {
     cairo_surface_t *mask_surf;
     cairo_matrix_t matrix;
@@ -2350,7 +2350,7 @@ _cairo_quartz_surface_mask (void *abstract_surface,
 			    cairo_operator_t op,
 			    const cairo_pattern_t *source,
 			    const cairo_pattern_t *mask,
-			    cairo_clip_t *clip)
+			    const cairo_clip_t *clip)
 {
     cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
     cairo_int_status_t rv;
diff --git a/src/cairo-recording-surface-private.h b/src/cairo-recording-surface-private.h
index 3d8cba3..a901e7b 100644
--- a/src/cairo-recording-surface-private.h
+++ b/src/cairo-recording-surface-private.h
@@ -40,7 +40,6 @@
 #include "cairoint.h"
 #include "cairo-path-fixed-private.h"
 #include "cairo-pattern-private.h"
-#include "cairo-clip-private.h"
 
 typedef enum {
     /* The 5 basic drawing operations. */
@@ -61,7 +60,7 @@ typedef struct _cairo_command_header {
     cairo_command_type_t	 type;
     cairo_recording_region_type_t     region;
     cairo_operator_t		 op;
-    cairo_clip_t		 clip;
+    cairo_clip_t		*clip;
 } cairo_command_header_t;
 
 typedef struct _cairo_command_paint {
@@ -130,8 +129,6 @@ typedef struct _cairo_recording_surface {
     cairo_rectangle_int_t extents;
     cairo_bool_t unbounded;
 
-    cairo_clip_t clip;
-
     cairo_array_t commands;
 
     int replay_start_idx;
diff --git a/src/cairo-recording-surface.c b/src/cairo-recording-surface.c
index 84ae347..ea5ee01 100644
--- a/src/cairo-recording-surface.c
+++ b/src/cairo-recording-surface.c
@@ -136,7 +136,6 @@ cairo_recording_surface_create (cairo_content_t		 content,
 				const cairo_rectangle_t	*extents)
 {
     cairo_recording_surface_t *recording_surface;
-    cairo_status_t status;
 
     recording_surface = malloc (sizeof (cairo_recording_surface_t));
     if (unlikely (recording_surface == NULL))
@@ -150,7 +149,6 @@ cairo_recording_surface_create (cairo_content_t		 content,
     recording_surface->content = content;
 
     recording_surface->unbounded = TRUE;
-    _cairo_clip_init (&recording_surface->clip);
 
     /* unbounded -> 'infinite' extents */
     if (extents != NULL) {
@@ -162,13 +160,6 @@ cairo_recording_surface_create (cairo_content_t		 content,
 	recording_surface->extents.width = ceil (extents->x + extents->width) - recording_surface->extents.x;
 	recording_surface->extents.height = ceil (extents->y + extents->height) - recording_surface->extents.y;
 
-	status = _cairo_clip_rectangle (&recording_surface->clip,
-					&recording_surface->extents);
-	if (unlikely (status)) {
-	    free (recording_surface);
-	    return _cairo_surface_create_in_error (status);
-	}
-
 	recording_surface->unbounded = FALSE;
     }
 
@@ -239,12 +230,11 @@ _cairo_recording_surface_finish (void *abstract_surface)
 	    ASSERT_NOT_REACHED;
 	}
 
-	_cairo_clip_fini (&command->header.clip);
+	_cairo_clip_destroy (command->header.clip);
 	free (command);
     }
 
     _cairo_array_fini (&recording_surface->commands);
-    _cairo_clip_fini (&recording_surface->clip);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -321,16 +311,14 @@ _command_init (cairo_recording_surface_t *recording_surface,
 	       cairo_command_header_t *command,
 	       cairo_command_type_t type,
 	       cairo_operator_t op,
-	       cairo_clip_t *clip)
+	       const cairo_clip_t *clip)
 {
     cairo_status_t status = CAIRO_STATUS_SUCCESS;
 
     command->type = type;
     command->op = op;
     command->region = CAIRO_RECORDING_REGION_ALL;
-    _cairo_clip_init_copy (&command->clip, clip);
-    if (recording_surface->clip.path != NULL)
-	status = _cairo_clip_apply_clip (&command->clip, &recording_surface->clip);
+    command->clip = _cairo_clip_copy (clip);
 
     return status;
 }
@@ -339,7 +327,7 @@ static cairo_int_status_t
 _cairo_recording_surface_paint (void			  *abstract_surface,
 				cairo_operator_t	   op,
 				const cairo_pattern_t	  *source,
-				cairo_clip_t		  *clip)
+				const cairo_clip_t		  *clip)
 {
     cairo_status_t status;
     cairo_recording_surface_t *recording_surface = abstract_surface;
@@ -373,7 +361,7 @@ _cairo_recording_surface_paint (void			  *abstract_surface,
   CLEANUP_SOURCE:
     _cairo_pattern_fini (&command->source.base);
   CLEANUP_COMMAND:
-    _cairo_clip_fini (&command->header.clip);
+    _cairo_clip_destroy (command->header.clip);
     free (command);
     return status;
 }
@@ -383,7 +371,7 @@ _cairo_recording_surface_mask (void			*abstract_surface,
 			       cairo_operator_t		 op,
 			       const cairo_pattern_t	*source,
 			       const cairo_pattern_t	*mask,
-			       cairo_clip_t		*clip)
+			       const cairo_clip_t	*clip)
 {
     cairo_status_t status;
     cairo_recording_surface_t *recording_surface = abstract_surface;
@@ -417,7 +405,7 @@ _cairo_recording_surface_mask (void			*abstract_surface,
   CLEANUP_SOURCE:
     _cairo_pattern_fini (&command->source.base);
   CLEANUP_COMMAND:
-    _cairo_clip_fini (&command->header.clip);
+    _cairo_clip_destroy (command->header.clip);
     free (command);
     return status;
 }
@@ -426,13 +414,13 @@ static cairo_int_status_t
 _cairo_recording_surface_stroke (void			*abstract_surface,
 				 cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
-				 cairo_path_fixed_t	*path,
+				 const cairo_path_fixed_t	*path,
 				 const cairo_stroke_style_t	*style,
 				 const cairo_matrix_t		*ctm,
 				 const cairo_matrix_t		*ctm_inverse,
 				 double			 tolerance,
 				 cairo_antialias_t	 antialias,
-				 cairo_clip_t		*clip)
+				 const cairo_clip_t	*clip)
 {
     cairo_status_t status;
     cairo_recording_surface_t *recording_surface = abstract_surface;
@@ -477,7 +465,7 @@ _cairo_recording_surface_stroke (void			*abstract_surface,
   CLEANUP_SOURCE:
     _cairo_pattern_fini (&command->source.base);
   CLEANUP_COMMAND:
-    _cairo_clip_fini (&command->header.clip);
+    _cairo_clip_destroy (command->header.clip);
     free (command);
     return status;
 }
@@ -486,11 +474,11 @@ static cairo_int_status_t
 _cairo_recording_surface_fill (void			*abstract_surface,
 			       cairo_operator_t		 op,
 			       const cairo_pattern_t	*source,
-			       cairo_path_fixed_t	*path,
+			       const cairo_path_fixed_t	*path,
 			       cairo_fill_rule_t	 fill_rule,
 			       double			 tolerance,
 			       cairo_antialias_t	 antialias,
-			       cairo_clip_t		*clip)
+			       const cairo_clip_t	*clip)
 {
     cairo_status_t status;
     cairo_recording_surface_t *recording_surface = abstract_surface;
@@ -528,7 +516,7 @@ _cairo_recording_surface_fill (void			*abstract_surface,
   CLEANUP_SOURCE:
     _cairo_pattern_fini (&command->source.base);
   CLEANUP_COMMAND:
-    _cairo_clip_fini (&command->header.clip);
+    _cairo_clip_destroy (command->header.clip);
     free (command);
     return status;
 }
@@ -551,7 +539,7 @@ _cairo_recording_surface_show_text_glyphs (void				*abstract_surface,
 					   int				 num_clusters,
 					   cairo_text_cluster_flags_t	 cluster_flags,
 					   cairo_scaled_font_t		*scaled_font,
-					   cairo_clip_t			*clip)
+					   const cairo_clip_t		*clip)
 {
     cairo_status_t status;
     cairo_recording_surface_t *recording_surface = abstract_surface;
@@ -622,7 +610,7 @@ _cairo_recording_surface_show_text_glyphs (void				*abstract_surface,
 
     _cairo_pattern_fini (&command->source.base);
   CLEANUP_COMMAND:
-    _cairo_clip_fini (&command->header.clip);
+    _cairo_clip_destroy (command->header.clip);
     free (command);
     return status;
 }
@@ -661,8 +649,6 @@ _cairo_recording_surface_snapshot (void *abstract_other)
     recording_surface->unbounded = other->unbounded;
     recording_surface->content = other->content;
 
-    _cairo_clip_init_copy (&recording_surface->clip, &other->clip);
-
     /* XXX We should in theory be able to reuse the original array, but we
      * need to handle reference cycles during subsurface and self-copy.
      */
@@ -795,7 +781,7 @@ _cairo_recording_surface_get_path (cairo_surface_t    *surface,
 							command->stroke.tolerance,
 							&traps);
 
-	    if (status == CAIRO_STATUS_SUCCESS)
+	    if (status == CAIRO_INT_STATUS_SUCCESS)
 		status = _cairo_traps_path (&traps, path);
 
 	    _cairo_traps_fini (&traps);
@@ -828,7 +814,6 @@ _cairo_recording_surface_get_path (cairo_surface_t    *surface,
     return _cairo_surface_set_error (surface, status);
 }
 
-#define _clip(c) ((c)->header.clip.path ? &(c)->header.clip : NULL)
 static cairo_status_t
 _cairo_recording_surface_replay_internal (cairo_surface_t	     *surface,
 					  const cairo_rectangle_int_t *surface_extents,
@@ -867,18 +852,24 @@ _cairo_recording_surface_replay_internal (cairo_surface_t	     *surface,
 
     for (i = recording_surface->replay_start_idx; i < num_elements; i++) {
 	cairo_command_t *command = elements[i];
+	cairo_clip_t *clip = command->header.clip;
 
 	if (type == CAIRO_RECORDING_REPLAY && region != CAIRO_RECORDING_REGION_ALL) {
 	    if (command->header.region != region)
 		continue;
         }
 
+	if (! recording_surface->unbounded)
+		clip = _cairo_clip_copy_intersect_rectangle (clip, &recording_surface->extents);
+	if (_cairo_clip_is_all_clipped (clip))
+		continue;
+
 	switch (command->header.type) {
 	case CAIRO_COMMAND_PAINT:
 	    status = _cairo_surface_wrapper_paint (&wrapper,
 						   command->header.op,
 						   &command->paint.source.base,
-						   _clip (command));
+						   clip);
 	    break;
 
 	case CAIRO_COMMAND_MASK:
@@ -886,7 +877,7 @@ _cairo_recording_surface_replay_internal (cairo_surface_t	     *surface,
 						  command->header.op,
 						  &command->mask.source.base,
 						  &command->mask.mask.base,
-						  _clip (command));
+						  clip);
 	    break;
 
 	case CAIRO_COMMAND_STROKE:
@@ -900,7 +891,7 @@ _cairo_recording_surface_replay_internal (cairo_surface_t	     *surface,
 						    &command->stroke.ctm_inverse,
 						    command->stroke.tolerance,
 						    command->stroke.antialias,
-						    _clip (command));
+						    clip);
 	    break;
 	}
 	case CAIRO_COMMAND_FILL:
@@ -938,7 +929,7 @@ _cairo_recording_surface_replay_internal (cairo_surface_t	     *surface,
 							     &stroke_command->stroke.ctm_inverse,
 							     stroke_command->stroke.tolerance,
 							     stroke_command->stroke.antialias,
-							     _clip (command));
+							     clip);
 		i++;
 	    }
 	    else
@@ -950,7 +941,7 @@ _cairo_recording_surface_replay_internal (cairo_surface_t	     *surface,
 						      command->fill.fill_rule,
 						      command->fill.tolerance,
 						      command->fill.antialias,
-						      _clip (command));
+						      clip);
 	    }
 	    break;
 	}
@@ -980,7 +971,7 @@ _cairo_recording_surface_replay_internal (cairo_surface_t	     *surface,
 							      command->show_text_glyphs.clusters, command->show_text_glyphs.num_clusters,
 							      command->show_text_glyphs.cluster_flags,
 							      command->show_text_glyphs.scaled_font,
-							      _clip (command));
+							      clip);
 	    free (glyphs_copy);
 	    break;
 	}
@@ -989,29 +980,24 @@ _cairo_recording_surface_replay_internal (cairo_surface_t	     *surface,
 	}
 
 	if (type == CAIRO_RECORDING_CREATE_REGIONS) {
-	    if (status == CAIRO_STATUS_SUCCESS) {
+	    if (status == CAIRO_INT_STATUS_SUCCESS) {
 		command->header.region = CAIRO_RECORDING_REGION_NATIVE;
 	    } else if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK) {
 		command->header.region = CAIRO_RECORDING_REGION_IMAGE_FALLBACK;
-		status = CAIRO_STATUS_SUCCESS;
+		status = CAIRO_INT_STATUS_SUCCESS;
 	    } else {
-		assert (_cairo_status_is_error (status));
+		assert (_cairo_int_status_is_error (status));
 	    }
 	}
 
+	if (clip != command->header.clip)
+	    _cairo_clip_destroy (clip);
+
 	if (unlikely (status))
 	    break;
     }
 
-    /* free up any caches */
-    for (i = recording_surface->replay_start_idx; i < num_elements; i++) {
-	cairo_command_t *command = elements[i];
-
-	_cairo_clip_drop_cache (&command->header.clip);
-    }
-
     _cairo_surface_wrapper_fini (&wrapper);
-
     return _cairo_surface_set_error (surface, status);
 }
 
diff --git a/src/cairo-scaled-font-subsets-private.h b/src/cairo-scaled-font-subsets-private.h
index 1f952c4..1504eaa 100644
--- a/src/cairo-scaled-font-subsets-private.h
+++ b/src/cairo-scaled-font-subsets-private.h
@@ -216,11 +216,11 @@ cairo_private cairo_status_t
 _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t	*font_subsets,
 				      cairo_scaled_font_t		*scaled_font,
 				      unsigned long			 scaled_font_glyph_index,
-				      const char * 			 utf8,
+				      const char *			 utf8,
 				      int				 utf8_len,
                                       cairo_scaled_font_subsets_glyph_t *subset_glyph_ret);
 
-typedef cairo_status_t
+typedef cairo_int_status_t
 (*cairo_scaled_font_subset_callback_func_t) (cairo_scaled_font_subset_t	*font_subset,
 					     void			*closure);
 
diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index 433ca3f..dd6b824 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -511,7 +511,7 @@ _cairo_sub_font_add_glyph (cairo_sub_font_t	   *sub_font,
     int *num_glyphs_in_subset_ptr;
     double x_advance;
     double y_advance;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     _cairo_scaled_font_freeze_cache (sub_font->scaled_font);
     status = _cairo_scaled_glyph_lookup (sub_font->scaled_font,
@@ -828,7 +828,7 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t	*subsets,
     cairo_matrix_t identity;
     cairo_font_options_t font_options;
     cairo_scaled_font_t	*unscaled_font;
-    cairo_status_t status;
+    cairo_int_status_t status;
     int max_glyphs;
     cairo_bool_t type1_font;
 
@@ -881,10 +881,10 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t	*subsets,
 					     &scaled_glyph);
 	_cairo_scaled_font_thaw_cache (scaled_font);
     }
-    if (_cairo_status_is_error (status))
+    if (_cairo_int_status_is_error (status))
         return status;
 
-    if (status == CAIRO_STATUS_SUCCESS &&
+    if (status == CAIRO_INT_STATUS_SUCCESS &&
 	subsets->type != CAIRO_SUBSETS_SCALED &&
 	! _cairo_font_face_is_user (scaled_font->font_face))
     {
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index c6c599b..6cca4ac 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -1858,7 +1858,7 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t   *scaled_font,
 				  cairo_text_cluster_flags_t *cluster_flags)
 {
     int num_chars = 0;
-    cairo_status_t status;
+    cairo_int_status_t status;
     cairo_glyph_t *orig_glyphs;
     cairo_text_cluster_t *orig_clusters;
 
@@ -1941,7 +1941,7 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t   *scaled_font,
 						       clusters, num_clusters,
 						       cluster_flags);
         if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
-	    if (status == CAIRO_STATUS_SUCCESS) {
+	    if (status == CAIRO_INT_STATUS_SUCCESS) {
 	        /* The checks here are crude; we only should do them in
 		 * user-font backend, but they don't hurt here.  This stuff
 		 * can be hard to get right. */
@@ -2193,7 +2193,7 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t	*scaled_font,
 				int			 num_glyphs,
 				cairo_region_t		*clip_region)
 {
-    cairo_status_t status;
+    cairo_int_status_t status;
     cairo_surface_t *mask = NULL;
     cairo_format_t mask_format = CAIRO_FORMAT_A1; /* shut gcc up */
     cairo_surface_pattern_t mask_pattern;
@@ -2224,7 +2224,7 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t	*scaled_font,
 	glyphs += num_glyphs - remaining_glyphs;
 	num_glyphs = remaining_glyphs;
 	if (remaining_glyphs == 0)
-	    status = CAIRO_STATUS_SUCCESS;
+	    status = CAIRO_INT_STATUS_SUCCESS;
 	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
 	    return _cairo_scaled_font_set_error (scaled_font, status);
     }
@@ -2480,7 +2480,7 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
 			       int		    num_glyphs,
 			       cairo_path_fixed_t  *path)
 {
-    cairo_status_t status;
+    cairo_int_status_t status;
     int	i;
 
     status = scaled_font->status;
@@ -2495,7 +2495,7 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
 					     glyphs[i].index,
 					     CAIRO_SCALED_GLYPH_INFO_PATH,
 					     &scaled_glyph);
-	if (status == CAIRO_STATUS_SUCCESS) {
+	if (status == CAIRO_INT_STATUS_SUCCESS) {
 	    status = _cairo_path_fixed_append (path,
 					       scaled_glyph->path,
 					       _cairo_fixed_from_double (glyphs[i].x),
@@ -2787,7 +2787,7 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
 			    cairo_scaled_glyph_info_t info,
 			    cairo_scaled_glyph_t **scaled_glyph_ret)
 {
-    cairo_status_t		 status = CAIRO_STATUS_SUCCESS;
+    cairo_int_status_t		 status = CAIRO_INT_STATUS_SUCCESS;
     cairo_scaled_glyph_t	*scaled_glyph;
     cairo_scaled_glyph_info_t	 need_info;
 
diff --git a/src/cairo-script-surface.c b/src/cairo-script-surface.c
index 4ca0faf..6f46320 100644
--- a/src/cairo-script-surface.c
+++ b/src/cairo-script-surface.c
@@ -839,6 +839,7 @@ _format_to_string (cairo_format_t format)
 {
     switch (format) {
     case CAIRO_FORMAT_ARGB32:  return "ARGB32";
+    case CAIRO_FORMAT_RGB30:   return "RGB30";
     case CAIRO_FORMAT_RGB24:   return "RGB24";
     case CAIRO_FORMAT_RGB16_565: return "RGB16_565";
     case CAIRO_FORMAT_A8:      return "A8";
@@ -1204,6 +1205,7 @@ _write_image_surface (cairo_output_stream_t *output,
 	    data += stride;
 	}
 	break;
+    case CAIRO_FORMAT_RGB30:
     case CAIRO_FORMAT_ARGB32:
 	for (row = image->height; row--; ) {
 	    uint32_t *src = (uint32_t *) data;
@@ -1279,14 +1281,14 @@ _undef (void *data)
     free (def);
 }
 
-static cairo_status_t
+static cairo_int_status_t
 _emit_image_surface (cairo_script_surface_t *surface,
 		     cairo_image_surface_t *image)
 {
     cairo_script_context_t *ctx = to_context (surface);
     cairo_output_stream_t *base85_stream;
     cairo_output_stream_t *zlib_stream;
-    cairo_status_t status, status2;
+    cairo_int_status_t status, status2;
     const uint8_t *mime_data;
     unsigned long mime_data_length;
     struct def *tag;
@@ -1297,11 +1299,11 @@ _emit_image_surface (cairo_script_surface_t *surface,
 	_cairo_output_stream_printf (ctx->stream,
 				     "s%u ",
 				     image->base.unique_id);
-	return CAIRO_STATUS_SUCCESS;
+	return CAIRO_INT_STATUS_SUCCESS;
     }
 
     status = _emit_png_surface (surface, image);
-    if (_cairo_status_is_error (status)) {
+    if (_cairo_int_status_is_error (status)) {
 	return status;
     } else if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
 	cairo_image_surface_t *clone;
@@ -1336,6 +1338,7 @@ _emit_image_surface (cairo_script_surface_t *surface,
 	case CAIRO_FORMAT_RGB24:
 	    len = clone->width * 3;
 	    break;
+	case CAIRO_FORMAT_RGB30:
 	case CAIRO_FORMAT_ARGB32:
 	    len = clone->width * 4;
 	    break;
@@ -1357,10 +1360,10 @@ _emit_image_surface (cairo_script_surface_t *surface,
 	    status = _write_image_surface (zlib_stream, clone);
 
 	    status2 = _cairo_output_stream_destroy (zlib_stream);
-	    if (status == CAIRO_STATUS_SUCCESS)
+	    if (status == CAIRO_INT_STATUS_SUCCESS)
 		status = status2;
 	    status2 = _cairo_output_stream_destroy (base85_stream);
-	    if (status == CAIRO_STATUS_SUCCESS)
+	    if (status == CAIRO_INT_STATUS_SUCCESS)
 		status = status2;
 	    if (unlikely (status))
 		return status;
@@ -1370,7 +1373,7 @@ _emit_image_surface (cairo_script_surface_t *surface,
 	    base85_stream = _cairo_base85_stream_create (ctx->stream);
 	    status = _write_image_surface (base85_stream, clone);
 	    status2 = _cairo_output_stream_destroy (base85_stream);
-	    if (status == CAIRO_STATUS_SUCCESS)
+	    if (status == CAIRO_INT_STATUS_SUCCESS)
 		status = status2;
 	    if (unlikely (status))
 		return status;
@@ -1432,10 +1435,10 @@ _emit_image_surface (cairo_script_surface_t *surface,
 	_cairo_output_stream_puts (ctx->stream, "~> set-mime-data\n");
     }
 
-    return CAIRO_STATUS_SUCCESS;
+    return CAIRO_INT_STATUS_SUCCESS;
 }
 
-static cairo_status_t
+static cairo_int_status_t
 _emit_image_surface_pattern (cairo_script_surface_t *surface,
 			     cairo_surface_t *source)
 {
@@ -1458,12 +1461,12 @@ _emit_image_surface_pattern (cairo_script_surface_t *surface,
     return status;
 }
 
-static cairo_status_t
+static cairo_int_status_t
 _emit_subsurface_pattern (cairo_script_surface_t *surface,
 			  cairo_surface_subsurface_t *sub)
 {
     cairo_surface_t *source = sub->target;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     switch ((int) source->backend->type) {
     case CAIRO_SURFACE_TYPE_RECORDING:
@@ -1485,16 +1488,16 @@ _emit_subsurface_pattern (cairo_script_surface_t *surface,
 				 sub->extents.y,
 				 sub->extents.width,
 				 sub->extents.height);
-    return CAIRO_STATUS_SUCCESS;
+    return CAIRO_INT_STATUS_SUCCESS;
 }
 
-static cairo_status_t
+static cairo_int_status_t
 _emit_surface_pattern (cairo_script_surface_t *surface,
 		       const cairo_pattern_t *pattern)
 {
     cairo_surface_pattern_t *surface_pattern;
     cairo_surface_t *source;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     surface_pattern = (cairo_surface_pattern_t *) pattern;
     source = surface_pattern->surface;
@@ -1520,15 +1523,15 @@ _emit_surface_pattern (cairo_script_surface_t *surface,
 	return status;
 
     _cairo_output_stream_puts (to_context (surface)->stream, "pattern");
-    return CAIRO_STATUS_SUCCESS;
+    return CAIRO_INT_STATUS_SUCCESS;
 }
 
-static cairo_status_t
+static cairo_int_status_t
 _emit_pattern (cairo_script_surface_t *surface,
 	       const cairo_pattern_t *pattern)
 {
     cairo_script_context_t *ctx = to_context (surface);
-    cairo_status_t status;
+    cairo_int_status_t status;
     cairo_bool_t is_default_extend;
     cairo_bool_t need_newline = TRUE;
 
@@ -1599,17 +1602,17 @@ _emit_pattern (cairo_script_surface_t *surface,
     if (need_newline)
 	_cairo_output_stream_puts (ctx->stream, "\n ");
 
-    return CAIRO_STATUS_SUCCESS;
+    return CAIRO_INT_STATUS_SUCCESS;
 }
 
-static cairo_status_t
+static cairo_int_status_t
 _emit_identity (cairo_script_surface_t *surface,
 		cairo_bool_t *matrix_updated)
 {
     assert (target_is_active (surface));
 
     if (_cairo_matrix_is_identity (&surface->cr.current_ctm))
-	return CAIRO_STATUS_SUCCESS;
+	return CAIRO_INT_STATUS_SUCCESS;
 
     _cairo_output_stream_puts (to_context (surface)->stream,
 			       "identity set-matrix\n");
@@ -1617,26 +1620,26 @@ _emit_identity (cairo_script_surface_t *surface,
     *matrix_updated = TRUE;
     cairo_matrix_init_identity (&surface->cr.current_ctm);
 
-    return CAIRO_STATUS_SUCCESS;
+    return CAIRO_INT_STATUS_SUCCESS;
 }
 
-static cairo_status_t
+static cairo_int_status_t
 _emit_source (cairo_script_surface_t *surface,
 	      cairo_operator_t op,
 	      const cairo_pattern_t *source)
 {
     cairo_bool_t matrix_updated = FALSE;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     assert (target_is_active (surface));
 
     if (op == CAIRO_OPERATOR_CLEAR) {
 	/* the source is ignored, so don't change it */
-	return CAIRO_STATUS_SUCCESS;
+	return CAIRO_INT_STATUS_SUCCESS;
     }
 
     if (_cairo_pattern_equal (&surface->cr.current_source.base, source))
-	return CAIRO_STATUS_SUCCESS;
+	return CAIRO_INT_STATUS_SUCCESS;
 
     _cairo_pattern_fini (&surface->cr.current_source.base);
     status = _cairo_pattern_init_copy (&surface->cr.current_source.base,
@@ -1655,7 +1658,7 @@ _emit_source (cairo_script_surface_t *surface,
     assert (target_is_active (surface));
     _cairo_output_stream_puts (to_context (surface)->stream,
 			       " set-source\n");
-    return CAIRO_STATUS_SUCCESS;
+    return CAIRO_INT_STATUS_SUCCESS;
 }
 
 static cairo_status_t
@@ -1711,7 +1714,7 @@ _path_close (void *closure)
 
 static cairo_status_t
 _emit_path (cairo_script_surface_t *surface,
-	    cairo_path_fixed_t *path)
+	    const cairo_path_fixed_t *path)
 {
     cairo_script_context_t *ctx = to_context (surface);
     cairo_box_t box;
@@ -2263,7 +2266,7 @@ static cairo_int_status_t
 _cairo_script_surface_paint (void			*abstract_surface,
 			     cairo_operator_t		 op,
 			     const cairo_pattern_t	*source,
-			     cairo_clip_t		*clip)
+			     const cairo_clip_t		*clip)
 {
     cairo_script_surface_t *surface = abstract_surface;
     cairo_status_t status;
@@ -2310,7 +2313,7 @@ _cairo_script_surface_mask (void			*abstract_surface,
 			    cairo_operator_t		 op,
 			    const cairo_pattern_t	*source,
 			    const cairo_pattern_t	*mask,
-			    cairo_clip_t		*clip)
+			    const cairo_clip_t		*clip)
 {
     cairo_script_surface_t *surface = abstract_surface;
     cairo_status_t status;
@@ -2366,13 +2369,13 @@ static cairo_int_status_t
 _cairo_script_surface_stroke (void				*abstract_surface,
 			      cairo_operator_t			 op,
 			      const cairo_pattern_t		*source,
-			      cairo_path_fixed_t		*path,
+			      const cairo_path_fixed_t		*path,
 			      const cairo_stroke_style_t	*style,
 			      const cairo_matrix_t		*ctm,
 			      const cairo_matrix_t		*ctm_inverse,
 			      double				 tolerance,
 			      cairo_antialias_t			 antialias,
-			      cairo_clip_t			*clip)
+			      const cairo_clip_t		*clip)
 {
     cairo_script_surface_t *surface = abstract_surface;
     cairo_bool_t matrix_updated = FALSE;
@@ -2457,11 +2460,11 @@ static cairo_int_status_t
 _cairo_script_surface_fill (void			*abstract_surface,
 			    cairo_operator_t		 op,
 			    const cairo_pattern_t	*source,
-			    cairo_path_fixed_t		*path,
+			    const cairo_path_fixed_t	*path,
 			    cairo_fill_rule_t		 fill_rule,
 			    double			 tolerance,
 			    cairo_antialias_t		 antialias,
-			    cairo_clip_t		*clip)
+			    const cairo_clip_t		*clip)
 {
     cairo_script_surface_t *surface = abstract_surface;
     cairo_bool_t matrix_updated = FALSE;
@@ -2743,7 +2746,7 @@ _emit_scaled_font_init (cairo_script_surface_t *surface,
 {
     cairo_script_context_t *ctx = to_context (surface);
     cairo_script_surface_font_private_t *font_private;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     font_private = malloc (sizeof (cairo_script_surface_font_private_t));
     if (unlikely (font_private == NULL))
@@ -3135,7 +3138,7 @@ _cairo_script_surface_show_text_glyphs (void			    *abstract_surface,
 					int			     num_clusters,
 					cairo_text_cluster_flags_t   backward,
 					cairo_scaled_font_t	    *scaled_font,
-					cairo_clip_t		    *clip)
+					const cairo_clip_t	    *clip)
 {
     cairo_script_surface_t *surface = abstract_surface;
     cairo_script_context_t *ctx = to_context (surface);
diff --git a/src/cairo-spans.c b/src/cairo-spans.c
index 09af57a..f658650 100644
--- a/src/cairo-spans.c
+++ b/src/cairo-spans.c
@@ -27,7 +27,10 @@
 #include "cairoint.h"
 
 #include "cairo-composite-rectangles-private.h"
+#include "cairo-clip-private.h"
+#include "cairo-error-private.h"
 #include "cairo-fixed-private.h"
+#include "cairo-types-private.h"
 
 static cairo_scan_converter_t *
 _create_scan_converter (cairo_fill_rule_t			 fill_rule,
@@ -62,6 +65,31 @@ _cairo_surface_composite_polygon (cairo_surface_t	*surface,
     cairo_span_renderer_t *renderer;
     cairo_scan_converter_t *converter;
     cairo_status_t status;
+    cairo_clip_path_t *clip_path = rects->clip->path;
+
+    if (rects->is_bounded) {
+	if (polygon->num_edges == 0)
+	    return CAIRO_STATUS_SUCCESS;
+
+	if (clip_path) { /* XXX */
+	    cairo_polygon_t clipper;
+	    cairo_fill_rule_t clipper_fill_rule;
+	    cairo_antialias_t clipper_antialias;
+
+	    if (_cairo_clip_get_polygon (rects->clip, &clipper,
+					 &clipper_fill_rule,
+					 &clipper_antialias) == CAIRO_INT_STATUS_SUCCESS) {
+		if (clipper_antialias != CAIRO_ANTIALIAS_NONE &&
+		    _cairo_polygon_intersect (polygon, fill_rule,
+					      &clipper, clipper_fill_rule) == CAIRO_STATUS_SUCCESS)
+		{
+		    rects->clip->path = NULL;
+		}
+
+		_cairo_polygon_fini (&clipper);
+	    }
+	}
+    }
 
     converter = _create_scan_converter (fill_rule, antialias, rects);
     status = converter->add_polygon (converter, polygon);
@@ -81,6 +109,7 @@ _cairo_surface_composite_polygon (cairo_surface_t	*surface,
     renderer->destroy (renderer);
  CLEANUP_CONVERTER:
     converter->destroy (converter);
+    rects->clip->path = clip_path;
     return status;
 }
 
diff --git a/src/cairo-surface-clipper-private.h b/src/cairo-surface-clipper-private.h
index b9ca3cb..e5b00af 100644
--- a/src/cairo-surface-clipper-private.h
+++ b/src/cairo-surface-clipper-private.h
@@ -51,14 +51,13 @@ typedef cairo_status_t
 						     double,
 						     cairo_antialias_t);
 struct _cairo_surface_clipper {
-    cairo_clip_t clip;
-    cairo_bool_t is_clipped;
+    cairo_clip_t *clip;
     cairo_surface_clipper_intersect_clip_path_func_t intersect_clip_path;
 };
 
 cairo_private cairo_status_t
 _cairo_surface_clipper_set_clip (cairo_surface_clipper_t *clipper,
-				 cairo_clip_t *clip);
+				 const cairo_clip_t *clip);
 
 cairo_private void
 _cairo_surface_clipper_init (cairo_surface_clipper_t *clipper,
diff --git a/src/cairo-surface-clipper.c b/src/cairo-surface-clipper.c
index 9487300..c1644b4 100644
--- a/src/cairo-surface-clipper.c
+++ b/src/cairo-surface-clipper.c
@@ -39,6 +39,63 @@
 
 /* A collection of routines to facilitate vector surface clipping */
 
+/* XXX Eliminate repeated paths and nested clips */
+
+static cairo_status_t
+_cairo_path_fixed_add_box (cairo_path_fixed_t *path,
+			   const cairo_box_t *box)
+{
+    cairo_status_t status;
+
+    status = _cairo_path_fixed_move_to (path, box->p1.x, box->p1.y);
+    if (unlikely (status))
+	return status;
+
+    status = _cairo_path_fixed_line_to (path, box->p2.x, box->p1.y);
+    if (unlikely (status))
+	return status;
+
+    status = _cairo_path_fixed_line_to (path, box->p2.x, box->p2.y);
+    if (unlikely (status))
+	return status;
+
+    status = _cairo_path_fixed_line_to (path, box->p1.x, box->p2.y);
+    if (unlikely (status))
+	return status;
+
+    return _cairo_path_fixed_close_path (path);
+}
+
+static cairo_status_t
+_cairo_surface_clipper_intersect_clip_boxes (cairo_surface_clipper_t *clipper,
+					     const cairo_clip_t *clip)
+{
+    cairo_path_fixed_t path;
+    cairo_status_t status;
+    int i;
+
+    /* Reconstruct the path for the clip boxes.
+     * XXX maybe a new clipper callback?
+     */
+
+    _cairo_path_fixed_init (&path);
+    for (i = 0; i < clip->num_boxes; i++) {
+	status = _cairo_path_fixed_add_box (&path, &clip->boxes[i]);
+	if (unlikely (status)) {
+	    _cairo_path_fixed_fini (&path);
+	    return status;
+	}
+    }
+
+    status = clipper->intersect_clip_path (clipper, &path,
+					   CAIRO_FILL_RULE_WINDING,
+					   0.,
+					   CAIRO_ANTIALIAS_DEFAULT);
+    _cairo_path_fixed_init (&path);
+
+    return status;
+}
+
 static cairo_status_t
 _cairo_surface_clipper_intersect_clip_path_recursive (cairo_surface_clipper_t *clipper,
 						      cairo_clip_path_t *clip_path)
@@ -62,57 +119,33 @@ _cairo_surface_clipper_intersect_clip_path_recursive (cairo_surface_clipper_t *c
 
 cairo_status_t
 _cairo_surface_clipper_set_clip (cairo_surface_clipper_t *clipper,
-				 cairo_clip_t *clip)
+				 const cairo_clip_t *clip)
 {
     cairo_status_t status;
-    cairo_bool_t clear;
-
-    /* XXX as we cache a reference to the path, and compare every time,
-     * we may in future need to install a notification if the clip->path
-     * is every modified (e.g. cairo_clip_translate).
-     */
 
-    if (clip == NULL && clipper->clip.path == NULL)
+    if (_cairo_clip_equal (clip, clipper->clip))
 	return CAIRO_STATUS_SUCCESS;
 
-    if (clip != NULL && clipper->clip.path != NULL &&
-	_cairo_clip_equal (clip, &clipper->clip))
-    {
-	return CAIRO_STATUS_SUCCESS;
-    }
-
     /* all clipped out state should never propagate this far */
-    assert (clip == NULL || clip->path != NULL);
+    assert (!_cairo_clip_is_all_clipped (clip));
 
-    /* Check whether this clip is a continuation of the previous.
-     * If not, we have to remove the current clip and rebuild.
-     */
-    clear = clip == NULL || clip->path->prev != clipper->clip.path;
+    _cairo_clip_destroy (clipper->clip);
+    clipper->clip = _cairo_clip_copy (clip);
 
-    _cairo_clip_reset (&clipper->clip);
-    _cairo_clip_init_copy (&clipper->clip, clip);
+    status = clipper->intersect_clip_path (clipper, NULL, 0, 0, 0);
+    if (unlikely (status))
+	return status;
 
-    if (clear) {
-	clipper->is_clipped = FALSE;
-	status = clipper->intersect_clip_path (clipper, NULL, 0, 0, 0);
-	if (unlikely (status))
-	    return status;
+    if (clip == NULL)
+	return CAIRO_STATUS_SUCCESS;
 
-	if (clip != NULL && clip->path != NULL) {
-	    status =
-		_cairo_surface_clipper_intersect_clip_path_recursive (clipper,
-								      clip->path);
-	    clipper->is_clipped = TRUE;
-	}
-    } else {
-	cairo_clip_path_t *path = clip->path;
-
-	clipper->is_clipped = TRUE;
-	status = clipper->intersect_clip_path (clipper,
-					       &path->path,
-					       path->fill_rule,
-					       path->tolerance,
-					       path->antialias);
+    status = _cairo_surface_clipper_intersect_clip_boxes (clipper, clip);
+    if (unlikely (status))
+	return status;
+
+    if (clip->path != NULL) {
+	    status = _cairo_surface_clipper_intersect_clip_path_recursive (clipper,
+									   clip->path);
     }
 
     return status;
@@ -122,14 +155,13 @@ void
 _cairo_surface_clipper_init (cairo_surface_clipper_t *clipper,
 			     cairo_surface_clipper_intersect_clip_path_func_t func)
 {
-    _cairo_clip_init (&clipper->clip);
-    clipper->is_clipped = FALSE;
+    clipper->clip = NULL;
     clipper->intersect_clip_path = func;
 }
 
 void
 _cairo_surface_clipper_reset (cairo_surface_clipper_t *clipper)
 {
-    _cairo_clip_reset (&clipper->clip);
-    clipper->is_clipped = FALSE;
+    _cairo_clip_destroy (clipper->clip);
+    clipper->clip = NULL;
 }
diff --git a/src/cairo-surface-fallback-private.h b/src/cairo-surface-fallback-private.h
index e993de6..ffb6f91 100644
--- a/src/cairo-surface-fallback-private.h
+++ b/src/cairo-surface-fallback-private.h
@@ -45,36 +45,36 @@ cairo_private cairo_status_t
 _cairo_surface_fallback_paint (cairo_surface_t		*surface,
 			       cairo_operator_t		 op,
 			       const cairo_pattern_t	*source,
-			       cairo_clip_t		*clip);
+			       const cairo_clip_t	*clip);
 
 cairo_private cairo_status_t
 _cairo_surface_fallback_mask (cairo_surface_t		*surface,
 			      cairo_operator_t		 op,
 			      const cairo_pattern_t	*source,
 			      const cairo_pattern_t	*mask,
-			      cairo_clip_t		*clip);
+			      const cairo_clip_t	*clip);
 
 cairo_private cairo_status_t
 _cairo_surface_fallback_stroke (cairo_surface_t		*surface,
 				cairo_operator_t	 op,
 				const cairo_pattern_t	*source,
-				cairo_path_fixed_t	*path,
+				const cairo_path_fixed_t	*path,
 				const cairo_stroke_style_t	*stroke_style,
 				const cairo_matrix_t		*ctm,
 				const cairo_matrix_t		*ctm_inverse,
 				double			 tolerance,
 				cairo_antialias_t	 antialias,
-				cairo_clip_t		*clip);
+				const cairo_clip_t	*clip);
 
 cairo_private cairo_status_t
 _cairo_surface_fallback_fill (cairo_surface_t		*surface,
 			      cairo_operator_t		 op,
 			      const cairo_pattern_t	*source,
-			      cairo_path_fixed_t	*path,
+			      const cairo_path_fixed_t	*path,
 			      cairo_fill_rule_t		 fill_rule,
 			      double			 tolerance,
 			      cairo_antialias_t		 antialias,
-			      cairo_clip_t		*clip);
+			      const cairo_clip_t	*clip);
 
 cairo_private cairo_status_t
 _cairo_surface_fallback_show_glyphs (cairo_surface_t		*surface,
@@ -83,7 +83,7 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t		*surface,
 				     cairo_glyph_t		*glyphs,
 				     int			 num_glyphs,
 				     cairo_scaled_font_t	*scaled_font,
-				     cairo_clip_t		*clip);
+				     const cairo_clip_t		*clip);
 
 cairo_private cairo_surface_t *
 _cairo_surface_fallback_snapshot (cairo_surface_t *surface);
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index 5a30d4f..21966fe 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -128,20 +128,10 @@ _create_composite_mask_pattern (cairo_surface_pattern_t       *mask_pattern,
 				const cairo_rectangle_int_t   *extents)
 {
     cairo_surface_t *mask;
-    cairo_region_t *clip_region = NULL, *fallback_region = NULL;
     cairo_status_t status;
-    cairo_bool_t clip_surface = FALSE;
-
-    if (clip != NULL) {
-	status = _cairo_clip_get_region (clip, &clip_region);
-	if (unlikely (_cairo_status_is_error (status) ||
-		      status == CAIRO_INT_STATUS_NOTHING_TO_DO))
-	{
-	    return status;
-	}
-
-	clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED;
-    }
+    cairo_region_t *clip_region = _cairo_clip_get_region (clip);
+    cairo_bool_t clip_surface = ! _cairo_clip_is_region (clip);
+    cairo_region_t *fallback_region = NULL;
 
     /* We need to use solid here, because to use CAIRO_OPERATOR_SOURCE with
      * a mask (as called via _cairo_surface_mask) triggers assertion failures.
@@ -282,7 +272,6 @@ _clip_and_composite_combine (cairo_clip_t                  *clip,
     if (unlikely (status))
 	goto CLEANUP_SURFACE;
 
-    assert (clip->path != NULL);
     clip_surface = _cairo_clip_get_surface (clip, dst, &clip_x, &clip_y);
     if (unlikely (clip_surface->status))
 	goto CLEANUP_SURFACE;
@@ -344,18 +333,9 @@ _clip_and_composite_source (cairo_clip_t                  *clip,
 			    const cairo_rectangle_int_t   *extents)
 {
     cairo_surface_pattern_t mask_pattern;
-    cairo_region_t *clip_region = NULL;
+    cairo_region_t *clip_region = _cairo_clip_get_region (clip);
     cairo_status_t status;
 
-    if (clip != NULL) {
-	status = _cairo_clip_get_region (clip, &clip_region);
-	if (unlikely (_cairo_status_is_error (status) ||
-		      status == CAIRO_INT_STATUS_NOTHING_TO_DO))
-	{
-	    return status;
-	}
-    }
-
     /* Create a surface that is mask IN clip */
     status = _create_composite_mask_pattern (&mask_pattern,
 					     clip,
@@ -390,12 +370,6 @@ _clip_and_composite_source (cairo_clip_t                  *clip,
     return status;
 }
 
-static int
-_cairo_rectangle_empty (const cairo_rectangle_int_t *rect)
-{
-    return rect->width == 0 || rect->height == 0;
-}
-
 /**
  * _clip_and_composite:
  * @clip: a #cairo_clip_t
@@ -428,10 +402,6 @@ _clip_and_composite (cairo_clip_t                  *clip,
 {
     cairo_status_t status;
 
-    if (_cairo_rectangle_empty (extents))
-	/* Nothing to do */
-	return CAIRO_STATUS_SUCCESS;
-
     if (op == CAIRO_OPERATOR_CLEAR) {
 	src = &_cairo_pattern_white.base;
 	op = CAIRO_OPERATOR_DEST_OUT;
@@ -443,21 +413,7 @@ _clip_and_composite (cairo_clip_t                  *clip,
 					     draw_func, draw_closure,
 					     dst, extents);
     } else {
-	cairo_bool_t clip_surface = FALSE;
-	cairo_region_t *clip_region = NULL;
-
-	if (clip != NULL) {
-	    status = _cairo_clip_get_region (clip, &clip_region);
-	    if (unlikely (_cairo_status_is_error (status) ||
-			  status == CAIRO_INT_STATUS_NOTHING_TO_DO))
-	    {
-		return status;
-	    }
-
-	    clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED;
-	}
-
-	if (clip_surface) {
+	if (! _cairo_clip_is_region (clip)) {
 	    if (_cairo_operator_bounded_by_mask (op)) {
 		status = _clip_and_composite_with_mask (clip, op,
 							src,
@@ -474,7 +430,7 @@ _clip_and_composite (cairo_clip_t                  *clip,
 				src, dst,
 				0, 0,
 				extents,
-				clip_region);
+				_cairo_clip_get_region (clip));
 	}
     }
 
@@ -779,23 +735,12 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
 				cairo_rectangle_int_t *extents)
 {
     cairo_composite_traps_info_t traps_info;
-    cairo_region_t *clip_region = NULL;
-    cairo_bool_t clip_surface = FALSE;
-    cairo_status_t status;
+    cairo_bool_t clip_surface = ! _cairo_clip_is_region (clip);
+    cairo_int_status_t status;
 
     if (traps->num_traps == 0 && _cairo_operator_bounded_by_mask (op))
 	return CAIRO_STATUS_SUCCESS;
 
-    if (clip != NULL) {
-	status = _cairo_clip_get_region (clip, &clip_region);
-	if (unlikely (_cairo_status_is_error (status)))
-	    return status;
-	if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
-	    return CAIRO_STATUS_SUCCESS;
-
-	clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED;
-    }
-
     /* Use a fast path if the trapezoids consist of a simple region,
      * but we can only do this if we do not have a clip surface, or can
      * substitute the mask with the clip.
@@ -815,8 +760,8 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
                 return status;
         }
 
-	status = _cairo_traps_extract_region (traps, &trap_region);
-	if (unlikely (_cairo_status_is_error (status)))
+	status = _cairo_traps_extract_region (traps, antialias, &trap_region);
+	if (unlikely (_cairo_int_status_is_error (status)))
 	    return status;
 
 	if (trap_region != NULL) {
@@ -826,21 +771,13 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
 		return status;
 	    }
 
-	    if (clip_region != NULL) {
-		status = cairo_region_intersect (trap_region, clip_region);
-		if (unlikely (status)) {
-		    cairo_region_destroy (trap_region);
-		    return status;
-		}
-	    }
-
 	    if (_cairo_operator_bounded_by_mask (op)) {
 		cairo_rectangle_int_t trap_extents;
 
 		cairo_region_get_extents (trap_region, &trap_extents);
 		if (! _cairo_rectangle_intersect (extents, &trap_extents)) {
 		    cairo_region_destroy (trap_region);
-		    return CAIRO_STATUS_SUCCESS;
+		    return CAIRO_INT_STATUS_SUCCESS;
 		}
 	    }
 
@@ -882,16 +819,12 @@ cairo_status_t
 _cairo_surface_fallback_paint (cairo_surface_t		*surface,
 			       cairo_operator_t		 op,
 			       const cairo_pattern_t	*source,
-			       cairo_clip_t		*clip)
+			       const cairo_clip_t	*clip)
 {
     cairo_composite_rectangles_t extents;
     cairo_rectangle_int_t rect;
-    cairo_clip_path_t *clip_path = clip ? clip->path : NULL;
-    cairo_box_t boxes_stack[32], *clip_boxes = boxes_stack;
     cairo_boxes_t  boxes;
-    int num_boxes = ARRAY_LENGTH (boxes_stack);
-    cairo_status_t status;
-    cairo_traps_t traps;
+    cairo_int_status_t status;
 
     if (!_cairo_surface_get_extents (surface, &rect))
         ASSERT_NOT_REACHED;
@@ -904,44 +837,22 @@ _cairo_surface_fallback_paint (cairo_surface_t		*surface,
     if (unlikely (status))
 	return status;
 
-    if (_cairo_clip_contains_extents (clip, &extents))
-	clip = NULL;
-
-    status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
-    if (unlikely (status))
-	return status;
-
-    /* If the clip cannot be reduced to a set of boxes, we will need to
-     * use a clipmask. Paint is special as it is the only operation that
-     * does not implicitly use a mask, so we may be able to reduce this
-     * operation to a fill...
-     */
-    if (clip != NULL && clip_path->prev == NULL &&
-	_cairo_operator_bounded_by_mask (op))
-    {
-	return _cairo_surface_fill (surface, op, source,
-				    &clip_path->path,
-				    clip_path->fill_rule,
-				    clip_path->tolerance,
-				    clip_path->antialias,
-				    NULL);
+    status = _cairo_clip_to_boxes (extents.clip, &boxes);
+    if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
+	cairo_traps_t traps;
+
+	/* meh, surface-fallback is dying anyway... */
+	status = _cairo_traps_init_boxes (&traps, &boxes);
+	if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
+	    status = _clip_and_composite_trapezoids (source, op, surface,
+						     &traps, CAIRO_ANTIALIAS_DEFAULT,
+						     extents.clip,
+						     extents.is_bounded ? &extents.bounded : &extents.unbounded);
+	    _cairo_traps_fini (&traps);
+	}
     }
 
-    /* meh, surface-fallback is dying anyway... */
-    _cairo_boxes_init_for_array (&boxes, clip_boxes, num_boxes);
-    status = _cairo_traps_init_boxes (&traps, &boxes);
-    if (unlikely (status))
-	goto CLEANUP_BOXES;
-
-    status = _clip_and_composite_trapezoids (source, op, surface,
-					     &traps, CAIRO_ANTIALIAS_DEFAULT,
-					     clip,
-                                             extents.is_bounded ? &extents.bounded : &extents.unbounded);
-    _cairo_traps_fini (&traps);
-
-CLEANUP_BOXES:
-    if (clip_boxes != boxes_stack)
-	free (clip_boxes);
+    _cairo_composite_rectangles_fini (&extents);
 
     return status;
 }
@@ -957,7 +868,7 @@ _cairo_surface_mask_draw_func (void                        *closure,
 			       cairo_region_t		   *clip_region)
 {
     cairo_pattern_t *mask = closure;
-    cairo_status_t status;
+    cairo_int_status_t status;
     cairo_region_t *extents_region = NULL;
 
     if (clip_region == NULL &&
@@ -998,7 +909,7 @@ _cairo_surface_fallback_mask (cairo_surface_t		*surface,
 			      cairo_operator_t		 op,
 			      const cairo_pattern_t	*source,
 			      const cairo_pattern_t	*mask,
-			      cairo_clip_t		*clip)
+			      const cairo_clip_t	*clip)
 {
     cairo_composite_rectangles_t extents;
     cairo_rectangle_int_t rect;
@@ -1013,38 +924,31 @@ _cairo_surface_fallback_mask (cairo_surface_t		*surface,
     if (unlikely (status))
 	return status;
 
-    if (_cairo_clip_contains_extents (clip, &extents))
-	clip = NULL;
+    status =  _clip_and_composite (extents.clip, op, source,
+				   _cairo_surface_mask_draw_func,
+				   (void *) mask,
+				   surface,
+				   extents.is_bounded ? &extents.bounded : &extents.unbounded);
 
-    if (clip != NULL && extents.is_bounded) {
-	status = _cairo_clip_rectangle (clip, &extents.bounded);
-	if (unlikely (status))
-	    return status;
-    }
+    _cairo_composite_rectangles_fini (&extents);
 
-    return _clip_and_composite (clip, op, source,
-				_cairo_surface_mask_draw_func,
-				(void *) mask,
-				surface,
-                                extents.is_bounded ? &extents.bounded : &extents.unbounded);
+    return status;
 }
 
 cairo_status_t
 _cairo_surface_fallback_stroke (cairo_surface_t		*surface,
 				cairo_operator_t	 op,
 				const cairo_pattern_t	*source,
-				cairo_path_fixed_t	*path,
+				const cairo_path_fixed_t	*path,
 				const cairo_stroke_style_t	*stroke_style,
 				const cairo_matrix_t		*ctm,
 				const cairo_matrix_t		*ctm_inverse,
 				double			 tolerance,
 				cairo_antialias_t	 antialias,
-				cairo_clip_t		*clip)
+				const cairo_clip_t		*clip)
 {
     cairo_polygon_t polygon;
     cairo_traps_t traps;
-    cairo_box_t boxes_stack[32], *clip_boxes = boxes_stack;
-    int num_boxes = ARRAY_LENGTH (boxes_stack);
     cairo_composite_rectangles_t extents;
     cairo_rectangle_int_t rect;
     cairo_status_t status;
@@ -1061,22 +965,14 @@ _cairo_surface_fallback_stroke (cairo_surface_t		*surface,
     if (unlikely (status))
 	return status;
 
-    if (_cairo_clip_contains_extents (clip, &extents))
-	clip = NULL;
-
-    status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
-    if (unlikely (status))
-	return status;
-
-    _cairo_polygon_init (&polygon, clip_boxes, num_boxes);
-
-    _cairo_traps_init (&traps);
-    _cairo_traps_limit (&traps, clip_boxes, num_boxes);
+    _cairo_polygon_init_with_clip (&polygon, extents.clip);
+    _cairo_traps_init_with_clip (&traps, extents.clip);
 
     if (_cairo_path_fixed_stroke_is_rectilinear (path)) {
 	status = _cairo_path_fixed_stroke_rectilinear_to_traps (path,
 								stroke_style,
 								ctm,
+								antialias,
 								&traps);
 	if (likely (status == CAIRO_STATUS_SUCCESS))
 	    goto DO_TRAPS;
@@ -1112,13 +1008,13 @@ _cairo_surface_fallback_stroke (cairo_surface_t		*surface,
   DO_TRAPS:
     status = _clip_and_composite_trapezoids (source, op, surface,
 					     &traps, antialias,
-					     clip,
+					     extents.clip,
                                              extents.is_bounded ? &extents.bounded : &extents.unbounded);
   CLEANUP:
     _cairo_traps_fini (&traps);
     _cairo_polygon_fini (&polygon);
-    if (clip_boxes != boxes_stack)
-	free (clip_boxes);
+
+    _cairo_composite_rectangles_fini (&extents);
 
     return status;
 }
@@ -1127,16 +1023,14 @@ cairo_status_t
 _cairo_surface_fallback_fill (cairo_surface_t		*surface,
 			      cairo_operator_t		 op,
 			      const cairo_pattern_t	*source,
-			      cairo_path_fixed_t	*path,
+			      const cairo_path_fixed_t	*path,
 			      cairo_fill_rule_t		 fill_rule,
 			      double			 tolerance,
 			      cairo_antialias_t		 antialias,
-			      cairo_clip_t		*clip)
+			      const cairo_clip_t	*clip)
 {
     cairo_polygon_t polygon;
     cairo_traps_t traps;
-    cairo_box_t boxes_stack[32], *clip_boxes = boxes_stack;
-    int num_boxes = ARRAY_LENGTH (boxes_stack);
     cairo_bool_t is_rectilinear;
     cairo_composite_rectangles_t extents;
     cairo_rectangle_int_t rect;
@@ -1153,17 +1047,8 @@ _cairo_surface_fallback_fill (cairo_surface_t		*surface,
     if (unlikely (status))
 	return status;
 
-    if (_cairo_clip_contains_extents (clip, &extents))
-	clip = NULL;
-
-    status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
-    if (unlikely (status))
-	return status;
-
-    _cairo_traps_init (&traps);
-    _cairo_traps_limit (&traps, clip_boxes, num_boxes);
-
-    _cairo_polygon_init (&polygon, clip_boxes, num_boxes);
+    _cairo_traps_init_with_clip (&traps, extents.clip);
+    _cairo_polygon_init_with_clip (&polygon, extents.clip);
 
     if (_cairo_path_fixed_fill_is_empty (path))
 	goto DO_TRAPS;
@@ -1172,6 +1057,7 @@ _cairo_surface_fallback_fill (cairo_surface_t		*surface,
     if (is_rectilinear) {
 	status = _cairo_path_fixed_fill_rectilinear_to_traps (path,
 							      fill_rule,
+							      antialias,
 							      &traps);
 	if (likely (status == CAIRO_STATUS_SUCCESS))
 	    goto DO_TRAPS;
@@ -1214,13 +1100,13 @@ _cairo_surface_fallback_fill (cairo_surface_t		*surface,
   DO_TRAPS:
     status = _clip_and_composite_trapezoids (source, op, surface,
 					     &traps, antialias,
-					     clip,
+					     extents.clip,
                                              extents.is_bounded ? &extents.bounded : &extents.unbounded);
   CLEANUP:
     _cairo_traps_fini (&traps);
     _cairo_polygon_fini (&polygon);
-    if (clip_boxes != boxes_stack)
-	free (clip_boxes);
+
+    _cairo_composite_rectangles_fini (&extents);
 
     return status;
 }
@@ -1242,17 +1128,7 @@ _cairo_surface_old_show_glyphs_draw_func (void                          *closure
 					  cairo_region_t		*clip_region)
 {
     cairo_show_glyphs_info_t *glyph_info = closure;
-    cairo_status_t status;
-    cairo_region_t *extents_region = NULL;
-
-    if (clip_region == NULL &&
-        !_cairo_operator_bounded_by_source (op)) {
-        extents_region = cairo_region_create_rectangle (extents);
-        if (unlikely (extents_region->status))
-            return extents_region->status;
-        cairo_region_translate (extents_region, -dst_x, -dst_y);
-        clip_region = extents_region;
-    }
+    cairo_int_status_t status;
 
     /* Modifying the glyph array is fine because we know that this function
      * will be called only once, and we've already made a copy of the
@@ -1291,9 +1167,6 @@ _cairo_surface_old_show_glyphs_draw_func (void                          *closure
                                                  clip_region);
     }
 
-    if (extents_region)
-        cairo_region_destroy (extents_region);
-
     return status;
 }
 
@@ -1304,12 +1177,12 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t		*surface,
 				     cairo_glyph_t		*glyphs,
 				     int			 num_glyphs,
 				     cairo_scaled_font_t	*scaled_font,
-				     cairo_clip_t		*clip)
+				     const cairo_clip_t		*clip)
 {
     cairo_show_glyphs_info_t glyph_info;
     cairo_composite_rectangles_t extents;
     cairo_rectangle_int_t rect;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     if (!_cairo_surface_get_extents (surface, &rect))
         ASSERT_NOT_REACHED;
@@ -1325,24 +1198,18 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t		*surface,
     if (unlikely (status))
 	return status;
 
-    if (_cairo_clip_contains_rectangle (clip, &extents.mask))
-	clip = NULL;
-
-    if (clip != NULL && extents.is_bounded) {
-	status = _cairo_clip_rectangle (clip, &extents.bounded);
-	if (unlikely (status))
-	    return status;
-    }
-
     glyph_info.font = scaled_font;
     glyph_info.glyphs = glyphs;
     glyph_info.num_glyphs = num_glyphs;
 
-    return _clip_and_composite (clip, op, source,
-				_cairo_surface_old_show_glyphs_draw_func,
-				&glyph_info,
-				surface,
-                                extents.is_bounded ? &extents.bounded : &extents.unbounded);
+    status = _clip_and_composite (extents.clip, op, source,
+				  _cairo_surface_old_show_glyphs_draw_func,
+				  &glyph_info, surface,
+				  extents.is_bounded ? &extents.bounded : &extents.unbounded);
+
+    _cairo_composite_rectangles_fini (&extents);
+
+    return status;
 }
 
 cairo_surface_t *
diff --git a/src/cairo-surface-offset-private.h b/src/cairo-surface-offset-private.h
index b7877b3..310ba56 100644
--- a/src/cairo-surface-offset-private.h
+++ b/src/cairo-surface-offset-private.h
@@ -48,7 +48,7 @@ _cairo_surface_offset_paint (cairo_surface_t *target,
 			     int x, int y,
 			     cairo_operator_t	 op,
 			     const cairo_pattern_t *source,
-			     cairo_clip_t	    *clip);
+			     const cairo_clip_t	    *clip);
 
 cairo_private cairo_status_t
 _cairo_surface_offset_mask (cairo_surface_t *target,
@@ -56,31 +56,31 @@ _cairo_surface_offset_mask (cairo_surface_t *target,
 			    cairo_operator_t	 op,
 			    const cairo_pattern_t *source,
 			    const cairo_pattern_t *mask,
-			    cairo_clip_t	    *clip);
+			    const cairo_clip_t	    *clip);
 
 cairo_private cairo_status_t
 _cairo_surface_offset_stroke (cairo_surface_t *surface,
 			      int x, int y,
 			      cairo_operator_t		 op,
 			      const cairo_pattern_t	*source,
-			      cairo_path_fixed_t	*path,
+			      const cairo_path_fixed_t	*path,
 			      const cairo_stroke_style_t	*stroke_style,
 			      const cairo_matrix_t		*ctm,
 			      const cairo_matrix_t		*ctm_inverse,
 			      double			 tolerance,
 			      cairo_antialias_t	 antialias,
-			      cairo_clip_t		*clip);
+			      const cairo_clip_t		*clip);
 
 cairo_private cairo_status_t
 _cairo_surface_offset_fill (cairo_surface_t	*surface,
 			    int x, int y,
 			    cairo_operator_t	 op,
 			    const cairo_pattern_t*source,
-			    cairo_path_fixed_t	*path,
+			    const cairo_path_fixed_t	*path,
 			    cairo_fill_rule_t	 fill_rule,
 			    double		 tolerance,
 			    cairo_antialias_t	 antialias,
-			    cairo_clip_t		*clip);
+			    const cairo_clip_t		*clip);
 
 cairo_private cairo_status_t
 _cairo_surface_offset_glyphs (cairo_surface_t		*surface,
@@ -90,6 +90,6 @@ _cairo_surface_offset_glyphs (cairo_surface_t		*surface,
 			      cairo_scaled_font_t	*scaled_font,
 			      cairo_glyph_t		*glyphs,
 			      int			 num_glyphs,
-			      cairo_clip_t		*clip);
+			      const cairo_clip_t		*clip);
 
 #endif /* CAIRO_SURFACE_OFFSET_PRIVATE_H */
diff --git a/src/cairo-surface-offset.c b/src/cairo-surface-offset.c
index c36196e..d2cc030 100644
--- a/src/cairo-surface-offset.c
+++ b/src/cairo-surface-offset.c
@@ -59,29 +59,22 @@ _cairo_surface_offset_paint (cairo_surface_t		*target,
 			     int x, int y,
 			     cairo_operator_t		 op,
 			     const cairo_pattern_t	*source,
-			     cairo_clip_t		*clip)
+			     const cairo_clip_t		*clip)
 {
     cairo_status_t status;
-    cairo_clip_t clip_copy, *dev_clip = clip;
+    cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
     cairo_pattern_union_t source_copy;
 
     if (unlikely (target->status))
 	return target->status;
 
-    if (clip && clip->all_clipped)
+    if (_cairo_clip_is_all_clipped (clip))
 	return CAIRO_STATUS_SUCCESS;
 
     if (x | y) {
 	cairo_matrix_t m;
 
-	if (clip != NULL) {
-	    cairo_matrix_init_translate (&m, -x, -y);
-	    status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
-	    if (unlikely (status))
-		goto FINISH;
-
-	    dev_clip = &clip_copy;
-	}
+	dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
 
 	cairo_matrix_init_translate (&m, x, y);
 	_copy_transformed_pattern (&source_copy.base, source, &m);
@@ -90,9 +83,8 @@ _cairo_surface_offset_paint (cairo_surface_t		*target,
 
     status = _cairo_surface_paint (target, op, source, dev_clip);
 
-  FINISH:
     if (dev_clip != clip)
-	_cairo_clip_reset (dev_clip);
+	_cairo_clip_destroy (dev_clip);
 
     return status;
 }
@@ -103,30 +95,23 @@ _cairo_surface_offset_mask (cairo_surface_t		*target,
 			    cairo_operator_t		 op,
 			    const cairo_pattern_t	*source,
 			    const cairo_pattern_t	*mask,
-			    cairo_clip_t		*clip)
+			    const cairo_clip_t		*clip)
 {
     cairo_status_t status;
-    cairo_clip_t clip_copy, *dev_clip = clip;
+    cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
     cairo_pattern_union_t source_copy;
     cairo_pattern_union_t mask_copy;
 
     if (unlikely (target->status))
 	return target->status;
 
-    if (clip && clip->all_clipped)
+    if (_cairo_clip_is_all_clipped (clip))
 	return CAIRO_STATUS_SUCCESS;
 
     if (x | y) {
 	cairo_matrix_t m;
 
-	if (clip != NULL) {
-	    cairo_matrix_init_translate (&m, -x, -y);
-	    status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
-	    if (unlikely (status))
-		goto FINISH;
-
-	    dev_clip = &clip_copy;
-	}
+	dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
 
 	cairo_matrix_init_translate (&m, x, y);
 	_copy_transformed_pattern (&source_copy.base, source, &m);
@@ -139,9 +124,8 @@ _cairo_surface_offset_mask (cairo_surface_t		*target,
 				  source, mask,
 				  dev_clip);
 
-  FINISH:
     if (dev_clip != clip)
-	_cairo_clip_reset (dev_clip);
+	_cairo_clip_destroy (dev_clip);
 
     return status;
 }
@@ -151,16 +135,16 @@ _cairo_surface_offset_stroke (cairo_surface_t		*surface,
 			      int x, int y,
 			      cairo_operator_t		 op,
 			      const cairo_pattern_t	*source,
-			      cairo_path_fixed_t	*path,
+			      const cairo_path_fixed_t	*path,
 			      const cairo_stroke_style_t*stroke_style,
 			      const cairo_matrix_t	*ctm,
 			      const cairo_matrix_t	*ctm_inverse,
 			      double			 tolerance,
 			      cairo_antialias_t		 antialias,
-			      cairo_clip_t		*clip)
+			      const cairo_clip_t		*clip)
 {
-    cairo_path_fixed_t path_copy, *dev_path = path;
-    cairo_clip_t clip_copy, *dev_clip = clip;
+    cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path;
+    cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
     cairo_matrix_t dev_ctm = *ctm;
     cairo_matrix_t dev_ctm_inverse = *ctm_inverse;
     cairo_pattern_union_t source_copy;
@@ -169,12 +153,14 @@ _cairo_surface_offset_stroke (cairo_surface_t		*surface,
     if (unlikely (surface->status))
 	return surface->status;
 
-    if (clip && clip->all_clipped)
+    if (_cairo_clip_is_all_clipped (clip))
 	return CAIRO_STATUS_SUCCESS;
 
     if (x | y) {
 	cairo_matrix_t m;
 
+	dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
+
 	status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
 	if (unlikely (status))
 	    goto FINISH;
@@ -186,13 +172,6 @@ _cairo_surface_offset_stroke (cairo_surface_t		*surface,
 
 	cairo_matrix_init_translate (&m, -x, -y);
 	cairo_matrix_multiply (&dev_ctm, &dev_ctm, &m);
-	if (clip != NULL) {
-	    status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
-	    if (unlikely (status))
-		goto FINISH;
-
-	    dev_clip = &clip_copy;
-	}
 
 	cairo_matrix_init_translate (&m, x, y);
 	_copy_transformed_pattern (&source_copy.base, source, &m);
@@ -206,11 +185,11 @@ _cairo_surface_offset_stroke (cairo_surface_t		*surface,
 				    tolerance, antialias,
 				    dev_clip);
 
- FINISH:
+FINISH:
     if (dev_path != path)
 	_cairo_path_fixed_fini (dev_path);
     if (dev_clip != clip)
-	_cairo_clip_reset (dev_clip);
+	_cairo_clip_destroy (dev_clip);
 
     return status;
 }
@@ -220,26 +199,28 @@ _cairo_surface_offset_fill (cairo_surface_t	*surface,
 			    int x, int y,
 			    cairo_operator_t	 op,
 			    const cairo_pattern_t*source,
-			    cairo_path_fixed_t	*path,
+			    const cairo_path_fixed_t	*path,
 			    cairo_fill_rule_t	 fill_rule,
 			    double		 tolerance,
 			    cairo_antialias_t	 antialias,
-			    cairo_clip_t	*clip)
+			    const cairo_clip_t	*clip)
 {
     cairo_status_t status;
-    cairo_path_fixed_t path_copy, *dev_path = path;
-    cairo_clip_t clip_copy, *dev_clip = clip;
+    cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path;
+    cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
     cairo_pattern_union_t source_copy;
 
     if (unlikely (surface->status))
 	return surface->status;
 
-    if (clip && clip->all_clipped)
+    if (_cairo_clip_is_all_clipped (clip))
 	return CAIRO_STATUS_SUCCESS;
 
     if (x | y) {
 	cairo_matrix_t m;
 
+	dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
+
 	status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
 	if (unlikely (status))
 	    goto FINISH;
@@ -249,15 +230,6 @@ _cairo_surface_offset_fill (cairo_surface_t	*surface,
 				     _cairo_fixed_from_int (-y));
 	dev_path = &path_copy;
 
-	if (clip != NULL) {
-	    cairo_matrix_init_translate (&m, -x, -y);
-	    status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
-	    if (unlikely (status))
-		goto FINISH;
-
-	    dev_clip = &clip_copy;
-	}
-
 	cairo_matrix_init_translate (&m, x, y);
 	_copy_transformed_pattern (&source_copy.base, source, &m);
 	source = &source_copy.base;
@@ -268,11 +240,11 @@ _cairo_surface_offset_fill (cairo_surface_t	*surface,
 				  tolerance, antialias,
 				  dev_clip);
 
- FINISH:
+FINISH:
     if (dev_path != path)
 	_cairo_path_fixed_fini (dev_path);
     if (dev_clip != clip)
-	_cairo_clip_reset (dev_clip);
+	_cairo_clip_destroy (dev_clip);
 
     return status;
 }
@@ -285,10 +257,10 @@ _cairo_surface_offset_glyphs (cairo_surface_t		*surface,
 			      cairo_scaled_font_t	*scaled_font,
 			      cairo_glyph_t		*glyphs,
 			      int			 num_glyphs,
-			      cairo_clip_t		*clip)
+			      const cairo_clip_t	*clip)
 {
     cairo_status_t status;
-    cairo_clip_t clip_copy, *dev_clip = clip;
+    cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
     cairo_pattern_union_t source_copy;
     cairo_glyph_t *dev_glyphs;
     int i;
@@ -296,7 +268,7 @@ _cairo_surface_offset_glyphs (cairo_surface_t		*surface,
     if (unlikely (surface->status))
 	return surface->status;
 
-    if (clip && clip->all_clipped)
+    if (_cairo_clip_is_all_clipped (clip))
 	return CAIRO_STATUS_SUCCESS;
 
     dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
@@ -308,14 +280,7 @@ _cairo_surface_offset_glyphs (cairo_surface_t		*surface,
     if (x | y) {
 	cairo_matrix_t m;
 
-	if (clip != NULL) {
-	    cairo_matrix_init_translate (&m, -x, -y);
-	    status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
-	    if (unlikely (status))
-		goto FINISH;
-
-	    dev_clip = &clip_copy;
-	}
+	dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
 
 	cairo_matrix_init_translate (&m, x, y);
 	_copy_transformed_pattern (&source_copy.base, source, &m);
@@ -334,9 +299,8 @@ _cairo_surface_offset_glyphs (cairo_surface_t		*surface,
 					      scaled_font,
 					      dev_clip);
 
- FINISH:
     if (dev_clip != clip)
-	_cairo_clip_reset (dev_clip);
+	_cairo_clip_destroy (dev_clip);
     free (dev_glyphs);
 
     return status;
diff --git a/src/cairo-surface-subsurface.c b/src/cairo-surface-subsurface.c
index ff1df83..2a4a4fb 100644
--- a/src/cairo-surface-subsurface.c
+++ b/src/cairo-surface-subsurface.c
@@ -65,23 +65,18 @@ static cairo_int_status_t
 _cairo_surface_subsurface_paint (void *abstract_surface,
 				 cairo_operator_t op,
 				 const cairo_pattern_t *source,
-				 cairo_clip_t *clip)
+				 const cairo_clip_t *clip)
 {
     cairo_surface_subsurface_t *surface = abstract_surface;
     cairo_rectangle_int_t rect = { 0, 0, surface->extents.width, surface->extents.height };
     cairo_status_t status;
-    cairo_clip_t target_clip;
-
-    _cairo_clip_init_copy (&target_clip, clip);
-    status = _cairo_clip_rectangle (&target_clip, &rect);
-    if (unlikely (status))
-	goto CLEANUP;
+    cairo_clip_t *target_clip;
 
+    target_clip = _cairo_clip_copy_intersect_rectangle (clip, &rect);
     status = _cairo_surface_offset_paint (surface->target,
 					 -surface->extents.x, -surface->extents.y,
-					  op, source, &target_clip);
-  CLEANUP:
-    _cairo_clip_fini (&target_clip);
+					  op, source, target_clip);
+    _cairo_clip_destroy (target_clip);
     return status;
 }
 
@@ -90,23 +85,18 @@ _cairo_surface_subsurface_mask (void *abstract_surface,
 				cairo_operator_t op,
 				const cairo_pattern_t *source,
 				const cairo_pattern_t *mask,
-				cairo_clip_t *clip)
+				const cairo_clip_t *clip)
 {
     cairo_surface_subsurface_t *surface = abstract_surface;
     cairo_rectangle_int_t rect = { 0, 0, surface->extents.width, surface->extents.height };
     cairo_status_t status;
-    cairo_clip_t target_clip;
-
-    _cairo_clip_init_copy (&target_clip, clip);
-    status = _cairo_clip_rectangle (&target_clip, &rect);
-    if (unlikely (status))
-	goto CLEANUP;
+    cairo_clip_t *target_clip;
 
+    target_clip = _cairo_clip_copy_intersect_rectangle (clip, &rect);
     status = _cairo_surface_offset_mask (surface->target,
 					 -surface->extents.x, -surface->extents.y,
-					 op, source, mask, &target_clip);
-  CLEANUP:
-    _cairo_clip_fini (&target_clip);
+					 op, source, mask, target_clip);
+    _cairo_clip_destroy (target_clip);
     return status;
 }
 
@@ -114,28 +104,23 @@ static cairo_int_status_t
 _cairo_surface_subsurface_fill (void			*abstract_surface,
 				cairo_operator_t	 op,
 				const cairo_pattern_t	*source,
-				cairo_path_fixed_t	*path,
+				const cairo_path_fixed_t	*path,
 				cairo_fill_rule_t	 fill_rule,
 				double			 tolerance,
 				cairo_antialias_t	 antialias,
-				cairo_clip_t		*clip)
+				const cairo_clip_t		*clip)
 {
     cairo_surface_subsurface_t *surface = abstract_surface;
     cairo_rectangle_int_t rect = { 0, 0, surface->extents.width, surface->extents.height };
     cairo_status_t status;
-    cairo_clip_t target_clip;
-
-    _cairo_clip_init_copy (&target_clip, clip);
-    status = _cairo_clip_rectangle (&target_clip, &rect);
-    if (unlikely (status))
-	goto CLEANUP;
+    cairo_clip_t *target_clip;
 
+    target_clip = _cairo_clip_copy_intersect_rectangle (clip, &rect);
     status = _cairo_surface_offset_fill (surface->target,
 					 -surface->extents.x, -surface->extents.y,
 					 op, source, path, fill_rule, tolerance, antialias,
-					 &target_clip);
-  CLEANUP:
-    _cairo_clip_fini (&target_clip);
+					 target_clip);
+    _cairo_clip_destroy (target_clip);
     return status;
 }
 
@@ -143,31 +128,26 @@ static cairo_int_status_t
 _cairo_surface_subsurface_stroke (void				*abstract_surface,
 				  cairo_operator_t		 op,
 				  const cairo_pattern_t		*source,
-				  cairo_path_fixed_t		*path,
+				  const cairo_path_fixed_t		*path,
 				  const cairo_stroke_style_t	*stroke_style,
 				  const cairo_matrix_t		*ctm,
 				  const cairo_matrix_t		*ctm_inverse,
 				  double			 tolerance,
 				  cairo_antialias_t		 antialias,
-				  cairo_clip_t			*clip)
+				  const cairo_clip_t			*clip)
 {
     cairo_surface_subsurface_t *surface = abstract_surface;
     cairo_rectangle_int_t rect = { 0, 0, surface->extents.width, surface->extents.height };
     cairo_status_t status;
-    cairo_clip_t target_clip;
-
-    _cairo_clip_init_copy (&target_clip, clip);
-    status = _cairo_clip_rectangle (&target_clip, &rect);
-    if (unlikely (status))
-	goto CLEANUP;
+    cairo_clip_t *target_clip;
 
+    target_clip = _cairo_clip_copy_intersect_rectangle (clip, &rect);
     status = _cairo_surface_offset_stroke (surface->target,
 					   -surface->extents.x, -surface->extents.y,
 					   op, source, path, stroke_style, ctm, ctm_inverse,
 					   tolerance, antialias,
-					   &target_clip);
-  CLEANUP:
-    _cairo_clip_fini (&target_clip);
+					   target_clip);
+    _cairo_clip_destroy (target_clip);
     return status;
 }
 
@@ -178,27 +158,22 @@ _cairo_surface_subsurface_glyphs (void			*abstract_surface,
 				  cairo_glyph_t		*glyphs,
 				  int			 num_glyphs,
 				  cairo_scaled_font_t	*scaled_font,
-				  cairo_clip_t		*clip,
+				  const cairo_clip_t		*clip,
 				  int *remaining_glyphs)
 {
     cairo_surface_subsurface_t *surface = abstract_surface;
     cairo_rectangle_int_t rect = { 0, 0, surface->extents.width, surface->extents.height };
     cairo_status_t status;
-    cairo_clip_t target_clip;
-
-    _cairo_clip_init_copy (&target_clip, clip);
-    status = _cairo_clip_rectangle (&target_clip, &rect);
-    if (unlikely (status))
-	goto CLEANUP;
+    cairo_clip_t *target_clip;
 
+    target_clip = _cairo_clip_copy_intersect_rectangle (clip, &rect);
     status = _cairo_surface_offset_glyphs (surface->target,
 					   -surface->extents.x, -surface->extents.y,
 					   op, source,
 					   scaled_font, glyphs, num_glyphs,
-					   &target_clip);
+					   target_clip);
     *remaining_glyphs = 0;
-  CLEANUP:
-    _cairo_clip_fini (&target_clip);
+    _cairo_clip_destroy (target_clip);
     return status;
 }
 
diff --git a/src/cairo-surface-wrapper-private.h b/src/cairo-surface-wrapper-private.h
index 39dad2b..b3d3a55 100644
--- a/src/cairo-surface-wrapper-private.h
+++ b/src/cairo-surface-wrapper-private.h
@@ -76,26 +76,26 @@ cairo_private cairo_status_t
 _cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper,
 			      cairo_operator_t	 op,
 			      const cairo_pattern_t *source,
-			      cairo_clip_t	    *clip);
+			      const cairo_clip_t	    *clip);
 
 cairo_private cairo_status_t
 _cairo_surface_wrapper_mask (cairo_surface_wrapper_t *wrapper,
 			     cairo_operator_t	 op,
 			     const cairo_pattern_t *source,
 			     const cairo_pattern_t *mask,
-			     cairo_clip_t	    *clip);
+			     const cairo_clip_t	    *clip);
 
 cairo_private cairo_status_t
 _cairo_surface_wrapper_stroke (cairo_surface_wrapper_t *wrapper,
 			       cairo_operator_t		 op,
 			       const cairo_pattern_t	*source,
-			       cairo_path_fixed_t	*path,
+			       const cairo_path_fixed_t	*path,
 			       const cairo_stroke_style_t	*stroke_style,
 			       const cairo_matrix_t		*ctm,
 			       const cairo_matrix_t		*ctm_inverse,
 			       double			 tolerance,
 			       cairo_antialias_t	 antialias,
-			       cairo_clip_t		*clip);
+			       const cairo_clip_t		*clip);
 
 cairo_private cairo_status_t
 _cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper,
@@ -112,17 +112,17 @@ _cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper,
 				    const cairo_matrix_t	    *stroke_ctm_inverse,
 				    double		     stroke_tolerance,
 				    cairo_antialias_t	     stroke_antialias,
-				    cairo_clip_t	    *clip);
+				    const cairo_clip_t	    *clip);
 
 cairo_private cairo_status_t
 _cairo_surface_wrapper_fill (cairo_surface_wrapper_t *wrapper,
 			     cairo_operator_t	 op,
 			     const cairo_pattern_t *source,
-			     cairo_path_fixed_t	*path,
+			     const cairo_path_fixed_t	*path,
 			     cairo_fill_rule_t	 fill_rule,
 			     double		 tolerance,
 			     cairo_antialias_t	 antialias,
-			     cairo_clip_t	*clip);
+			     const cairo_clip_t	*clip);
 
 cairo_private cairo_status_t
 _cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
@@ -136,7 +136,7 @@ _cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
 					 int			     num_clusters,
 					 cairo_text_cluster_flags_t  cluster_flags,
 					 cairo_scaled_font_t	    *scaled_font,
-					 cairo_clip_t		    *clip);
+					 const cairo_clip_t		    *clip);
 
 cairo_private cairo_surface_t *
 _cairo_surface_wrapper_create_similar (cairo_surface_wrapper_t *wrapper,
diff --git a/src/cairo-surface-wrapper.c b/src/cairo-surface-wrapper.c
index a76003b..9e746f9 100644
--- a/src/cairo-surface-wrapper.c
+++ b/src/cairo-surface-wrapper.c
@@ -90,26 +90,20 @@ cairo_status_t
 _cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper,
 			      cairo_operator_t	 op,
 			      const cairo_pattern_t *source,
-			      cairo_clip_t	    *clip)
+			      const cairo_clip_t	    *clip)
 {
     cairo_status_t status;
-    cairo_clip_t clip_copy, *dev_clip = clip;
+    cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
+    cairo_clip_t *target_clip = NULL;
     cairo_pattern_union_t source_copy;
-    cairo_clip_t target_clip;
 
     if (unlikely (wrapper->target->status))
 	return wrapper->target->status;
 
-    if (wrapper->has_extents) {
-	_cairo_clip_init_copy (&target_clip, clip);
-	status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
-	if (unlikely (status))
-	    goto FINISH;
-
-	dev_clip = clip = &target_clip;
-    }
+    if (wrapper->has_extents)
+	dev_clip = target_clip = _cairo_clip_copy_intersect_rectangle (clip, &wrapper->extents);
 
-    if (clip && clip->all_clipped) {
+    if (_cairo_clip_is_all_clipped (dev_clip)) {
 	status = CAIRO_STATUS_SUCCESS;
 	goto FINISH;
     }
@@ -127,13 +121,8 @@ _cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper,
 	if (_cairo_surface_wrapper_needs_device_transform (wrapper))
 	    cairo_matrix_multiply (&m, &wrapper->target->device_transform, &m);
 
-	if (clip != NULL) {
-	    status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
-	    if (unlikely (status))
-		goto FINISH;
-
-	    dev_clip = &clip_copy;
-	}
+	/* XXX */
+	dev_clip = _cairo_clip_copy_with_translation (clip, wrapper->extents.x, wrapper->extents.y);
 
 	status = cairo_matrix_invert (&m);
 	assert (status == CAIRO_STATUS_SUCCESS);
@@ -145,10 +134,9 @@ _cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper,
     status = _cairo_surface_paint (wrapper->target, op, source, dev_clip);
 
   FINISH:
-    if (wrapper->has_extents)
-	_cairo_clip_reset (&target_clip);
+    _cairo_clip_destroy (target_clip);
     if (dev_clip != clip)
-	_cairo_clip_reset (dev_clip);
+	_cairo_clip_destroy (dev_clip);
     return status;
 }
 
@@ -157,27 +145,21 @@ _cairo_surface_wrapper_mask (cairo_surface_wrapper_t *wrapper,
 			     cairo_operator_t	 op,
 			     const cairo_pattern_t *source,
 			     const cairo_pattern_t *mask,
-			     cairo_clip_t	    *clip)
+			     const cairo_clip_t	    *clip)
 {
     cairo_status_t status;
-    cairo_clip_t clip_copy, *dev_clip = clip;
+    cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
     cairo_pattern_union_t source_copy;
     cairo_pattern_union_t mask_copy;
-    cairo_clip_t target_clip;
+    cairo_clip_t *target_clip = NULL;
 
     if (unlikely (wrapper->target->status))
 	return wrapper->target->status;
 
-    if (wrapper->has_extents) {
-	_cairo_clip_init_copy (&target_clip, clip);
-	status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
-	if (unlikely (status))
-	    goto FINISH;
-
-	dev_clip = clip = &target_clip;
-    }
+    if (wrapper->has_extents)
+	dev_clip = target_clip = _cairo_clip_copy_intersect_rectangle (clip, &wrapper->extents);
 
-    if (clip && clip->all_clipped) {
+    if (_cairo_clip_is_all_clipped (dev_clip)) {
 	status = CAIRO_STATUS_SUCCESS;
 	goto FINISH;
     }
@@ -195,13 +177,8 @@ _cairo_surface_wrapper_mask (cairo_surface_wrapper_t *wrapper,
 	if (_cairo_surface_wrapper_needs_device_transform (wrapper))
 	    cairo_matrix_multiply (&m, &wrapper->target->device_transform, &m);
 
-	if (clip != NULL) {
-	    status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
-	    if (unlikely (status))
-		goto FINISH;
-
-	    dev_clip = &clip_copy;
-	}
+	/* XXX */
+	dev_clip = _cairo_clip_copy_with_translation (clip, wrapper->extents.x, wrapper->extents.y);
 
 	status = cairo_matrix_invert (&m);
 	assert (status == CAIRO_STATUS_SUCCESS);
@@ -216,10 +193,9 @@ _cairo_surface_wrapper_mask (cairo_surface_wrapper_t *wrapper,
     status = _cairo_surface_mask (wrapper->target, op, source, mask, dev_clip);
 
   FINISH:
-    if (wrapper->has_extents)
-	_cairo_clip_reset (&target_clip);
+    _cairo_clip_destroy (target_clip);
     if (dev_clip != clip)
-	_cairo_clip_reset (dev_clip);
+	_cairo_clip_destroy (dev_clip);
     return status;
 }
 
@@ -227,35 +203,29 @@ cairo_status_t
 _cairo_surface_wrapper_stroke (cairo_surface_wrapper_t *wrapper,
 			       cairo_operator_t		 op,
 			       const cairo_pattern_t	*source,
-			       cairo_path_fixed_t	*path,
+			       const cairo_path_fixed_t	*path,
 			       const cairo_stroke_style_t	*stroke_style,
 			       const cairo_matrix_t		*ctm,
 			       const cairo_matrix_t		*ctm_inverse,
 			       double			 tolerance,
 			       cairo_antialias_t	 antialias,
-			       cairo_clip_t		*clip)
+			       const cairo_clip_t		*clip)
 {
     cairo_status_t status;
-    cairo_path_fixed_t path_copy, *dev_path = path;
-    cairo_clip_t clip_copy, *dev_clip = clip;
+    cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path;
+    cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
     cairo_matrix_t dev_ctm = *ctm;
     cairo_matrix_t dev_ctm_inverse = *ctm_inverse;
     cairo_pattern_union_t source_copy;
-    cairo_clip_t target_clip;
+    cairo_clip_t *target_clip = NULL;
 
     if (unlikely (wrapper->target->status))
 	return wrapper->target->status;
 
-    if (wrapper->has_extents) {
-	_cairo_clip_init_copy (&target_clip, clip);
-	status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
-	if (unlikely (status))
-	    goto FINISH;
-
-	dev_clip = clip = &target_clip;
-    }
+    if (wrapper->has_extents)
+	dev_clip = target_clip = _cairo_clip_copy_intersect_rectangle (clip, &wrapper->extents);
 
-    if (clip && clip->all_clipped) {
+    if (_cairo_clip_is_all_clipped (dev_clip)) {
 	status = CAIRO_STATUS_SUCCESS;
 	goto FINISH;
     }
@@ -280,13 +250,8 @@ _cairo_surface_wrapper_stroke (cairo_surface_wrapper_t *wrapper,
 	_cairo_path_fixed_transform (&path_copy, &m);
 	dev_path = &path_copy;
 
-	if (clip != NULL) {
-	    status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
-	    if (unlikely (status))
-		goto FINISH;
-
-	    dev_clip = &clip_copy;
-	}
+	/* XXX */
+	dev_clip = _cairo_clip_copy_with_translation (clip, wrapper->extents.x, wrapper->extents.y);
 
 	cairo_matrix_multiply (&dev_ctm, &dev_ctm, &m);
 
@@ -298,13 +263,6 @@ _cairo_surface_wrapper_stroke (cairo_surface_wrapper_t *wrapper,
 	_copy_transformed_pattern (&source_copy.base, source, &m);
 	source = &source_copy.base;
     }
-    else
-    {
-	if (clip != NULL) {
-	    dev_clip = &clip_copy;
-	    _cairo_clip_init_copy (&clip_copy, clip);
-	}
-    }
 
     status = _cairo_surface_stroke (wrapper->target, op, source,
 				    dev_path, stroke_style,
@@ -315,10 +273,9 @@ _cairo_surface_wrapper_stroke (cairo_surface_wrapper_t *wrapper,
  FINISH:
     if (dev_path != path)
 	_cairo_path_fixed_fini (dev_path);
-    if (wrapper->has_extents)
-	_cairo_clip_reset (&target_clip);
+    _cairo_clip_destroy (target_clip);
     if (dev_clip != clip)
-	_cairo_clip_reset (dev_clip);
+	_cairo_clip_destroy (dev_clip);
     return status;
 }
 
@@ -337,30 +294,24 @@ _cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper,
 				    const cairo_matrix_t	    *stroke_ctm_inverse,
 				    double		     stroke_tolerance,
 				    cairo_antialias_t	     stroke_antialias,
-				    cairo_clip_t	    *clip)
+				    const cairo_clip_t	    *clip)
 {
     cairo_status_t status;
     cairo_path_fixed_t path_copy, *dev_path = path;
-    cairo_clip_t clip_copy, *dev_clip = clip;
+    cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
     cairo_matrix_t dev_ctm = *stroke_ctm;
     cairo_matrix_t dev_ctm_inverse = *stroke_ctm_inverse;
     cairo_pattern_union_t stroke_source_copy;
     cairo_pattern_union_t fill_source_copy;
-    cairo_clip_t target_clip;
+    cairo_clip_t *target_clip = NULL;
 
     if (unlikely (wrapper->target->status))
 	return wrapper->target->status;
 
-    if (wrapper->has_extents) {
-	_cairo_clip_init_copy (&target_clip, clip);
-	status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
-	if (unlikely (status))
-	    goto FINISH;
-
-	dev_clip = clip = &target_clip;
-    }
+    if (wrapper->has_extents)
+	dev_clip = target_clip = _cairo_clip_copy_intersect_rectangle (clip, &wrapper->extents);
 
-    if (clip && clip->all_clipped) {
+    if (_cairo_clip_is_all_clipped (dev_clip)) {
 	status = CAIRO_STATUS_SUCCESS;
 	goto FINISH;
     }
@@ -385,13 +336,8 @@ _cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper,
 	_cairo_path_fixed_transform (&path_copy, &m);
 	dev_path = &path_copy;
 
-	if (clip != NULL) {
-	    status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
-	    if (unlikely (status))
-		goto FINISH;
-
-	    dev_clip = &clip_copy;
-	}
+	/* XXX */
+	dev_clip = _cairo_clip_copy_with_translation (clip, wrapper->extents.x, wrapper->extents.y);
 
 	cairo_matrix_multiply (&dev_ctm, &dev_ctm, &m);
 
@@ -406,13 +352,6 @@ _cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper,
 	_copy_transformed_pattern (&fill_source_copy.base, fill_source, &m);
 	fill_source = &fill_source_copy.base;
     }
-    else
-    {
-	if (clip != NULL) {
-	    dev_clip = &clip_copy;
-	    _cairo_clip_init_copy (&clip_copy, clip);
-	}
-    }
 
     status = _cairo_surface_fill_stroke (wrapper->target,
 					 fill_op, fill_source, fill_rule,
@@ -427,10 +366,9 @@ _cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper,
   FINISH:
     if (dev_path != path)
 	_cairo_path_fixed_fini (dev_path);
-    if (wrapper->has_extents)
-	_cairo_clip_reset (&target_clip);
+    _cairo_clip_destroy (target_clip);
     if (dev_clip != clip)
-	_cairo_clip_reset (dev_clip);
+	_cairo_clip_destroy (dev_clip);
     return status;
 }
 
@@ -438,31 +376,25 @@ cairo_status_t
 _cairo_surface_wrapper_fill (cairo_surface_wrapper_t	*wrapper,
 			     cairo_operator_t	 op,
 			     const cairo_pattern_t *source,
-			     cairo_path_fixed_t	*path,
+			     const cairo_path_fixed_t	*path,
 			     cairo_fill_rule_t	 fill_rule,
 			     double		 tolerance,
 			     cairo_antialias_t	 antialias,
-			     cairo_clip_t	*clip)
+			     const cairo_clip_t	*clip)
 {
     cairo_status_t status;
-    cairo_path_fixed_t path_copy, *dev_path = path;
-    cairo_clip_t clip_copy, *dev_clip = clip;
+    cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path;
+    cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
     cairo_pattern_union_t source_copy;
-    cairo_clip_t target_clip;
+    cairo_clip_t *target_clip = NULL;
 
     if (unlikely (wrapper->target->status))
 	return wrapper->target->status;
 
-    if (wrapper->has_extents) {
-	_cairo_clip_init_copy (&target_clip, clip);
-	status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
-	if (unlikely (status))
-	    goto FINISH;
-
-	dev_clip = clip = &target_clip;
-    }
+    if (wrapper->has_extents)
+	dev_clip = target_clip = _cairo_clip_copy_intersect_rectangle (clip, &wrapper->extents);
 
-    if (clip && clip->all_clipped) {
+    if (_cairo_clip_is_all_clipped (dev_clip)) {
 	status = CAIRO_STATUS_SUCCESS;
 	goto FINISH;
     }
@@ -487,13 +419,8 @@ _cairo_surface_wrapper_fill (cairo_surface_wrapper_t	*wrapper,
 	_cairo_path_fixed_transform (&path_copy, &m);
 	dev_path = &path_copy;
 
-	if (clip != NULL) {
-	    status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
-	    if (unlikely (status))
-		goto FINISH;
-
-	    dev_clip = &clip_copy;
-	}
+	/* XXX */
+	dev_clip = _cairo_clip_copy_with_translation (clip, wrapper->extents.x, wrapper->extents.y);
 
 	status = cairo_matrix_invert (&m);
 	assert (status == CAIRO_STATUS_SUCCESS);
@@ -501,13 +428,6 @@ _cairo_surface_wrapper_fill (cairo_surface_wrapper_t	*wrapper,
 	_copy_transformed_pattern (&source_copy.base, source, &m);
 	source = &source_copy.base;
     }
-    else
-    {
-	if (clip != NULL) {
-	    dev_clip = &clip_copy;
-	    _cairo_clip_init_copy (&clip_copy, clip);
-	}
-    }
 
     status = _cairo_surface_fill (wrapper->target, op, source,
 				  dev_path, fill_rule,
@@ -517,10 +437,9 @@ _cairo_surface_wrapper_fill (cairo_surface_wrapper_t	*wrapper,
  FINISH:
     if (dev_path != path)
 	_cairo_path_fixed_fini (dev_path);
-    if (wrapper->has_extents)
-	_cairo_clip_reset (&target_clip);
+    _cairo_clip_destroy (target_clip);
     if (dev_clip != clip)
-	_cairo_clip_reset (dev_clip);
+	_cairo_clip_destroy (dev_clip);
     return status;
 }
 
@@ -536,13 +455,13 @@ _cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
 					 int			     num_clusters,
 					 cairo_text_cluster_flags_t  cluster_flags,
 					 cairo_scaled_font_t	    *scaled_font,
-					 cairo_clip_t		    *clip)
+					 const cairo_clip_t		    *clip)
 {
     cairo_status_t status;
-    cairo_clip_t clip_copy, *dev_clip = clip;
+    cairo_clip_t *dev_clip = (cairo_clip_t *)clip;
     cairo_glyph_t *dev_glyphs = glyphs;
     cairo_pattern_union_t source_copy;
-    cairo_clip_t target_clip;
+    cairo_clip_t *target_clip = NULL;
 
     if (unlikely (wrapper->target->status))
 	return wrapper->target->status;
@@ -550,16 +469,10 @@ _cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
     if (glyphs == NULL || num_glyphs == 0)
 	return CAIRO_STATUS_SUCCESS;
 
-    if (wrapper->has_extents) {
-	_cairo_clip_init_copy (&target_clip, clip);
-	status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
-	if (unlikely (status))
-	    goto FINISH;
-
-	dev_clip = clip = &target_clip;
-    }
+    if (wrapper->has_extents)
+	dev_clip = target_clip = _cairo_clip_copy_intersect_rectangle (clip, &wrapper->extents);
 
-    if (clip && clip->all_clipped) {
+    if (_cairo_clip_is_all_clipped (dev_clip)) {
 	status = CAIRO_STATUS_SUCCESS;
 	goto FINISH;
     }
@@ -578,13 +491,8 @@ _cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
 	if (_cairo_surface_wrapper_needs_device_transform (wrapper))
 	    cairo_matrix_multiply (&m, &wrapper->target->device_transform, &m);
 
-	if (clip != NULL) {
-	    status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
-	    if (unlikely (status))
-		goto FINISH;
-
-	    dev_clip = &clip_copy;
-	}
+	/* XXX */
+	dev_clip = _cairo_clip_copy_with_translation (clip, wrapper->extents.x, wrapper->extents.y);
 
 	dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
 	if (dev_glyphs == NULL) {
@@ -603,13 +511,6 @@ _cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
 	_copy_transformed_pattern (&source_copy.base, source, &m);
 	source = &source_copy.base;
     }
-    else
-    {
-	if (clip != NULL) {
-	    dev_clip = &clip_copy;
-	    _cairo_clip_init_copy (&clip_copy, clip);
-	}
-    }
 
     status = _cairo_surface_show_text_glyphs (wrapper->target, op, source,
 					      utf8, utf8_len,
@@ -621,9 +522,8 @@ _cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
 
  FINISH:
     if (dev_clip != clip)
-	_cairo_clip_reset (dev_clip);
-    if (wrapper->has_extents)
-	_cairo_clip_reset (&target_clip);
+	_cairo_clip_destroy (dev_clip);
+    _cairo_clip_destroy (target_clip);
     if (dev_glyphs != glyphs)
 	free (dev_glyphs);
     return status;
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 98903dc..1f9028d 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -170,7 +170,7 @@ _cairo_surface_set_error (cairo_surface_t *surface,
 			  cairo_status_t status)
 {
     if (status == CAIRO_STATUS_SUCCESS ||
-        status == CAIRO_INT_STATUS_NOTHING_TO_DO)
+        status == (int)CAIRO_INT_STATUS_NOTHING_TO_DO)
         return CAIRO_STATUS_SUCCESS;
 
     /* Don't overwrite an existing error. This preserves the first
@@ -498,6 +498,8 @@ cairo_surface_create_similar (cairo_surface_t  *other,
 			      int		width,
 			      int		height)
 {
+    cairo_surface_t *surface;
+
     if (unlikely (other->status))
 	return _cairo_surface_create_in_error (other->status);
     if (unlikely (other->finished))
@@ -508,10 +510,13 @@ cairo_surface_create_similar (cairo_surface_t  *other,
     if (unlikely (! CAIRO_CONTENT_VALID (content)))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT));
 
-    return _cairo_surface_create_similar_solid (other,
-						content, width, height,
-						CAIRO_COLOR_TRANSPARENT,
-						TRUE);
+    surface = _cairo_surface_create_similar_solid (other,
+						   content, width, height,
+						   CAIRO_COLOR_TRANSPARENT,
+						   TRUE);
+    assert (surface->is_clear);
+
+    return surface;
 }
 
 cairo_surface_t *
@@ -1699,7 +1704,7 @@ _cairo_surface_clone_similar (cairo_surface_t  *surface,
 			      int              *clone_offset_y,
 			      cairo_surface_t **clone_out)
 {
-    cairo_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
+    cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
     cairo_image_surface_t *image;
     void *image_extra;
 
@@ -1746,7 +1751,7 @@ _cairo_surface_clone_similar (cairo_surface_t  *surface,
 
 	    /* If we failed, try again with an image surface */
 	    status = _cairo_surface_acquire_source_image (src, &image, &image_extra);
-	    if (status == CAIRO_STATUS_SUCCESS) {
+	    if (status == CAIRO_INT_STATUS_SUCCESS) {
 		status =
 		    surface->backend->clone_similar (surface, &image->base,
 						     src_x, src_y,
@@ -1995,27 +2000,27 @@ _pattern_has_error (const cairo_pattern_t *pattern)
 }
 
 cairo_status_t
-_cairo_surface_paint (cairo_surface_t	*surface,
-		      cairo_operator_t	 op,
-		      const cairo_pattern_t *source,
-		      cairo_clip_t	    *clip)
+_cairo_surface_paint (cairo_surface_t		*surface,
+		      cairo_operator_t		 op,
+		      const cairo_pattern_t	*source,
+		      const cairo_clip_t	*clip)
 {
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     if (unlikely (surface->status))
 	return surface->status;
 
-    if (clip && clip->all_clipped)
+    if (_cairo_clip_is_all_clipped (clip))
 	return CAIRO_STATUS_SUCCESS;
 
+    if (op == CAIRO_OPERATOR_SOURCE && _cairo_pattern_is_clear (source))
+	op = CAIRO_OPERATOR_CLEAR;
+
     if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear)
 	return CAIRO_STATUS_SUCCESS;
 
-    if (op == CAIRO_OPERATOR_OVER &&
-	_cairo_pattern_is_clear (source))
-    {
+    if (op == CAIRO_OPERATOR_OVER && _cairo_pattern_is_clear (source))
 	return CAIRO_STATUS_SUCCESS;
-    }
 
     status = _pattern_has_error (source);
     if (unlikely (status))
@@ -2043,14 +2048,14 @@ _cairo_surface_mask (cairo_surface_t		*surface,
 		     cairo_operator_t		 op,
 		     const cairo_pattern_t	*source,
 		     const cairo_pattern_t	*mask,
-		     cairo_clip_t		*clip)
+		     const cairo_clip_t		*clip)
 {
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     if (unlikely (surface->status))
 	return surface->status;
 
-    if (clip && clip->all_clipped)
+    if (_cairo_clip_is_all_clipped (clip))
 	return CAIRO_STATUS_SUCCESS;
 
     if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear)
@@ -2109,14 +2114,14 @@ _cairo_surface_fill_stroke (cairo_surface_t	    *surface,
 			    const cairo_matrix_t	    *stroke_ctm_inverse,
 			    double		     stroke_tolerance,
 			    cairo_antialias_t	     stroke_antialias,
-			    cairo_clip_t	    *clip)
+			    const cairo_clip_t	    *clip)
 {
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     if (unlikely (surface->status))
 	return surface->status;
 
-    if (clip && clip->all_clipped)
+    if (_cairo_clip_is_all_clipped (clip))
 	return CAIRO_STATUS_SUCCESS;
 
     if (surface->is_clear &&
@@ -2178,20 +2183,20 @@ cairo_status_t
 _cairo_surface_stroke (cairo_surface_t		*surface,
 		       cairo_operator_t		 op,
 		       const cairo_pattern_t	*source,
-		       cairo_path_fixed_t	*path,
+		       const cairo_path_fixed_t	*path,
 		       const cairo_stroke_style_t	*stroke_style,
 		       const cairo_matrix_t		*ctm,
 		       const cairo_matrix_t		*ctm_inverse,
 		       double			 tolerance,
 		       cairo_antialias_t	 antialias,
-		       cairo_clip_t		*clip)
+		       const cairo_clip_t	*clip)
 {
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     if (unlikely (surface->status))
 	return surface->status;
 
-    if (clip && clip->all_clipped)
+    if (_cairo_clip_is_all_clipped (clip))
 	return CAIRO_STATUS_SUCCESS;
 
     if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear)
@@ -2237,18 +2242,18 @@ cairo_status_t
 _cairo_surface_fill (cairo_surface_t	*surface,
 		     cairo_operator_t	 op,
 		     const cairo_pattern_t *source,
-		     cairo_path_fixed_t	*path,
+		     const cairo_path_fixed_t	*path,
 		     cairo_fill_rule_t	 fill_rule,
 		     double		 tolerance,
 		     cairo_antialias_t	 antialias,
-		     cairo_clip_t	*clip)
+		     const cairo_clip_t	*clip)
 {
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     if (unlikely (surface->status))
 	return surface->status;
 
-    if (clip && clip->all_clipped)
+    if (_cairo_clip_is_all_clipped (clip))
 	return CAIRO_STATUS_SUCCESS;
 
     if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear)
@@ -2355,11 +2360,8 @@ _cairo_surface_create_span_renderer (cairo_operator_t		 op,
 	return _cairo_span_renderer_create_in_error (CAIRO_STATUS_SURFACE_FINISHED);
 
     if (dst->backend->create_span_renderer) {
-	return dst->backend->create_span_renderer (op,
-						   pattern, dst,
-						   antialias,
-						   rects,
-						   clip_region);
+	return dst->backend->create_span_renderer (op, pattern, dst, antialias,
+						   rects, clip_region);
     }
     ASSERT_NOT_REACHED;
     return _cairo_span_renderer_create_in_error (CAIRO_INT_STATUS_UNSUPPORTED);
@@ -2570,9 +2572,9 @@ _cairo_surface_show_text_glyphs (cairo_surface_t	    *surface,
 				 int			     num_clusters,
 				 cairo_text_cluster_flags_t  cluster_flags,
 				 cairo_scaled_font_t	    *scaled_font,
-				 cairo_clip_t		    *clip)
+				 const cairo_clip_t		*clip)
 {
-    cairo_status_t status;
+    cairo_int_status_t status;
     cairo_scaled_font_t *dev_scaled_font = scaled_font;
 
     if (unlikely (surface->status))
@@ -2581,7 +2583,7 @@ _cairo_surface_show_text_glyphs (cairo_surface_t	    *surface,
     if (num_glyphs == 0 && utf8_len == 0)
 	return CAIRO_STATUS_SUCCESS;
 
-    if (clip && clip->all_clipped)
+    if (_cairo_clip_is_all_clipped (clip))
 	return CAIRO_STATUS_SUCCESS;
 
     if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear)
@@ -2641,7 +2643,7 @@ _cairo_surface_show_text_glyphs (cairo_surface_t	    *surface,
 	    glyphs += num_glyphs - remaining_glyphs;
 	    num_glyphs = remaining_glyphs;
 	    if (status == CAIRO_INT_STATUS_UNSUPPORTED && remaining_glyphs == 0)
-		status = CAIRO_STATUS_SUCCESS;
+		status = CAIRO_INT_STATUS_SUCCESS;
 	}
     } else {
 	/* A mere show_glyphs call.  Try show_glyphs backend method first */
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 7adcfb7..e5ddb7e 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -85,7 +85,7 @@ static const cairo_svg_version_t _cairo_svg_versions[] =
 
 static void
 _cairo_svg_surface_emit_path (cairo_output_stream_t	*output,
-			      cairo_path_fixed_t	*path,
+			      const cairo_path_fixed_t	*path,
 			      const cairo_matrix_t	*ctm_inverse);
 
 static cairo_bool_t
@@ -562,10 +562,10 @@ _cairo_svg_surface_create_for_stream_internal (cairo_output_stream_t	*stream,
 static cairo_svg_page_t *
 _cairo_svg_surface_store_page (cairo_svg_surface_t *surface)
 {
-    unsigned int i;
     cairo_svg_page_t page;
     cairo_output_stream_t *stream;
-    cairo_status_t status;
+    cairo_int_status_t status;
+    unsigned int i;
 
     stream = _cairo_memory_stream_create ();
     if (_cairo_output_stream_get_status (stream)) {
@@ -715,7 +715,7 @@ _cairo_svg_path_close_path (void *closure)
 
 static void
 _cairo_svg_surface_emit_path (cairo_output_stream_t	*output,
-			      cairo_path_fixed_t	*path,
+			      const cairo_path_fixed_t	*path,
 			      const cairo_matrix_t	*ctm_inverse)
 {
     cairo_status_t status;
@@ -814,14 +814,14 @@ _cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t	*document,
     return CAIRO_STATUS_SUCCESS;
 }
 
-static cairo_status_t
+static cairo_int_status_t
 _cairo_svg_document_emit_glyph (cairo_svg_document_t	*document,
 				cairo_scaled_font_t	*scaled_font,
 				unsigned long		 scaled_font_glyph_index,
 				unsigned int		 font_id,
 				unsigned int		 subset_glyph_index)
 {
-    cairo_status_t	     status;
+    cairo_int_status_t	     status;
 
     _cairo_output_stream_printf (document->xml_node_glyphs,
 				 "<symbol overflow=\"visible\" id=\"glyph%d-%d\">\n",
@@ -840,16 +840,16 @@ _cairo_svg_document_emit_glyph (cairo_svg_document_t	*document,
 
     _cairo_output_stream_printf (document->xml_node_glyphs, "</symbol>\n");
 
-    return CAIRO_STATUS_SUCCESS;
+    return CAIRO_INT_STATUS_SUCCESS;
 }
 
-static cairo_status_t
+static cairo_int_status_t
 _cairo_svg_document_emit_font_subset (cairo_scaled_font_subset_t	*font_subset,
 				      void				*closure)
 {
     cairo_svg_document_t *document = closure;
+    cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
     unsigned int i;
-    cairo_status_t status = CAIRO_STATUS_SUCCESS;
 
     _cairo_scaled_font_freeze_cache (font_subset->scaled_font);
     for (i = 0; i < font_subset->num_glyphs; i++) {
@@ -1163,7 +1163,7 @@ static cairo_int_status_t
 _cairo_surface_base64_encode (cairo_surface_t       *surface,
 			      cairo_output_stream_t *output)
 {
-    cairo_status_t status;
+    cairo_int_status_t status;
     base64_write_closure_t info;
 
     status = _cairo_surface_base64_encode_jpeg (surface, output);
@@ -2137,7 +2137,7 @@ _cairo_svg_surface_fill_stroke (void			*abstract_surface,
 				cairo_fill_rule_t	 fill_rule,
 				double			 fill_tolerance,
 				cairo_antialias_t	 fill_antialias,
-				cairo_path_fixed_t	*path,
+				const cairo_path_fixed_t*path,
 				cairo_operator_t	 stroke_op,
 				const cairo_pattern_t	*stroke_source,
 				const cairo_stroke_style_t	*stroke_style,
@@ -2145,7 +2145,7 @@ _cairo_svg_surface_fill_stroke (void			*abstract_surface,
 				const cairo_matrix_t		*stroke_ctm_inverse,
 				double			 stroke_tolerance,
 				cairo_antialias_t	 stroke_antialias,
-				cairo_clip_t		*clip)
+				const cairo_clip_t	*clip)
 {
     cairo_svg_surface_t *surface = abstract_surface;
     cairo_status_t status;
@@ -2179,11 +2179,11 @@ static cairo_int_status_t
 _cairo_svg_surface_fill (void			*abstract_surface,
 			 cairo_operator_t	 op,
 			 const cairo_pattern_t	*source,
-			 cairo_path_fixed_t	*path,
+			 const cairo_path_fixed_t*path,
 			 cairo_fill_rule_t	 fill_rule,
 			 double			 tolerance,
 			 cairo_antialias_t	 antialias,
-			 cairo_clip_t		*clip)
+			 const cairo_clip_t	*clip)
 {
     cairo_svg_surface_t *surface = abstract_surface;
     cairo_status_t status;
@@ -2274,7 +2274,7 @@ static cairo_int_status_t
 _cairo_svg_surface_paint (void		    *abstract_surface,
 			  cairo_operator_t   op,
 			  const cairo_pattern_t   *source,
-			  cairo_clip_t		  *clip)
+			  const cairo_clip_t	  *clip)
 {
     cairo_status_t status;
     cairo_svg_surface_t *surface = abstract_surface;
@@ -2340,7 +2340,7 @@ _cairo_svg_surface_mask (void		    *abstract_surface,
 			 cairo_operator_t     op,
 			 const cairo_pattern_t	    *source,
 			 const cairo_pattern_t	    *mask,
-			 cairo_clip_t		    *clip)
+			 const cairo_clip_t	    *clip)
 {
     cairo_status_t status;
     cairo_svg_surface_t *surface = abstract_surface;
@@ -2430,13 +2430,13 @@ static cairo_int_status_t
 _cairo_svg_surface_stroke (void			*abstract_dst,
 			   cairo_operator_t      op,
 			   const cairo_pattern_t *source,
-			   cairo_path_fixed_t	*path,
+			   const cairo_path_fixed_t*path,
 			   const cairo_stroke_style_t *stroke_style,
 			   const cairo_matrix_t	*ctm,
 			   const cairo_matrix_t	*ctm_inverse,
 			   double		 tolerance,
 			   cairo_antialias_t	 antialias,
-			   cairo_clip_t		*clip)
+			   const cairo_clip_t	*clip)
 {
     cairo_svg_surface_t *surface = abstract_dst;
     cairo_status_t status;
@@ -2473,13 +2473,13 @@ _cairo_svg_surface_show_glyphs (void			*abstract_surface,
 				cairo_glyph_t		*glyphs,
 				int			 num_glyphs,
 				cairo_scaled_font_t	*scaled_font,
-				cairo_clip_t		*clip,
+				const cairo_clip_t	*clip,
 				int			*remaining_glyphs)
 {
     cairo_svg_surface_t *surface = abstract_surface;
     cairo_svg_document_t *document = surface->document;
     cairo_path_fixed_t path;
-    cairo_status_t status;
+    cairo_int_status_t status;
     cairo_scaled_font_subsets_glyph_t subset_glyph;
     int i;
 
@@ -2834,7 +2834,7 @@ _cairo_svg_surface_supports_fine_grained_fallbacks (void	*abstract_surface)
 						       CAIRO_OPERATOR_SOURCE);
     }
 
-    return status == CAIRO_STATUS_SUCCESS;
+    return status == CAIRO_INT_STATUS_SUCCESS;
 }
 
 static const cairo_paginated_surface_backend_t cairo_svg_surface_paginated_backend = {
diff --git a/src/cairo-tee-surface.c b/src/cairo-tee-surface.c
index df0ae99..40f8aa3 100644
--- a/src/cairo-tee-surface.c
+++ b/src/cairo-tee-surface.c
@@ -199,12 +199,12 @@ static cairo_int_status_t
 _cairo_tee_surface_paint (void			*abstract_surface,
 			  cairo_operator_t	 op,
 			  const cairo_pattern_t	*source,
-			  cairo_clip_t		*clip)
+			  const cairo_clip_t	*clip)
 {
     cairo_tee_surface_t *surface = abstract_surface;
     cairo_surface_wrapper_t *slaves;
     int n, num_slaves;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     status = _cairo_surface_wrapper_paint (&surface->master, op, source, clip);
     if (unlikely (status))
@@ -226,12 +226,12 @@ _cairo_tee_surface_mask (void			*abstract_surface,
 			 cairo_operator_t	 op,
 			 const cairo_pattern_t	*source,
 			 const cairo_pattern_t	*mask,
-			 cairo_clip_t		*clip)
+			 const cairo_clip_t	*clip)
 {
     cairo_tee_surface_t *surface = abstract_surface;
     cairo_surface_wrapper_t *slaves;
+    cairo_int_status_t status;
     int n, num_slaves;
-    cairo_status_t status;
 
     status = _cairo_surface_wrapper_mask (&surface->master,
 					  op, source, mask, clip);
@@ -254,18 +254,18 @@ static cairo_int_status_t
 _cairo_tee_surface_stroke (void				*abstract_surface,
 			   cairo_operator_t		 op,
 			   const cairo_pattern_t	*source,
-			   cairo_path_fixed_t		*path,
+			   const cairo_path_fixed_t	*path,
 			   const cairo_stroke_style_t	*style,
 			   const cairo_matrix_t		*ctm,
 			   const cairo_matrix_t		*ctm_inverse,
 			   double			 tolerance,
 			   cairo_antialias_t		 antialias,
-			   cairo_clip_t			*clip)
+			   const cairo_clip_t		*clip)
 {
     cairo_tee_surface_t *surface = abstract_surface;
     cairo_surface_wrapper_t *slaves;
+    cairo_int_status_t status;
     int n, num_slaves;
-    cairo_status_t status;
 
     status = _cairo_surface_wrapper_stroke (&surface->master,
 					    op, source,
@@ -296,16 +296,16 @@ static cairo_int_status_t
 _cairo_tee_surface_fill (void				*abstract_surface,
 			 cairo_operator_t		 op,
 			 const cairo_pattern_t		*source,
-			 cairo_path_fixed_t		*path,
+			 const cairo_path_fixed_t	*path,
 			 cairo_fill_rule_t		 fill_rule,
 			 double				 tolerance,
 			 cairo_antialias_t		 antialias,
-			 cairo_clip_t			*clip)
+			 const cairo_clip_t		*clip)
 {
     cairo_tee_surface_t *surface = abstract_surface;
     cairo_surface_wrapper_t *slaves;
+    cairo_int_status_t status;
     int n, num_slaves;
-    cairo_status_t status;
 
     status = _cairo_surface_wrapper_fill (&surface->master,
 					  op, source,
@@ -327,7 +327,7 @@ _cairo_tee_surface_fill (void				*abstract_surface,
 	    return status;
     }
 
-    return CAIRO_STATUS_SUCCESS;
+    return CAIRO_INT_STATUS_SUCCESS;
 }
 
 static cairo_bool_t
@@ -348,12 +348,12 @@ _cairo_tee_surface_show_text_glyphs (void		    *abstract_surface,
 				     int		     num_clusters,
 				     cairo_text_cluster_flags_t cluster_flags,
 				     cairo_scaled_font_t    *scaled_font,
-				     cairo_clip_t	    *clip)
+				     const cairo_clip_t	    *clip)
 {
     cairo_tee_surface_t *surface = abstract_surface;
     cairo_surface_wrapper_t *slaves;
+    cairo_int_status_t status;
     int n, num_slaves;
-    cairo_status_t status;
     cairo_glyph_t *glyphs_copy;
 
     /* XXX: This copying is ugly. */
@@ -504,8 +504,8 @@ cairo_tee_surface_remove (cairo_surface_t *abstract_surface,
 {
     cairo_tee_surface_t *surface;
     cairo_surface_wrapper_t *slaves;
+    cairo_int_status_t status;
     int n, num_slaves;
-    cairo_status_t status;
 
     if (unlikely (abstract_surface->status))
 	return;
@@ -549,7 +549,7 @@ cairo_tee_surface_remove (cairo_surface_t *abstract_surface,
 
 cairo_surface_t *
 cairo_tee_surface_index (cairo_surface_t *abstract_surface,
-			 int index)
+			 unsigned int index)
 {
     cairo_tee_surface_t *surface;
 
diff --git a/src/cairo-tee.h b/src/cairo-tee.h
index 9c048c6..9125a3a 100644
--- a/src/cairo-tee.h
+++ b/src/cairo-tee.h
@@ -55,7 +55,7 @@ cairo_tee_surface_remove (cairo_surface_t *surface,
 
 cairo_public cairo_surface_t *
 cairo_tee_surface_index (cairo_surface_t *surface,
-			 int index);
+			 unsigned int index);
 
 CAIRO_END_DECLS
 
diff --git a/src/cairo-tor-scan-converter.c b/src/cairo-tor-scan-converter.c
index 888a395..4c0d8dc 100644
--- a/src/cairo-tor-scan-converter.c
+++ b/src/cairo-tor-scan-converter.c
@@ -1960,8 +1960,8 @@ blit_with_span_renderer (struct cell_list *cells,
 			 int xmin, int xmax)
 {
     struct cell *cell = cells->head;
-    int prev_x = xmin;
-    int cover = 0;
+    int prev_x = xmin, last_x = -1;
+    int cover = 0, last_cover = -1;
     cairo_half_open_span_t *spans;
     unsigned num_spans;
 
@@ -2005,26 +2005,34 @@ blit_with_span_renderer (struct cell_list *cells,
 	if (x > prev_x) {
 	    spans[num_spans].x = prev_x;
 	    spans[num_spans].coverage = GRID_AREA_TO_ALPHA (cover);
+	    last_cover = cover;
+	    last_x = prev_x;
 	    ++num_spans;
 	}
 
 	cover += cell->covered_height*GRID_X*2;
 	area = cover - cell->uncovered_area;
 
-	spans[num_spans].x = x;
-	spans[num_spans].coverage = GRID_AREA_TO_ALPHA (area);
-	++num_spans;
+	if (area != last_cover) {
+	    spans[num_spans].x = x;
+	    spans[num_spans].coverage = GRID_AREA_TO_ALPHA (area);
+	    last_cover = area;
+	    last_x = x;
+	    ++num_spans;
+	}
 
 	prev_x = x+1;
     }
 
-    if (prev_x <= xmax) {
+    if (prev_x <= xmax && cover != last_cover) {
 	spans[num_spans].x = prev_x;
 	spans[num_spans].coverage = GRID_AREA_TO_ALPHA (cover);
+	last_cover = cover;
+	last_x = prev_x;
 	++num_spans;
     }
 
-    if (prev_x < xmax && cover) {
+    if (last_x < xmax && last_cover) {
 	spans[num_spans].x = xmax;
 	spans[num_spans].coverage = 0;
 	++num_spans;
diff --git a/src/cairo-traps.c b/src/cairo-traps.c
index 2fe6684..42e2eb5 100644
--- a/src/cairo-traps.c
+++ b/src/cairo-traps.c
@@ -76,6 +76,15 @@ _cairo_traps_limit (cairo_traps_t	*traps,
 }
 
 void
+_cairo_traps_init_with_clip (cairo_traps_t *traps,
+			     const cairo_clip_t *clip)
+{
+    _cairo_traps_init (traps);
+    if (clip)
+	_cairo_traps_limit (traps, clip->boxes, clip->num_boxes);
+}
+
+void
 _cairo_traps_clear (cairo_traps_t *traps)
 {
     traps->status = CAIRO_STATUS_SUCCESS;
@@ -485,6 +494,44 @@ _cairo_traps_extents (const cairo_traps_t *traps,
     }
 }
 
+static cairo_bool_t
+_mono_edge_is_vertical (const cairo_line_t *line)
+{
+    return _cairo_fixed_integer_round_down (line->p1.x) == _cairo_fixed_integer_round_down (line->p2.x);
+}
+
+static cairo_bool_t
+_traps_are_pixel_aligned (cairo_traps_t *traps,
+			  cairo_antialias_t antialias)
+{
+    int i;
+
+    if (antialias == CAIRO_ANTIALIAS_NONE) {
+	for (i = 0; i < traps->num_traps; i++) {
+	    if (! _mono_edge_is_vertical (&traps->traps[i].left)   ||
+		! _mono_edge_is_vertical (&traps->traps[i].right))
+	    {
+		traps->maybe_region = FALSE;
+		return FALSE;
+	    }
+	}
+    } else {
+	for (i = 0; i < traps->num_traps; i++) {
+	    if (traps->traps[i].left.p1.x != traps->traps[i].left.p2.x   ||
+		traps->traps[i].right.p1.x != traps->traps[i].right.p2.x ||
+		! _cairo_fixed_is_integer (traps->traps[i].top)          ||
+		! _cairo_fixed_is_integer (traps->traps[i].bottom)       ||
+		! _cairo_fixed_is_integer (traps->traps[i].left.p1.x)    ||
+		! _cairo_fixed_is_integer (traps->traps[i].right.p1.x))
+	    {
+		traps->maybe_region = FALSE;
+		return FALSE;
+	    }
+	}
+    }
+
+    return TRUE;
+}
 
 /**
  * _cairo_traps_extract_region:
@@ -502,6 +549,7 @@ _cairo_traps_extents (const cairo_traps_t *traps,
  **/
 cairo_int_status_t
 _cairo_traps_extract_region (cairo_traps_t   *traps,
+			     cairo_antialias_t antialias,
 			     cairo_region_t **region)
 {
     cairo_rectangle_int_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (cairo_rectangle_int_t)];
@@ -510,20 +558,12 @@ _cairo_traps_extract_region (cairo_traps_t   *traps,
     int i, rect_count;
 
     /* we only treat this a hint... */
-    if (! traps->maybe_region)
+    if (antialias != CAIRO_ANTIALIAS_NONE && ! traps->maybe_region)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    for (i = 0; i < traps->num_traps; i++) {
-	if (traps->traps[i].left.p1.x != traps->traps[i].left.p2.x   ||
-	    traps->traps[i].right.p1.x != traps->traps[i].right.p2.x ||
-	    ! _cairo_fixed_is_integer (traps->traps[i].top)          ||
-	    ! _cairo_fixed_is_integer (traps->traps[i].bottom)       ||
-	    ! _cairo_fixed_is_integer (traps->traps[i].left.p1.x)    ||
-	    ! _cairo_fixed_is_integer (traps->traps[i].right.p1.x))
-	{
-	    traps->maybe_region = FALSE;
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-	}
+    if (! _traps_are_pixel_aligned (traps, antialias)) {
+	traps->maybe_region = FALSE;
+	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
     if (traps->num_traps > ARRAY_LENGTH (stack_rects)) {
@@ -535,19 +575,30 @@ _cairo_traps_extract_region (cairo_traps_t   *traps,
 
     rect_count = 0;
     for (i = 0; i < traps->num_traps; i++) {
-	int x1 = _cairo_fixed_integer_part (traps->traps[i].left.p1.x);
-	int y1 = _cairo_fixed_integer_part (traps->traps[i].top);
-	int x2 = _cairo_fixed_integer_part (traps->traps[i].right.p1.x);
-	int y2 = _cairo_fixed_integer_part (traps->traps[i].bottom);
-
-	rects[rect_count].x = x1;
-	rects[rect_count].y = y1;
-	rects[rect_count].width = x2 - x1;
-	rects[rect_count].height = y2 - y1;
+	int x1, y1, x2, y2;
+
+	if (antialias == CAIRO_ANTIALIAS_NONE) {
+	    x1 = _cairo_fixed_integer_round_down (traps->traps[i].left.p1.x);
+	    y1 = _cairo_fixed_integer_round_down (traps->traps[i].top);
+	    x2 = _cairo_fixed_integer_round_down (traps->traps[i].right.p1.x);
+	    y2 = _cairo_fixed_integer_round_down (traps->traps[i].bottom);
+	} else {
+	    x1 = _cairo_fixed_integer_part (traps->traps[i].left.p1.x);
+	    y1 = _cairo_fixed_integer_part (traps->traps[i].top);
+	    x2 = _cairo_fixed_integer_part (traps->traps[i].right.p1.x);
+	    y2 = _cairo_fixed_integer_part (traps->traps[i].bottom);
+	}
 
-	rect_count++;
+	if (x2 > x1 && y2 > y1) {
+	    rects[rect_count].x = x1;
+	    rects[rect_count].y = y1;
+	    rects[rect_count].width  = x2 - x1;
+	    rects[rect_count].height = y2 - y1;
+	    rect_count++;
+	}
     }
 
+
     *region = cairo_region_create_rectangles (rects, rect_count);
     status = (*region)->status;
 
diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c
index 176f163..844e521 100644
--- a/src/cairo-truetype-subset.c
+++ b/src/cairo-truetype-subset.c
@@ -122,7 +122,8 @@ static cairo_status_t
 _cairo_truetype_font_set_error (cairo_truetype_font_t *font,
 			        cairo_status_t status)
 {
-    if (status == CAIRO_STATUS_SUCCESS || status == CAIRO_INT_STATUS_UNSUPPORTED)
+    if (status == CAIRO_STATUS_SUCCESS ||
+	status == (int)CAIRO_INT_STATUS_UNSUPPORTED)
 	return status;
 
     _cairo_status_set_error (&font->status, status);
@@ -1056,19 +1057,19 @@ cairo_truetype_font_create_truetype_table_list (cairo_truetype_font_t *font)
     size = 0;
     if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
                                       TT_TAG_cvt, 0, NULL,
-                                      &size) == CAIRO_STATUS_SUCCESS)
+                                      &size) == CAIRO_INT_STATUS_SUCCESS)
         has_cvt = TRUE;
 
     size = 0;
     if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
                                       TT_TAG_fpgm, 0, NULL,
-                                      &size) == CAIRO_STATUS_SUCCESS)
+                                      &size) == CAIRO_INT_STATUS_SUCCESS)
         has_fpgm = TRUE;
 
     size = 0;
     if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
                                       TT_TAG_prep, 0, NULL,
-                                      &size) == CAIRO_STATUS_SUCCESS)
+                                      &size) == CAIRO_INT_STATUS_SUCCESS)
         has_prep = TRUE;
 
     font->num_tables = 0;
@@ -1344,7 +1345,7 @@ _cairo_truetype_index_to_ucs4 (cairo_scaled_font_t *scaled_font,
                                unsigned long        index,
                                uint32_t            *ucs4)
 {
-    cairo_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
+    cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
     const cairo_scaled_font_backend_t *backend;
     tt_cmap_t *cmap;
     char buf[4];
diff --git a/src/cairo-type1-fallback.c b/src/cairo-type1-fallback.c
index 39bc53f..5284cfe 100644
--- a/src/cairo-type1-fallback.c
+++ b/src/cairo-type1-fallback.c
@@ -626,7 +626,7 @@ cairo_type1_font_write_private_dict (cairo_type1_font_t *font,
 
   fail:
     status2 = _cairo_output_stream_destroy (encrypted_output);
-    if (status == CAIRO_STATUS_SUCCESS)
+    if (status == CAIRO_INT_STATUS_SUCCESS)
 	status = status2;
 
     return status;
diff --git a/src/cairo-type3-glyph-surface.c b/src/cairo-type3-glyph-surface.c
index e9e8311..bad0d3b 100644
--- a/src/cairo-type3-glyph-surface.c
+++ b/src/cairo-type3-glyph-surface.c
@@ -188,7 +188,7 @@ static cairo_int_status_t
 _cairo_type3_glyph_surface_paint (void			*abstract_surface,
 				  cairo_operator_t	 op,
 				  const cairo_pattern_t	*source,
-				  cairo_clip_t		*clip)
+				  const cairo_clip_t	*clip)
 {
     cairo_type3_glyph_surface_t *surface = abstract_surface;
     const cairo_surface_pattern_t *pattern;
@@ -224,7 +224,7 @@ _cairo_type3_glyph_surface_mask (void			*abstract_surface,
 				 cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
 				 const cairo_pattern_t	*mask,
-				 cairo_clip_t		*clip)
+				 const cairo_clip_t	*clip)
 {
     return _cairo_type3_glyph_surface_paint (abstract_surface,
 					     op, mask,
@@ -235,13 +235,13 @@ static cairo_int_status_t
 _cairo_type3_glyph_surface_stroke (void			*abstract_surface,
 				   cairo_operator_t	 op,
 				   const cairo_pattern_t *source,
-				   cairo_path_fixed_t	*path,
+				   const cairo_path_fixed_t	*path,
 				   const cairo_stroke_style_t	*style,
 				   const cairo_matrix_t	*ctm,
 				   const cairo_matrix_t	*ctm_inverse,
 				   double		 tolerance,
 				   cairo_antialias_t	 antialias,
-				   cairo_clip_t		*clip)
+				   const cairo_clip_t	*clip)
 {
     cairo_type3_glyph_surface_t *surface = abstract_surface;
     cairo_int_status_t status;
@@ -261,11 +261,11 @@ static cairo_int_status_t
 _cairo_type3_glyph_surface_fill (void			*abstract_surface,
 				 cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
-				 cairo_path_fixed_t	*path,
+				 const cairo_path_fixed_t	*path,
 				 cairo_fill_rule_t	 fill_rule,
 				 double			 tolerance,
 				 cairo_antialias_t	 antialias,
-				 cairo_clip_t		*clip)
+				 const cairo_clip_t		*clip)
 {
     cairo_type3_glyph_surface_t *surface = abstract_surface;
     cairo_int_status_t status;
@@ -286,7 +286,7 @@ _cairo_type3_glyph_surface_show_glyphs (void		     *abstract_surface,
 					cairo_glyph_t        *glyphs,
 					int		      num_glyphs,
 					cairo_scaled_font_t  *scaled_font,
-					cairo_clip_t	     *clip,
+					const cairo_clip_t     *clip,
 					int		     *remaining_glyphs)
 {
     cairo_type3_glyph_surface_t *surface = abstract_surface;
@@ -418,7 +418,7 @@ _cairo_type3_glyph_surface_analyze_glyph (void		     *abstract_surface,
 {
     cairo_type3_glyph_surface_t *surface = abstract_surface;
     cairo_scaled_glyph_t *scaled_glyph;
-    cairo_status_t status, status2;
+    cairo_int_status_t status, status2;
     cairo_output_stream_t *null_stream;
 
     if (unlikely (surface->base.status))
@@ -436,11 +436,11 @@ _cairo_type3_glyph_surface_analyze_glyph (void		     *abstract_surface,
 					 CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE,
 					 &scaled_glyph);
 
-    if (_cairo_status_is_error (status))
+    if (_cairo_int_status_is_error (status))
 	goto cleanup;
 
     if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
-	status = CAIRO_STATUS_SUCCESS;
+	status = CAIRO_INT_STATUS_SUCCESS;
 	goto cleanup;
     }
 
@@ -451,13 +451,13 @@ _cairo_type3_glyph_surface_analyze_glyph (void		     *abstract_surface,
 
     status = _cairo_pdf_operators_flush (&surface->pdf_operators);
     if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK)
-	status = CAIRO_STATUS_SUCCESS;
+	status = CAIRO_INT_STATUS_SUCCESS;
 
 cleanup:
     _cairo_scaled_font_thaw_cache (surface->scaled_font);
 
     status2 = _cairo_output_stream_destroy (null_stream);
-    if (status == CAIRO_STATUS_SUCCESS)
+    if (status == CAIRO_INT_STATUS_SUCCESS)
 	status = status2;
 
     return status;
@@ -472,7 +472,7 @@ _cairo_type3_glyph_surface_emit_glyph (void		     *abstract_surface,
 {
     cairo_type3_glyph_surface_t *surface = abstract_surface;
     cairo_scaled_glyph_t *scaled_glyph;
-    cairo_status_t status, status2;
+    cairo_int_status_t status, status2;
     double x_advance, y_advance;
     cairo_matrix_t font_matrix_inverse;
 
@@ -492,10 +492,10 @@ _cairo_type3_glyph_surface_emit_glyph (void		     *abstract_surface,
 					     glyph_index,
 					     CAIRO_SCALED_GLYPH_INFO_METRICS,
 					     &scaled_glyph);
-	if (status == CAIRO_STATUS_SUCCESS)
+	if (status == CAIRO_INT_STATUS_SUCCESS)
 	    status = CAIRO_INT_STATUS_IMAGE_FALLBACK;
     }
-    if (_cairo_status_is_error (status)) {
+    if (_cairo_int_status_is_error (status)) {
 	_cairo_scaled_font_thaw_cache (surface->scaled_font);
 	return status;
     }
@@ -508,7 +508,7 @@ _cairo_type3_glyph_surface_emit_glyph (void		     *abstract_surface,
     /* The invertability of font_matrix is tested in
      * pdf_operators_show_glyphs before any glyphs are mapped to the
      * subset. */
-    assert (status2 == CAIRO_STATUS_SUCCESS);
+    assert (status2 == CAIRO_INT_STATUS_SUCCESS);
 
     cairo_matrix_transform_distance (&font_matrix_inverse, &x_advance, &y_advance);
     *width = x_advance;
@@ -525,7 +525,7 @@ _cairo_type3_glyph_surface_emit_glyph (void		     *abstract_surface,
 				 _cairo_fixed_to_double (bbox->p2.x),
 				 - _cairo_fixed_to_double (bbox->p1.y));
 
-    if (status == CAIRO_STATUS_SUCCESS) {
+    if (status == CAIRO_INT_STATUS_SUCCESS) {
 	cairo_output_stream_t *mem_stream;
 
 	mem_stream = _cairo_memory_stream_create ();
@@ -540,17 +540,17 @@ _cairo_type3_glyph_surface_emit_glyph (void		     *abstract_surface,
 						  &surface->base);
 
 	status2 = _cairo_pdf_operators_flush (&surface->pdf_operators);
-	if (status == CAIRO_STATUS_SUCCESS)
+	if (status == CAIRO_INT_STATUS_SUCCESS)
 	    status = status2;
 
 	_cairo_output_stream_printf (surface->stream, "Q\n");
 
 	_cairo_type3_glyph_surface_set_stream (surface, stream);
-	if (status == CAIRO_STATUS_SUCCESS)
+	if (status == CAIRO_INT_STATUS_SUCCESS)
 	    _cairo_memory_stream_copy (mem_stream, stream);
 
 	status2 = _cairo_output_stream_destroy (mem_stream);
-	if (status == CAIRO_STATUS_SUCCESS)
+	if (status == CAIRO_INT_STATUS_SUCCESS)
 	    status = status2;
     }
 
diff --git a/src/cairo-types-private.h b/src/cairo-types-private.h
index 8881055..bed6412 100644
--- a/src/cairo-types-private.h
+++ b/src/cairo-types-private.h
@@ -228,16 +228,7 @@ typedef enum _cairo_paginated_mode {
  * from #cairo_status_t. Oh well, without that, I'll use this bogus 100
  * offset.  We want to keep it fit in int8_t as the compiler may choose
  * that for #cairo_status_t */
-typedef enum _cairo_int_status {
-    CAIRO_INT_STATUS_UNSUPPORTED = 100,
-    CAIRO_INT_STATUS_DEGENERATE,
-    CAIRO_INT_STATUS_NOTHING_TO_DO,
-    CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY,
-    CAIRO_INT_STATUS_IMAGE_FALLBACK,
-    CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN,
-
-    CAIRO_INT_STATUS_LAST_STATUS
-} cairo_int_status_t;
+typedef enum _cairo_int_status cairo_int_status_t;
 
 typedef enum _cairo_internal_surface_type {
     CAIRO_INTERNAL_SURFACE_TYPE_SNAPSHOT = 0x1000,
diff --git a/src/cairo-user-font.c b/src/cairo-user-font.c
index a524d58..522711d 100644
--- a/src/cairo-user-font.c
+++ b/src/cairo-user-font.c
@@ -158,7 +158,7 @@ _cairo_user_scaled_glyph_init (void			 *abstract_font,
 	    status = face->scaled_font_methods.render_glyph ((cairo_scaled_font_t *)scaled_font,
 							     _cairo_scaled_glyph_index(scaled_glyph),
 							     cr, &extents);
-	    if (status == CAIRO_STATUS_SUCCESS)
+	    if (status == CAIRO_INT_STATUS_SUCCESS)
 	        status = cairo_status (cr);
 
 	    cairo_destroy (cr);
@@ -328,11 +328,12 @@ _cairo_user_text_to_glyphs (void		      *abstract_font,
 							   glyphs, num_glyphs,
 							   clusters, num_clusters, cluster_flags);
 
-	if (status != CAIRO_STATUS_SUCCESS &&
-	    status != CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED)
+	if (status != CAIRO_INT_STATUS_SUCCESS &&
+	    status != CAIRO_INT_STATUS_USER_FONT_NOT_IMPLEMENTED)
 	    return status;
 
-	if (status == CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED || *num_glyphs < 0) {
+	if (status == CAIRO_INT_STATUS_USER_FONT_NOT_IMPLEMENTED ||
+	    *num_glyphs < 0) {
 	    if (orig_glyphs != *glyphs) {
 		cairo_glyph_free (*glyphs);
 		*glyphs = orig_glyphs;
diff --git a/src/cairo-win32-printing-surface.c b/src/cairo-win32-printing-surface.c
index 58d404a..a5d2787 100644
--- a/src/cairo-win32-printing-surface.c
+++ b/src/cairo-win32-printing-surface.c
@@ -1167,7 +1167,7 @@ static cairo_int_status_t
 _cairo_win32_printing_surface_paint (void			*abstract_surface,
                                      cairo_operator_t		 op,
                                      const cairo_pattern_t	*source,
-				     cairo_clip_t      *clip)
+				     const cairo_clip_t      *clip)
 {
     cairo_win32_surface_t *surface = abstract_surface;
     cairo_solid_pattern_t clear;
@@ -1244,13 +1244,13 @@ static cairo_int_status_t
 _cairo_win32_printing_surface_stroke (void			*abstract_surface,
                                       cairo_operator_t		 op,
                                       const cairo_pattern_t	*source,
-                                      cairo_path_fixed_t	*path,
+                                      const cairo_path_fixed_t	*path,
                                       const cairo_stroke_style_t *style,
                                       const cairo_matrix_t	*stroke_ctm,
                                       const cairo_matrix_t	*stroke_ctm_inverse,
                                       double			tolerance,
                                       cairo_antialias_t		antialias,
-				      cairo_clip_t    *clip)
+				      const cairo_clip_t    *clip)
 {
     cairo_win32_surface_t *surface = abstract_surface;
     cairo_int_status_t status;
@@ -1373,11 +1373,11 @@ static cairo_int_status_t
 _cairo_win32_printing_surface_fill (void		        *abstract_surface,
 				    cairo_operator_t		 op,
 				    const cairo_pattern_t	*source,
-				    cairo_path_fixed_t		*path,
+				    const cairo_path_fixed_t	*path,
 				    cairo_fill_rule_t		 fill_rule,
 				    double			 tolerance,
 				    cairo_antialias_t		 antialias,
-				    cairo_clip_t		*clip)
+				    const cairo_clip_t		*clip)
 {
     cairo_win32_surface_t *surface = abstract_surface;
     cairo_int_status_t status;
@@ -1528,7 +1528,7 @@ _cairo_win32_printing_surface_show_glyphs (void                 *abstract_surfac
                                            cairo_glyph_t        *glyphs,
                                            int			 num_glyphs,
                                            cairo_scaled_font_t  *scaled_font,
-					   cairo_clip_t		*clip,
+					   const cairo_clip_t	*clip,
 					   int			*remaining_glyphs)
 {
     cairo_win32_surface_t *surface = abstract_surface;
diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index 0f0bffc..f309b4b 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -1522,7 +1522,7 @@ _cairo_win32_surface_show_glyphs_internal (void			 *surface,
 					   cairo_glyph_t	 *glyphs,
 					   int			  num_glyphs,
 					   cairo_scaled_font_t	 *scaled_font,
-					   cairo_clip_t		 *clip,
+					   const cairo_clip_t	 *clip,
 					   int			 *remaining_glyphs,
 					   cairo_bool_t		  glyph_indexing)
 {
@@ -1674,11 +1674,11 @@ cairo_int_status_t
 _cairo_win32_surface_show_glyphs (void			*surface,
 				  cairo_operator_t	 op,
 				  const cairo_pattern_t *source,
-				  cairo_glyph_t	 	*glyphs,
+				  cairo_glyph_t		*glyphs,
 				  int			 num_glyphs,
 				  cairo_scaled_font_t	*scaled_font,
-				  cairo_clip_t          *clip,
-				  int		      	*remaining_glyphs)
+				  const cairo_clip_t          *clip,
+				  int			*remaining_glyphs)
 {
     return _cairo_win32_surface_show_glyphs_internal (surface,
 						      op,
diff --git a/src/cairo-xcb-private.h b/src/cairo-xcb-private.h
index 92898b8..d52306e 100644
--- a/src/cairo-xcb-private.h
+++ b/src/cairo-xcb-private.h
@@ -360,36 +360,36 @@ cairo_private cairo_int_status_t
 _cairo_xcb_surface_cairo_paint (cairo_xcb_surface_t	*surface,
 				cairo_operator_t	 op,
 				const cairo_pattern_t	*source,
-				cairo_clip_t		*clip);
+				const cairo_clip_t		*clip);
 
 cairo_private cairo_int_status_t
 _cairo_xcb_surface_cairo_mask (cairo_xcb_surface_t	*surface,
 			       cairo_operator_t		 op,
 			       const cairo_pattern_t	*source,
 			       const cairo_pattern_t	*mask,
-			       cairo_clip_t		*clip);
+			       const cairo_clip_t		*clip);
 
 cairo_private cairo_int_status_t
 _cairo_xcb_surface_cairo_stroke (cairo_xcb_surface_t	*surface,
 				 cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
-				 cairo_path_fixed_t	*path,
+				 const cairo_path_fixed_t	*path,
 				 const cairo_stroke_style_t	*style,
 				 const cairo_matrix_t		*ctm,
 				 const cairo_matrix_t		*ctm_inverse,
 				 double			 tolerance,
 				 cairo_antialias_t	 antialias,
-				 cairo_clip_t		*clip);
+				 const cairo_clip_t		*clip);
 
 cairo_private cairo_int_status_t
 _cairo_xcb_surface_cairo_fill (cairo_xcb_surface_t	*surface,
 			       cairo_operator_t		 op,
 			       const cairo_pattern_t	*source,
-			       cairo_path_fixed_t	*path,
+			       const cairo_path_fixed_t	*path,
 			       cairo_fill_rule_t	 fill_rule,
 			       double			 tolerance,
 			       cairo_antialias_t	 antialias,
-			       cairo_clip_t		*clip);
+			       const cairo_clip_t		*clip);
 
 cairo_private cairo_int_status_t
 _cairo_xcb_surface_cairo_glyphs (cairo_xcb_surface_t	*surface,
@@ -398,42 +398,42 @@ _cairo_xcb_surface_cairo_glyphs (cairo_xcb_surface_t	*surface,
 				 cairo_scaled_font_t	*scaled_font,
 				 cairo_glyph_t		*glyphs,
 				 int			 num_glyphs,
-				 cairo_clip_t		*clip);
+				 const cairo_clip_t		*clip);
 
 cairo_private cairo_int_status_t
 _cairo_xcb_surface_render_paint (cairo_xcb_surface_t	*surface,
 				 cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
-				 cairo_clip_t		*clip);
+				 const cairo_clip_t		*clip);
 
 cairo_private cairo_int_status_t
 _cairo_xcb_surface_render_mask (cairo_xcb_surface_t	*surface,
 				cairo_operator_t		 op,
 				const cairo_pattern_t	*source,
 				const cairo_pattern_t	*mask,
-				cairo_clip_t		*clip);
+				const cairo_clip_t		*clip);
 
 cairo_private cairo_int_status_t
-_cairo_xcb_surface_render_stroke (cairo_xcb_surface_t	*surface,
-				  cairo_operator_t	 op,
-				  const cairo_pattern_t	*source,
-				  cairo_path_fixed_t	*path,
+_cairo_xcb_surface_render_stroke (cairo_xcb_surface_t		*surface,
+				  cairo_operator_t		 op,
+				  const cairo_pattern_t		*source,
+				  const cairo_path_fixed_t	*path,
 				  const cairo_stroke_style_t	*style,
 				  const cairo_matrix_t		*ctm,
 				  const cairo_matrix_t		*ctm_inverse,
 				  double			 tolerance,
-				  cairo_antialias_t	 antialias,
-				  cairo_clip_t		*clip);
+				  cairo_antialias_t		 antialias,
+				  const cairo_clip_t		*clip);
 
 cairo_private cairo_int_status_t
 _cairo_xcb_surface_render_fill (cairo_xcb_surface_t	*surface,
-				cairo_operator_t		 op,
+				cairo_operator_t	 op,
 				const cairo_pattern_t	*source,
-				cairo_path_fixed_t	*path,
+				const cairo_path_fixed_t*path,
 				cairo_fill_rule_t	 fill_rule,
 				double			 tolerance,
 				cairo_antialias_t	 antialias,
-				cairo_clip_t		*clip);
+				const cairo_clip_t	*clip);
 
 cairo_private cairo_int_status_t
 _cairo_xcb_surface_render_glyphs (cairo_xcb_surface_t	*surface,
@@ -442,7 +442,7 @@ _cairo_xcb_surface_render_glyphs (cairo_xcb_surface_t	*surface,
 				  cairo_scaled_font_t	*scaled_font,
 				  cairo_glyph_t		*glyphs,
 				  int			 num_glyphs,
-				  cairo_clip_t		*clip);
+				  const cairo_clip_t		*clip);
 cairo_private void
 _cairo_xcb_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font);
 
diff --git a/src/cairo-xcb-surface-cairo.c b/src/cairo-xcb-surface-cairo.c
index 79c4d6c..338a616 100644
--- a/src/cairo-xcb-surface-cairo.c
+++ b/src/cairo-xcb-surface-cairo.c
@@ -38,7 +38,7 @@ cairo_int_status_t
 _cairo_xcb_surface_cairo_paint (cairo_xcb_surface_t	*surface,
 				cairo_operator_t	 op,
 				const cairo_pattern_t	*source,
-				cairo_clip_t		*clip)
+				const cairo_clip_t	*clip)
 {
     return CAIRO_INT_STATUS_UNSUPPORTED;
 }
@@ -48,7 +48,7 @@ _cairo_xcb_surface_cairo_mask (cairo_xcb_surface_t	*surface,
 			       cairo_operator_t		 op,
 			       const cairo_pattern_t	*source,
 			       const cairo_pattern_t	*mask,
-			       cairo_clip_t		*clip)
+			       const cairo_clip_t	*clip)
 {
     return CAIRO_INT_STATUS_UNSUPPORTED;
 }
@@ -57,13 +57,13 @@ cairo_int_status_t
 _cairo_xcb_surface_cairo_stroke (cairo_xcb_surface_t	*surface,
 				 cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
-				 cairo_path_fixed_t	*path,
+				 const cairo_path_fixed_t	*path,
 				 const cairo_stroke_style_t	*style,
 				 const cairo_matrix_t		*ctm,
 				 const cairo_matrix_t		*ctm_inverse,
 				 double			 tolerance,
 				 cairo_antialias_t	 antialias,
-				 cairo_clip_t		*clip)
+				 const cairo_clip_t		*clip)
 {
     return CAIRO_INT_STATUS_UNSUPPORTED;
 }
@@ -72,11 +72,11 @@ cairo_int_status_t
 _cairo_xcb_surface_cairo_fill (cairo_xcb_surface_t	*surface,
 			       cairo_operator_t		 op,
 			       const cairo_pattern_t	*source,
-			       cairo_path_fixed_t	*path,
+			       const cairo_path_fixed_t	*path,
 			       cairo_fill_rule_t	 fill_rule,
 			       double			 tolerance,
 			       cairo_antialias_t	 antialias,
-			       cairo_clip_t		*clip)
+			       const cairo_clip_t		*clip)
 {
     return CAIRO_INT_STATUS_UNSUPPORTED;
 }
@@ -88,7 +88,7 @@ _cairo_xcb_surface_cairo_glyphs (cairo_xcb_surface_t	*surface,
 				 cairo_scaled_font_t	*scaled_font,
 				 cairo_glyph_t		*glyphs,
 				 int			 num_glyphs,
-				 cairo_clip_t		*clip)
+				 const cairo_clip_t	*clip)
 {
     return CAIRO_INT_STATUS_UNSUPPORTED;
 }
diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c
index fc349a3..000f00f 100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -425,7 +425,7 @@ _cairo_xcb_picture_set_matrix (cairo_xcb_picture_t *picture,
 {
     xcb_render_transform_t transform;
     pixman_transform_t *pixman_transform;
-    cairo_status_t ignored;
+    cairo_int_status_t ignored;
 
     /* Casting between pixman_transform_t and xcb_render_transform_t is safe
      * because they happen to be the exact same type.
@@ -1572,13 +1572,7 @@ _create_composite_mask (cairo_clip_t		*clip,
     cairo_bool_t clip_surface = FALSE;
     cairo_status_t status;
 
-    if (clip != NULL) {
-	cairo_region_t *clip_region;
-
-	status = _cairo_clip_get_region (clip, &clip_region);
-	assert (! _cairo_status_is_error (status));
-	clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED;
-    }
+    clip_surface = ! _cairo_clip_is_region (clip);
 
     surface = (cairo_xcb_surface_t *)
 	_cairo_xcb_surface_create_similar (dst, CAIRO_CONTENT_ALPHA,
@@ -1794,6 +1788,7 @@ _clip_and_composite_combine (cairo_clip_t		*clip,
 						extents->x,     extents->y,
 						extents->width, extents->height);
     }
+    cairo_surface_destroy (clip_surface);
 
  CLEANUP_SURFACE:
     cairo_surface_destroy (&tmp->base);
@@ -2056,6 +2051,8 @@ _cairo_xcb_surface_fixup_unbounded_with_mask (cairo_xcb_surface_t *dst,
 						width, height);
     }
 
+    cairo_surface_destroy (&mask->base);
+
     return CAIRO_STATUS_SUCCESS;
 }
 
@@ -2086,7 +2083,7 @@ _cairo_xcb_surface_fixup_unbounded_boxes (cairo_xcb_surface_t *dst,
 
 	_cairo_boxes_init (&tmp);
 
-	status = _cairo_boxes_add (&tmp, &box);
+	status = _cairo_boxes_add (&tmp, CAIRO_ANTIALIAS_DEFAULT, &box);
 	assert (status == CAIRO_STATUS_SUCCESS);
 
 	tmp.chunks.next = &boxes->chunks;
@@ -2103,12 +2100,14 @@ _cairo_xcb_surface_fixup_unbounded_boxes (cairo_xcb_surface_t *dst,
 	pbox = pixman_region32_rectangles (&clip_region->rgn, &i);
 	_cairo_boxes_limit (&clear, (cairo_box_t *) pbox, i);
 
-	status = _cairo_boxes_add (&clear, &box);
+	status = _cairo_boxes_add (&clear, CAIRO_ANTIALIAS_DEFAULT, &box);
 	assert (status == CAIRO_STATUS_SUCCESS);
 
 	for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
 	    for (i = 0; i < chunk->count; i++) {
-		status = _cairo_boxes_add (&clear, &chunk->base[i]);
+		status = _cairo_boxes_add (&clear,
+					   CAIRO_ANTIALIAS_DEFAULT,
+					   &chunk->base[i]);
 		if (unlikely (status)) {
 		    _cairo_boxes_fini (&clear);
 		    return status;
@@ -2173,6 +2172,22 @@ _cairo_xcb_surface_clear (cairo_xcb_surface_t *dst)
     return CAIRO_STATUS_SUCCESS;
 }
 
+static cairo_bool_t
+need_bounded_clip (cairo_composite_rectangles_t *extents)
+{
+	return ! _cairo_clip_is_region (extents->clip);
+}
+
+static cairo_bool_t
+need_unbounded_clip (cairo_composite_rectangles_t *extents)
+{
+    if (! extents->is_bounded)
+	return need_bounded_clip (extents);
+
+    return extents->clip->path != NULL;
+}
+
+
 static cairo_status_t
 _clip_and_composite (cairo_xcb_surface_t	*dst,
 		     cairo_operator_t		 op,
@@ -2180,43 +2195,10 @@ _clip_and_composite (cairo_xcb_surface_t	*dst,
 		     xcb_draw_func_t		 draw_func,
 		     void			*draw_closure,
 		     cairo_composite_rectangles_t*extents,
-		     cairo_clip_t		*clip)
+		     cairo_bool_t need_clip_surface)
 {
     cairo_status_t status;
-    cairo_region_t *clip_region = NULL;
-    cairo_region_t extents_region;
-    cairo_bool_t need_clip_surface = FALSE;
-
-    if (clip != NULL) {
-	status = _cairo_clip_get_region (clip, &clip_region);
-	if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
-	    return CAIRO_STATUS_SUCCESS;
-
-	assert (! _cairo_status_is_error (status));
-	need_clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED;
-
-	if (clip_region != NULL) {
-	    cairo_rectangle_int_t rect;
-	    cairo_bool_t is_empty;
-
-	    cairo_region_get_extents (clip_region, &rect);
-	    is_empty = ! _cairo_rectangle_intersect (&extents->unbounded, &rect);
-	    if (unlikely (is_empty))
-		return CAIRO_STATUS_SUCCESS;
-
-	    is_empty = ! _cairo_rectangle_intersect (&extents->bounded, &rect);
-	    if (unlikely (is_empty && extents->is_bounded))
-		return CAIRO_STATUS_SUCCESS;
-	}
-    } else if (!extents->is_bounded) {
-	/* The X server will estimate the affected region of the unbounded
-	 * operation and will apply the operation to that rectangle.
-	 * However, there are cases where this estimate is too high (e.g.
-	 * the test suite's clip-fill-{eo,nz}-unbounded tests).
-	 */
-	_cairo_region_init_rectangle (&extents_region, &extents->unbounded);
-	clip_region = &extents_region;
-    }
+    cairo_region_t *clip_region = _cairo_clip_get_region (extents->clip);
 
     status = _cairo_xcb_connection_acquire (dst->connection);
     if (unlikely (status))
@@ -2241,7 +2223,7 @@ _clip_and_composite (cairo_xcb_surface_t	*dst,
     }
 
     if (op == CAIRO_OPERATOR_SOURCE) {
-	status = _clip_and_composite_source (clip, src,
+	status = _clip_and_composite_source (extents->clip, src,
 					     draw_func, draw_closure,
 					     dst, &extents->bounded);
     } else {
@@ -2252,11 +2234,11 @@ _clip_and_composite (cairo_xcb_surface_t	*dst,
 
 	if (need_clip_surface) {
 	    if (extents->is_bounded) {
-		status = _clip_and_composite_with_mask (clip, op, src,
+		status = _clip_and_composite_with_mask (extents->clip, op, src,
 							draw_func, draw_closure,
 							dst, &extents->bounded);
 	    } else {
-		status = _clip_and_composite_combine (clip, op, src,
+		status = _clip_and_composite_combine (extents->clip, op, src,
 						      draw_func, draw_closure,
 						      dst, &extents->bounded);
 	    }
@@ -2271,15 +2253,13 @@ _clip_and_composite (cairo_xcb_surface_t	*dst,
 
     if (status == CAIRO_STATUS_SUCCESS && ! extents->is_bounded) {
 	if (need_clip_surface)
-	    status = _cairo_xcb_surface_fixup_unbounded_with_mask (dst, extents, clip);
+	    status = _cairo_xcb_surface_fixup_unbounded_with_mask (dst, extents, extents->clip);
 	else
 	    status = _cairo_xcb_surface_fixup_unbounded (dst, extents);
     }
 
     if (clip_region != NULL)
 	_cairo_xcb_surface_clear_clip_region (dst);
-    if (clip_region == &extents_region)
-	_cairo_region_fini (&extents_region);
 
     _cairo_xcb_connection_release (dst->connection);
 
@@ -2291,26 +2271,13 @@ _core_boxes (cairo_xcb_surface_t *dst,
 	     cairo_operator_t op,
 	     const cairo_pattern_t *src,
 	     cairo_boxes_t *boxes,
-	     cairo_antialias_t antialias,
-	     cairo_clip_t *clip,
 	     const cairo_composite_rectangles_t *extents)
 {
-    if (antialias != CAIRO_ANTIALIAS_NONE) {
-	if (! boxes->is_pixel_aligned)
-	    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_STATUS_SUCCESS ||
-		status == CAIRO_INT_STATUS_UNSUPPORTED);
+    if (! boxes->is_pixel_aligned)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-	if (status == CAIRO_INT_STATUS_UNSUPPORTED)
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-    }
+    if (! _cairo_clip_is_region (extents->clip))
+	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     if (op == CAIRO_OPERATOR_CLEAR)
 	return _cairo_xcb_surface_core_fill_boxes (dst, CAIRO_COLOR_TRANSPARENT, boxes);
@@ -2336,36 +2303,25 @@ _composite_boxes (cairo_xcb_surface_t *dst,
 		  cairo_operator_t op,
 		  const cairo_pattern_t *src,
 		  cairo_boxes_t *boxes,
-		  cairo_antialias_t antialias,
-		  cairo_clip_t *clip,
 		  const cairo_composite_rectangles_t *extents)
 {
-    cairo_bool_t need_clip_mask = FALSE;
-    cairo_region_t *clip_region = NULL;
+    cairo_bool_t need_clip_mask = extents->clip->path != NULL;
+    cairo_region_t *clip_region = _cairo_clip_get_region (extents->clip);
     cairo_status_t status;
 
     /* If the boxes are not pixel-aligned, we will need to compute a real mask */
-    if (antialias != CAIRO_ANTIALIAS_NONE) {
-	if (! boxes->is_pixel_aligned)
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-    }
-
-    if (clip != NULL) {
-	status = _cairo_clip_get_region (clip, &clip_region);
-	assert (status == CAIRO_STATUS_SUCCESS ||
-		status == CAIRO_INT_STATUS_UNSUPPORTED);
-
-	need_clip_mask = status == CAIRO_INT_STATUS_UNSUPPORTED;
-	if (need_clip_mask &&
-	    (! extents->is_bounded || op == CAIRO_OPERATOR_SOURCE))
-	{
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-	}
+    if (! boxes->is_pixel_aligned)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-	if (clip_region != NULL && cairo_region_num_rectangles (clip_region) == 1)
-	    clip_region = NULL;
+    if (need_clip_mask &&
+	(! extents->is_bounded || op == CAIRO_OPERATOR_SOURCE))
+    {
+	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
+    if (clip_region != NULL && cairo_region_num_rectangles (clip_region) == 1)
+	clip_region = NULL;
+
     status = _cairo_xcb_connection_acquire (dst->connection);
     if (unlikely (status))
 	return status;
@@ -2391,7 +2347,9 @@ _composite_boxes (cairo_xcb_surface_t *dst,
 	    cairo_surface_t *clip_surface;
 	    int clip_x, clip_y;
 
-	    clip_surface = _cairo_clip_get_surface (clip, &dst->base, &clip_x, &clip_y);
+	    clip_surface = _cairo_clip_get_surface (extents->clip,
+						    &dst->base,
+						    &clip_x, &clip_y);
 	    if (unlikely (clip_surface->status))
 		return clip_surface->status;
 
@@ -2400,6 +2358,7 @@ _composite_boxes (cairo_xcb_surface_t *dst,
 	    cairo_matrix_init_translate (&mask.base.matrix,
 					 -clip_x,
 					 -clip_y);
+	    cairo_surface_destroy (clip_surface);
 
 	    if (op == CAIRO_OPERATOR_CLEAR) {
 		src = NULL;
@@ -2426,17 +2385,96 @@ _composite_boxes (cairo_xcb_surface_t *dst,
     return status;
 }
 
+static cairo_bool_t
+cairo_boxes_for_each_box (cairo_boxes_t *boxes,
+			  cairo_bool_t (*func) (cairo_box_t *box,
+						void *data),
+			  void *data)
+{
+    struct _cairo_boxes_chunk *chunk;
+    int i;
+
+    for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
+	for (i = 0; i < chunk->count; i++)
+	    if (! func (&chunk->base[i], data))
+		return FALSE;
+    }
+
+    return TRUE;
+}
+
+struct image_contains_box {
+    int width, height;
+    int tx, ty;
+};
+
+static cairo_bool_t image_contains_box (cairo_box_t *box, void *closure)
+{
+    struct image_contains_box *data = closure;
+
+    return
+	box->p1.x + data->tx >= 0 &&
+	box->p1.y + data->ty >= 0 &&
+	box->p2.x + data->tx <= data->width &&
+	box->p2.y + data->ty <= data->height;
+}
+
+struct image_upload_box {
+    cairo_xcb_surface_t *surface;
+    cairo_image_surface_t *image;
+    xcb_gcontext_t gc;
+    int tx, ty;
+};
+
+static cairo_bool_t image_upload_box (cairo_box_t *box, void *closure)
+{
+    const struct image_upload_box *iub = closure;
+    int width = box->p2.x - box->p1.x;
+    int height = box->p2.y - box->p1.y;
+    int bpp = PIXMAN_FORMAT_BPP (iub->image->pixman_format);
+    int len = CAIRO_STRIDE_FOR_WIDTH_BPP (width, bpp);
+    if (len == iub->image->stride) {
+	_cairo_xcb_connection_put_image (iub->surface->connection,
+					 iub->surface->drawable,
+					 iub->gc,
+					 width, height,
+					 box->p1.x, box->p2.y,
+					 iub->image->depth,
+					 iub->image->stride,
+					 iub->image->data +
+					 (box->p1.y + iub->ty) * iub->image->stride +
+					 (box->p1.x + iub->tx) * bpp/8);
+    } else {
+	_cairo_xcb_connection_put_subimage (iub->surface->connection,
+					    iub->surface->drawable,
+					    iub->gc,
+					    box->p1.x + iub->tx,
+					    box->p1.y + iub->ty,
+					    width, height,
+					    bpp / 8,
+					    iub->image->stride,
+					    box->p1.x, box->p2.y,
+					    iub->image->depth,
+					    iub->image->data);
+    }
+
+    return TRUE;
+}
+
 static cairo_status_t
 _upload_image_inplace (cairo_xcb_surface_t *surface,
 		       const cairo_pattern_t *source,
-		       const cairo_rectangle_int_t *extents)
+		       cairo_boxes_t *boxes)
 {
     const cairo_surface_pattern_t *pattern;
+    struct image_contains_box icb;
+    struct image_upload_box iub;
     cairo_image_surface_t *image;
-    xcb_gcontext_t gc;
     cairo_status_t status;
     int tx, ty;
-    int len, bpp;
+
+    if (! boxes->is_pixel_aligned)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     if (source->type != CAIRO_PATTERN_TYPE_SURFACE)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -2445,6 +2483,7 @@ _upload_image_inplace (cairo_xcb_surface_t *surface,
     if (pattern->surface->type != CAIRO_SURFACE_TYPE_IMAGE)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
+    /* Have we already upload this image to a pixmap? */
     {
 	cairo_xcb_picture_t *snapshot;
 
@@ -2466,79 +2505,73 @@ _upload_image_inplace (cairo_xcb_surface_t *surface,
     if (! _cairo_matrix_is_integer_translation (&source->matrix, &tx, &ty))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    image = (cairo_image_surface_t *) pattern->surface;
-    if (source->extend != CAIRO_EXTEND_NONE &&
-	(extents->x + tx < 0 ||
-	 extents->y + ty < 0 ||
-	 extents->x + tx + extents->width > image->width ||
-	 extents->y + ty + extents->height > image->height))
-    {
+    /* Check that the data is entirely within the image */
+    icb.width = image->width;
+    icb.height = image->height;
+    icb.tx = tx;
+    icb.ty = ty;
+    if (! cairo_boxes_for_each_box (boxes, image_contains_box, &icb))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
-    }
 
     status = _cairo_xcb_connection_acquire (surface->connection);
     if (unlikely (status))
 	return status;
 
-    gc = _cairo_xcb_screen_get_gc (surface->screen, surface->drawable, image->depth);
-
-    /* Do we need to trim the image? */
-    bpp = PIXMAN_FORMAT_BPP (image->pixman_format);
-    len = CAIRO_STRIDE_FOR_WIDTH_BPP (extents->width, bpp);
-    if (len == image->stride) {
-	_cairo_xcb_connection_put_image (surface->connection,
-					 surface->drawable, gc,
-					 extents->width, extents->height,
-					 extents->x, extents->y,
-					 image->depth,
-					 image->stride,
-					 image->data +
-					 (extents->y + ty) * image->stride +
-					 (extents->x + tx) * bpp/8);
-    } else {
-	_cairo_xcb_connection_put_subimage (surface->connection,
-					    surface->drawable, gc,
-					    extents->x + tx, extents->y + ty,
-					    extents->width, extents->height,
-					    bpp / 8,
-					    image->stride,
-					    extents->x, extents->y,
-					    image->depth,
-					    image->data);
 
-    }
+    iub.surface = surface;
+    iub.image = image;
+    iub.gc = _cairo_xcb_screen_get_gc (surface->screen,
+				       surface->drawable,
+				       image->depth);
+    iub.tx = tx;
+    iub.ty = ty;
+    cairo_boxes_for_each_box (boxes, image_upload_box, &iub);
 
-    _cairo_xcb_screen_put_gc (surface->screen, image->depth, gc);
+    _cairo_xcb_screen_put_gc (surface->screen, image->depth, iub.gc);
     _cairo_xcb_connection_release (surface->connection);
 
     return CAIRO_STATUS_SUCCESS;
 }
 
+static void
+trim_extents_to_traps (cairo_composite_rectangles_t *extents,
+		       cairo_traps_t *traps)
+{
+    cairo_box_t box;
+
+    /* X trims the affected area to the extents of the trapezoids, so
+     * we need to compensate when fixing up the unbounded area.
+    */
+    _cairo_traps_extents (traps, &box);
+    _cairo_box_round_to_rectangle (&box, &extents->mask);
+    _cairo_rectangle_intersect (&extents->bounded, &extents->mask);
+}
+
 static cairo_status_t
 _clip_and_composite_boxes (cairo_xcb_surface_t *dst,
 			   cairo_operator_t op,
 			   const cairo_pattern_t *src,
 			   cairo_boxes_t *boxes,
-			   cairo_antialias_t antialias,
-			   cairo_composite_rectangles_t *extents,
-			   cairo_clip_t *clip)
+			   cairo_composite_rectangles_t *extents)
 {
     composite_traps_info_t info;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     if (boxes->num_boxes == 0 && extents->is_bounded)
 	return CAIRO_STATUS_SUCCESS;
 
-    if (clip == NULL &&
-	(op == CAIRO_OPERATOR_SOURCE || (op == CAIRO_OPERATOR_OVER && dst->base.is_clear)) &&
-	boxes->num_boxes == 1 &&
-	extents->bounded.width  == dst->width &&
-	extents->bounded.height == dst->height)
+    if (boxes->is_pixel_aligned && _cairo_clip_is_region (extents->clip) &&
+	(op == CAIRO_OPERATOR_SOURCE || (op == CAIRO_OPERATOR_OVER && dst->base.is_clear)))
     {
-	op = CAIRO_OPERATOR_SOURCE;
-	dst->deferred_clear = FALSE;
+	if (boxes->num_boxes == 1 &&
+	    extents->bounded.width  == dst->width &&
+	    extents->bounded.height == dst->height)
+	{
+	    op = CAIRO_OPERATOR_SOURCE;
+	    dst->deferred_clear = FALSE;
+	}
 
-	status = _upload_image_inplace (dst, src, &extents->bounded);
+	status = _upload_image_inplace (dst, src, boxes);
 	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
 	    return status;
     }
@@ -2553,14 +2586,16 @@ _clip_and_composite_boxes (cairo_xcb_surface_t *dst,
 	    op = CAIRO_OPERATOR_SOURCE;
     }
 
-    if (clip == NULL && op == CAIRO_OPERATOR_SOURCE && boxes->num_boxes == 1) {
-	status = _upload_image_inplace (dst, src, &extents->bounded);
+    if (boxes->is_pixel_aligned &&
+	_cairo_clip_is_region (extents->clip) &&
+	op == CAIRO_OPERATOR_SOURCE) {
+	status = _upload_image_inplace (dst, src, boxes);
 	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
 	    return status;
     }
 
     if ((dst->flags & CAIRO_XCB_RENDER_HAS_COMPOSITE) == 0)
-	return _core_boxes (dst, op, src, boxes, antialias, clip, extents);
+	return _core_boxes (dst, op, src, boxes, extents);
 
     if (dst->deferred_clear) {
 	status = _cairo_xcb_surface_clear (dst);
@@ -2569,7 +2604,7 @@ _clip_and_composite_boxes (cairo_xcb_surface_t *dst,
     }
 
     /* Use a fast path if the boxes are pixel aligned */
-    status = _composite_boxes (dst, op, src, boxes, antialias, clip, extents);
+    status = _composite_boxes (dst, op, src, boxes, extents);
     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
 	return status;
 
@@ -2581,10 +2616,11 @@ _clip_and_composite_boxes (cairo_xcb_surface_t *dst,
     if (unlikely (status))
 	return status;
 
-    info.antialias = antialias;
+    trim_extents_to_traps (extents, &info.traps);
+    info.antialias = CAIRO_ANTIALIAS_DEFAULT;
     status = _clip_and_composite (dst, op, src,
 				  _composite_traps, &info,
-				  extents, clip);
+				  extents, need_unbounded_clip (extents));
 
     _cairo_traps_fini (&info.traps);
     return status;
@@ -2738,38 +2774,14 @@ _composite_mask (void				*closure,
 
 /* high level rasteriser -> compositor */
 
-static cairo_clip_path_t *
-_clip_get_single_path (cairo_clip_t *clip)
-{
-    cairo_clip_path_t *iter = clip->path;
-    cairo_clip_path_t *path = NULL;
-
-    do {
-	if ((iter->flags & CAIRO_CLIP_PATH_IS_BOX) == 0) {
-	    if (path != NULL)
-		return FALSE;
-
-	    path = iter;
-	}
-	iter = iter->prev;
-    } while (iter != NULL);
-
-    return path;
-}
-
 cairo_int_status_t
 _cairo_xcb_surface_render_paint (cairo_xcb_surface_t	*surface,
 				 cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
-				 cairo_clip_t		*clip)
+				 const cairo_clip_t	*clip)
 {
     cairo_composite_rectangles_t extents;
     cairo_boxes_t boxes;
-    cairo_box_t *clip_boxes = boxes.boxes_embedded;
-    cairo_clip_t local_clip;
-    cairo_clip_path_t *clip_path;
-    cairo_bool_t have_clip = FALSE;
-    int num_boxes = ARRAY_LENGTH (boxes.boxes_embedded);
     cairo_status_t status;
 
     if (unlikely (! _operator_is_supported (surface->flags, op)))
@@ -2794,45 +2806,13 @@ _cairo_xcb_surface_render_paint (cairo_xcb_surface_t	*surface,
     if (unlikely (status))
 	return status;
 
-    if (_cairo_clip_contains_extents (clip, &extents))
-	clip = NULL;
-
-    if (clip != NULL) {
-	clip = _cairo_clip_init_copy (&local_clip, clip);
-	have_clip = TRUE;
-    }
-
-    status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
-    if (unlikely (status)) {
-	if (have_clip)
-	    _cairo_clip_fini (&local_clip);
-
-	return status;
-    }
-
-    if (clip != NULL &&
-	extents.is_bounded &&
-	(clip_path = _clip_get_single_path (clip)) != NULL)
-    {
-	status = _cairo_xcb_surface_render_fill (surface, op, source,
-						 &clip_path->path,
-						 clip_path->fill_rule,
-						 clip_path->tolerance,
-						 clip_path->antialias,
-						 NULL);
-    }
-    else
-    {
-	_cairo_boxes_init_for_array (&boxes, clip_boxes, num_boxes);
+    status = _cairo_clip_to_boxes(extents.clip, &boxes);
+    if (likely (status == CAIRO_STATUS_SUCCESS)) {
 	status = _clip_and_composite_boxes (surface, op, source,
-					    &boxes, CAIRO_ANTIALIAS_DEFAULT,
-					    &extents, clip);
-	if (clip_boxes != boxes.boxes_embedded)
-	    free (clip_boxes);
+					    &boxes, &extents);
     }
 
-    if (have_clip)
-	_cairo_clip_fini (&local_clip);
+    _cairo_composite_rectangles_fini (&extents);
 
     return status;
 }
@@ -2842,11 +2822,9 @@ _cairo_xcb_surface_render_mask (cairo_xcb_surface_t	*surface,
 				cairo_operator_t	 op,
 				const cairo_pattern_t	*source,
 				const cairo_pattern_t	*mask,
-				cairo_clip_t		*clip)
+				const cairo_clip_t	*clip)
 {
     cairo_composite_rectangles_t extents;
-    cairo_clip_t local_clip;
-    cairo_bool_t have_clip = FALSE;
     cairo_status_t status;
 
     if (unlikely (! _operator_is_supported (surface->flags, op)))
@@ -2861,25 +2839,11 @@ _cairo_xcb_surface_render_mask (cairo_xcb_surface_t	*surface,
     if (unlikely (status))
 	return status;
 
-    if (_cairo_clip_contains_extents (clip, &extents))
-	clip = NULL;
-
-    if (clip != NULL && extents.is_bounded) {
-	clip = _cairo_clip_init_copy (&local_clip, clip);
-	status = _cairo_clip_rectangle (clip, &extents.bounded);
-	if (unlikely (status)) {
-	    _cairo_clip_fini (&local_clip);
-	    return status;
-	}
-	have_clip = TRUE;
-    }
-
     status = _clip_and_composite (surface, op, source,
 				  _composite_mask, (void *) mask,
-				  &extents, clip);
+				  &extents, need_bounded_clip (&extents));
 
-    if (have_clip)
-	_cairo_clip_fini (&local_clip);
+    _cairo_composite_rectangles_fini (&extents);
 
     return status;
 }
@@ -2891,27 +2855,19 @@ _cairo_xcb_surface_render_composite_polygon (cairo_xcb_surface_t *dst,
 					     cairo_polygon_t *polygon,
 					     cairo_antialias_t antialias,
 					     cairo_fill_rule_t fill_rule,
-					     cairo_composite_rectangles_t *extents,
-					     cairo_clip_t *clip)
+					     cairo_composite_rectangles_t *extents)
 {
     composite_traps_info_t traps;
-    cairo_bool_t clip_surface = FALSE;
+    cairo_bool_t clip_surface = ! _cairo_clip_is_region (extents->clip);
+    cairo_region_t *clip_region = _cairo_clip_get_region (extents->clip);
     cairo_status_t status;
-    cairo_bool_t is_not_empty;
 
     if (polygon->num_edges == 0) {
 	status = CAIRO_STATUS_SUCCESS;
 
 	if (! extents->is_bounded) {
-	    cairo_region_t *clip_region = NULL;
-
-	    if (clip != NULL) {
-		status = _cairo_clip_get_region (clip, &clip_region);
-		clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED;
-
 		if (clip_region != NULL && cairo_region_num_rectangles (clip_region) == 1)
 		    clip_region = NULL;
-	    }
 
 	    if (clip_surface == FALSE) {
 		if (clip_region != NULL)
@@ -2924,31 +2880,19 @@ _cairo_xcb_surface_render_composite_polygon (cairo_xcb_surface_t *dst,
 	    } else {
 		status = _cairo_xcb_surface_fixup_unbounded_with_mask (dst,
 								       extents,
-								       clip);
+								       extents->clip);
 	    }
 	}
 
 	return status;
     }
 
-    _cairo_box_round_to_rectangle (&polygon->extents, &extents->mask);
-    is_not_empty = _cairo_rectangle_intersect (&extents->bounded, &extents->mask);
-    if (extents->is_bounded && ! is_not_empty)
-	return CAIRO_STATUS_SUCCESS;
-
     _cairo_traps_init (&traps.traps);
 
     status = _cairo_bentley_ottmann_tessellate_polygon (&traps.traps, polygon, fill_rule);
     if (unlikely (status))
 	goto CLEANUP_TRAPS;
 
-    if (clip != NULL) {
-	cairo_region_t *clip_region;
-
-	status = _cairo_clip_get_region (clip, &clip_region);
-	clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED;
-    }
-
     if (traps.traps.has_intersections) {
 	if (traps.traps.is_rectangular)
 	    status = _cairo_bentley_ottmann_tessellate_rectangular_traps (&traps.traps, CAIRO_FILL_RULE_WINDING);
@@ -2973,18 +2917,18 @@ _cairo_xcb_surface_render_composite_polygon (cairo_xcb_surface_t *dst,
 
 	_boxes_for_traps (&boxes, &traps.traps, antialias);
 	status = _clip_and_composite_boxes (dst, op, source,
-					    &boxes, antialias,
-					    extents, clip);
+					    &boxes, extents);
     }
     else
     {
 	/* Otherwise render the trapezoids to a mask and composite in the usual
 	 * fashion.
 	 */
+	trim_extents_to_traps (extents, &traps.traps);
 	traps.antialias = antialias;
 	status = _clip_and_composite (dst, op, source,
 				      _composite_traps, &traps,
-				      extents, clip);
+				      extents, need_unbounded_clip (extents));
     }
 
 CLEANUP_TRAPS:
@@ -2997,22 +2941,18 @@ static cairo_int_status_t
 _cairo_xcb_surface_render_stroke_as_polygon (cairo_xcb_surface_t	*dst,
 					     cairo_operator_t		 op,
 					     const cairo_pattern_t	*source,
-					     cairo_path_fixed_t		*path,
+					     const cairo_path_fixed_t		*path,
 					     const cairo_stroke_style_t	*stroke_style,
 					     const cairo_matrix_t	*ctm,
 					     const cairo_matrix_t	*ctm_inverse,
 					     double			 tolerance,
 					     cairo_antialias_t		 antialias,
-					     cairo_clip_t		*clip,
-					     const cairo_box_t		*clip_boxes,
-					     int			 num_boxes,
 					     cairo_composite_rectangles_t *extents)
 {
     cairo_polygon_t polygon;
     cairo_status_t status;
 
-    _cairo_polygon_init (&polygon, clip_boxes, num_boxes);
-
+    _cairo_polygon_init_with_clip (&polygon, extents->clip);
     status = _cairo_path_fixed_stroke_to_polygon (path,
 						  stroke_style,
 						  ctm, ctm_inverse,
@@ -3022,9 +2962,8 @@ _cairo_xcb_surface_render_stroke_as_polygon (cairo_xcb_surface_t	*dst,
 	status = _cairo_xcb_surface_render_composite_polygon (dst, op, source,
 							      &polygon, antialias,
 							      CAIRO_FILL_RULE_WINDING,
-							      extents, clip);
+							      extents);
     }
-
     _cairo_polygon_fini (&polygon);
 
     return status;
@@ -3042,13 +2981,12 @@ static cairo_status_t
 _cairo_xcb_surface_render_stroke_via_mask (cairo_xcb_surface_t		*dst,
 					   cairo_operator_t		 op,
 					   const cairo_pattern_t	*source,
-					   cairo_path_fixed_t		*path,
+					   const cairo_path_fixed_t		*path,
 					   const cairo_stroke_style_t	*stroke_style,
 					   const cairo_matrix_t		*ctm,
 					   const cairo_matrix_t		*ctm_inverse,
 					   double			 tolerance,
 					   cairo_antialias_t		 antialias,
-					   cairo_clip_t			*clip,
 					   cairo_composite_rectangles_t *extents)
 {
     cairo_surface_t *image;
@@ -3081,7 +3019,7 @@ _cairo_xcb_surface_render_stroke_via_mask (cairo_xcb_surface_t		*dst,
 	cairo_matrix_init_translate (&mask.base.matrix, -x, -y);
 	status = _clip_and_composite (dst, op, source,
 				      _composite_mask, (void *) &mask.base,
-				      extents, clip);
+				      extents, need_bounded_clip (extents));
 	_cairo_pattern_fini (&mask.base);
     }
 
@@ -3095,20 +3033,16 @@ cairo_int_status_t
 _cairo_xcb_surface_render_stroke (cairo_xcb_surface_t	*surface,
 				  cairo_operator_t	 op,
 				  const cairo_pattern_t	*source,
-				  cairo_path_fixed_t	*path,
+				  const cairo_path_fixed_t	*path,
 				  const cairo_stroke_style_t	*style,
 				  const cairo_matrix_t	*ctm,
 				  const cairo_matrix_t	*ctm_inverse,
 				  double		 tolerance,
 				  cairo_antialias_t	 antialias,
-				  cairo_clip_t		*clip)
+				  const cairo_clip_t		*clip)
 {
     cairo_composite_rectangles_t extents;
-    cairo_box_t boxes_stack[32], *clip_boxes = boxes_stack;
-    int num_boxes = ARRAY_LENGTH (boxes_stack);
-    cairo_clip_t local_clip;
-    cairo_bool_t have_clip = FALSE;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     if (unlikely (! _operator_is_supported (surface->flags, op)))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -3128,39 +3062,21 @@ _cairo_xcb_surface_render_stroke (cairo_xcb_surface_t	*surface,
     if (unlikely (status))
 	return status;
 
-    if (_cairo_clip_contains_extents (clip, &extents))
-	clip = NULL;
-
-    if (clip != NULL) {
-	clip = _cairo_clip_init_copy (&local_clip, clip);
-	have_clip = TRUE;
-    }
-
-    status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
-    if (unlikely (status)) {
-	if (have_clip)
-	    _cairo_clip_fini (&local_clip);
-
-	return status;
-    }
 
     status = CAIRO_INT_STATUS_UNSUPPORTED;
     if (_cairo_path_fixed_stroke_is_rectilinear (path)) {
 	cairo_boxes_t boxes;
 
-	_cairo_boxes_init (&boxes);
-	_cairo_boxes_limit (&boxes, clip_boxes, num_boxes);
-
+	_cairo_boxes_init_with_clip (&boxes, extents.clip);
 	status = _cairo_path_fixed_stroke_rectilinear_to_boxes (path,
 								style,
 								ctm,
+								antialias,
 								&boxes);
-	if (likely (status == CAIRO_STATUS_SUCCESS)) {
+	if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
 	    status = _clip_and_composite_boxes (surface, op, source,
-						&boxes, antialias,
-						&extents, clip);
+						&boxes, &extents);
 	}
-
 	_cairo_boxes_fini (&boxes);
     }
 
@@ -3170,25 +3086,19 @@ _cairo_xcb_surface_render_stroke (cairo_xcb_surface_t	*surface,
 								  path, style,
 								  ctm, ctm_inverse,
 								  tolerance, antialias,
-								  clip, clip_boxes, num_boxes,
 								  &extents);
 	} else if (surface->flags & CAIRO_XCB_RENDER_HAS_COMPOSITE) {
 	    status = _cairo_xcb_surface_render_stroke_via_mask (surface, op, source,
 								path, style,
 								ctm, ctm_inverse,
 								tolerance, antialias,
-								have_clip ? &local_clip : NULL,
 								&extents);
 	} else {
 	    ASSERT_NOT_REACHED;
 	}
     }
 
-    if (clip_boxes != boxes_stack)
-	free (clip_boxes);
-
-    if (have_clip)
-	_cairo_clip_fini (&local_clip);
+    _cairo_composite_rectangles_fini (&extents);
 
     return status;
 }
@@ -3197,28 +3107,24 @@ static cairo_status_t
 _cairo_xcb_surface_render_fill_as_polygon (cairo_xcb_surface_t	*dst,
 					   cairo_operator_t	 op,
 					   const cairo_pattern_t*source,
-					   cairo_path_fixed_t	*path,
+					   const cairo_path_fixed_t	*path,
 					   cairo_fill_rule_t	 fill_rule,
 					   double		 tolerance,
 					   cairo_antialias_t	 antialias,
-					   cairo_clip_t		*clip,
-					   cairo_box_t		*clip_boxes,
-					   int			 num_boxes,
 					   cairo_composite_rectangles_t *extents)
 {
     cairo_polygon_t polygon;
     cairo_status_t status;
 
-    _cairo_polygon_init (&polygon, clip_boxes, num_boxes);
-
+    _cairo_polygon_init_with_clip (&polygon, extents->clip);
     status = _cairo_path_fixed_fill_to_polygon (path, tolerance, &polygon);
     if (likely (status == CAIRO_STATUS_SUCCESS)) {
 	status = _cairo_xcb_surface_render_composite_polygon (dst, op, source,
-							      &polygon, antialias,
+							      &polygon,
+							      antialias,
 							      fill_rule,
-							      extents, clip);
+							      extents);
     }
-
     _cairo_polygon_fini (&polygon);
 
     return status;
@@ -3228,11 +3134,10 @@ static cairo_status_t
 _cairo_xcb_surface_render_fill_via_mask (cairo_xcb_surface_t	*dst,
 					 cairo_operator_t	 op,
 					 const cairo_pattern_t	*source,
-					 cairo_path_fixed_t	*path,
+					 const cairo_path_fixed_t	*path,
 					 cairo_fill_rule_t	 fill_rule,
 					 double			 tolerance,
 					 cairo_antialias_t	 antialias,
-					 cairo_clip_t		*clip,
 					 cairo_composite_rectangles_t *extents)
 {
     cairo_surface_t *image;
@@ -3264,7 +3169,7 @@ _cairo_xcb_surface_render_fill_via_mask (cairo_xcb_surface_t	*dst,
 	cairo_matrix_init_translate (&mask.base.matrix, -x, -y);
 	status = _clip_and_composite (dst, op, source,
 				      _composite_mask, (void *) &mask.base,
-				      extents, clip);
+				      extents, need_bounded_clip (extents));
 
 	_cairo_pattern_fini (&mask.base);
     }
@@ -3279,18 +3184,14 @@ cairo_int_status_t
 _cairo_xcb_surface_render_fill (cairo_xcb_surface_t	*surface,
 			       cairo_operator_t		 op,
 			       const cairo_pattern_t	*source,
-			       cairo_path_fixed_t	*path,
+			       const cairo_path_fixed_t	*path,
 			       cairo_fill_rule_t	 fill_rule,
 			       double			 tolerance,
 			       cairo_antialias_t	 antialias,
-			       cairo_clip_t		*clip)
+			       const cairo_clip_t	*clip)
 {
     cairo_composite_rectangles_t extents;
-    cairo_box_t boxes_stack[32], *clip_boxes = boxes_stack;
-    int num_boxes = ARRAY_LENGTH (boxes_stack);
-    cairo_clip_t local_clip;
-    cairo_bool_t have_clip = FALSE;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     if (unlikely (! _operator_is_supported (surface->flags, op)))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -3309,38 +3210,19 @@ _cairo_xcb_surface_render_fill (cairo_xcb_surface_t	*surface,
     if (unlikely (status))
 	return status;
 
-    if (_cairo_clip_contains_extents (clip, &extents))
-	clip = NULL;
-
-    if (clip != NULL) {
-	clip = _cairo_clip_init_copy (&local_clip, clip);
-	have_clip = TRUE;
-    }
-
-    status = _cairo_clip_to_boxes (&clip, &extents, &clip_boxes, &num_boxes);
-    if (unlikely (status)) {
-	if (have_clip)
-	    _cairo_clip_fini (&local_clip);
-
-	return status;
-    }
-
     status = CAIRO_INT_STATUS_UNSUPPORTED;
     if (_cairo_path_fixed_fill_is_rectilinear (path)) {
 	cairo_boxes_t boxes;
 
-	_cairo_boxes_init (&boxes);
-	_cairo_boxes_limit (&boxes, clip_boxes, num_boxes);
-
+	_cairo_boxes_init_with_clip (&boxes, extents.clip);
 	status = _cairo_path_fixed_fill_rectilinear_to_boxes (path,
 							      fill_rule,
+							      antialias,
 							      &boxes);
-	if (likely (status == CAIRO_STATUS_SUCCESS)) {
+	if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
 	    status = _clip_and_composite_boxes (surface, op, source,
-						&boxes, antialias,
-						&extents, clip);
+						&boxes, &extents);
 	}
-
 	_cairo_boxes_fini (&boxes);
     }
 
@@ -3348,23 +3230,17 @@ _cairo_xcb_surface_render_fill (cairo_xcb_surface_t	*surface,
 	if (surface->flags & CAIRO_XCB_RENDER_HAS_COMPOSITE_TRAPEZOIDS) {
 	    status = _cairo_xcb_surface_render_fill_as_polygon (surface, op, source, path,
 								fill_rule, tolerance, antialias,
-								clip, clip_boxes, num_boxes,
 								&extents);
 	} else if (surface->flags & CAIRO_XCB_RENDER_HAS_COMPOSITE) {
 	    status = _cairo_xcb_surface_render_fill_via_mask (surface, op, source, path,
 							      fill_rule, tolerance, antialias,
-							      have_clip ? &local_clip : NULL,
 							      &extents);
 	} else {
 	    ASSERT_NOT_REACHED;
 	}
     }
 
-    if (clip_boxes != boxes_stack)
-	free (clip_boxes);
-
-    if (have_clip)
-	_cairo_clip_fini (&local_clip);
+    _cairo_composite_rectangles_fini (&extents);
 
     return status;
 }
@@ -3376,7 +3252,6 @@ _cairo_xcb_surface_render_glyphs_via_mask (cairo_xcb_surface_t		*dst,
 					   cairo_scaled_font_t		*scaled_font,
 					   cairo_glyph_t		*glyphs,
 					   int				 num_glyphs,
-					   cairo_clip_t			*clip,
 					   cairo_composite_rectangles_t *extents)
 {
     cairo_surface_t *image;
@@ -3414,7 +3289,7 @@ _cairo_xcb_surface_render_glyphs_via_mask (cairo_xcb_surface_t		*dst,
 	cairo_matrix_init_translate (&mask.base.matrix, -x, -y);
 	status = _clip_and_composite (dst, op, source,
 				      _composite_mask, (void *) &mask.base,
-				      extents, clip);
+				      extents, need_bounded_clip (extents));
 
 	_cairo_pattern_fini (&mask.base);
     }
@@ -4290,12 +4165,10 @@ _cairo_xcb_surface_render_glyphs (cairo_xcb_surface_t	*surface,
 				  cairo_scaled_font_t	*scaled_font,
 				  cairo_glyph_t		*glyphs,
 				  int			 num_glyphs,
-				  cairo_clip_t		*clip)
+				  const cairo_clip_t	*clip)
 {
     cairo_composite_rectangles_t extents;
-    cairo_clip_t local_clip;
-    cairo_bool_t have_clip = FALSE;
-    cairo_status_t status;
+    cairo_int_status_t status;
     cairo_bool_t overlap;
 
     if (unlikely (! _operator_is_supported (surface->flags, op)))
@@ -4314,20 +4187,6 @@ _cairo_xcb_surface_render_glyphs (cairo_xcb_surface_t	*surface,
     if (unlikely (status))
 	return status;
 
-    if (_cairo_clip_contains_rectangle (clip, &extents.mask))
-	clip = NULL;
-
-    if (clip != NULL && extents.is_bounded) {
-	clip = _cairo_clip_init_copy (&local_clip, clip);
-	status = _cairo_clip_rectangle (clip, &extents.bounded);
-	if (unlikely (status)) {
-	    _cairo_clip_fini (&local_clip);
-	    return status;
-	}
-
-	have_clip = TRUE;
-    }
-
     status = CAIRO_INT_STATUS_UNSUPPORTED;
     if (surface->flags & CAIRO_XCB_RENDER_HAS_COMPOSITE_GLYPHS) {
 	_cairo_scaled_font_freeze_cache (scaled_font);
@@ -4335,17 +4194,20 @@ _cairo_xcb_surface_render_glyphs (cairo_xcb_surface_t	*surface,
 	if (_surface_owns_font (surface, scaled_font)) {
 	    status = _can_composite_glyphs (surface, &extents.bounded,
 					    scaled_font, glyphs, &num_glyphs);
-	    if (likely (status == CAIRO_STATUS_SUCCESS)) {
+	    if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
 		composite_glyphs_info_t info;
 
 		info.font = scaled_font;
 		info.glyphs = (cairo_xcb_glyph_t *) glyphs;
 		info.num_glyphs = num_glyphs;
-		info.use_mask = overlap || clip != NULL || ! extents.is_bounded;
+		info.use_mask =
+		    overlap ||
+		    ! extents.is_bounded ||
+		    ! _cairo_clip_is_region(extents.clip);
 
 		status = _clip_and_composite (surface, op, source,
 					      _composite_glyphs, &info,
-					      &extents, clip);
+					      &extents, need_bounded_clip (&extents));
 	    }
 	}
 
@@ -4357,11 +4219,10 @@ _cairo_xcb_surface_render_glyphs (cairo_xcb_surface_t	*surface,
 	status =
 	    _cairo_xcb_surface_render_glyphs_via_mask (surface, op, source,
 						       scaled_font, glyphs, num_glyphs,
-						       clip, &extents);
+						       &extents);
     }
 
-    if (have_clip)
-	_cairo_clip_fini (&local_clip);
+    _cairo_composite_rectangles_fini (&extents);
 
     return status;
 }
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index 157c8fb..6738cdd 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -379,7 +379,7 @@ _get_image (cairo_xcb_surface_t		 *surface,
     cairo_image_surface_t *image;
     cairo_xcb_connection_t *connection;
     xcb_get_image_reply_t *reply;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     if (surface->base.is_clear || surface->deferred_clear) {
 	image = (cairo_image_surface_t *)
@@ -594,7 +594,7 @@ static cairo_status_t
 _put_image (cairo_xcb_surface_t    *surface,
 	    cairo_image_surface_t  *image)
 {
-    cairo_status_t status = CAIRO_STATUS_SUCCESS;
+    cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
 
     /* XXX track damaged region? */
 
@@ -688,10 +688,10 @@ static cairo_int_status_t
 _cairo_xcb_surface_paint (void			*abstract_surface,
 			  cairo_operator_t	 op,
 			  const cairo_pattern_t	*source,
-			  cairo_clip_t		*clip)
+			  const cairo_clip_t	*clip)
 {
     cairo_xcb_surface_t *surface = abstract_surface;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     if (surface->fallback == NULL) {
 	status = _cairo_xcb_surface_cairo_paint (surface, op, source, clip);
@@ -713,10 +713,10 @@ _cairo_xcb_surface_mask (void			*abstract_surface,
 			 cairo_operator_t	 op,
 			 const cairo_pattern_t	*source,
 			 const cairo_pattern_t	*mask,
-			 cairo_clip_t		*clip)
+			 const cairo_clip_t	*clip)
 {
     cairo_xcb_surface_t *surface = abstract_surface;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     if (surface->fallback == NULL) {
 	status =  _cairo_xcb_surface_cairo_mask (surface,
@@ -741,16 +741,16 @@ static cairo_int_status_t
 _cairo_xcb_surface_stroke (void				*abstract_surface,
 			   cairo_operator_t		 op,
 			   const cairo_pattern_t	*source,
-			   cairo_path_fixed_t		*path,
+			   const cairo_path_fixed_t	*path,
 			   const cairo_stroke_style_t	*style,
 			   const cairo_matrix_t		*ctm,
 			   const cairo_matrix_t		*ctm_inverse,
 			   double			 tolerance,
 			   cairo_antialias_t		 antialias,
-			   cairo_clip_t			*clip)
+			   const cairo_clip_t		*clip)
 {
     cairo_xcb_surface_t *surface = abstract_surface;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     if (surface->fallback == NULL) {
 	status = _cairo_xcb_surface_cairo_stroke (surface, op, source,
@@ -786,14 +786,14 @@ static cairo_int_status_t
 _cairo_xcb_surface_fill (void			*abstract_surface,
 			 cairo_operator_t	 op,
 			 const cairo_pattern_t	*source,
-			 cairo_path_fixed_t	*path,
+			 const cairo_path_fixed_t*path,
 			 cairo_fill_rule_t	 fill_rule,
 			 double			 tolerance,
 			 cairo_antialias_t	 antialias,
-			 cairo_clip_t		*clip)
+			 const cairo_clip_t	*clip)
 {
     cairo_xcb_surface_t *surface = abstract_surface;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     if (surface->fallback == NULL) {
 	status = _cairo_xcb_surface_cairo_fill (surface, op, source,
@@ -827,11 +827,11 @@ _cairo_xcb_surface_glyphs (void				*abstract_surface,
 			   cairo_glyph_t		*glyphs,
 			   int				 num_glyphs,
 			   cairo_scaled_font_t		*scaled_font,
-			   cairo_clip_t			*clip,
+			   const cairo_clip_t		*clip,
 			   int *num_remaining)
 {
     cairo_xcb_surface_t *surface = abstract_surface;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     *num_remaining = 0;
 
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 25cfc68..46ca63f 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -175,7 +175,7 @@ _cairo_xlib_surface_show_glyphs (void                *abstract_dst,
 				 cairo_glyph_t       *glyphs,
 				 int		      num_glyphs,
 				 cairo_scaled_font_t *scaled_font,
-				 cairo_clip_t	     *clip,
+				 const cairo_clip_t	     *clip,
 				 int		     *remaining_glyphs);
 
 /*
@@ -369,6 +369,9 @@ _cairo_xlib_surface_create_similar (void	       *abstract_src,
     if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX)
 	return NULL;
 
+    if (width == 0 || height == 0)
+	return NULL;
+
     if (! CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE (src))
 	return NULL;
 
@@ -1695,7 +1698,7 @@ _cairo_xlib_surface_can_repaint_solid_pattern_surface (void *abstract_surface,
     return CAIRO_SURFACE_RENDER_HAS_COMPOSITE (other);
 }
 
-static cairo_status_t
+static cairo_int_status_t
 _cairo_xlib_surface_set_matrix (cairo_xlib_display_t *display,
                                 cairo_xlib_surface_t *surface,
 				const cairo_matrix_t *matrix,
@@ -1707,7 +1710,7 @@ _cairo_xlib_surface_set_matrix (cairo_xlib_display_t *display,
 {
     XTransform xtransform;
     pixman_transform_t *pixman_transform;
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     /* Casting between pixman_transform_t and XTransform is safe because
      * they happen to be the exact same type.
@@ -1718,8 +1721,8 @@ _cairo_xlib_surface_set_matrix (cairo_xlib_display_t *display,
 						    pixman_transform,
 						    x_offset, y_offset);
     if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
-	status = CAIRO_STATUS_SUCCESS;
-    if (unlikely (status != CAIRO_STATUS_SUCCESS))
+	status = CAIRO_INT_STATUS_SUCCESS;
+    if (unlikely (status != CAIRO_INT_STATUS_SUCCESS))
 	return status;
 
     if (memcmp (&xtransform, &surface->xtransform, sizeof (XTransform)) == 0)
@@ -4573,7 +4576,7 @@ _cairo_xlib_surface_emit_glyphs (cairo_xlib_display_t *display,
 				 int *remaining_glyphs)
 {
     int i;
-    cairo_status_t status = CAIRO_STATUS_SUCCESS;
+    cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
     cairo_scaled_glyph_t *scaled_glyph;
     cairo_fixed_t x = 0, y = 0;
     cairo_xlib_font_glyphset_info_t *glyphset_info = NULL, *this_glyphset_info;
@@ -4725,7 +4728,7 @@ _cairo_xlib_surface_emit_glyphs (cairo_xlib_display_t *display,
     }
 
     *remaining_glyphs = num_glyphs - i;
-    if (*remaining_glyphs != 0 && status == CAIRO_STATUS_SUCCESS)
+    if (*remaining_glyphs != 0 && status == CAIRO_INT_STATUS_SUCCESS)
 	status = CAIRO_INT_STATUS_UNSUPPORTED;
 
     return status;
@@ -4755,7 +4758,7 @@ _cairo_xlib_surface_show_glyphs (void                *abstract_dst,
 				 cairo_glyph_t       *glyphs,
 				 int		      num_glyphs,
 				 cairo_scaled_font_t *scaled_font,
-				 cairo_clip_t	     *clip,
+				 const cairo_clip_t	     *clip,
 				 int		     *remaining_glyphs)
 {
     cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
@@ -4779,23 +4782,16 @@ _cairo_xlib_surface_show_glyphs (void                *abstract_dst,
      * then the entire thing is copied to the destination surface,
      * including the fully transparent "background" of the rectangular
      * glyph surface. */
-    if (op == CAIRO_OPERATOR_SOURCE &&
-        ! CAIRO_SURFACE_RENDER_AT_LEAST(dst, 0, 11))
-    {
+    if (op == CAIRO_OPERATOR_SOURCE)
         return UNSUPPORTED ("known bug in Render");
-    }
 
     /* We can only use our code if we either have no clip or
      * have a real native clip region set.  If we're using
      * fallback clip masking, we have to go through the full
      * fallback path.
      */
-    if (clip != NULL) {
-	status = _cairo_clip_get_region (clip, &clip_region);
-	assert (status != CAIRO_INT_STATUS_NOTHING_TO_DO);
-	if (status)
-	    return status;
-    }
+    if (!_cairo_clip_is_region (clip))
+        return UNSUPPORTED ("clip mask required");
 
     operation = _categorize_composite_operation (dst, op, src_pattern, TRUE);
     if (operation == DO_UNSUPPORTED)
diff --git a/src/cairo-xml-surface.c b/src/cairo-xml-surface.c
index cf99ee6..1a6b01d 100644
--- a/src/cairo-xml-surface.c
+++ b/src/cairo-xml-surface.c
@@ -206,6 +206,7 @@ _format_to_string (cairo_format_t format)
 {
     switch (format) {
     case CAIRO_FORMAT_ARGB32:  return "ARGB32";
+    case CAIRO_FORMAT_RGB30:   return "RGB30";
     case CAIRO_FORMAT_RGB24:   return "RGB24";
     case CAIRO_FORMAT_RGB16_565:   return "RGB16_565";
     case CAIRO_FORMAT_A8:      return "A8";
@@ -416,7 +417,7 @@ _cairo_xml_close_path (void *closure)
 
 static void
 _cairo_xml_emit_path (cairo_xml_t *xml,
-		      cairo_path_fixed_t *path)
+		      const cairo_path_fixed_t *path)
 {
     cairo_status_t status;
 
@@ -500,7 +501,7 @@ _cairo_xml_surface_emit_clip_path (cairo_xml_surface_t *surface,
 
 static cairo_status_t
 _cairo_xml_surface_emit_clip (cairo_xml_surface_t *surface,
-			      cairo_clip_t *clip)
+			      const cairo_clip_t *clip)
 {
     if (clip == NULL)
 	return CAIRO_STATUS_SUCCESS;
@@ -686,7 +687,7 @@ static cairo_int_status_t
 _cairo_xml_surface_paint (void			*abstract_surface,
 			  cairo_operator_t	 op,
 			  const cairo_pattern_t	*source,
-			  cairo_clip_t		*clip)
+			  const cairo_clip_t	*clip)
 {
     cairo_xml_surface_t *surface = abstract_surface;
     cairo_xml_t *xml = to_xml (surface);
@@ -713,10 +714,10 @@ _cairo_xml_surface_paint (void			*abstract_surface,
 
 static cairo_int_status_t
 _cairo_xml_surface_mask (void			*abstract_surface,
-			  cairo_operator_t	 op,
-			  const cairo_pattern_t	*source,
-			  const cairo_pattern_t	*mask,
-			  cairo_clip_t		*clip)
+			 cairo_operator_t	 op,
+			 const cairo_pattern_t	*source,
+			 const cairo_pattern_t	*mask,
+			 const cairo_clip_t	*clip)
 {
     cairo_xml_surface_t *surface = abstract_surface;
     cairo_xml_t *xml = to_xml (surface);
@@ -749,13 +750,13 @@ static cairo_int_status_t
 _cairo_xml_surface_stroke (void				*abstract_surface,
 			   cairo_operator_t		 op,
 			   const cairo_pattern_t	*source,
-			   cairo_path_fixed_t		*path,
+			   const cairo_path_fixed_t		*path,
 			   const cairo_stroke_style_t		*style,
 			   const cairo_matrix_t		*ctm,
 			   const cairo_matrix_t		*ctm_inverse,
 			   double			 tolerance,
 			   cairo_antialias_t		 antialias,
-			   cairo_clip_t			*clip)
+			   const cairo_clip_t		*clip)
 {
     cairo_xml_surface_t *surface = abstract_surface;
     cairo_xml_t *xml = to_xml (surface);
@@ -805,11 +806,11 @@ static cairo_int_status_t
 _cairo_xml_surface_fill (void			*abstract_surface,
 			 cairo_operator_t	 op,
 			 const cairo_pattern_t	*source,
-			 cairo_path_fixed_t	*path,
+			 const cairo_path_fixed_t*path,
 			 cairo_fill_rule_t	 fill_rule,
 			 double			 tolerance,
 			 cairo_antialias_t	 antialias,
-			 cairo_clip_t		*clip)
+			 const cairo_clip_t	*clip)
 {
     cairo_xml_surface_t *surface = abstract_surface;
     cairo_xml_t *xml = to_xml (surface);
@@ -924,7 +925,7 @@ _cairo_xml_emit_scaled_font (cairo_xml_t *xml,
 			     cairo_glyph_t *glyphs,
 			     int num_glyphs)
 {
-    cairo_status_t status;
+    cairo_int_status_t status;
 
     _cairo_xml_printf (xml, "<scaled-font>");
     _cairo_xml_indent (xml, 2);
@@ -948,7 +949,7 @@ _cairo_xml_surface_glyphs (void			    *abstract_surface,
 			   cairo_glyph_t	    *glyphs,
 			   int			     num_glyphs,
 			   cairo_scaled_font_t	    *scaled_font,
-			   cairo_clip_t		    *clip,
+			   const cairo_clip_t	    *clip,
 			   int			    *remaining_glyphs)
 {
     cairo_xml_surface_t *surface = abstract_surface;
diff --git a/src/cairoint.h b/src/cairoint.h
index 0ae2051..5503a07 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -744,7 +744,8 @@ struct _cairo_surface_backend {
                                  void					*dst,
                                  cairo_antialias_t			 antialias,
                                  const cairo_composite_rectangles_t *rects,
-				 cairo_region_t *clip_region);
+				 cairo_region_t			*clip_region);
+
 
     cairo_warn cairo_bool_t
     (*check_span_renderer)	(cairo_operator_t			 op,
@@ -818,36 +819,36 @@ struct _cairo_surface_backend {
     (*paint)			(void			*surface,
 				 cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
-				 cairo_clip_t		*clip);
+				 const cairo_clip_t		*clip);
 
     cairo_warn cairo_int_status_t
     (*mask)			(void			*surface,
 				 cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
 				 const cairo_pattern_t	*mask,
-				 cairo_clip_t		*clip);
+				 const cairo_clip_t		*clip);
 
     cairo_warn cairo_int_status_t
     (*stroke)			(void			*surface,
 				 cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
-				 cairo_path_fixed_t	*path,
+				 const cairo_path_fixed_t	*path,
 				 const cairo_stroke_style_t	*style,
 				 const cairo_matrix_t	*ctm,
 				 const cairo_matrix_t	*ctm_inverse,
 				 double			 tolerance,
 				 cairo_antialias_t	 antialias,
-				 cairo_clip_t		*clip);
+				 const cairo_clip_t		*clip);
 
     cairo_warn cairo_int_status_t
     (*fill)			(void			*surface,
 				 cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
-				 cairo_path_fixed_t	*path,
+				 const cairo_path_fixed_t	*path,
 				 cairo_fill_rule_t	 fill_rule,
 				 double			 tolerance,
 				 cairo_antialias_t	 antialias,
-				 cairo_clip_t           *clip);
+				 const cairo_clip_t           *clip);
 
     cairo_warn cairo_int_status_t
     (*show_glyphs)		(void			*surface,
@@ -856,7 +857,7 @@ struct _cairo_surface_backend {
 				 cairo_glyph_t		*glyphs,
 				 int			 num_glyphs,
 				 cairo_scaled_font_t	*scaled_font,
-				 cairo_clip_t           *clip,
+				 const cairo_clip_t           *clip,
 				 int			*remaining_glyphs);
 
     cairo_surface_t *
@@ -873,7 +874,7 @@ struct _cairo_surface_backend {
 				 cairo_fill_rule_t	 fill_rule,
 				 double			 fill_tolerance,
 				 cairo_antialias_t	 fill_antialias,
-				 cairo_path_fixed_t	*path,
+				 const cairo_path_fixed_t*path,
 				 cairo_operator_t	 stroke_op,
 				 const cairo_pattern_t	*stroke_source,
 				 const cairo_stroke_style_t	*stroke_style,
@@ -881,7 +882,7 @@ struct _cairo_surface_backend {
 				 const cairo_matrix_t	*stroke_ctm_inverse,
 				 double			 stroke_tolerance,
 				 cairo_antialias_t	 stroke_antialias,
-				 cairo_clip_t		*clip);
+				 const cairo_clip_t	*clip);
 
     cairo_surface_t *
     (*create_solid_pattern_surface)
@@ -908,7 +909,7 @@ struct _cairo_surface_backend {
 				 int			     num_clusters,
 				 cairo_text_cluster_flags_t  cluster_flags,
 				 cairo_scaled_font_t	    *scaled_font,
-				 cairo_clip_t               *clip);
+				 const cairo_clip_t               *clip);
 
     cairo_warn cairo_status_t
     (*acquire_source_image_transformed)	(void                    *abstract_surface,
@@ -1357,14 +1358,21 @@ _cairo_path_fixed_fill_to_polygon (const cairo_path_fixed_t *path,
 				   double              tolerance,
 				   cairo_polygon_t      *polygon);
 
+cairo_private cairo_status_t
+_cairo_path_fixed_fill_rectilinear_to_polygon (const cairo_path_fixed_t *path,
+					       cairo_antialias_t antialias,
+					       cairo_polygon_t *polygon);
+
 cairo_private cairo_int_status_t
 _cairo_path_fixed_fill_rectilinear_to_traps (const cairo_path_fixed_t *path,
 					     cairo_fill_rule_t fill_rule,
+					     cairo_antialias_t antialias,
 					     cairo_traps_t *traps);
 
 cairo_private cairo_status_t
 _cairo_path_fixed_fill_rectilinear_to_boxes (const cairo_path_fixed_t *path,
 					     cairo_fill_rule_t fill_rule,
+					     cairo_antialias_t antialias,
 					     cairo_boxes_t *boxes);
 
 cairo_private cairo_region_t *
@@ -1391,12 +1399,14 @@ cairo_private cairo_int_status_t
 _cairo_path_fixed_stroke_rectilinear_to_traps (const cairo_path_fixed_t	*path,
 					       const cairo_stroke_style_t	*stroke_style,
 					       const cairo_matrix_t	*ctm,
+					       cairo_antialias_t	 antialias,
 					       cairo_traps_t		*traps);
 
 cairo_private cairo_int_status_t
 _cairo_path_fixed_stroke_rectilinear_to_boxes (const cairo_path_fixed_t	*path,
 					       const cairo_stroke_style_t	*stroke_style,
 					       const cairo_matrix_t	*ctm,
+					       cairo_antialias_t	 antialias,
 					       cairo_boxes_t		*boxes);
 
 cairo_private cairo_int_status_t
@@ -1656,14 +1666,14 @@ cairo_private cairo_status_t
 _cairo_surface_paint (cairo_surface_t	*surface,
 		      cairo_operator_t	 op,
 		      const cairo_pattern_t *source,
-		      cairo_clip_t	    *clip);
+		      const cairo_clip_t	    *clip);
 
 cairo_private cairo_status_t
 _cairo_surface_mask (cairo_surface_t	*surface,
 		     cairo_operator_t	 op,
 		     const cairo_pattern_t	*source,
 		     const cairo_pattern_t	*mask,
-		     cairo_clip_t		*clip);
+		     const cairo_clip_t		*clip);
 
 cairo_private cairo_status_t
 _cairo_surface_fill_stroke (cairo_surface_t	    *surface,
@@ -1680,29 +1690,29 @@ _cairo_surface_fill_stroke (cairo_surface_t	    *surface,
 			    const cairo_matrix_t	    *stroke_ctm_inverse,
 			    double		     stroke_tolerance,
 			    cairo_antialias_t	     stroke_antialias,
-			    cairo_clip_t	    *clip);
+			    const cairo_clip_t	    *clip);
 
 cairo_private cairo_status_t
 _cairo_surface_stroke (cairo_surface_t		*surface,
 		       cairo_operator_t		 op,
 		       const cairo_pattern_t	*source,
-		       cairo_path_fixed_t	*path,
+		       const cairo_path_fixed_t	*path,
 		       const cairo_stroke_style_t	*style,
 		       const cairo_matrix_t		*ctm,
 		       const cairo_matrix_t		*ctm_inverse,
 		       double			 tolerance,
 		       cairo_antialias_t	 antialias,
-		       cairo_clip_t		*clip);
+		       const cairo_clip_t		*clip);
 
 cairo_private cairo_status_t
 _cairo_surface_fill (cairo_surface_t	*surface,
 		     cairo_operator_t	 op,
 		     const cairo_pattern_t *source,
-		     cairo_path_fixed_t	*path,
+		     const cairo_path_fixed_t	*path,
 		     cairo_fill_rule_t	 fill_rule,
 		     double		 tolerance,
 		     cairo_antialias_t	 antialias,
-		     cairo_clip_t	*clip);
+		     const cairo_clip_t	*clip);
 
 cairo_private cairo_status_t
 _cairo_surface_show_text_glyphs (cairo_surface_t	    *surface,
@@ -1716,7 +1726,7 @@ _cairo_surface_show_text_glyphs (cairo_surface_t	    *surface,
 				 int			     num_clusters,
 				 cairo_text_cluster_flags_t  cluster_flags,
 				 cairo_scaled_font_t	    *scaled_font,
-				 cairo_clip_t		    *clip);
+				 const cairo_clip_t		    *clip);
 
 cairo_private cairo_status_t
 _cairo_surface_composite_trapezoids (cairo_operator_t	op,
@@ -2026,6 +2036,19 @@ _cairo_polygon_init (cairo_polygon_t   *polygon,
 		     int		num_boxes);
 
 cairo_private void
+_cairo_polygon_init_with_clip (cairo_polygon_t *polygon,
+			       const cairo_clip_t *clip);
+
+cairo_private cairo_status_t
+_cairo_polygon_init_boxes (cairo_polygon_t *polygon,
+			   const cairo_boxes_t *boxes);
+
+cairo_private cairo_status_t
+_cairo_polygon_init_box_array (cairo_polygon_t *polygon,
+			       cairo_box_t *boxes,
+			       int num_boxes);
+
+cairo_private void
 _cairo_polygon_fini (cairo_polygon_t *polygon);
 
 cairo_private cairo_status_t
@@ -2039,6 +2062,14 @@ _cairo_polygon_add_external_edge (void *polygon,
 				  const cairo_point_t *p1,
 				  const cairo_point_t *p2);
 
+cairo_private cairo_status_t
+_cairo_polygon_reduce (cairo_polygon_t *polygon,
+		       cairo_fill_rule_t fill_rule);
+
+cairo_private cairo_status_t
+_cairo_polygon_intersect (cairo_polygon_t *a, int winding_a,
+			  cairo_polygon_t *b, int winding_b);
+
 #define _cairo_polygon_status(P) ((cairo_polygon_t *) (P))->status
 
 /* cairo-spline.c */
@@ -2129,6 +2160,10 @@ cairo_private void
 _cairo_traps_init (cairo_traps_t *traps);
 
 cairo_private void
+_cairo_traps_init_with_clip (cairo_traps_t *traps,
+			     const cairo_clip_t *clip);
+
+cairo_private void
 _cairo_traps_limit (cairo_traps_t	*traps,
 		    const cairo_box_t	*boxes,
 		    int			 num_boxes);
@@ -2200,6 +2235,7 @@ _cairo_traps_extents (const cairo_traps_t *traps,
 
 cairo_private cairo_int_status_t
 _cairo_traps_extract_region (cairo_traps_t  *traps,
+			     cairo_antialias_t antialias,
 			     cairo_region_t **region);
 
 cairo_private cairo_status_t
@@ -2454,6 +2490,9 @@ cairo_private void
 _cairo_debug_print_path (FILE *stream, cairo_path_fixed_t *path);
 
 cairo_private void
-_cairo_debug_print_clip (FILE *stream, cairo_clip_t *clip);
+_cairo_debug_print_polygon (FILE *stream, cairo_polygon_t *polygon);
+
+cairo_private void
+_cairo_debug_print_clip (FILE *stream, const cairo_clip_t *clip);
 
 #endif
diff --git a/src/test-null-surface.c b/src/test-null-surface.c
index 620dd2f..a71ce8b 100644
--- a/src/test-null-surface.c
+++ b/src/test-null-surface.c
@@ -56,36 +56,36 @@ typedef cairo_int_status_t
 (*_paint_func)			(void			*surface,
 			         cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
-				 cairo_clip_t		*clip);
+				 const cairo_clip_t	*clip);
 
 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);
+				 const cairo_clip_t	*clip);
 
 typedef cairo_int_status_t
 (*_stroke_func)			(void			*surface,
 			         cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
-				 cairo_path_fixed_t	*path,
+				 const cairo_path_fixed_t	*path,
 				 const cairo_stroke_style_t	*style,
 				 const cairo_matrix_t		*ctm,
 				 const cairo_matrix_t		*ctm_inverse,
 				 double			 tolerance,
 				 cairo_antialias_t	 antialias,
-				 cairo_clip_t		*clip);
+				 const cairo_clip_t	*clip);
 
 typedef cairo_int_status_t
 (*_fill_func)			(void			*surface,
 			         cairo_operator_t	 op,
 				 const cairo_pattern_t	*source,
-				 cairo_path_fixed_t	*path,
+				 const cairo_path_fixed_t*path,
 				 cairo_fill_rule_t	 fill_rule,
 				 double			 tolerance,
 				 cairo_antialias_t	 antialias,
-				 cairo_clip_t		*clip);
+				 const cairo_clip_t	*clip);
 
 typedef cairo_int_status_t
 (*_show_glyphs_func)		(void			*surface,
@@ -94,7 +94,7 @@ typedef cairo_int_status_t
 				 cairo_glyph_t		*glyphs,
 				 int			 num_glyphs,
 				 cairo_scaled_font_t	*scaled_font,
-				 cairo_clip_t		*clip,
+				 const cairo_clip_t	*clip,
 				 int			*remaining_glyphs);
 
 typedef cairo_int_status_t
@@ -109,7 +109,7 @@ typedef cairo_int_status_t
 				 int			     num_clusters,
 				 cairo_text_cluster_flags_t  cluster_flags,
 				 cairo_scaled_font_t	    *scaled_font,
-				 cairo_clip_t		    *clip);
+				 const cairo_clip_t	    *clip);
 
 static cairo_surface_t *
 _cairo_null_surface_create_similar (void *other,
diff --git a/src/test-paginated-surface.c b/src/test-paginated-surface.c
index 241f1bd..7736282 100644
--- a/src/test-paginated-surface.c
+++ b/src/test-paginated-surface.c
@@ -122,7 +122,7 @@ static cairo_int_status_t
 _test_paginated_surface_paint (void		*abstract_surface,
 			       cairo_operator_t	 op,
 			       const cairo_pattern_t	*source,
-			       cairo_clip_t		*clip)
+			       const cairo_clip_t	*clip)
 {
     test_paginated_surface_t *surface = abstract_surface;
 
@@ -137,7 +137,7 @@ _test_paginated_surface_mask (void		*abstract_surface,
 			      cairo_operator_t	 op,
 			      const cairo_pattern_t	*source,
 			      const cairo_pattern_t	*mask,
-			      cairo_clip_t		*clip)
+			      const cairo_clip_t	*clip)
 {
     test_paginated_surface_t *surface = abstract_surface;
 
@@ -152,13 +152,13 @@ static cairo_int_status_t
 _test_paginated_surface_stroke (void				*abstract_surface,
 				cairo_operator_t		 op,
 				const cairo_pattern_t		*source,
-				cairo_path_fixed_t		*path,
+				const cairo_path_fixed_t		*path,
 				const cairo_stroke_style_t		*style,
 				const cairo_matrix_t			*ctm,
 				const cairo_matrix_t			*ctm_inverse,
 				double				 tolerance,
 				cairo_antialias_t		 antialias,
-				cairo_clip_t			*clip)
+				const cairo_clip_t		*clip)
 {
     test_paginated_surface_t *surface = abstract_surface;
 
@@ -176,11 +176,11 @@ static cairo_int_status_t
 _test_paginated_surface_fill (void				*abstract_surface,
 			      cairo_operator_t			 op,
 			      const cairo_pattern_t		*source,
-			      cairo_path_fixed_t		*path,
+			      const cairo_path_fixed_t		*path,
 			      cairo_fill_rule_t			 fill_rule,
 			      double				 tolerance,
 			      cairo_antialias_t			 antialias,
-			      cairo_clip_t			*clip)
+			      const cairo_clip_t		*clip)
 {
     test_paginated_surface_t *surface = abstract_surface;
 
@@ -213,7 +213,7 @@ _test_paginated_surface_show_text_glyphs (void			    *abstract_surface,
 					  int			     num_clusters,
 					  cairo_text_cluster_flags_t cluster_flags,
 					  cairo_scaled_font_t	    *scaled_font,
-					  cairo_clip_t		    *clip)
+					  const cairo_clip_t	    *clip)
 {
     test_paginated_surface_t *surface = abstract_surface;
 
diff --git a/src/test-wrapping-surface.c b/src/test-wrapping-surface.c
index 4dd6c4c..cef7055 100644
--- a/src/test-wrapping-surface.c
+++ b/src/test-wrapping-surface.c
@@ -138,7 +138,7 @@ static cairo_int_status_t
 _test_wrapping_surface_paint (void		*abstract_surface,
 			       cairo_operator_t	 op,
 			       const cairo_pattern_t	*source,
-			       cairo_clip_t		*clip)
+			       const cairo_clip_t	*clip)
 {
     test_wrapping_surface_t *surface = abstract_surface;
 
@@ -150,7 +150,7 @@ _test_wrapping_surface_mask (void		*abstract_surface,
 			      cairo_operator_t	 op,
 			      const cairo_pattern_t	*source,
 			      const cairo_pattern_t	*mask,
-			      cairo_clip_t		*clip)
+			      const cairo_clip_t	*clip)
 {
     test_wrapping_surface_t *surface = abstract_surface;
 
@@ -162,13 +162,13 @@ static cairo_int_status_t
 _test_wrapping_surface_stroke (void				*abstract_surface,
 				cairo_operator_t		 op,
 				const cairo_pattern_t		*source,
-				cairo_path_fixed_t		*path,
+				const cairo_path_fixed_t		*path,
 				const cairo_stroke_style_t		*style,
 				const cairo_matrix_t			*ctm,
 				const cairo_matrix_t			*ctm_inverse,
 				double				 tolerance,
 				cairo_antialias_t		 antialias,
-				cairo_clip_t			*clip)
+				const cairo_clip_t			*clip)
 {
     test_wrapping_surface_t *surface = abstract_surface;
 
@@ -184,11 +184,11 @@ static cairo_int_status_t
 _test_wrapping_surface_fill (void				*abstract_surface,
 			      cairo_operator_t			 op,
 			      const cairo_pattern_t		*source,
-			      cairo_path_fixed_t		*path,
+			      const cairo_path_fixed_t		*path,
 			      cairo_fill_rule_t			 fill_rule,
 			      double				 tolerance,
 			      cairo_antialias_t			 antialias,
-			      cairo_clip_t			*clip)
+			      const cairo_clip_t		*clip)
 {
     test_wrapping_surface_t *surface = abstract_surface;
 
@@ -219,7 +219,7 @@ _test_wrapping_surface_show_text_glyphs (void			    *abstract_surface,
 					  int			     num_clusters,
 					  cairo_text_cluster_flags_t cluster_flags,
 					  cairo_scaled_font_t	    *scaled_font,
-					  cairo_clip_t		    *clip)
+					  const cairo_clip_t	    *clip)
 {
     test_wrapping_surface_t *surface = abstract_surface;
 
diff --git a/test/clip-group-shapes-circles.ref.png b/test/clip-group-shapes-circles.ref.png
index 064cc58..7dd6a83 100644
Binary files a/test/clip-group-shapes-circles.ref.png and b/test/clip-group-shapes-circles.ref.png differ
diff --git a/test/clip-shape.ref.png b/test/clip-shape.ref.png
index e80f666..313e245 100644
Binary files a/test/clip-shape.ref.png and b/test/clip-shape.ref.png differ
diff --git a/test/clip-stroke.ref.png b/test/clip-stroke.ref.png
index e66cc43..0b316e6 100644
Binary files a/test/clip-stroke.ref.png and b/test/clip-stroke.ref.png differ
commit f58ade7bace8c82d0ea6740f56d227696181d616
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jul 19 21:14:08 2011 +0100

    ps: Add HAS_FT_FONT guards for type1
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 72a82f3..0b5f8e9 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -339,6 +339,8 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
     }
 }
 
+#if CAIRO_HAS_FT_FONT
+
 static cairo_status_t
 _cairo_ps_surface_emit_type1_font_subset (cairo_ps_surface_t		*surface,
 					  cairo_scaled_font_subset_t	*font_subset)
@@ -371,6 +373,7 @@ _cairo_ps_surface_emit_type1_font_subset (cairo_ps_surface_t		*surface,
     return CAIRO_STATUS_SUCCESS;
 }
 
+
 static cairo_status_t
 _cairo_ps_surface_emit_type1_font_fallback (cairo_ps_surface_t		*surface,
                                             cairo_scaled_font_subset_t	*font_subset)
@@ -400,6 +403,23 @@ _cairo_ps_surface_emit_type1_font_fallback (cairo_ps_surface_t		*surface,
 
     return CAIRO_STATUS_SUCCESS;
 }
+#else
+
+static cairo_status_t
+_cairo_ps_surface_emit_type1_font_subset (cairo_ps_surface_t		*surface,
+					  cairo_scaled_font_subset_t	*font_subset)
+{
+    return CAIRO_INT_STATUS_UNSUPPORTED;
+}
+
+static cairo_status_t
+_cairo_ps_surface_emit_type1_font_fallback (cairo_ps_surface_t		*surface,
+                                            cairo_scaled_font_subset_t	*font_subset)
+{
+    return CAIRO_INT_STATUS_UNSUPPORTED;
+}
+
+#endif
 
 static cairo_status_t
 _cairo_ps_surface_emit_truetype_font_subset (cairo_ps_surface_t		*surface,


More information about the cairo-commit mailing list