[cairo-commit] 2 commits - AUTHORS src/cairo-svg-surface.c test/.gitignore test/Makefile.am test/mask-ctm-image.c test/mask-ctm-image-ref.png test/mask-ctm-similar.c test/mask-ctm-similar-ref.png

Chris Wilson ickle at kemper.freedesktop.org
Mon Sep 22 05:04:15 PDT 2008


 AUTHORS                       |    1 
 src/cairo-svg-surface.c       |    9 ++-
 test/.gitignore               |    2 
 test/Makefile.am              |    4 +
 test/mask-ctm-image-ref.png   |binary
 test/mask-ctm-image.c         |  100 +++++++++++++++++++++++++++++++++++++++++
 test/mask-ctm-similar-ref.png |binary
 test/mask-ctm-similar.c       |  102 ++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 214 insertions(+), 4 deletions(-)

New commits:
commit 20be3182ef29bb07ffac749f5cf1844b4781e1bb
Author: Kai-Uwe Behrmann <ku.b at gmx.de>
Date:   Mon Sep 22 10:10:51 2008 +0100

    [svg] Counteract application of object matrix to mask.
    
    The expected behaviour for masking in Cairo is to set the mask according
    to the current active matrix and apply unchanged to the masked surface.
    
    In SVG, the mask element is bound to the masked object and thus the local
    matrix from that image object applies to the nested mask as well.
    
    Attached is a small patch for substracting the matrix of a image
    surface from the matrix of the mask to comply to Cairo's behaviour.
    I did not test for other stuff like vectors or text and would expect this
    part is incomplete.

diff --git a/AUTHORS b/AUTHORS
index bdde62a..ef14e3a 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -4,6 +4,7 @@ Shawn T. Amundson <amundson at gtk.org> Build fix
 Olivier Andrieu <oliv__a at users.sourceforge.net> PNG backend
 Peter Dennis Bartok <peter at novonyx.com> Bug fix for clipping
 Dave Beckett <dajobe at debian.org> Build fixes, Debian packaging
+Kai-Uwe Behrmann <ku.b at gmx.de> SVG bug fixes
 Christian Biesinger <cbiesinger at web.de> BeOS backend
 Billy Biggs <vektor at dumbterm.net> Pixman code merge. Optimization. Fixes for subtle rendering bugs.
 Hans Breuer <hans at breuer.org> win32 bug fixes, build fixes, and improvements
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 63b0bfb..e8567bc 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -1938,6 +1938,7 @@ _cairo_svg_surface_emit_paint (cairo_output_stream_t *output,
 			       cairo_svg_surface_t   *surface,
 			       cairo_operator_t	      op,
 			       cairo_pattern_t	     *source,
+			       cairo_pattern_t	     *mask_source,
 			       const char	     *extra_attributes)
 {
     cairo_status_t status;
@@ -1948,7 +1949,7 @@ _cairo_svg_surface_emit_paint (cairo_output_stream_t *output,
 				       surface,
 				       (cairo_surface_pattern_t *) source,
 				       invalid_pattern_id,
-				       NULL,
+				       mask_source ? &mask_source->matrix :NULL,
 				       extra_attributes);
 
     _cairo_output_stream_printf (output,
@@ -2031,7 +2032,7 @@ _cairo_svg_surface_paint (void		    *abstract_surface,
 	}
     }
 
-    return _cairo_svg_surface_emit_paint (surface->xml_node, surface, op, source, NULL);
+    return _cairo_svg_surface_emit_paint (surface->xml_node, surface, op, source, 0, NULL);
 }
 
 static cairo_int_status_t
@@ -2077,7 +2078,7 @@ _cairo_svg_surface_mask (void		    *abstract_surface,
 				 "%s",
 				 mask_id,
 				 discard_filter ? "" : "  <g filter=\"url(#alpha)\">\n");
