[cairo-commit] 3 commits - src/cairo-gstate.c src/cairo-pattern.c test/degenerate-arcs.c test/degenerate-arcs.ref.png test/linear-uniform.c test/linear-uniform.ref.png test/Makefile.am test/Makefile.sources

Chris Wilson ickle at kemper.freedesktop.org
Fri Jan 15 04:26:15 PST 2010


 src/cairo-gstate.c           |   26 ++++++++++++-----
 src/cairo-pattern.c          |   32 ++++++++++++++-------
 test/Makefile.am             |    2 +
 test/Makefile.sources        |    2 +
 test/degenerate-arcs.c       |   57 ++++++++++++++++++++++++++++++++++++++
 test/degenerate-arcs.ref.png |binary
 test/linear-uniform.c        |   63 +++++++++++++++++++++++++++++++++++++++++++
 test/linear-uniform.ref.png  |binary
 8 files changed, 164 insertions(+), 18 deletions(-)

New commits:
commit 4e315d84723b27746a6a012ab7de429b2f2ef90b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jan 15 12:21:52 2010 +0000

    pattern: Premultiply color-stop when converting to solid
    
    Fixes: test/linear-uniform
           https://bugzilla.mozilla.org/show_bug.cgi?id=539165
           Bug 539165 - gradients with a single stop do not have their color
                        multiplied by the alpha.
    
    As reported by Jeff Muizelaar, we regressed in 2d790daa as the
    color-stops are not premultiplied and so could not be treated as an
    ordinary cairo_color_t. Instead we have to create a intermediate
    cairo_color_t from the original values in order for the
    premultiplication to be performed.

diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 78faed9..2799392 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -821,6 +821,21 @@ _cairo_gstate_path_extents (cairo_gstate_t     *gstate,
 }
 
 static void
