From dfa2544f158930b002df74e676f3ef7aeeee1bd4 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 13 May 2010 09:52:39 +0100 Subject: [PATCH] color: Special case comparing color stops. color stops are not premultiplied so we need to handle them carefully when comparing. The next step will be to make cairo_color_stop_t a unique type to prevent this mistake again. --- src/cairo-color.c | 30 ++++++++++++++++++++++++++++++ src/cairo-gl-surface.c | 4 ++-- src/cairo-gstate.c | 4 ++-- src/cairo-pattern.c | 6 +++--- src/cairoint.h | 4 ++++ src/drm/cairo-drm-intel.c | 2 +- 6 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/cairo-color.c b/src/cairo-color.c index 1df82bbe4..d6c6c3d9f 100644 --- a/src/cairo-color.c +++ b/src/cairo-color.c @@ -174,3 +174,33 @@ _cairo_color_equal (const cairo_color_t *color_a, color_a->blue_short == color_b->blue_short && color_a->alpha_short == color_b->alpha_short; } + +cairo_bool_t +_cairo_color_stop_equal (const cairo_color_t *color_a, + const cairo_color_t *color_b) +{ + uint16_t a, b; + + if (color_a == color_b) + return TRUE; + + if (color_a->alpha_short != color_b->alpha_short) + return FALSE; + + a = _cairo_color_double_to_short (color_a->red * color_a->alpha); + b = _cairo_color_double_to_short (color_b->red * color_b->alpha); + if (a != b) + return FALSE; + + a = _cairo_color_double_to_short (color_a->green * color_a->alpha); + b = _cairo_color_double_to_short (color_b->green * color_b->alpha); + if (a != b) + return FALSE; + + a = _cairo_color_double_to_short (color_a->blue * color_a->alpha); + b = _cairo_color_double_to_short (color_b->blue * color_b->alpha); + if (a != b) + return FALSE; + + return TRUE; +} diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c index 82a398181..27fc02c77 100644 --- a/src/cairo-gl-surface.c +++ b/src/cairo-gl-surface.c @@ -1253,8 +1253,8 @@ _cairo_gl_gradient_operand_init(cairo_gl_context_t *ctx, * Happens more often than you would believe. */ for (i = 1; i < gradient->n_stops; i++) { - if (! _cairo_color_equal (&gradient->stops[0].color, - &gradient->stops[i].color)) + if (! _cairo_color_stop_equal (&gradient->stops[0].color, + &gradient->stops[i].color)) { break; } diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 78aab5080..c3f63db10 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -887,8 +887,8 @@ _cairo_gstate_copy_pattern (cairo_pattern_t *pattern, * Happens more often than you would believe. */ for (i = 1; i < src->n_stops; i++) { - if (! _cairo_color_equal (&src->stops[0].color, - &src->stops[i].color)) + if (! _cairo_color_stop_equal (&src->stops[0].color, + &src->stops[i].color)) { break; } diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c index 85045270a..2fea11a2e 100644 --- a/src/cairo-pattern.c +++ b/src/cairo-pattern.c @@ -2294,8 +2294,8 @@ _cairo_pattern_acquire_surface (const cairo_pattern_t *pattern, * Happens more often than you would believe. */ for (i = 1; i < src->n_stops; i++) { - if (! _cairo_color_equal (&src->stops[0].color, - &src->stops[i].color)) + if (! _cairo_color_stop_equal (&src->stops[0].color, + &src->stops[i].color)) { break; } @@ -2767,7 +2767,7 @@ _cairo_gradient_color_stops_equal (const cairo_gradient_pattern_t *a, for (n = 0; n < a->n_stops; n++) { if (a->stops[n].offset != b->stops[n].offset) return FALSE; - if (! _cairo_color_equal (&a->stops[n].color, &b->stops[n].color)) + if (! _cairo_color_stop_equal (&a->stops[n].color, &b->stops[n].color)) return FALSE; } diff --git a/src/cairoint.h b/src/cairoint.h index 5cf0bcf7b..6fe370294 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -1309,6 +1309,10 @@ cairo_private cairo_bool_t _cairo_color_equal (const cairo_color_t *color_a, const cairo_color_t *color_b) cairo_pure; +cairo_private cairo_bool_t +_cairo_color_stop_equal (const cairo_color_t *color_a, + const cairo_color_t *color_b) cairo_pure; + /* cairo-font-face.c */ extern const cairo_private cairo_font_face_t _cairo_font_face_nil; diff --git a/src/drm/cairo-drm-intel.c b/src/drm/cairo-drm-intel.c index 4d69f8ab6..032647c39 100644 --- a/src/drm/cairo-drm-intel.c +++ b/src/drm/cairo-drm-intel.c @@ -1421,7 +1421,7 @@ _gradient_color_stops_equal (const cairo_gradient_pattern_t *a, return FALSE; } - if (! _cairo_color_equal (&a->stops[n].color, &b->stops[n].color)) + if (! _cairo_color_stop_equal (&a->stops[n].color, &b->stops[n].color)) return FALSE; }