-    status = _cairo_svg_surface_emit_paint (mask_stream, surface, op, mask, NULL);
+    status = _cairo_svg_surface_emit_paint (mask_stream, surface, op, mask, source, NULL);
     if (status) {
 	cairo_status_t ignore = _cairo_output_stream_destroy (mask_stream);
 	return status;
@@ -2096,7 +2097,7 @@ _cairo_svg_surface_mask (void		    *abstract_surface,
 
     snprintf (buffer, sizeof buffer, "mask=\"url(#mask%d)\"",
 	      mask_id);
-    status = _cairo_svg_surface_emit_paint (surface->xml_node, surface, op, source, buffer);
+    status = _cairo_svg_surface_emit_paint (surface->xml_node, surface, op, source, 0, buffer);
     if (status)
 	return status;
 
commit 223e7b9ed0053f9569df4bafc7688439aeb12572
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Sep 22 08:03:41 2008 +0100

    [test] Add an exercise for masking an image using the ctm.
    
    Quote Kai-Uwe Behrmann:
    "The expected behaviour for masking in Cairo is to set the mask according
    to the current active matrix and apply unchanged to a to be masked
    surface.
    
    In SVG the mask element is bound to the masked object and thus the local
    matrix from that image object applies to the nested mask as well."
    
    This is a test case to exercise applying a mask to an image under
    separate transformations.
    
    Original patch by Kai-Uwe Behrmann, altered to run the test against all
    backends (where it causes poppler to crash on my machine <evil grin>).

diff --git a/test/.gitignore b/test/.gitignore
index 0ad92da..3068cac 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -119,6 +119,8 @@ long-lines
 mask
 mask-alpha
 mask-ctm
+mask-ctm-image
+mask-ctm-similar
 mask-surface-ctm
 meta-surface-pattern
 miter-precision
diff --git a/test/Makefile.am b/test/Makefile.am
index 1dcde7d..d5fdead 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -95,6 +95,8 @@ long-lines$(EXEEXT)					\
 mask$(EXEEXT)						\
 mask-alpha$(EXEEXT)					\
 mask-ctm$(EXEEXT)					\
+mask-ctm-image$(EXEEXT)					\
+mask-ctm-similar$(EXEEXT)				\
 mask-surface-ctm$(EXEEXT)				\
 meta-surface-pattern$(EXEEXT)				\
 miter-precision$(EXEEXT)				\
@@ -507,6 +509,8 @@ REFERENCE_IMAGES = \
 	mask-ctm-ref.png	\
 	mask-ctm-rgb24-ref.png	\
 	mask-ctm-svg-argb32-ref.png	\
+	mask-ctm-image-ref.png	\
+	mask-ctm-similar-ref.png	\
 	mask-ref.png	\
 	mask-rgb24-ref.png	\
 	mask-pdf-argb32-ref.png	\
diff --git a/test/mask-ctm-image-ref.png b/test/mask-ctm-image-ref.png
new file mode 100644
index 0000000..e634f75
Binary files /dev/null and b/test/mask-ctm-image-ref.png differ
diff --git a/test/mask-ctm-image.c b/test/mask-ctm-image.c
new file mode 100644
index 0000000..e57e697
--- /dev/null
+++ b/test/mask-ctm-image.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2008 Kai-Uwe Behrmann
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Kai-Uwe Behrmann not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Kai-Uwe Behrmann makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * KAI_UWE BEHRMANN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL KAI_UWE BEHRMANN BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Kai-Uwe Behrmann <ku.b at gmx.de>
+ *         Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_draw_function_t draw;
+static const char png_filename[] = "romedalen.png";
+
+static const cairo_test_t test = {
+    "mask-ctm-image",
+    "Test that cairo_mask() is affected properly by the CTM and not the image",
+    80, 80,
+    draw
+};
+
+static cairo_surface_t *
+create_mask (cairo_t *dst, int width, int height)
+{
+    cairo_surface_t *mask;
+    cairo_t *cr;
+
+    mask = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
+    cr = cairo_create (mask);
+    cairo_surface_destroy (mask);
+
+    cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+    cairo_rectangle (cr, width/4, height/4, width/2, height/2);
+    cairo_fill (cr);
+
+    mask = cairo_surface_reference (cairo_get_target (cr));
+    cairo_destroy (cr);
+
+    return mask;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+    cairo_surface_t *image, *mask;
+
+    image = cairo_test_create_surface_from_png (ctx, png_filename);
+    mask = create_mask (cr, 40, 40);
+
+    /* opaque background */
+    cairo_paint (cr);
+
+    /* center */
+    cairo_translate (cr,
+	             (width - cairo_image_surface_get_width (image)) / 2.,
+		     (height - cairo_image_surface_get_height (image)) / 2.);
+
+    /* rotate 30 degree around the center */
+    cairo_translate (cr, width/2., height/2.);
+    cairo_rotate (cr, -30 * 2 * M_PI / 360);
+    cairo_translate (cr, -width/2., -height/2.);
+
+    /* place the image on our surface */
+    cairo_set_source_surface (cr, image, 0, 0);
+
+    /* reset the drawing matrix */
+    cairo_identity_matrix (cr);
+
+    /* fill nicely */
+    cairo_scale (cr, width / 40., height / 40.);
+
+    /* apply the mask */
+    cairo_mask_surface (cr, mask, 0, 0);
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+int
+main (void)
+{
+    return cairo_test (&test);
+}
diff --git a/test/mask-ctm-similar-ref.png b/test/mask-ctm-similar-ref.png
new file mode 100644
index 0000000..e634f75
Binary files /dev/null and b/test/mask-ctm-similar-ref.png differ
diff --git a/test/mask-ctm-similar.c b/test/mask-ctm-similar.c
new file mode 100644
index 0000000..502837a
--- /dev/null
+++ b/test/mask-ctm-similar.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2008 Kai-Uwe Behrmann
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Kai-Uwe Behrmann not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Kai-Uwe Behrmann makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * KAI_UWE BEHRMANN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL KAI_UWE BEHRMANN BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Kai-Uwe Behrmann <ku.b at gmx.de>
+ *         Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_draw_function_t draw;
+static const char png_filename[] = "romedalen.png";
+
+static const cairo_test_t test = {
+    "mask-ctm-similar",
+    "Test that cairo_mask() is affected properly by the CTM and not the image",
+    80, 80,
+    draw
+};
+
+static cairo_surface_t *
+create_mask (cairo_t *dst, int width, int height)
+{
+    cairo_surface_t *mask;
+    cairo_t *cr;
+
+    mask = cairo_surface_create_similar (cairo_get_target (dst),
+	                                 CAIRO_CONTENT_ALPHA,
+					 width, height);
+    cr = cairo_create (mask);
+    cairo_surface_destroy (mask);
+
+    cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+    cairo_rectangle (cr, width/4, height/4, width/2, height/2);
+    cairo_fill (cr);
+
+    mask = cairo_surface_reference (cairo_get_target (cr));
+    cairo_destroy (cr);
+
+    return mask;
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
+    cairo_surface_t *image, *mask;
+
+    image = cairo_test_create_surface_from_png (ctx, png_filename);
+    mask = create_mask (cr, 40, 40);
+
+    /* opaque background */
+    cairo_paint (cr);
+
+    /* center */
+    cairo_translate (cr,
+	             (width - cairo_image_surface_get_width (image)) / 2.,
+		     (height - cairo_image_surface_get_height (image)) / 2.);
+
+    /* rotate 30 degree around the center */
+    cairo_translate (cr, width/2., height/2.);
+    cairo_rotate (cr, -30 * 2 * M_PI / 360);
+    cairo_translate (cr, -width/2., -height/2.);
+
+    /* place the image on our surface */
+    cairo_set_source_surface (cr, image, 0, 0);
+
+    /* reset the drawing matrix */
+    cairo_identity_matrix (cr);
+
+    /* fill nicely */
+    cairo_scale (cr, width / 40., height / 40.);
+
+    /* apply the mask */
+    cairo_mask_surface (cr, mask, 0, 0);
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+int
+main (void)
+{
+    return cairo_test (&test);
+}


More information about the cairo-commit mailing list