diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2008-09-06 09:10:25 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2008-09-06 09:10:25 +0100 |
commit | 85ed37da33522efa101eb508a4091bcfa24ae944 (patch) | |
tree | e140357142b01c70c60c385ca657fdeb54f76a91 | |
parent | c1c86afa877b80a284365bcdaee11986bdd7da1f (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.c | 46 | ||||
-rw-r--r-- | test/Makefile.am | 2 | ||||
-rw-r--r-- | test/clip-operator-ps-argb32-ref.png | bin | 9102 -> 0 bytes | |||
-rw-r--r-- | test/clip-operator-ps-rgb24-ref.png | bin | 4620 -> 0 bytes | |||
-rw-r--r-- | test/gradient-alpha-ps-argb32-ref.png | bin | 189 -> 0 bytes | |||
-rw-r--r-- | test/gradient-alpha-ps-rgb24-ref.png | bin | 179 -> 0 bytes | |||
-rw-r--r-- | test/operator-clear-ps-argb32-ref.png | bin | 1435 -> 0 bytes | |||
-rw-r--r-- | test/operator-source-ps-argb32-ref.png | bin | 3890 -> 0 bytes | |||
-rw-r--r-- | test/operator-source-ps-rgb24-ref.png | bin | 3181 -> 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 Binary files differdeleted file mode 100644 index 35014bd8..00000000 --- a/test/clip-operator-ps-argb32-ref.png +++ /dev/null diff --git a/test/clip-operator-ps-rgb24-ref.png b/test/clip-operator-ps-rgb24-ref.png Binary files differdeleted file mode 100644 index 1736e4bb..00000000 --- a/test/clip-operator-ps-rgb24-ref.png +++ /dev/null diff --git a/test/gradient-alpha-ps-argb32-ref.png b/test/gradient-alpha-ps-argb32-ref.png Binary files differdeleted file mode 100644 index 323238bd..00000000 --- a/test/gradient-alpha-ps-argb32-ref.png +++ /dev/null diff --git a/test/gradient-alpha-ps-rgb24-ref.png b/test/gradient-alpha-ps-rgb24-ref.png Binary files differdeleted file mode 100644 index 430052cb..00000000 --- a/test/gradient-alpha-ps-rgb24-ref.png +++ /dev/null diff --git a/test/operator-clear-ps-argb32-ref.png b/test/operator-clear-ps-argb32-ref.png Binary files differdeleted file mode 100644 index d9a77694..00000000 --- a/test/operator-clear-ps-argb32-ref.png +++ /dev/null diff --git a/test/operator-source-ps-argb32-ref.png b/test/operator-source-ps-argb32-ref.png Binary files differdeleted file mode 100644 index d5cb053a..00000000 --- a/test/operator-source-ps-argb32-ref.png +++ /dev/null diff --git a/test/operator-source-ps-rgb24-ref.png b/test/operator-source-ps-rgb24-ref.png Binary files differdeleted file mode 100644 index eb73a9e3..00000000 --- a/test/operator-source-ps-rgb24-ref.png +++ /dev/null |