[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