diff options
author | Andrea Canciani <ranma42@gmail.com> | 2010-06-08 15:45:09 +0200 |
---|---|---|
committer | Andrea Canciani <ranma42@gmail.com> | 2010-06-10 16:07:42 +0200 |
commit | bccd89b4177b5f5bd05def9bee5f0927a9f25e4a (patch) | |
tree | e45146a93c9a0e2a69a9d2bfc38d57d5f633f4a5 /src | |
parent | 06c6207ad4205f211be70e324c6d32ea7d28dca8 (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.c | 85 |
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; } } |