[cairo-commit] src/cairo-clip.c src/cairo-clip-private.h src/cairo-compositor-private.h src/cairo-image-compositor.c src/cairo-image-spans-compositor.c src/cairo-shape-mask-compositor.c src/cairo-spans-compositor.c src/Makefile.sources test/reference

Chris Wilson ickle at kemper.freedesktop.org
Tue Feb 28 14:29:44 PST 2012


 dev/null                                              |binary
 src/Makefile.sources                                  |    1 
 src/cairo-clip-private.h                              |    3 
 src/cairo-clip.c                                      |   18 
 src/cairo-compositor-private.h                        |    4 
 src/cairo-image-compositor.c                          |   36 +
 src/cairo-image-spans-compositor.c                    |  131 ------
 src/cairo-shape-mask-compositor.c                     |  337 ++++++++++++++++++
 src/cairo-spans-compositor.c                          |   49 +-
 test/reference/clip-disjoint.ref.png                  |binary
 test/reference/clip-operator.argb32.ref.png           |binary
 test/reference/clip-operator.rgb24.ref.png            |binary
 test/reference/clip-stroke.ref.png                    |binary
 test/reference/degenerate-arc.ref.png                 |binary
 test/reference/finer-grained-fallbacks.argb32.ref.png |binary
 test/reference/finer-grained-fallbacks.rgb24.ref.png  |binary
 test/reference/hatchings.ref.png                      |binary
 test/reference/operator-source.argb32.ref.png         |binary
 test/reference/operator-source.rgb24.ref.png          |binary
 test/reference/over-around-source.argb32.ref.png      |binary
 test/reference/over-around-source.rgb24.ref.png       |binary
 test/reference/over-below-source.argb32.ref.png       |binary
 test/reference/over-below-source.rgb24.ref.png        |binary
 test/reference/over-between-source.argb32.ref.png     |binary
 test/reference/over-between-source.rgb24.ref.png      |binary
 test/reference/overlapping-boxes.argb32.ref.png       |binary
 test/reference/overlapping-boxes.rgb24.ref.png        |binary
 test/reference/random-clip.ref.png                    |binary
 test/reference/tighten-bounds.argb32.ref.png          |binary
 test/reference/tighten-bounds.rgb24.ref.png           |binary
 30 files changed, 420 insertions(+), 159 deletions(-)

New commits:
commit 3c665102c2b7ccd69aec7658e398ce6dd6dae38b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Feb 28 22:27:18 2012 +0000

    spans+image: Fix clipping with polygons and spans
    
    Fixes: clip-source, random-clip
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/Makefile.sources b/src/Makefile.sources
index 19a14a7..30e0d65 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -195,6 +195,7 @@ cairo_sources = \
 	cairo-region.c \
 	cairo-rtree.c \
 	cairo-scaled-font.c \
+	cairo-shape-mask-compositor.c \
 	cairo-slope.c \
 	cairo-spans.c \
 	cairo-spans-compositor.c \
diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h
index 2c2aa95..c1c24d8 100644
--- a/src/cairo-clip-private.h
+++ b/src/cairo-clip-private.h
@@ -103,6 +103,9 @@ cairo_private cairo_clip_t *
 _cairo_clip_copy_region (const cairo_clip_t *clip);
 
 cairo_private cairo_clip_t *
+_cairo_clip_copy_path (const cairo_clip_t *clip);
+
+cairo_private cairo_clip_t *
 _cairo_clip_translate (cairo_clip_t *clip, int tx, int ty);
 
 cairo_private cairo_clip_t *
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index d32bdec..6bf1f39 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -174,6 +174,24 @@ _cairo_clip_copy (const cairo_clip_t *clip)
 }
 
 cairo_clip_t *
