1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/cairo/libpixman/src/pixman-dither.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,51 @@ 1.4 +#define R16_BITS 5 1.5 +#define G16_BITS 6 1.6 +#define B16_BITS 5 1.7 + 1.8 +#define R16_SHIFT (B16_BITS + G16_BITS) 1.9 +#define G16_SHIFT (B16_BITS) 1.10 +#define B16_SHIFT 0 1.11 + 1.12 +#define MASK 0xff 1.13 +#define ONE_HALF 0x80 1.14 + 1.15 +#define A_SHIFT 8 * 3 1.16 +#define R_SHIFT 8 * 2 1.17 +#define G_SHIFT 8 1.18 +#define A_MASK 0xff000000 1.19 +#define R_MASK 0xff0000 1.20 +#define G_MASK 0xff00 1.21 + 1.22 +#define RB_MASK 0xff00ff 1.23 +#define AG_MASK 0xff00ff00 1.24 +#define RB_ONE_HALF 0x800080 1.25 +#define RB_MASK_PLUS_ONE 0x10000100 1.26 + 1.27 +#define ALPHA_8(x) ((x) >> A_SHIFT) 1.28 +#define RED_8(x) (((x) >> R_SHIFT) & MASK) 1.29 +#define GREEN_8(x) (((x) >> G_SHIFT) & MASK) 1.30 +#define BLUE_8(x) ((x) & MASK) 1.31 + 1.32 +// This uses the same dithering technique that Skia does. 1.33 +// It is essentially preturbing the lower bit based on the 1.34 +// high bit 1.35 +static inline uint16_t dither_32_to_16(uint32_t c) 1.36 +{ 1.37 + uint8_t b = BLUE_8(c); 1.38 + uint8_t g = GREEN_8(c); 1.39 + uint8_t r = RED_8(c); 1.40 + r = ((r << 1) - ((r >> (8 - R16_BITS) << (8 - R16_BITS)) | (r >> R16_BITS))) >> (8 - R16_BITS); 1.41 + g = ((g << 1) - ((g >> (8 - G16_BITS) << (8 - G16_BITS)) | (g >> G16_BITS))) >> (8 - G16_BITS); 1.42 + b = ((b << 1) - ((b >> (8 - B16_BITS) << (8 - B16_BITS)) | (b >> B16_BITS))) >> (8 - B16_BITS); 1.43 + return ((r << R16_SHIFT) | (g << G16_SHIFT) | (b << B16_SHIFT)); 1.44 +} 1.45 + 1.46 +static inline uint16_t dither_8888_to_0565(uint32_t color, pixman_bool_t toggle) 1.47 +{ 1.48 + // alternate between a preturbed truncation and a regular truncation 1.49 + if (toggle) { 1.50 + return dither_32_to_16(color); 1.51 + } else { 1.52 + return convert_8888_to_0565(color); 1.53 + } 1.54 +}