diff --git a/gfx/cairo/cairo/src/cairo-fixed-private.h b/gfx/cairo/cairo/src/cairo-fixed-private.h index 35b3748d377..4114ef88e82 100644 --- a/gfx/cairo/cairo/src/cairo-fixed-private.h +++ b/gfx/cairo/cairo/src/cairo-fixed-private.h @@ -51,15 +51,12 @@ typedef cairo_int128_t cairo_fixed_96_32_t; /* Eventually, we should allow changing this, but I think * there are some assumptions in the tesselator about the - * size of a fixed type. + * size of a fixed type. For now, it must be 32. */ #define CAIRO_FIXED_BITS 32 -/* The number of fractional bits. Changing this involves - * making sure that you compute a double-to-fixed magic number. - * (see below). - */ -#define CAIRO_FIXED_FRAC_BITS 16 +/* The number of fractional bits. */ +#define CAIRO_FIXED_FRAC_BITS 8 /* A signed type CAIRO_FIXED_BITS in size; the main fixed point type */ typedef int32_t cairo_fixed_t; @@ -206,10 +203,25 @@ _cairo_fixed_integer_ceil (cairo_fixed_t f) static inline cairo_fixed_16_16_t _cairo_fixed_to_16_16 (cairo_fixed_t f) { -#if CAIRO_FIXED_FRAC_BITS > 16 +#if (CAIRO_FIXED_FRAC_BITS == 16) && (CAIRO_FIXED_BITS == 32) + return f; +#elif CAIRO_FIXED_FRAC_BITS > 16 return f >> (CAIRO_FIXED_FRAC_BITS - 16); #else - return f << (16 - CAIRO_FIXED_FRAC_BITS); + cairo_fixed_16_16_t x; + + /* Clamp to INT16 so that we don't get odd overflow or underflow by + * just shifting. + */ + if ((f >> CAIRO_FIXED_FRAC_BITS) < INT16_MIN) { + x = INT32_MIN; + } else if ((f >> CAIRO_FIXED_FRAC_BITS) > INT16_MAX) { + x = INT32_MAX; + } else { + x = f << (16 - CAIRO_FIXED_FRAC_BITS); + } + + return x; #endif }