+_init_solid_for_color_stop (cairo_solid_pattern_t *solid,
+			    const cairo_color_t *color)
+{
+    cairo_color_t premult;
+
+    /* Color stops aren't premultiplied, so fix that here */
+    _cairo_color_init_rgba (&premult,
+			    color->red,
+			    color->green,
+			    color->blue,
+			    color->alpha);
+    _cairo_pattern_init_solid (solid, &premult, CAIRO_CONTENT_COLOR_ALPHA);
+}
+
+static void
 _cairo_gstate_copy_pattern (cairo_pattern_t *pattern,
 			    const cairo_pattern_t *original)
 {
@@ -841,9 +856,8 @@ _cairo_gstate_copy_pattern (cairo_pattern_t *pattern,
 	    /* fast path for gradients with less than 2 color stops */
 	    if (src->n_stops < 2) {
 		if (src->n_stops) {
-		    _cairo_pattern_init_solid ((cairo_solid_pattern_t *) pattern,
-					       &src->stops->color,
-					       CAIRO_CONTENT_COLOR_ALPHA);
+		    _init_solid_for_color_stop ((cairo_solid_pattern_t *) pattern,
+						&src->stops->color);
 		} else {
 		    _cairo_pattern_init_solid ((cairo_solid_pattern_t *) pattern,
 					       CAIRO_COLOR_TRANSPARENT,
@@ -865,10 +879,8 @@ _cairo_gstate_copy_pattern (cairo_pattern_t *pattern,
 		    }
 		}
 		if (i == src->n_stops) {
-		    _cairo_pattern_init_solid ((cairo_solid_pattern_t *) pattern,
-					       &src->stops->color,
-					       CAIRO_CONTENT_COLOR_ALPHA);
-
+		    _init_solid_for_color_stop ((cairo_solid_pattern_t *) pattern,
+						&src->stops->color);
 		    return;
 		}
 	    }
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index a744118..598d204 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -2206,6 +2206,21 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t   *pat
     return status;
 }
 
+static void
+_init_solid_for_color_stop (cairo_solid_pattern_t *solid,
+			    const cairo_color_t *color)
+{
+    cairo_color_t premult;
+
+    /* Color stops aren't premultiplied, so fix that here */
+    _cairo_color_init_rgba (&premult,
+			    color->red,
+			    color->green,
+			    color->blue,
+			    color->alpha);
+    _cairo_pattern_init_solid (solid, &premult, CAIRO_CONTENT_COLOR_ALPHA);
+}
+
 /**
  * _cairo_pattern_acquire_surface:
  * @pattern: a #cairo_pattern_t
@@ -2257,19 +2272,16 @@ _cairo_pattern_acquire_surface (const cairo_pattern_t	   *pattern,
     case CAIRO_PATTERN_TYPE_RADIAL: {
 	cairo_gradient_pattern_t *src = (cairo_gradient_pattern_t *) pattern;
 
+	/* XXX The gradient->solid conversion code should now be redundant. */
+
 	/* fast path for gradients with less than 2 color stops */
 	if (src->n_stops < 2)
 	{
 	    cairo_solid_pattern_t solid;
 
-	    if (src->n_stops)
-	    {
-		_cairo_pattern_init_solid (&solid,
-					   &src->stops->color,
-					   CAIRO_CONTENT_COLOR_ALPHA);
-	    }
-	    else
-	    {
+	    if (src->n_stops) {
+		_init_solid_for_color_stop (&solid, &src->stops->color);
+	    } else {
 		_cairo_pattern_init_solid (&solid,
 					   CAIRO_COLOR_TRANSPARENT,
 					   CAIRO_CONTENT_ALPHA);
@@ -2298,9 +2310,7 @@ _cairo_pattern_acquire_surface (const cairo_pattern_t	   *pattern,
 	    if (i == src->n_stops) {
 		cairo_solid_pattern_t solid;
 
-		_cairo_pattern_init_solid (&solid,
-					   &src->stops->color,
-					   CAIRO_CONTENT_COLOR_ALPHA);
+		_init_solid_for_color_stop (&solid, &src->stops->color);
 
 		status =
 		    _cairo_pattern_acquire_surface_for_solid (&solid, dst,
commit f40560a9bb5b12d2584ed297bf4114baf2aa9cc1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jan 15 12:17:30 2010 +0000

    test: Add linear-uniform
    
    Jeff reported a regression found by Mozilla whereby a uniform gradient
    was not being premultiplied on conversion to a solid pattern.
    
      https://bugzilla.mozilla.org/show_bug.cgi?id=539165
      [Bug 539165] gradients with a single stop do not have their color
                   multiplied by the alpha.

diff --git a/test/Makefile.am b/test/Makefile.am
index ff81eee..51fced5 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -605,6 +605,7 @@ REFERENCE_IMAGES = \
 	linear-gradient.quartz.ref.png \
 	linear-gradient.ref.png \
 	linear-gradient.xlib.ref.png \
+	linear-uniform.ref.png \
 	long-dashed-lines.ps2.ref.png \
 	long-dashed-lines.ps3.ref.png \
 	long-dashed-lines.quartz.ref.png \
diff --git a/test/Makefile.sources b/test/Makefile.sources
index d123d3a..068858a 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -126,6 +126,7 @@ test_sources = \
 	line-width-zero.c				\
 	linear-gradient.c				\
 	linear-gradient-reflect.c			\
+	linear-uniform.c				\
 	long-dashed-lines.c				\
 	long-lines.c					\
 	mask.c						\
diff --git a/test/linear-uniform.c b/test/linear-uniform.c
new file mode 100644
index 0000000..2f65535
--- /dev/null
+++ b/test/linear-uniform.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * 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: Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+    cairo_pattern_t *pattern;
+
+    cairo_set_source_rgb (cr, 0, 0, 0);
+    cairo_paint (cr);
+
+    /* with alpha */
+    pattern = cairo_pattern_create_linear (0, 0, 0, height);
+    cairo_pattern_add_color_stop_rgba (pattern, 0, 1, 1, 1, .5);
+    cairo_pattern_add_color_stop_rgba (pattern, 1, 1, 1, 1, .5);
+    cairo_set_source (cr, pattern);
+    cairo_pattern_destroy (pattern);
+    cairo_rectangle (cr, 0, 0, width/2, height);
+    cairo_fill (cr);
+
+    /* without alpha */
+    pattern = cairo_pattern_create_linear (0, 0, 0, height);
+    cairo_pattern_add_color_stop_rgb (pattern, 0, 1, 1, 1);
+    cairo_pattern_add_color_stop_rgb (pattern, 1, 1, 1, 1);
+    cairo_set_source (cr, pattern);
+    cairo_pattern_destroy (pattern);
+    cairo_rectangle (cr, width/2, 0, width/2, height);
+    cairo_fill (cr);
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (linear_uniform,
+	    "Tests handling of \"solid\" linear gradients",
+	    "gradient, linear", /* keywords */
+	    NULL, /* requirements */
+	    40, 40,
+	    NULL, draw)
diff --git a/test/linear-uniform.ref.png b/test/linear-uniform.ref.png
new file mode 100644
index 0000000..94ca336
Binary files /dev/null and b/test/linear-uniform.ref.png differ
commit e22c02dbaeda6941083fc89b517508dc0c4386a0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jan 15 12:02:58 2010 +0000

    test: Add degenerate-arcs
    
    A simple test to ensure that using degenerate-arcs such as when drawing
    a rounded rectangle with radii=0 construct a proper path.

diff --git a/test/Makefile.am b/test/Makefile.am
index 4e5b273..ff81eee 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -336,6 +336,7 @@ REFERENCE_IMAGES = \
 	degenerate-arc.ps3.ref.png \
 	degenerate-arc.ref.png \
 	degenerate-arc.xlib.ref.png \
+	degenerate-arcs.ref.png \
 	degenerate-curve-to.ref.png \
 	degenerate-curve-to.ps.xfail.png \
 	degenerate-dash.ps.xfail.png \
diff --git a/test/Makefile.sources b/test/Makefile.sources
index 0b4ba42..d123d3a 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -56,6 +56,7 @@ test_sources = \
 	dash-state.c					\
 	dash-zero-length.c				\
 	degenerate-arc.c				\
+	degenerate-arcs.c				\
 	degenerate-curve-to.c				\
 	degenerate-dash.c				\
 	degenerate-path.c				\
diff --git a/test/degenerate-arcs.c b/test/degenerate-arcs.c
new file mode 100644
index 0000000..2470828
--- /dev/null
+++ b/test/degenerate-arcs.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2010 Intel Corporation
+ *
+ * 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
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON 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: Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH 20
+#define HEIGHT 20
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+    cairo_set_source_rgb (cr, 1, 1, 1);
+    cairo_paint (cr);
+
+    cairo_set_source_rgb (cr, 0.3, 0.4, 0.5);
+
+    /* This should be equivalent to a simple rectangle, such as may be
+     * constructed for a rounded-rectangle with corner radii of 0...
+     */
+    cairo_arc (cr, 5, 5, 0, M_PI, 3*M_PI/2);
+    cairo_arc (cr, 15, 5, 0, 3*M_PI/2, 2*M_PI);
+    cairo_arc (cr, 15, 15, 0, 0, M_PI/2);
+    cairo_arc (cr, 5, 15, 0, M_PI/2, M_PI);
+
+    cairo_fill (cr);
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (degenerate_arcs,
+	    "Tests path construction using a series of degenerate (radius=0) arcs",
+	    "arc, fill", /* keywords */
+	    NULL, /* requirements */
+	    WIDTH, HEIGHT,
+	    NULL, draw)
diff --git a/test/degenerate-arcs.ref.png b/test/degenerate-arcs.ref.png
new file mode 100644
index 0000000..fc1869d
Binary files /dev/null and b/test/degenerate-arcs.ref.png differ


More information about the cairo-commit mailing list