summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2008-09-06 09:10:25 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2008-09-06 09:10:25 +0100
commit85ed37da33522efa101eb508a4091bcfa24ae944 (patch)
treee140357142b01c70c60c385ca657fdeb54f76a91
parentc1c86afa877b80a284365bcdaee11986bdd7da1f (diff)
[ps] A flattened gradient is not linear.
We cannot express an alpha-gradient as a simple linear interpolation between 2 flattened colors. So fallback.
-rw-r--r--src/cairo-ps-surface.c46
-rw-r--r--test/Makefile.am2
-rw-r--r--test/clip-operator-ps-argb32-ref.pngbin9102 -> 0 bytes
-rw-r--r--test/clip-operator-ps-rgb24-ref.pngbin4620 -> 0 bytes
-rw-r--r--test/gradient-alpha-ps-argb32-ref.pngbin189 -> 0 bytes
-rw-r--r--test/gradient-alpha-ps-rgb24-ref.pngbin179 -> 0 bytes
-rw-r--r--test/operator-clear-ps-argb32-ref.pngbin1435 -> 0 bytes
-rw-r--r--test/operator-source-ps-argb32-ref.pngbin3890 -> 0 bytes
-rw-r--r--test/operator-source-ps-rgb24-ref.pngbin3181 -> 0 bytes
9 files changed, 20 insertions, 28 deletions
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index c31ed2b0..bb80651d 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -1427,6 +1427,10 @@ _gradient_pattern_supported (cairo_ps_surface_t *surface,
if (surface->ps_level == CAIRO_PS_LEVEL_2)
return FALSE;
+ /* alpha-blended gradients cannot be expressed as a linear function */
+ if (! _cairo_pattern_is_opaque (pattern))
+ return FALSE;
+
surface->ps_level_used = CAIRO_PS_LEVEL_3;
extend = cairo_pattern_get_extend (pattern);
@@ -2413,7 +2417,7 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
typedef struct _cairo_ps_color_stop {
double offset;
- double color[4];
+ double color[3];
} cairo_ps_color_stop_t;
static void
@@ -2438,7 +2442,7 @@ _cairo_ps_surface_emit_linear_colorgradient (cairo_ps_surface_t *surface,
static void
_cairo_ps_surface_emit_stitched_colorgradient (cairo_ps_surface_t *surface,
- unsigned int n_stops,
+ unsigned int n_stops,
cairo_ps_color_stop_t stops[])
{
unsigned int i;
@@ -2468,11 +2472,14 @@ calc_gradient_color (cairo_ps_color_stop_t *new_stop,
cairo_ps_color_stop_t *stop1,
cairo_ps_color_stop_t *stop2)
{
- int i;
double offset = stop1->offset / (stop1->offset + 1.0 - stop2->offset);
+ double one_minus_offset = 1. - offset;
+ int i;
- for (i = 0; i < 4; i++)
- new_stop->color[i] = stop1->color[i] + offset*(stop2->color[i] - stop1->color[i]);
+ for (i = 0; i < 3; i++) {
+ new_stop->color[i] = stop1->color[i] * one_minus_offset +
+ stop2->color[i] * offset;
+ }
}
#define COLOR_STOP_EPSILON 1e-6
@@ -2484,7 +2491,8 @@ _cairo_ps_surface_emit_pattern_stops (cairo_ps_surface_t *surface,
cairo_ps_color_stop_t *allstops, *stops;
unsigned int i, n_stops;
- allstops = _cairo_malloc_ab ((pattern->n_stops + 2), sizeof (cairo_ps_color_stop_t));
+ allstops = _cairo_malloc_ab (pattern->n_stops + 2,
+ sizeof (cairo_ps_color_stop_t));
if (allstops == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -2497,7 +2505,6 @@ _cairo_ps_surface_emit_pattern_stops (cairo_ps_surface_t *surface,
stops[i].color[0] = stop->color.red;
stops[i].color[1] = stop->color.green;
stops[i].color[2] = stop->color.blue;
- stops[i].color[3] = stop->color.alpha;
stops[i].offset = pattern->stops[i].offset;
}
@@ -2507,7 +2514,8 @@ _cairo_ps_surface_emit_pattern_stops (cairo_ps_surface_t *surface,
if (pattern->base.extend == CAIRO_EXTEND_REFLECT)
memcpy (allstops, stops, sizeof (cairo_ps_color_stop_t));
else
- calc_gradient_color (&allstops[0], &stops[0], &stops[n_stops-1]);
+ calc_gradient_color (&allstops[0], &stops[0],
+ &stops[n_stops-1]);
stops = allstops;
n_stops++;
}
@@ -2519,34 +2527,20 @@ _cairo_ps_surface_emit_pattern_stops (cairo_ps_surface_t *surface,
&stops[n_stops - 1],
sizeof (cairo_ps_color_stop_t));
} else {
- calc_gradient_color (&stops[n_stops], &stops[0], &stops[n_stops-1]);
+ calc_gradient_color (&stops[n_stops], &stops[0],
+ &stops[n_stops-1]);
}
n_stops++;
}
stops[n_stops-1].offset = 1.0;
}
- for (i = 0; i < n_stops; i++) {
- double red, green, blue;
- cairo_color_t color;
-
- _cairo_color_init_rgba (&color,
- stops[i].color[0],
- stops[i].color[1],
- stops[i].color[2],
- stops[i].color[3]);
- _cairo_ps_surface_flatten_transparency (surface, &color,
- &red, &green, &blue);
- stops[i].color[0] = red;
- stops[i].color[1] = green;
- stops[i].color[2] = blue;
- }
-
_cairo_output_stream_printf (surface->stream,
"/CairoFunction\n");
if (n_stops == 2) {
/* no need for stitched function */
- _cairo_ps_surface_emit_linear_colorgradient (surface, &stops[0], &stops[1]);
+ _cairo_ps_surface_emit_linear_colorgradient (surface,
+ &stops[0], &stops[1]);
} else {
/* multiple stops: stitch. XXX possible optimization: regulary spaced
* stops do not require stitching. XXX */
diff --git a/test/Makefile.am b/test/Makefile.am
index 562f4d49..9424d2ea 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -448,8 +448,6 @@ REFERENCE_IMAGES = \
glyph-cache-pressure-quartz-ref.png \
gradient-alpha-pdf-argb32-ref.png \
gradient-alpha-pdf-rgb24-ref.png \
- gradient-alpha-ps-argb32-ref.png \
- gradient-alpha-ps-rgb24-ref.png \
gradient-alpha-ref.png \
gradient-alpha-rgb24-ref.png \
gradient-zero-stops-ref.png \
diff --git a/test/clip-operator-ps-argb32-ref.png b/test/clip-operator-ps-argb32-ref.png
deleted file mode 100644
index 35014bd8..00000000
--- a/test/clip-operator-ps-argb32-ref.png
+++ /dev/null
Binary files differ
diff --git a/test/clip-operator-ps-rgb24-ref.png b/test/clip-operator-ps-rgb24-ref.png
deleted file mode 100644
index 1736e4bb..00000000
--- a/test/clip-operator-ps-rgb24-ref.png
+++ /dev/null
Binary files differ
diff --git a/test/gradient-alpha-ps-argb32-ref.png b/test/gradient-alpha-ps-argb32-ref.png
deleted file mode 100644
index 323238bd..00000000
--- a/test/gradient-alpha-ps-argb32-ref.png
+++ /dev/null
Binary files differ
diff --git a/test/gradient-alpha-ps-rgb24-ref.png b/test/gradient-alpha-ps-rgb24-ref.png
deleted file mode 100644
index 430052cb..00000000
--- a/test/gradient-alpha-ps-rgb24-ref.png
+++ /dev/null
Binary files differ
diff --git a/test/operator-clear-ps-argb32-ref.png b/test/operator-clear-ps-argb32-ref.png
deleted file mode 100644
index d9a77694..00000000
--- a/test/operator-clear-ps-argb32-ref.png
+++ /dev/null
Binary files differ
diff --git a/test/operator-source-ps-argb32-ref.png b/test/operator-source-ps-argb32-ref.png
deleted file mode 100644
index d5cb053a..00000000
--- a/test/operator-source-ps-argb32-ref.png
+++ /dev/null
Binary files differ
diff --git a/test/operator-source-ps-rgb24-ref.png b/test/operator-source-ps-rgb24-ref.png
deleted file mode 100644
index eb73a9e3..00000000
--- a/test/operator-source-ps-rgb24-ref.png
+++ /dev/null
Binary files differ