summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.sources1
-rw-r--r--src/cairo-clip-private.h3
-rw-r--r--src/cairo-clip.c18
-rw-r--r--src/cairo-compositor-private.h4
-rw-r--r--src/cairo-image-compositor.c36
-rw-r--r--src/cairo-image-spans-compositor.c131
-rw-r--r--src/cairo-shape-mask-compositor.c337
-rw-r--r--src/cairo-spans-compositor.c49
-rw-r--r--test/reference/a1-tiger.argb32.ref.pngbin20328 -> 0 bytes
-rw-r--r--test/reference/a1-tiger.rgb24.ref.pngbin20328 -> 0 bytes
-rw-r--r--test/reference/clip-disjoint.argb32.ref.pngbin5399 -> 0 bytes
-rw-r--r--test/reference/clip-disjoint.ref.pngbin3934 -> 5438 bytes
-rw-r--r--test/reference/clip-disjoint.rgb24.ref.pngbin5399 -> 0 bytes
-rw-r--r--test/reference/clip-operator.argb32.ref.pngbin8158 -> 8245 bytes
-rw-r--r--test/reference/clip-operator.rgb24.ref.pngbin3231 -> 3333 bytes
-rw-r--r--test/reference/clip-stroke.argb32.ref.pngbin1522 -> 0 bytes
-rw-r--r--test/reference/clip-stroke.ref.pngbin1206 -> 1445 bytes
-rw-r--r--test/reference/clip-stroke.rgb24.ref.pngbin1522 -> 0 bytes
-rw-r--r--test/reference/degenerate-arc.argb32.ref.pngbin653 -> 0 bytes
-rw-r--r--test/reference/degenerate-arc.ref.pngbin690 -> 646 bytes
-rw-r--r--test/reference/degenerate-arc.rgb24.ref.pngbin653 -> 0 bytes
-rw-r--r--test/reference/finer-grained-fallbacks.argb32.ref.pngbin1167 -> 1068 bytes
-rw-r--r--test/reference/finer-grained-fallbacks.rgb24.ref.pngbin891 -> 837 bytes
-rw-r--r--test/reference/hatchings.argb32.ref.pngbin92730 -> 0 bytes
-rw-r--r--test/reference/hatchings.ref.pngbin45496 -> 93764 bytes
-rw-r--r--test/reference/hatchings.rgb24.ref.pngbin92730 -> 0 bytes
-rw-r--r--test/reference/operator-source.argb32.ref.pngbin5585 -> 5612 bytes
-rw-r--r--test/reference/operator-source.rgb24.ref.pngbin3954 -> 3975 bytes
-rw-r--r--test/reference/over-around-source.argb32.ref.pngbin618 -> 633 bytes
-rw-r--r--test/reference/over-around-source.rgb24.ref.pngbin501 -> 499 bytes
-rw-r--r--test/reference/over-below-source.argb32.ref.pngbin443 -> 447 bytes
-rw-r--r--test/reference/over-below-source.rgb24.ref.pngbin377 -> 385 bytes
-rw-r--r--test/reference/over-between-source.argb32.ref.pngbin593 -> 596 bytes
-rw-r--r--test/reference/over-between-source.rgb24.ref.pngbin460 -> 463 bytes
-rw-r--r--test/reference/overlapping-boxes.argb32.ref.pngbin210 -> 187 bytes
-rw-r--r--test/reference/overlapping-boxes.rgb24.ref.pngbin201 -> 179 bytes
-rw-r--r--test/reference/random-clip.ref.pngbin523342 -> 529871 bytes
-rw-r--r--test/reference/tighten-bounds.argb32.ref.pngbin9127 -> 9115 bytes
-rw-r--r--test/reference/tighten-bounds.rgb24.ref.pngbin8433 -> 8256 bytes
39 files changed, 420 insertions, 159 deletions
diff --git a/src/Makefile.sources b/src/Makefile.sources
index 19a14a7b..30e0d653 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 2c2aa957..c1c24d8c 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 d32bdec6..6bf1f39c 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 ff4b93b1..e5ad3671 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 7c044c4b..83b0cf3a 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 5718b555..00000000
--- 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@cworth.org>
- * Chris Wilson <chris@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 00000000..c2425b08
--- /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@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 f069bcdc..b106d73c 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 9a62af76..00000000
--- a/test/reference/a1-tiger.argb32.ref.png
+++ /dev/null
Binary files differ
diff --git a/test/reference/a1-tiger.rgb24.ref.png b/test/reference/a1-tiger.rgb24.ref.png
deleted file mode 100644
index 9a62af76..00000000
--- a/test/reference/a1-tiger.rgb24.ref.png
+++ /dev/null
Binary files differ
diff --git a/test/reference/clip-disjoint.argb32.ref.png b/test/reference/clip-disjoint.argb32.ref.png
deleted file mode 100644
index 4e18b7c7..00000000
--- a/test/reference/clip-disjoint.argb32.ref.png
+++ /dev/null
Binary files differ
diff --git a/test/reference/clip-disjoint.ref.png b/test/reference/clip-disjoint.ref.png
index a4c9989f..6577a08b 100644
--- a/test/reference/clip-disjoint.ref.png
+++ b/test/reference/clip-disjoint.ref.png
Binary files differ
diff --git a/test/reference/clip-disjoint.rgb24.ref.png b/test/reference/clip-disjoint.rgb24.ref.png
deleted file mode 100644
index 4e18b7c7..00000000
--- a/test/reference/clip-disjoint.rgb24.ref.png
+++ /dev/null
Binary files differ
diff --git a/test/reference/clip-operator.argb32.ref.png b/test/reference/clip-operator.argb32.ref.png
index 131c66f0..5ab96311 100644
--- a/test/reference/clip-operator.argb32.ref.png
+++ b/test/reference/clip-operator.argb32.ref.png
Binary files differ
diff --git a/test/reference/clip-operator.rgb24.ref.png b/test/reference/clip-operator.rgb24.ref.png
index 5ec44cae..bcf474dc 100644
--- a/test/reference/clip-operator.rgb24.ref.png
+++ b/test/reference/clip-operator.rgb24.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke.argb32.ref.png b/test/reference/clip-stroke.argb32.ref.png
deleted file mode 100644
index c75416ec..00000000
--- a/test/reference/clip-stroke.argb32.ref.png
+++ /dev/null
Binary files differ
diff --git a/test/reference/clip-stroke.ref.png b/test/reference/clip-stroke.ref.png
index c40fe63e..bf6d8884 100644
--- a/test/reference/clip-stroke.ref.png
+++ b/test/reference/clip-stroke.ref.png
Binary files differ
diff --git a/test/reference/clip-stroke.rgb24.ref.png b/test/reference/clip-stroke.rgb24.ref.png
deleted file mode 100644
index c75416ec..00000000
--- a/test/reference/clip-stroke.rgb24.ref.png
+++ /dev/null
Binary files differ
diff --git a/test/reference/degenerate-arc.argb32.ref.png b/test/reference/degenerate-arc.argb32.ref.png
deleted file mode 100644
index 4da4fd6e..00000000
--- a/test/reference/degenerate-arc.argb32.ref.png
+++ /dev/null
Binary files differ
diff --git a/test/reference/degenerate-arc.ref.png b/test/reference/degenerate-arc.ref.png
index 6bcfb8b8..d83e2c7b 100644
--- a/test/reference/degenerate-arc.ref.png
+++ b/test/reference/degenerate-arc.ref.png
Binary files differ
diff --git a/test/reference/degenerate-arc.rgb24.ref.png b/test/reference/degenerate-arc.rgb24.ref.png
deleted file mode 100644
index 4da4fd6e..00000000
--- a/test/reference/degenerate-arc.rgb24.ref.png
+++ /dev/null
Binary files differ
diff --git a/test/reference/finer-grained-fallbacks.argb32.ref.png b/test/reference/finer-grained-fallbacks.argb32.ref.png
index 8cd99d0e..89601794 100644
--- a/test/reference/finer-grained-fallbacks.argb32.ref.png
+++ b/test/reference/finer-grained-fallbacks.argb32.ref.png
Binary files differ
diff --git a/test/reference/finer-grained-fallbacks.rgb24.ref.png b/test/reference/finer-grained-fallbacks.rgb24.ref.png
index 5d6cd94f..1a9a0c0c 100644
--- a/test/reference/finer-grained-fallbacks.rgb24.ref.png
+++ b/test/reference/finer-grained-fallbacks.rgb24.ref.png
Binary files differ
diff --git a/test/reference/hatchings.argb32.ref.png b/test/reference/hatchings.argb32.ref.png
deleted file mode 100644
index 46b73808..00000000
--- a/test/reference/hatchings.argb32.ref.png
+++ /dev/null
Binary files differ
diff --git a/test/reference/hatchings.ref.png b/test/reference/hatchings.ref.png
index e8efd45f..5aabc2c4 100644
--- a/test/reference/hatchings.ref.png
+++ b/test/reference/hatchings.ref.png
Binary files differ
diff --git a/test/reference/hatchings.rgb24.ref.png b/test/reference/hatchings.rgb24.ref.png
deleted file mode 100644
index 46b73808..00000000
--- a/test/reference/hatchings.rgb24.ref.png
+++ /dev/null
Binary files differ
diff --git a/test/reference/operator-source.argb32.ref.png b/test/reference/operator-source.argb32.ref.png
index 49011eda..74ad1dad 100644
--- a/test/reference/operator-source.argb32.ref.png
+++ b/test/reference/operator-source.argb32.ref.png
Binary files differ
diff --git a/test/reference/operator-source.rgb24.ref.png b/test/reference/operator-source.rgb24.ref.png
index 18aa82bb..c0033562 100644
--- a/test/reference/operator-source.rgb24.ref.png
+++ b/test/reference/operator-source.rgb24.ref.png
Binary files differ
diff --git a/test/reference/over-around-source.argb32.ref.png b/test/reference/over-around-source.argb32.ref.png
index e045a62a..38df9b73 100644
--- a/test/reference/over-around-source.argb32.ref.png
+++ b/test/reference/over-around-source.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-around-source.rgb24.ref.png b/test/reference/over-around-source.rgb24.ref.png
index fc464497..65fd8e80 100644
--- a/test/reference/over-around-source.rgb24.ref.png
+++ b/test/reference/over-around-source.rgb24.ref.png
Binary files differ
diff --git a/test/reference/over-below-source.argb32.ref.png b/test/reference/over-below-source.argb32.ref.png
index 9079c2c6..0b55974b 100644
--- a/test/reference/over-below-source.argb32.ref.png
+++ b/test/reference/over-below-source.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-below-source.rgb24.ref.png b/test/reference/over-below-source.rgb24.ref.png
index c90bdc21..9ddde0e2 100644
--- a/test/reference/over-below-source.rgb24.ref.png
+++ b/test/reference/over-below-source.rgb24.ref.png
Binary files differ
diff --git a/test/reference/over-between-source.argb32.ref.png b/test/reference/over-between-source.argb32.ref.png
index d4ef2aba..dd03f982 100644
--- a/test/reference/over-between-source.argb32.ref.png
+++ b/test/reference/over-between-source.argb32.ref.png
Binary files differ
diff --git a/test/reference/over-between-source.rgb24.ref.png b/test/reference/over-between-source.rgb24.ref.png
index fa0f8d16..8569720b 100644
--- a/test/reference/over-between-source.rgb24.ref.png
+++ b/test/reference/over-between-source.rgb24.ref.png
Binary files differ
diff --git a/test/reference/overlapping-boxes.argb32.ref.png b/test/reference/overlapping-boxes.argb32.ref.png
index c8161c0a..1c428e1b 100644
--- a/test/reference/overlapping-boxes.argb32.ref.png
+++ b/test/reference/overlapping-boxes.argb32.ref.png
Binary files differ
diff --git a/test/reference/overlapping-boxes.rgb24.ref.png b/test/reference/overlapping-boxes.rgb24.ref.png
index 83ca3fa6..58ec73c1 100644
--- a/test/reference/overlapping-boxes.rgb24.ref.png
+++ b/test/reference/overlapping-boxes.rgb24.ref.png
Binary files differ
diff --git a/test/reference/random-clip.ref.png b/test/reference/random-clip.ref.png
index 374d6fe9..6e67010b 100644
--- a/test/reference/random-clip.ref.png
+++ b/test/reference/random-clip.ref.png
Binary files differ
diff --git a/test/reference/tighten-bounds.argb32.ref.png b/test/reference/tighten-bounds.argb32.ref.png
index 97026047..e3480188 100644
--- a/test/reference/tighten-bounds.argb32.ref.png
+++ b/test/reference/tighten-bounds.argb32.ref.png
Binary files differ
diff --git a/test/reference/tighten-bounds.rgb24.ref.png b/test/reference/tighten-bounds.rgb24.ref.png
index 33ed7179..28e3c1be 100644
--- a/test/reference/tighten-bounds.rgb24.ref.png
+++ b/test/reference/tighten-bounds.rgb24.ref.png
Binary files differ