diff options
Diffstat (limited to 'gfx/cairo/pixman-dither.patch')
-rw-r--r-- | gfx/cairo/pixman-dither.patch | 310 |
1 files changed, 0 insertions, 310 deletions
diff --git a/gfx/cairo/pixman-dither.patch b/gfx/cairo/pixman-dither.patch deleted file mode 100644 index 633a8d7282..0000000000 --- a/gfx/cairo/pixman-dither.patch +++ /dev/null @@ -1,310 +0,0 @@ -diff --git a/gfx/cairo/libpixman/src/pixman-dither.h b/gfx/cairo/libpixman/src/pixman-dither.h -new file mode 100644 ---- /dev/null -+++ b/gfx/cairo/libpixman/src/pixman-dither.h -@@ -0,0 +1,51 @@ -+#define R16_BITS 5 -+#define G16_BITS 6 -+#define B16_BITS 5 -+ -+#define R16_SHIFT (B16_BITS + G16_BITS) -+#define G16_SHIFT (B16_BITS) -+#define B16_SHIFT 0 -+ -+#define MASK 0xff -+#define ONE_HALF 0x80 -+ -+#define A_SHIFT 8 * 3 -+#define R_SHIFT 8 * 2 -+#define G_SHIFT 8 -+#define A_MASK 0xff000000 -+#define R_MASK 0xff0000 -+#define G_MASK 0xff00 -+ -+#define RB_MASK 0xff00ff -+#define AG_MASK 0xff00ff00 -+#define RB_ONE_HALF 0x800080 -+#define RB_MASK_PLUS_ONE 0x10000100 -+ -+#define ALPHA_8(x) ((x) >> A_SHIFT) -+#define RED_8(x) (((x) >> R_SHIFT) & MASK) -+#define GREEN_8(x) (((x) >> G_SHIFT) & MASK) -+#define BLUE_8(x) ((x) & MASK) -+ -+// This uses the same dithering technique that Skia does. -+// It is essentially preturbing the lower bit based on the -+// high bit -+static inline uint16_t dither_32_to_16(uint32_t c) -+{ -+ uint8_t b = BLUE_8(c); -+ uint8_t g = GREEN_8(c); -+ uint8_t r = RED_8(c); -+ r = ((r << 1) - ((r >> (8 - R16_BITS) << (8 - R16_BITS)) | (r >> R16_BITS))) >> (8 - R16_BITS); -+ g = ((g << 1) - ((g >> (8 - G16_BITS) << (8 - G16_BITS)) | (g >> G16_BITS))) >> (8 - G16_BITS); -+ b = ((b << 1) - ((b >> (8 - B16_BITS) << (8 - B16_BITS)) | (b >> B16_BITS))) >> (8 - B16_BITS); -+ return ((r << R16_SHIFT) | (g << G16_SHIFT) | (b << B16_SHIFT)); -+} -+ -+static inline uint16_t dither_8888_to_0565(uint32_t color, pixman_bool_t toggle) -+{ -+ // alternate between a preturbed truncation and a regular truncation -+ if (toggle) { -+ return dither_32_to_16(color); -+ } else { -+ return CONVERT_8888_TO_0565(color); -+ } -+} -diff --git a/gfx/cairo/libpixman/src/pixman-linear-gradient.c b/gfx/cairo/libpixman/src/pixman-linear-gradient.c ---- a/gfx/cairo/libpixman/src/pixman-linear-gradient.c -+++ b/gfx/cairo/libpixman/src/pixman-linear-gradient.c -@@ -26,16 +26,18 @@ - */ - - #ifdef HAVE_CONFIG_H - #include <config.h> - #endif - #include <stdlib.h> - #include "pixman-private.h" - -+#include "pixman-dither.h" -+ - static pixman_bool_t - linear_gradient_is_horizontal (pixman_image_t *image, - int x, - int y, - int width, - int height) - { - linear_gradient_t *linear = (linear_gradient_t *)image; -@@ -222,25 +224,28 @@ linear_get_scanline_narrow (pixman_iter_ - return iter->buffer; - } - - static uint16_t convert_8888_to_0565(uint32_t color) - { - return CONVERT_8888_TO_0565(color); - } - -+ -+ - static uint32_t * - linear_get_scanline_16 (pixman_iter_t *iter, - const uint32_t *mask) - { - pixman_image_t *image = iter->image; - int x = iter->x; - int y = iter->y; - int width = iter->width; - uint16_t * buffer = (uint16_t*)iter->buffer; -+ pixman_bool_t toggle = ((x ^ y) & 1); - - pixman_vector_t v, unit; - pixman_fixed_32_32_t l; - pixman_fixed_48_16_t dx, dy; - gradient_t *gradient = (gradient_t *)image; - linear_gradient_t *linear = (linear_gradient_t *)image; - uint16_t *end = buffer + width; - pixman_gradient_walker_t walker; -@@ -294,34 +299,47 @@ linear_get_scanline_16 (pixman_iter_t * - t = ((dx * v.vector[0] + dy * v.vector[1]) - - (dx * linear->p1.x + dy * linear->p1.y) * v2) * invden; - inc = (dx * unit.vector[0] + dy * unit.vector[1]) * invden; - } - next_inc = 0; - - if (((pixman_fixed_32_32_t )(inc * width)) == 0) - { -- register uint16_t color; -+ register uint32_t color; -+ uint16_t dither_diff; -+ uint16_t color16; -+ uint16_t color16b; - -- color = convert_8888_to_0565(_pixman_gradient_walker_pixel (&walker, t)); -- while (buffer < end) -- *buffer++ = color; -+ color = _pixman_gradient_walker_pixel (&walker, t); -+ color16 = dither_8888_to_0565(color, toggle); -+ color16b = dither_8888_to_0565(color, toggle^1); -+ // compute the difference -+ dither_diff = color16 ^ color16b; -+ while (buffer < end) { -+ *buffer++ = color16; -+ // use dither_diff to toggle between color16 and color16b -+ color16 ^= dither_diff; -+ toggle ^= 1; -+ } - } - else - { - int i; - - i = 0; - while (buffer < end) - { - if (!mask || *mask++) - { -- *buffer = convert_8888_to_0565(_pixman_gradient_walker_pixel (&walker, -- t + next_inc)); -+ *buffer = dither_8888_to_0565(_pixman_gradient_walker_pixel (&walker, -+ t + next_inc), -+ toggle); - } -+ toggle ^= 1; - i++; - next_inc = inc * i; - buffer++; - } - } - } - else - { -@@ -340,18 +358,20 @@ linear_get_scanline_16 (pixman_iter_t * - - invden = pixman_fixed_1 * (double) pixman_fixed_1 / - (l * (double) v.vector[2]); - v2 = v.vector[2] * (1. / pixman_fixed_1); - t = ((dx * v.vector[0] + dy * v.vector[1]) - - (dx * linear->p1.x + dy * linear->p1.y) * v2) * invden; - } - -- *buffer = convert_8888_to_0565(_pixman_gradient_walker_pixel (&walker, t)); -+ *buffer = dither_8888_to_0565(_pixman_gradient_walker_pixel (&walker, t), -+ toggle); - } -+ toggle ^= 1; - - ++buffer; - - v.vector[0] += unit.vector[0]; - v.vector[1] += unit.vector[1]; - v.vector[2] += unit.vector[2]; - } - } -@@ -369,17 +389,18 @@ linear_get_scanline_wide (pixman_iter_t - pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); - - return buffer; - } - - void - _pixman_linear_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter) - { -- if (linear_gradient_is_horizontal ( -+ // XXX: we can't use this optimization when dithering -+ if (0 && linear_gradient_is_horizontal ( - iter->image, iter->x, iter->y, iter->width, iter->height)) - { - if (iter->flags & ITER_16) - linear_get_scanline_16 (iter, NULL); - else if (iter->flags & ITER_NARROW) - linear_get_scanline_narrow (iter, NULL); - else - linear_get_scanline_wide (iter, NULL); -diff --git a/gfx/cairo/libpixman/src/pixman-radial-gradient.c b/gfx/cairo/libpixman/src/pixman-radial-gradient.c ---- a/gfx/cairo/libpixman/src/pixman-radial-gradient.c -+++ b/gfx/cairo/libpixman/src/pixman-radial-gradient.c -@@ -29,16 +29,18 @@ - - #ifdef HAVE_CONFIG_H - #include <config.h> - #endif - #include <stdlib.h> - #include <math.h> - #include "pixman-private.h" - -+#include "pixman-dither.h" -+ - static inline pixman_fixed_32_32_t - dot (pixman_fixed_48_16_t x1, - pixman_fixed_48_16_t y1, - pixman_fixed_48_16_t z1, - pixman_fixed_48_16_t x2, - pixman_fixed_48_16_t y2, - pixman_fixed_48_16_t z2) - { -@@ -489,16 +491,17 @@ radial_get_scanline_16 (pixman_iter_t *i - * <=> for every p, the radiuses associated with the two t solutions - * have opposite sign - */ - pixman_image_t *image = iter->image; - int x = iter->x; - int y = iter->y; - int width = iter->width; - uint16_t *buffer = iter->buffer; -+ pixman_bool_t toggle = ((x ^ y) & 1); - - gradient_t *gradient = (gradient_t *)image; - radial_gradient_t *radial = (radial_gradient_t *)image; - uint16_t *end = buffer + width; - pixman_gradient_walker_t walker; - pixman_vector_t v, unit; - - /* reference point is the center of the pixel */ -@@ -575,25 +578,27 @@ radial_get_scanline_16 (pixman_iter_t *i - unit.vector[0], unit.vector[1], 0); - ddc = 2 * dot (unit.vector[0], unit.vector[1], 0, - unit.vector[0], unit.vector[1], 0); - - while (buffer < end) - { - if (!mask || *mask++) - { -- *buffer = convert_8888_to_0565( -+ *buffer = dither_8888_to_0565( - radial_compute_color (radial->a, b, c, - radial->inva, - radial->delta.radius, - radial->mindr, - &walker, -- image->common.repeat)); -+ image->common.repeat), -+ toggle); - } - -+ toggle ^= 1; - b += db; - c += dc; - dc += ddc; - ++buffer; - } - } - else - { -@@ -621,31 +626,33 @@ radial_get_scanline_16 (pixman_iter_t *i - radial->delta.x, radial->delta.y, - radial->delta.radius); - /* / pixman_fixed_1 / pixman_fixed_1 */ - - c = fdot (pdx, pdy, -radial->c1.radius, - pdx, pdy, radial->c1.radius); - /* / pixman_fixed_1 / pixman_fixed_1 */ - -- *buffer = convert_8888_to_0565 ( -+ *buffer = dither_8888_to_0565 ( - radial_compute_color (radial->a, b, c, - radial->inva, - radial->delta.radius, - radial->mindr, - &walker, -- image->common.repeat)); -+ image->common.repeat), -+ toggle); - } - else - { - *buffer = 0; - } - } - - ++buffer; -+ toggle ^= 1; - - v.vector[0] += unit.vector[0]; - v.vector[1] += unit.vector[1]; - v.vector[2] += unit.vector[2]; - } - } - - iter->y++; - |