+_cairo_clip_copy_path (const cairo_clip_t *clip)
+{
+    cairo_clip_t *copy;
+
+    if (clip == NULL || _cairo_clip_is_all_clipped (clip))
+	return (cairo_clip_t *) clip;
+
+    assert (clip->num_boxes);
+
+    copy = _cairo_clip_create ();
+    copy->extents = clip->extents;
+    if (clip->path)
+	copy->path = _cairo_clip_path_reference (clip->path);
+
+    return copy;
+}
+
+cairo_clip_t *
 _cairo_clip_copy_region (const cairo_clip_t *clip)
 {
     cairo_clip_t *copy;
diff --git a/src/cairo-compositor-private.h b/src/cairo-compositor-private.h
index ff4b93b..e5ad367 100644
--- a/src/cairo-compositor-private.h
+++ b/src/cairo-compositor-private.h
@@ -301,6 +301,10 @@ _cairo_mask_compositor_init (cairo_mask_compositor_t *compositor,
 			     const cairo_compositor_t *delegate);
 
 cairo_private void
+_cairo_shape_mask_compositor_init (cairo_compositor_t *compositor,
+				   const cairo_compositor_t  *delegate);
+
+cairo_private void
 _cairo_traps_compositor_init (cairo_traps_compositor_t *compositor,
 			      const cairo_compositor_t *delegate);
 
diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c
index 7c044c4..83b0cf3 100644
--- a/src/cairo-image-compositor.c
+++ b/src/cairo-image-compositor.c
@@ -1597,27 +1597,31 @@ span_renderer_fini (cairo_abstract_span_renderer_t *_r,
 const cairo_compositor_t *
 _cairo_image_spans_compositor_get (void)
 {
-    static cairo_spans_compositor_t compositor;
+    static cairo_spans_compositor_t spans;
+    static cairo_compositor_t shape;
 
-    if (compositor.base.delegate == NULL) {
-	_cairo_spans_compositor_init (&compositor,
-				      _cairo_image_traps_compositor_get());
+    if (spans.base.delegate == NULL) {
+	_cairo_shape_mask_compositor_init (&shape,
+					   _cairo_image_traps_compositor_get());
+	shape.glyphs = NULL;
+
+	_cairo_spans_compositor_init (&spans, &shape);
 
-	compositor.flags = 0;
+	spans.flags = 0;
 #if PIXMAN_HAS_OP_LERP
-	compositor.flags |= CAIRO_SPANS_COMPOSITOR_HAS_LERP;
+	spans.flags |= CAIRO_SPANS_COMPOSITOR_HAS_LERP;
 #endif
 
-	//compositor.acquire = acquire;
-	//compositor.release = release;
-	compositor.fill_boxes = fill_boxes;
-	compositor.pattern_to_surface = _cairo_image_source_create_for_pattern;
-	//compositor.check_composite_boxes = check_composite_boxes;
-	compositor.composite_boxes = composite_boxes;
-	//compositor.check_span_renderer = check_span_renderer;
-	compositor.renderer_init = span_renderer_init;
-	compositor.renderer_fini = span_renderer_fini;
+	//spans.acquire = acquire;
+	//spans.release = release;
+	spans.fill_boxes = fill_boxes;
+	spans.pattern_to_surface = _cairo_image_source_create_for_pattern;
+	//spans.check_composite_boxes = check_composite_boxes;
+	spans.composite_boxes = composite_boxes;
+	//spans.check_span_renderer = check_span_renderer;
+	spans.renderer_init = span_renderer_init;
+	spans.renderer_fini = span_renderer_fini;
     }
 
-    return &compositor.base;
+    return &spans.base;
 }
diff --git a/src/cairo-image-spans-compositor.c b/src/cairo-image-spans-compositor.c
deleted file mode 100644
index 5718b55..0000000
--- a/src/cairo-image-spans-compositor.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2003 University of Southern California
- * Copyright © 2009,2010,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):
- *	Carl D. Worth <cworth at cworth.org>
- *	Chris Wilson <chris at chris-wilson.co.uk>
- */
-
-#include "cairoint.h"
-
-#include "cairo-compositor-private.h"
-#include "cairo-image-surface-private.h"
-#include "cairo-spans-compositor-private.h"
-
-typedef struct _cairo_image_span_renderer {
-    cairo_span_renderer_t base;
-
-    pixman_image_compositor_t *compositor;
-    pixman_image_t *src;
-    float opacity;
-    cairo_rectangle_int_t extents;
-} cairo_image_span_renderer_t;
-
-static cairo_status_t
-_cairo_image_span_renderer_init (cairo_abstract_span_renderer_t *_r,
-				 cairo_surface_t *dst,
-				 cairo_operator_t op,
-				 cairo_surface_t *src,
-				 int src_x, int src_y;
-				 float opacity,
-				 const cairo_composite_rectangles_t *composite,
-				 cairo_bool_t needs_clip)
-{
-    cairo_image_span_renderer_t *r = (cairo_image_span_renderer_t *)_r;
-    cairo_pixman_source_t *src = (cairo_pixman_source_t *)_src;
-    int src_x, src_y;
-
-    if (op == CAIRO_OPERATOR_CLEAR) {
-	op = CAIRO_OPERATOR_DEST_OUT;
-	pattern = NULL;
-    }
-
-    r->src = ((cairo_pixman_source_t *) src)->pixman_image;
-    r->opacity = opacity;
-
-    if (composite->is_bounded) {
-	if (opacity == 1.)
-	    r->base.render_rows = _cairo_image_bounded_opaque_spans;
-	else
-	    r->base.render_rows = _cairo_image_bounded_spans;
-	r->base.finish = NULL;
-    } else {
-	if (needs_clip)
-	    r->base.render_rows = _cairo_image_clipped_spans;
-	else
-	    r->base.render_rows = _cairo_image_unbounded_spans;
-        r->base.finish =      _cairo_image_finish_unbounded_spans;
-	r->extents = composite->unbounded;
-	r->extents.height += r->extents.y;
-
-    }
-    r->compositor =
-	pixman_image_create_compositor (_pixman_operator (op),
-					r->src, NULL, dst->pixman_image,
-					composite->bounded.x + src_x,
-					composite->bounded.y + src_y,
-					0, 0,
-					composite->bounded.x,
-					composite->bounded.y,
-					composite->bounded.width,
-					composite->bounded.height);
-    if (unlikely (r->compositor == NULL))
-	return CAIRO_INT_STATUS_NOTHING_TO_DO;
-
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static void
-_cairo_image_span_renderer_fini (cairo_abstract_span_renderer_t *_r)
-{
-    cairo_image_span_renderer_t *r = (cairo_image_span_renderer_t *) r;
-    pixman_image_compositor_destroy (r->compositor);
-}
-
-const cairo_compositor_t *
-_cairo_image_spans_compositor_get (void)
-{
-    static cairo_spans_compositor_t compositor;
-
-    if (compositor.base.delegate == NULL) {
-	/* Can't fallback to the mask compositor as that will simply
-	 * call the spans-compositor again to render the mask!
-	 */
-	_cairo_spans_compositor_init (&compositor,
-				      _cairo_image_traps_compositor_get());
-
-    }
-
-    return &compositor.base;
-}
diff --git a/src/cairo-shape-mask-compositor.c b/src/cairo-shape-mask-compositor.c
new file mode 100644
index 0000000..c2425b0
--- /dev/null
+++ b/src/cairo-shape-mask-compositor.c
@@ -0,0 +1,337 @@
+/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2012 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-compositor-private.h"
+#include "cairo-clip-private.h"
+#include "cairo-pattern-private.h"
+#include "cairo-surface-private.h"
+#include "cairo-surface-offset-private.h"
+
+static cairo_int_status_t
+_cairo_shape_mask_compositor_stroke (const cairo_compositor_t *_compositor,
+				     cairo_composite_rectangles_t *extents,
+				     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_surface_t *mask;
+    cairo_surface_pattern_t pattern;
+    cairo_int_status_t status;
+    cairo_clip_t *clip;
+
+    if (! extents->is_bounded)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    TRACE ((stderr, "%s\n", __FUNCTION__));
+    mask = _cairo_surface_create_similar_scratch (extents->surface,
+						  CAIRO_CONTENT_ALPHA,
+						  extents->bounded.width,
+						  extents->bounded.height);
+    if (unlikely (mask->status))
+	return mask->status;
+
+    clip = extents->clip;
+    if (! _cairo_clip_is_region (clip))
+	clip = _cairo_clip_copy_region (clip);
+
+    if (! mask->is_clear) {
+	status = _cairo_surface_offset_paint (mask,
+					      extents->bounded.x,
+					      extents->bounded.y,
+					      CAIRO_OPERATOR_CLEAR,
+					      &_cairo_pattern_clear.base,
+					      clip);
+	if (unlikely (status))
+	    goto error;
+    }
+
+    status = _cairo_surface_offset_stroke (mask,
+					   extents->bounded.x,
+					   extents->bounded.y,
+					   CAIRO_OPERATOR_ADD,
+					   &_cairo_pattern_white.base,
+					   path, style, ctm, ctm_inverse,
+					   tolerance, antialias,
+					   clip);
+    if (unlikely (status))
+	goto error;
+
+    if (clip != extents->clip) {
+	status = _cairo_clip_combine_with_surface (extents->clip, mask,
+						   extents->bounded.x,
+						   extents->bounded.y);
+	if (unlikely (status))
+	    goto error;
+    }
+
+    _cairo_pattern_init_for_surface (&pattern, mask);
+    cairo_matrix_init_translate (&pattern.base.matrix,
+				 -extents->bounded.x,
+				 -extents->bounded.y);
+    pattern.base.filter = CAIRO_FILTER_NEAREST;
+    pattern.base.extend = CAIRO_EXTEND_NONE;
+    if (extents->op == CAIRO_OPERATOR_SOURCE) {
+	status = _cairo_surface_mask (extents->surface,
+				      CAIRO_OPERATOR_DEST_OUT,
+				      &_cairo_pattern_white.base,
+				      &pattern.base,
+				      clip);
+	if ((status == CAIRO_INT_STATUS_SUCCESS)) {
+	    status = _cairo_surface_mask (extents->surface,
+					  CAIRO_OPERATOR_ADD,
+					  &extents->source_pattern.base,
+					  &pattern.base,
+					  clip);
+	}
+    } else {
+	status = _cairo_surface_mask (extents->surface,
+				      extents->op,
+				      &extents->source_pattern.base,
+				      &pattern.base,
+				      clip);
+    }
+    _cairo_pattern_fini (&pattern.base);
+
+error:
+    cairo_surface_destroy (mask);
+    if (clip != extents->clip)
+	_cairo_clip_destroy (clip);
+    return status;
+}
+
+static cairo_int_status_t
+_cairo_shape_mask_compositor_fill (const cairo_compositor_t *_compositor,
+				   cairo_composite_rectangles_t *extents,
+				   const cairo_path_fixed_t	*path,
+				   cairo_fill_rule_t	 fill_rule,
+				   double			 tolerance,
+				   cairo_antialias_t	 antialias)
+{
+    cairo_surface_t *mask;
+    cairo_surface_pattern_t pattern;
+    cairo_int_status_t status;
+    cairo_clip_t *clip;
+
+    TRACE ((stderr, "%s\n", __FUNCTION__));
+
+    if (! extents->is_bounded)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    mask = _cairo_surface_create_similar_scratch (extents->surface,
+						  CAIRO_CONTENT_ALPHA,
+						  extents->bounded.width,
+						  extents->bounded.height);
+    if (unlikely (mask->status))
+	return mask->status;
+
+    clip = extents->clip;
+    if (! _cairo_clip_is_region (clip))
+	clip = _cairo_clip_copy_region (clip);
+
+    if (! mask->is_clear) {
+	status = _cairo_surface_offset_paint (mask,
+					      extents->bounded.x,
+					      extents->bounded.y,
+					      CAIRO_OPERATOR_CLEAR,
+					      &_cairo_pattern_clear.base,
+					      clip);
+	if (unlikely (status))
+	    goto error;
+    }
+
+    status = _cairo_surface_offset_fill (mask,
+					 extents->bounded.x,
+					 extents->bounded.y,
+					 CAIRO_OPERATOR_ADD,
+					 &_cairo_pattern_white.base,
+					 path, fill_rule, tolerance, antialias,
+					 clip);
+    if (unlikely (status))
+	goto error;
+
+    if (clip != extents->clip) {
+	status = _cairo_clip_combine_with_surface (extents->clip, mask,
+						   extents->bounded.x,
+						   extents->bounded.y);
+	if (unlikely (status))
+	    goto error;
+    }
+
+    _cairo_pattern_init_for_surface (&pattern, mask);
+    cairo_matrix_init_translate (&pattern.base.matrix,
+				 -extents->bounded.x,
+				 -extents->bounded.y);
+    pattern.base.filter = CAIRO_FILTER_NEAREST;
+    pattern.base.extend = CAIRO_EXTEND_NONE;
+    if (extents->op == CAIRO_OPERATOR_SOURCE) {
+	status = _cairo_surface_mask (extents->surface,
+				      CAIRO_OPERATOR_DEST_OUT,
+				      &_cairo_pattern_white.base,
+				      &pattern.base,
+				      clip);
+	if ((status == CAIRO_INT_STATUS_SUCCESS)) {
+	    status = _cairo_surface_mask (extents->surface,
+					  CAIRO_OPERATOR_ADD,
+					  &extents->source_pattern.base,
+					  &pattern.base,
+					  clip);
+	}
+    } else {
+	status = _cairo_surface_mask (extents->surface,
+				      extents->op,
+				      &extents->source_pattern.base,
+				      &pattern.base,
+				      clip);
+    }
+    _cairo_pattern_fini (&pattern.base);
+
+error:
+    if (clip != extents->clip)
+	_cairo_clip_destroy (clip);
+    cairo_surface_destroy (mask);
+    return status;
+}
+
+static cairo_int_status_t
+_cairo_shape_mask_compositor_glyphs (const cairo_compositor_t *_compositor,
+				     cairo_composite_rectangles_t *extents,
+				     cairo_scaled_font_t	*scaled_font,
+				     cairo_glyph_t		*glyphs,
+				     int			 num_glyphs,
+				     cairo_bool_t		 overlap)
+{
+    cairo_surface_t *mask;
+    cairo_surface_pattern_t pattern;
+    cairo_int_status_t status;
+    cairo_clip_t *clip;
+
+    if (! extents->is_bounded)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    TRACE ((stderr, "%s\n", __FUNCTION__));
+    mask = _cairo_surface_create_similar_scratch (extents->surface,
+						  CAIRO_CONTENT_ALPHA,
+						  extents->bounded.width,
+						  extents->bounded.height);
+    if (unlikely (mask->status))
+	return mask->status;
+
+    clip = extents->clip;
+    if (! _cairo_clip_is_region (clip))
+	clip = _cairo_clip_copy_region (clip);
+
+    if (! mask->is_clear) {
+	status = _cairo_surface_offset_paint (mask,
+					      extents->bounded.x,
+					      extents->bounded.y,
+					      CAIRO_OPERATOR_CLEAR,
+					      &_cairo_pattern_clear.base,
+					      clip);
+	if (unlikely (status))
+	    goto error;
+    }
+
+    status = _cairo_surface_offset_glyphs (mask,
+					   extents->bounded.x,
+					   extents->bounded.y,
+					   CAIRO_OPERATOR_ADD,
+					   &_cairo_pattern_white.base,
+					   scaled_font, glyphs, num_glyphs,
+					   clip);
+    if (unlikely (status))
+	goto error;
+
+    if (clip != extents->clip) {
+	status = _cairo_clip_combine_with_surface (extents->clip, mask,
+						   extents->bounded.x,
+						   extents->bounded.y);
+	if (unlikely (status))
+	    goto error;
+    }
+
+    _cairo_pattern_init_for_surface (&pattern, mask);
+    cairo_matrix_init_translate (&pattern.base.matrix,
+				 -extents->bounded.x,
+				 -extents->bounded.y);
+    pattern.base.filter = CAIRO_FILTER_NEAREST;
+    pattern.base.extend = CAIRO_EXTEND_NONE;
+    if (extents->op == CAIRO_OPERATOR_SOURCE) {
+	status = _cairo_surface_mask (extents->surface,
+				      CAIRO_OPERATOR_DEST_OUT,
+				      &_cairo_pattern_white.base,
+				      &pattern.base,
+				      clip);
+	if ((status == CAIRO_INT_STATUS_SUCCESS)) {
+	    status = _cairo_surface_mask (extents->surface,
+					  CAIRO_OPERATOR_ADD,
+					  &extents->source_pattern.base,
+					  &pattern.base,
+					  clip);
+	}
+    } else {
+	status = _cairo_surface_mask (extents->surface,
+				      extents->op,
+				      &extents->source_pattern.base,
+				      &pattern.base,
+				      clip);
+    }
+    _cairo_pattern_fini (&pattern.base);
+
+error:
+    if (clip != extents->clip)
+	_cairo_clip_destroy (clip);
+    cairo_surface_destroy (mask);
+    return status;
+}
+
+void
+_cairo_shape_mask_compositor_init (cairo_compositor_t *compositor,
+				   const cairo_compositor_t  *delegate)
+{
+    compositor->delegate = delegate;
+
+    compositor->paint  = NULL;
+    compositor->mask   = NULL;
+    compositor->fill   = _cairo_shape_mask_compositor_fill;
+    compositor->stroke = _cairo_shape_mask_compositor_stroke;
+    compositor->glyphs = _cairo_shape_mask_compositor_glyphs;
+}
diff --git a/src/cairo-spans-compositor.c b/src/cairo-spans-compositor.c
index f069bcd..b106d73 100644
--- a/src/cairo-spans-compositor.c
+++ b/src/cairo-spans-compositor.c
@@ -620,7 +620,7 @@ composite_polygon (const cairo_spans_compositor_t	*compositor,
     cairo_bool_t needs_clip;
     cairo_int_status_t status;
 
-    needs_clip = composite_needs_clip (extents, &polygon->extents);
+    needs_clip = extents->clip->path != NULL || extents->clip->num_boxes > 1;
     if (needs_clip) {
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 	converter = _cairo_clip_tor_scan_converter_create (extents->clip,
@@ -879,25 +879,45 @@ _cairo_spans_compositor_stroke (const cairo_compositor_t	*_compositor,
 
     if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
 	cairo_polygon_t polygon;
+	cairo_fill_rule_t fill_rule = CAIRO_FILL_RULE_WINDING;
 
 	if (extents->mask.width  > extents->unbounded.width ||
 	    extents->mask.height > extents->unbounded.height)
 	{
-	    _cairo_polygon_init_with_clip (&polygon, extents->clip);
+	    cairo_box_t limits;
+	    _cairo_box_from_rectangle (&limits, &extents->unbounded);
+	    _cairo_polygon_init (&polygon, &limits, 1);
 	}
 	else
 	{
-	    _cairo_polygon_init_with_clip (&polygon, NULL);
+	    _cairo_polygon_init (&polygon, NULL, 0);
 	}
 	status = _cairo_path_fixed_stroke_to_polygon (path,
 						      style,
 						      ctm, ctm_inverse,
 						      tolerance,
 						      &polygon);
+	if (status == CAIRO_INT_STATUS_SUCCESS && extents->clip->num_boxes > 1) {
+	    status = _cairo_polygon_intersect_with_boxes (&polygon, &fill_rule,
+							  extents->clip->boxes,
+							  extents->clip->num_boxes);
+	}
 	if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
+	    cairo_clip_t *saved_clip = extents->clip;
+
+	    if (extents->is_bounded) {
+		extents->clip = _cairo_clip_copy_path (extents->clip);
+		extents->clip = _cairo_clip_intersect_box(extents->clip,
+							  &polygon.extents);
+	    }
+
 	    status = clip_and_composite_polygon (compositor, extents, &polygon,
-						 CAIRO_FILL_RULE_WINDING,
-						 antialias);
+						 fill_rule, antialias);
+
+	    if (extents->clip != saved_clip) {
+		_cairo_clip_destroy (extents->clip);
+		extents->clip = saved_clip;
+	    }
 	}
 	_cairo_polygon_fini (&polygon);
     }
@@ -949,22 +969,27 @@ _cairo_spans_compositor_fill (const cairo_compositor_t		*_compositor,
 	}
 
 	status = _cairo_path_fixed_fill_to_polygon (path, tolerance, &polygon);
-	if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
+	if (status == CAIRO_INT_STATUS_SUCCESS && extents->clip->num_boxes > 1) {
 	    status = _cairo_polygon_intersect_with_boxes (&polygon, &fill_rule,
 							  extents->clip->boxes,
 							  extents->clip->num_boxes);
 	}
 	if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
-	    if (extents->is_bounded) {
-		if (extents->clip->boxes != &extents->clip->embedded_box)
-		    free (extents->clip->boxes);
+	    cairo_clip_t *saved_clip = extents->clip;
 
-		extents->clip->num_boxes = 1;
-		extents->clip->boxes = &extents->clip->embedded_box;
-		extents->clip->boxes[0] = polygon.extents;
+	    if (extents->is_bounded) {
+		extents->clip = _cairo_clip_copy_path (extents->clip);
+		extents->clip = _cairo_clip_intersect_box(extents->clip,
+							  &polygon.extents);
 	    }
+
 	    status = clip_and_composite_polygon (compositor, extents, &polygon,
 						 fill_rule, antialias);
+
+	    if (extents->clip != saved_clip) {
+		_cairo_clip_destroy (extents->clip);
+		extents->clip = saved_clip;
+	    }
 	}
 	_cairo_polygon_fini (&polygon);
     }
diff --git a/test/reference/a1-tiger.argb32.ref.png b/test/reference/a1-tiger.argb32.ref.png
deleted file mode 100644
index 9a62af7..0000000
Binary files a/test/reference/a1-tiger.argb32.ref.png and /dev/null differ
diff --git a/test/reference/a1-tiger.rgb24.ref.png b/test/reference/a1-tiger.rgb24.ref.png
deleted file mode 100644
index 9a62af7..0000000
Binary files a/test/reference/a1-tiger.rgb24.ref.png and /dev/null differ
diff --git a/test/reference/clip-disjoint.argb32.ref.png b/test/reference/clip-disjoint.argb32.ref.png
deleted file mode 100644
index 4e18b7c..0000000
Binary files a/test/reference/clip-disjoint.argb32.ref.png and /dev/null differ
diff --git a/test/reference/clip-disjoint.ref.png b/test/reference/clip-disjoint.ref.png
index a4c9989..6577a08 100644
Binary files a/test/reference/clip-disjoint.ref.png and b/test/reference/clip-disjoint.ref.png differ
diff --git a/test/reference/clip-disjoint.rgb24.ref.png b/test/reference/clip-disjoint.rgb24.ref.png
deleted file mode 100644
index 4e18b7c..0000000
Binary files a/test/reference/clip-disjoint.rgb24.ref.png and /dev/null differ
diff --git a/test/reference/clip-operator.argb32.ref.png b/test/reference/clip-operator.argb32.ref.png
index 131c66f..5ab9631 100644
Binary files a/test/reference/clip-operator.argb32.ref.png and b/test/reference/clip-operator.argb32.ref.png differ
diff --git a/test/reference/clip-operator.rgb24.ref.png b/test/reference/clip-operator.rgb24.ref.png
index 5ec44ca..bcf474d 100644
Binary files a/test/reference/clip-operator.rgb24.ref.png and b/test/reference/clip-operator.rgb24.ref.png differ
diff --git a/test/reference/clip-stroke.argb32.ref.png b/test/reference/clip-stroke.argb32.ref.png
deleted file mode 100644
index c75416e..0000000
Binary files a/test/reference/clip-stroke.argb32.ref.png and /dev/null differ
diff --git a/test/reference/clip-stroke.ref.png b/test/reference/clip-stroke.ref.png
index c40fe63..bf6d888 100644
Binary files a/test/reference/clip-stroke.ref.png and b/test/reference/clip-stroke.ref.png differ
diff --git a/test/reference/clip-stroke.rgb24.ref.png b/test/reference/clip-stroke.rgb24.ref.png
deleted file mode 100644
index c75416e..0000000
Binary files a/test/reference/clip-stroke.rgb24.ref.png and /dev/null differ
diff --git a/test/reference/degenerate-arc.argb32.ref.png b/test/reference/degenerate-arc.argb32.ref.png
deleted file mode 100644
index 4da4fd6..0000000
Binary files a/test/reference/degenerate-arc.argb32.ref.png and /dev/null differ
diff --git a/test/reference/degenerate-arc.ref.png b/test/reference/degenerate-arc.ref.png
index 6bcfb8b..d83e2c7 100644
Binary files a/test/reference/degenerate-arc.ref.png and b/test/reference/degenerate-arc.ref.png differ
diff --git a/test/reference/degenerate-arc.rgb24.ref.png b/test/reference/degenerate-arc.rgb24.ref.png
deleted file mode 100644
index 4da4fd6..0000000
Binary files a/test/reference/degenerate-arc.rgb24.ref.png and /dev/null differ
diff --git a/test/reference/finer-grained-fallbacks.argb32.ref.png b/test/reference/finer-grained-fallbacks.argb32.ref.png
index 8cd99d0..8960179 100644
Binary files a/test/reference/finer-grained-fallbacks.argb32.ref.png and b/test/reference/finer-grained-fallbacks.argb32.ref.png differ
diff --git a/test/reference/finer-grained-fallbacks.rgb24.ref.png b/test/reference/finer-grained-fallbacks.rgb24.ref.png
index 5d6cd94..1a9a0c0 100644
Binary files a/test/reference/finer-grained-fallbacks.rgb24.ref.png and b/test/reference/finer-grained-fallbacks.rgb24.ref.png differ
diff --git a/test/reference/hatchings.argb32.ref.png b/test/reference/hatchings.argb32.ref.png
deleted file mode 100644
index 46b7380..0000000
Binary files a/test/reference/hatchings.argb32.ref.png and /dev/null differ
diff --git a/test/reference/hatchings.ref.png b/test/reference/hatchings.ref.png
index e8efd45..5aabc2c 100644
Binary files a/test/reference/hatchings.ref.png and b/test/reference/hatchings.ref.png differ
diff --git a/test/reference/hatchings.rgb24.ref.png b/test/reference/hatchings.rgb24.ref.png
deleted file mode 100644
index 46b7380..0000000
Binary files a/test/reference/hatchings.rgb24.ref.png and /dev/null differ
diff --git a/test/reference/operator-source.argb32.ref.png b/test/reference/operator-source.argb32.ref.png
index 49011ed..74ad1da 100644
Binary files a/test/reference/operator-source.argb32.ref.png and b/test/reference/operator-source.argb32.ref.png differ
diff --git a/test/reference/operator-source.rgb24.ref.png b/test/reference/operator-source.rgb24.ref.png
index 18aa82b..c003356 100644
Binary files a/test/reference/operator-source.rgb24.ref.png and b/test/reference/operator-source.rgb24.ref.png differ
diff --git a/test/reference/over-around-source.argb32.ref.png b/test/reference/over-around-source.argb32.ref.png
index e045a62..38df9b7 100644
Binary files a/test/reference/over-around-source.argb32.ref.png and b/test/reference/over-around-source.argb32.ref.png differ
diff --git a/test/reference/over-around-source.rgb24.ref.png b/test/reference/over-around-source.rgb24.ref.png
index fc46449..65fd8e8 100644
Binary files a/test/reference/over-around-source.rgb24.ref.png and b/test/reference/over-around-source.rgb24.ref.png differ
diff --git a/test/reference/over-below-source.argb32.ref.png b/test/reference/over-below-source.argb32.ref.png
index 9079c2c..0b55974 100644
Binary files a/test/reference/over-below-source.argb32.ref.png and b/test/reference/over-below-source.argb32.ref.png differ
diff --git a/test/reference/over-below-source.rgb24.ref.png b/test/reference/over-below-source.rgb24.ref.png
index c90bdc2..9ddde0e 100644
Binary files a/test/reference/over-below-source.rgb24.ref.png and b/test/reference/over-below-source.rgb24.ref.png differ
diff --git a/test/reference/over-between-source.argb32.ref.png b/test/reference/over-between-source.argb32.ref.png
index d4ef2ab..dd03f98 100644
Binary files a/test/reference/over-between-source.argb32.ref.png and b/test/reference/over-between-source.argb32.ref.png differ
diff --git a/test/reference/over-between-source.rgb24.ref.png b/test/reference/over-between-source.rgb24.ref.png
index fa0f8d1..8569720 100644
Binary files a/test/reference/over-between-source.rgb24.ref.png and b/test/reference/over-between-source.rgb24.ref.png differ
diff --git a/test/reference/overlapping-boxes.argb32.ref.png b/test/reference/overlapping-boxes.argb32.ref.png
index c8161c0..1c428e1 100644
Binary files a/test/reference/overlapping-boxes.argb32.ref.png and b/test/reference/overlapping-boxes.argb32.ref.png differ
diff --git a/test/reference/overlapping-boxes.rgb24.ref.png b/test/reference/overlapping-boxes.rgb24.ref.png
index 83ca3fa..58ec73c 100644
Binary files a/test/reference/overlapping-boxes.rgb24.ref.png and b/test/reference/overlapping-boxes.rgb24.ref.png differ
diff --git a/test/reference/random-clip.ref.png b/test/reference/random-clip.ref.png
index 374d6fe..6e67010 100644
Binary files a/test/reference/random-clip.ref.png and b/test/reference/random-clip.ref.png differ
diff --git a/test/reference/tighten-bounds.argb32.ref.png b/test/reference/tighten-bounds.argb32.ref.png
index 9702604..e348018 100644
Binary files a/test/reference/tighten-bounds.argb32.ref.png and b/test/reference/tighten-bounds.argb32.ref.png differ
diff --git a/test/reference/tighten-bounds.rgb24.ref.png b/test/reference/tighten-bounds.rgb24.ref.png
index 33ed717..28e3c1b 100644
Binary files a/test/reference/tighten-bounds.rgb24.ref.png and b/test/reference/tighten-bounds.rgb24.ref.png differ


More information about the cairo-commit mailing list