[cairo-commit] 2 commits - src/cairo-composite-rectangles.c test/bug-source-cu.c test/Makefile.sources test/reference

Chris Wilson ickle at kemper.freedesktop.org
Wed Mar 28 16:52:34 PDT 2012


 src/cairo-composite-rectangles.c                  |   18 ++++
 test/Makefile.sources                             |    1 
 test/bug-source-cu.c                              |   81 ++++++++++++++++++++++
 test/reference/bug-source-cu.argb32.ref.png       |binary
 test/reference/bug-source-cu.rgb24.ref.png        |binary
 test/reference/bug-source-cu.traps.argb32.ref.png |binary
 test/reference/bug-source-cu.traps.rgb24.ref.png  |binary
 7 files changed, 97 insertions(+), 3 deletions(-)

New commits:
commit d304f0e57be8036719c3709e2419487326369105
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Mar 29 00:32:36 2012 +0100

    composite-rectangles: Trim extents for SOURCE and CLEAR to the mask
    
    The SOURCE and CLEAR are the odd pair in Cairo's range of operators that
    are bound by the shape/mask, but are unbound by the source. This
    regularly leads to bugs as only track the bound/unbound rectangles and
    confuse the meaning when bound only by the mask.
    
    What is required is that the unbound extents in this case is only
    trimmed by the mask (the bounded extents are still the intersection of
    all).
    
    Fixes bug-source-cu
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-composite-rectangles.c b/src/cairo-composite-rectangles.c
index 106571e..8c5cd5a 100644
--- a/src/cairo-composite-rectangles.c
+++ b/src/cairo-composite-rectangles.c
@@ -147,8 +147,12 @@ _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;
 
-    if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE))
+    if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) {
 	extents->unbounded = extents->bounded;
+    } else if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) {
+	if (!_cairo_rectangle_intersect (&extents->unbounded, &extents->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))
@@ -199,8 +203,12 @@ _cairo_composite_rectangles_intersect_source_extents (cairo_composite_rectangles
 	rect.height == extents->bounded.height)
 	return CAIRO_INT_STATUS_SUCCESS;
 
-    if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE))
+    if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) {
 	extents->unbounded = extents->bounded;
+    } else if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) {
+	if (!_cairo_rectangle_intersect (&extents->unbounded, &extents->mask))
+	    return CAIRO_INT_STATUS_NOTHING_TO_DO;
+    }
 
     clip = extents->clip;
     extents->clip = _cairo_clip_reduce_for_composite (clip, extents);
@@ -253,8 +261,12 @@ _cairo_composite_rectangles_intersect_mask_extents (cairo_composite_rectangles_t
 	mask.height == extents->bounded.height)
 	return CAIRO_INT_STATUS_SUCCESS;
 
-    if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE))
+    if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) {
 	extents->unbounded = extents->bounded;
+    } else if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) {
+	if (!_cairo_rectangle_intersect (&extents->unbounded, &extents->mask))
+	    return CAIRO_INT_STATUS_NOTHING_TO_DO;
+    }
 
     clip = extents->clip;
     extents->clip = _cairo_clip_reduce_for_composite (clip, extents);
commit 5b3d878c82fc862038c8e6730f34de317d734bd0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Mar 29 00:47:37 2012 +0100

    test: Add test case for tracking source operator extents

diff --git a/test/Makefile.sources b/test/Makefile.sources
index 61fa707..025790f 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -26,6 +26,7 @@ test_sources = \
 	bug-40410.c					\
 	bug-bo-rectangular.c				\
 	bug-bo-ricotz.c					\
+	bug-source-cu.c					\
 	bug-extents.c					\
 	bug-seams.c					\
 	caps.c						\
diff --git a/test/bug-source-cu.c b/test/bug-source-cu.c
new file mode 100644
index 0000000..4c1e2bc
--- /dev/null
+++ b/test/bug-source-cu.c
@@ -0,0 +1,81 @@
+/*
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "cairo-test.h"
+
+static cairo_pattern_t *
+create_pattern (cairo_surface_t *target)
+{
+    cairo_surface_t *surface;
+    cairo_pattern_t *pattern;
+    cairo_t *cr;
+    cairo_matrix_t m;
+
+    surface = cairo_surface_create_similar(target,
+					   cairo_surface_get_content (target),
+					   1000, 600);
+    cr = cairo_create (surface);
+    cairo_surface_destroy (surface);
+
+    cairo_set_source_rgb (cr, 0, 1, 0);
+    cairo_paint(cr);
+
+    pattern = cairo_pattern_create_for_surface (cairo_get_target (cr));
+    cairo_destroy(cr);
+
+    cairo_matrix_init_translate (&m, 0, 0.1); // y offset must be non-integer
+    cairo_pattern_set_matrix (pattern, &m);
+    return pattern;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+    cairo_pattern_t *pattern;
+
+    cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+    cairo_set_source_rgb (cr, 1, 0, 0);
+    cairo_paint (cr);
+
+    cairo_new_path (cr);
+    cairo_move_to (cr, 10, 400.1);
+    cairo_line_to (cr, 990, 400.1);
+    cairo_line_to (cr, 990, 600);
+    cairo_line_to (cr, 10,  600);
+    cairo_close_path (cr);
+
+    pattern = create_pattern (cairo_get_target (cr));
+    cairo_set_source (cr, pattern);
+    cairo_pattern_destroy (pattern);
+
+    cairo_fill(cr);
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (bug_source_cu,
+	    "Exercises a bug discovered in the tracking of unbounded source extents",
+	    "fill", /* keywords */
+	    NULL, /* requirements */
+	    1000, 600,
+	    NULL, draw)
diff --git a/test/reference/bug-source-cu.argb32.ref.png b/test/reference/bug-source-cu.argb32.ref.png
new file mode 100644
index 0000000..808feb5
Binary files /dev/null and b/test/reference/bug-source-cu.argb32.ref.png differ
diff --git a/test/reference/bug-source-cu.rgb24.ref.png b/test/reference/bug-source-cu.rgb24.ref.png
new file mode 100644
index 0000000..6cf2b1a
Binary files /dev/null and b/test/reference/bug-source-cu.rgb24.ref.png differ
diff --git a/test/reference/bug-source-cu.traps.argb32.ref.png b/test/reference/bug-source-cu.traps.argb32.ref.png
new file mode 100644
index 0000000..d8837c3
Binary files /dev/null and b/test/reference/bug-source-cu.traps.argb32.ref.png differ
diff --git a/test/reference/bug-source-cu.traps.rgb24.ref.png b/test/reference/bug-source-cu.traps.rgb24.ref.png
new file mode 100644
index 0000000..75e3b32
Binary files /dev/null and b/test/reference/bug-source-cu.traps.rgb24.ref.png differ


More information about the cairo-commit mailing list