[cairo-commit] 3 commits - src/cairo-analysis-surface.c test/finer-grained-fallbacks.c test/finer-grained-fallbacks-ps-argb32-ref.png test/finer-grained-fallbacks-ps-rgb24-ref.png test/finer-grained-fallbacks-ref.png test/finer-grained-fallbacks-rgb24-ref.png test/.gitignore test/Makefile.am

Adrian Johnson ajohnson at kemper.freedesktop.org
Sun Mar 23 19:03:14 PDT 2008


 src/cairo-analysis-surface.c                   |   73 ++++++++++++----
 test/.gitignore                                |    1 
 test/Makefile.am                               |    3 
 test/finer-grained-fallbacks-ps-argb32-ref.png |binary
 test/finer-grained-fallbacks-ps-rgb24-ref.png  |binary
 test/finer-grained-fallbacks-ref.png           |binary
 test/finer-grained-fallbacks-rgb24-ref.png     |binary
 test/finer-grained-fallbacks.c                 |  111 +++++++++++++++++++++++++
 8 files changed, 170 insertions(+), 18 deletions(-)

New commits:
commit 2ad39157975d71735da936977dd10e66d055ece7
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Mon Mar 24 12:32:07 2008 +1030

    Add PS reference images for finer-grained-fallbacks test

diff --git a/test/finer-grained-fallbacks-ps-argb32-ref.png b/test/finer-grained-fallbacks-ps-argb32-ref.png
new file mode 100644
index 0000000..402f01b
Binary files /dev/null and b/test/finer-grained-fallbacks-ps-argb32-ref.png differ
diff --git a/test/finer-grained-fallbacks-ps-rgb24-ref.png b/test/finer-grained-fallbacks-ps-rgb24-ref.png
new file mode 100644
index 0000000..e821344
Binary files /dev/null and b/test/finer-grained-fallbacks-ps-rgb24-ref.png differ
commit ae9635bf33cb989f5c525800b82b81daad699e01
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Mon Mar 24 12:16:20 2008 +1030

    Fix assertion in PS/PDF/Win32-print when fallback image is off the page
    
    If during analysis the bounding box of an operation or the number of
    traps is 0, the operation is marked as natively supported. The problem
    here is if the operation is unsupported by the backend, we get an
    assertion when the operation is replayed during
    CAIRO_PAGINATED_MODE_RENDER.
    
    This bug was found in Inkscape when printing to the
    win32_printing_surface a page that has been layed out as landscape but
    landscape paper had not been selected in the print dialog.
    
    Fix this by being careful not to mark unsupported operations as
    supported during analysis even they may not be visible on the page.

diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index 29919f0..749f3e3 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -125,8 +125,20 @@ _cairo_analysis_surface_add_operation  (cairo_analysis_surface_t *surface,
     cairo_int_status_t status;
     cairo_box_t bbox;
 
-    if (rect->width == 0 || rect->height == 0)
-	return CAIRO_STATUS_SUCCESS;
+    if (rect->width == 0 || rect->height == 0) {
+	/* 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 ||
+	    backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
+	{
+	    return CAIRO_STATUS_SUCCESS;
+	}
+	else
+	{
+	    return CAIRO_INT_STATUS_IMAGE_FALLBACK;
+	}
+    }
 
     if (surface->has_ctm) {
 	double x1, y1, x2, y2;
@@ -143,8 +155,21 @@ _cairo_analysis_surface_add_operation  (cairo_analysis_surface_t *surface,
 
 	x2 = ceil (x2) - rect->x;
 	y2 = ceil (y2) - rect->y;
-	if (x2 <= 0 || y2 <= 0)
-	    return CAIRO_STATUS_SUCCESS;
+	if (x2 <= 0 || y2 <= 0) {
+	    /* 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 ||
+		backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
+	    {
+		return CAIRO_STATUS_SUCCESS;
+	    }
+	    else
+	    {
+		return CAIRO_INT_STATUS_IMAGE_FALLBACK;
+	    }
+	}
 
 	rect->width  = x2;
 	rect->height = y2;
@@ -434,17 +459,23 @@ _cairo_analysis_surface_stroke (void			*abstract_surface,
 						    ctm, ctm_inverse,
 						    tolerance,
 						    &traps);
-
-	if (status || traps.num_traps == 0) {
+	if (status) {
 	    _cairo_traps_fini (&traps);
 	    return status;
 	}
 
-	_cairo_traps_extents (&traps, &box);
-	extents.x = _cairo_fixed_integer_floor (box.p1.x);
-	extents.y = _cairo_fixed_integer_floor (box.p1.y);
-	extents.width = _cairo_fixed_integer_ceil (box.p2.x) - extents.x;
-	extents.height = _cairo_fixed_integer_ceil (box.p2.y) - extents.y;
+	if (traps.num_traps == 0) {
+	    extents.x = 0;
+	    extents.y = 0;
+	    extents.width = 0;
+	    extents.height = 0;
+	} else {
+	    _cairo_traps_extents (&traps, &box);
+	    extents.x = _cairo_fixed_integer_floor (box.p1.x);
+	    extents.y = _cairo_fixed_integer_floor (box.p1.y);
+	    extents.width = _cairo_fixed_integer_ceil (box.p2.x) - extents.x;
+	    extents.height = _cairo_fixed_integer_ceil (box.p2.y) - extents.y;
+	}
 	_cairo_traps_fini (&traps);
     }
 
@@ -506,17 +537,23 @@ _cairo_analysis_surface_fill (void			*abstract_surface,
 						  fill_rule,
 						  tolerance,
 						  &traps);
-
-	if (status || traps.num_traps == 0) {
+	if (status) {
 	    _cairo_traps_fini (&traps);
 	    return status;
 	}
 
-	_cairo_traps_extents (&traps, &box);
-	extents.x = _cairo_fixed_integer_floor (box.p1.x);
-	extents.y = _cairo_fixed_integer_floor (box.p1.y);
-	extents.width = _cairo_fixed_integer_ceil (box.p2.x) - extents.x;
-	extents.height = _cairo_fixed_integer_ceil (box.p2.y) - extents.y;
+	if (traps.num_traps == 0) {
+	    extents.x = 0;
+	    extents.y = 0;
+	    extents.width = 0;
+	    extents.height = 0;
+	} else {
+	    _cairo_traps_extents (&traps, &box);
+	    extents.x = _cairo_fixed_integer_floor (box.p1.x);
+	    extents.y = _cairo_fixed_integer_floor (box.p1.y);
+	    extents.width = _cairo_fixed_integer_ceil (box.p2.x) - extents.x;
+	    extents.height = _cairo_fixed_integer_ceil (box.p2.y) - extents.y;
+	}
 
 	_cairo_traps_fini (&traps);
     }
commit 179ab7d2860b8ff94fe491896c50505fde7cf6af
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Mon Mar 24 11:43:29 2008 +1030

    Add finer-grained-fallbacks test
    
    This reproduces the bug in PS/PDF/Win32-printing where an unsupported
    operation that is off the page causes an unsupported operation
    assertion in the backend.

diff --git a/test/.gitignore b/test/.gitignore
index 19a4a1f..3f7b2af 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -62,6 +62,7 @@ fill-degenerate-sort-order
 fill-missed-stop
 fill-rule
 filter-nearest-offset
+finer-grained-fallbacks
 ft-text-antialias-none
 ft-font-create-for-ft-face
 ft-show-glyphs-positioning
diff --git a/test/Makefile.am b/test/Makefile.am
index 7d0c52b..73f4ad2 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -50,6 +50,7 @@ fill-degenerate-sort-order$(EXEEXT)			\
 fill-missed-stop$(EXEEXT)				\
 fill-rule$(EXEEXT)					\
 filter-nearest-offset$(EXEEXT)				\
+finer-grained-fallbacks$(EXEEXT)			\
 font-face-get-type$(EXEEXT)				\
 font-matrix-translation$(EXEEXT)			\
 font-options$(EXEEXT)					\
@@ -367,6 +368,8 @@ REFERENCE_IMAGES = \
 	fill-rule-rgb24-ref.png	\
 	fill-rule-ps-rgb24-ref.png \
 	filter-nearest-offset-ref.png	\
+	finer-grained-fallbacks-ref.png			\
+	finer-grained-fallbacks-rgb24-ref.png		\
 	font-matrix-translation-ps-argb32-ref.png	\
 	font-matrix-translation-ps-rgb24-ref.png	\
 	font-matrix-translation-ref.png	\
diff --git a/test/finer-grained-fallbacks-ref.png b/test/finer-grained-fallbacks-ref.png
new file mode 100644
index 0000000..7dce860
Binary files /dev/null and b/test/finer-grained-fallbacks-ref.png differ
diff --git a/test/finer-grained-fallbacks-rgb24-ref.png b/test/finer-grained-fallbacks-rgb24-ref.png
new file mode 100644
index 0000000..7328482
Binary files /dev/null and b/test/finer-grained-fallbacks-rgb24-ref.png differ
diff --git a/test/finer-grained-fallbacks.c b/test/finer-grained-fallbacks.c
new file mode 100644
index 0000000..2dd006c
--- /dev/null
+++ b/test/finer-grained-fallbacks.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright © 2008 Adrian Johnson
+ *
+ * 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.
+ *
+ * Author: Adrian Johnson <ajohnson at redneon.com>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_draw_function_t draw;
+
+#define CIRCLE_SIZE 10
+#define PAD 2
+#define WIDTH (CIRCLE_SIZE*6.5 + PAD)
+#define HEIGHT (CIRCLE_SIZE*3.5 + PAD)
+
+cairo_test_t test = {
+    "finer-grained-fallbacks",
+    "Test that multiple PS/PDF fallback images in various locations are correct",
+    WIDTH, HEIGHT,
+    draw
+};
+
+static void
+draw_circle (cairo_t *cr, double x, double y)
+{
+    cairo_save (cr);
+    cairo_translate (cr, x, y);
+    cairo_arc (cr, 0, 0, CIRCLE_SIZE / 2, 0., 2. * M_PI);
+    cairo_fill (cr);
+    cairo_restore (cr);
+}
+
+static void
+draw_circles (cairo_t *cr)
+{
+    draw_circle (cr, 0,               -CIRCLE_SIZE*0.1);
+    draw_circle (cr, CIRCLE_SIZE*0.4,  CIRCLE_SIZE*0.25);
+
+    draw_circle (cr, CIRCLE_SIZE*2, 0);
+    draw_circle (cr, CIRCLE_SIZE*4, 0);
+    draw_circle (cr, CIRCLE_SIZE*6, 0);
+}
+
+/* For each of circle and fallback_circle we draw:
+ *  - two overlapping
+ *  - one isolated
+ *  - one off the page
+ *  - one overlapping the edge of the page.
+ *
+ * We also draw a circle and fallback_circle overlapping each other.
+ *
+ * Circles are drawn in green. An opaque color and CAIRO_OPERATOR_OVER
+ * is used to ensure they will be emitted as a vectors in PS/PDF.
+ *
+ * Fallback circles are drawn in red. CAIRO_OPERATOR_ADD is used to
+ * ensure they will be emitted as a fallback image in PS/PDF.
+ */
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+    cairo_translate (cr, PAD, PAD);
+
+    /* Draw overlapping circle and fallback circle */
+    cairo_set_source_rgb (cr, 0.0, 1.0, 0.0);
+    cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+    draw_circle (cr, CIRCLE_SIZE*0.5,  CIRCLE_SIZE*1.5);
+
+    cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
+    cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+    draw_circle (cr, CIRCLE_SIZE*0.75, CIRCLE_SIZE*1.75);
+
+    /* Draw circles */
+    cairo_set_source_rgb (cr, 0.0, 1.0, 0.0);
+    cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+    cairo_translate (cr, CIRCLE_SIZE*2.5, CIRCLE_SIZE*0.6);
+    draw_circles (cr);
+
+    /* Draw fallback circles */
+    cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
+    cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
+    cairo_translate (cr, 0, CIRCLE_SIZE*2);
+    draw_circles (cr);
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+int
+main (void)
+{
+    return cairo_test (&test);
+}


More information about the cairo-commit mailing list