summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrea Canciani <ranma42@gmail.com>2010-06-08 15:45:09 +0200
committerAndrea Canciani <ranma42@gmail.com>2010-06-10 16:07:42 +0200
commitbccd89b4177b5f5bd05def9bee5f0927a9f25e4a (patch)
treee45146a93c9a0e2a69a9d2bfc38d57d5f633f4a5 /src
parent06c6207ad4205f211be70e324c6d32ea7d28dca8 (diff)
gstate: correct optimizations
Gradient were previously hand-optimized (without properly checking for extend modes). By properly using _cairo_pattern functions we avoid code duplication and bugs. Fixes linear-gradient-extend, radial-gradient-extend.
Diffstat (limited to 'src')
-rw-r--r--src/cairo-gstate.c85
1 files changed, 17 insertions, 68 deletions
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 4738449b..28266dd0 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -849,21 +849,6 @@ _cairo_gstate_path_extents (cairo_gstate_t *gstate,
}
static void
-_init_solid_for_color_stop (cairo_solid_pattern_t *solid,
- const cairo_color_stop_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);
-}
-
-static void
_cairo_gstate_copy_pattern (cairo_pattern_t *pattern,
const cairo_pattern_t *original)
{
@@ -871,60 +856,24 @@ _cairo_gstate_copy_pattern (cairo_pattern_t *pattern,
* pattern. For example, gradients that are uniform or just have a single
* stop can be replace with a solid.
*/
- switch (original->type) {
- case CAIRO_PATTERN_TYPE_SOLID:
- break;
-
- case CAIRO_PATTERN_TYPE_SURFACE:
- {
- cairo_surface_pattern_t *surface = (cairo_surface_pattern_t *) original;
- cairo_rectangle_int_t extents;
-
- if (_cairo_surface_get_extents (surface->surface, &extents) &&
- (extents.width == 0 || extents.height == 0)) {
- _cairo_pattern_init_solid ((cairo_solid_pattern_t *) pattern,
- CAIRO_COLOR_TRANSPARENT);
-
- return;
- }
- }
- break;
-
- case CAIRO_PATTERN_TYPE_LINEAR:
- case CAIRO_PATTERN_TYPE_RADIAL:
- {
- cairo_gradient_pattern_t *src = (cairo_gradient_pattern_t *) original;
-
- /* fast path for gradients with less than 2 color stops */
- if (src->n_stops < 2) {
- if (src->n_stops) {
- _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);
- }
- return;
- } else {
- unsigned int i;
-
- /* Is the gradient a uniform colour?
- * Happens more often than you would believe.
- */
- for (i = 1; i < src->n_stops; i++) {
- if (! _cairo_color_stop_equal (&src->stops[0].color,
- &src->stops[i].color))
- {
- break;
- }
- }
- if (i == src->n_stops) {
- _init_solid_for_color_stop ((cairo_solid_pattern_t *) pattern,
- &src->stops->color);
- return;
- }
- }
+ if (_cairo_pattern_is_clear (original)) {
+ _cairo_pattern_init_solid ((cairo_solid_pattern_t *) pattern,
+ CAIRO_COLOR_TRANSPARENT);
+ return;
+ }
+
+ if (original->type == CAIRO_PATTERN_TYPE_LINEAR ||
+ original->type == CAIRO_PATTERN_TYPE_RADIAL)
+ {
+ cairo_color_t color;
+ if (_cairo_gradient_pattern_is_solid ((cairo_gradient_pattern_t *) original,
+ NULL,
+ &color))
+ {
+ _cairo_pattern_init_solid ((cairo_solid_pattern_t *) pattern,
+ &color);
+ return;
}
}