From d2ab45fed7bd38cde000a158294784bd2292ca26 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 30 Aug 2006 14:43:21 -0700 Subject: [PATCH] Bug #7497: Change _cairo_color_compute_shorts to not rely on any particular floating-point epsilon value. (cherry picked from b62710d4f8602203d848daf2d444865b611fff09 commit) --- src/cairo-color.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/cairo-color.c b/src/cairo-color.c index e202af249..a34883926 100644 --- a/src/cairo-color.c +++ b/src/cairo-color.c @@ -89,19 +89,27 @@ _cairo_color_init_rgb (cairo_color_t *color, _cairo_color_init_rgba (color, red, green, blue, 1.0); } -/* We multiply colors by (0x10000 - epsilon), such that we get a uniform - * range even for 0xffff. In other words, (1.0 - epsilon) would convert - * to 0xffff, not 0xfffe. +/* Convert a double in [0.0, 1.0] to an integer in [0, 65535] + * The conversion is designed to divide the input range into 65536 + * equally-sized regions. This is achieved by multiplying by 65536 and + * then special-casing the result of an input value of 1.0 so that it + * maps to 65535 instead of 65536. */ -#define CAIRO_COLOR_ONE_MINUS_EPSILON (65536.0 - 1e-5) +static inline uint16_t _color_to_short (double d) +{ + uint32_t i; + i = (uint32_t) (d * 65536); + i -= (i >> 16); + return i; +} static void _cairo_color_compute_shorts (cairo_color_t *color) { - color->red_short = color->red * color->alpha * CAIRO_COLOR_ONE_MINUS_EPSILON; - color->green_short = color->green * color->alpha * CAIRO_COLOR_ONE_MINUS_EPSILON; - color->blue_short = color->blue * color->alpha * CAIRO_COLOR_ONE_MINUS_EPSILON; - color->alpha_short = color->alpha * CAIRO_COLOR_ONE_MINUS_EPSILON; + color->red_short = _color_to_short (color->red * color->alpha); + color->green_short = _color_to_short (color->green * color->alpha); + color->blue_short = _color_to_short (color->blue * color->alpha); + color->alpha_short = _color_to_short (color->alpha); } void