diff options
Diffstat (limited to 'pixman/pixman-gradient-walker.c')
-rw-r--r-- | pixman/pixman-gradient-walker.c | 72 |
1 files changed, 61 insertions, 11 deletions
diff --git a/pixman/pixman-gradient-walker.c b/pixman/pixman-gradient-walker.c index dd666b4..ec5285e 100644 --- a/pixman/pixman-gradient-walker.c +++ b/pixman/pixman-gradient-walker.c @@ -28,10 +28,26 @@ #endif #include "pixman-private.h" -void +typedef struct +{ + uint32_t left_ag; + uint32_t left_rb; + uint32_t right_ag; + uint32_t right_rb; + int32_t left_x; + int32_t right_x; + int32_t stepper; + + const pixman_gradient_stop_t *stops; + int num_stops; + unsigned int spread; + + int need_reset; +} pixman_gradient_walker_t; + +static void _pixman_gradient_walker_init (pixman_gradient_walker_t *walker, - gradient_t * gradient, - unsigned int spread) + const gradient_t *gradient) { walker->num_stops = gradient->n_stops; walker->stops = gradient->stops; @@ -42,19 +58,19 @@ _pixman_gradient_walker_init (pixman_gradient_walker_t *walker, walker->left_rb = 0; walker->right_ag = 0; walker->right_rb = 0; - walker->spread = spread; + walker->spread = gradient->common.repeat; walker->need_reset = TRUE; } -void +static void _pixman_gradient_walker_reset (pixman_gradient_walker_t *walker, - pixman_fixed_32_32_t pos) + pixman_fixed_16_16_t pos) { int32_t x, left_x, right_x; - pixman_color_t *left_c, *right_c; + const pixman_color_t *left_c, *right_c; int n, count = walker->num_stops; - pixman_gradient_stop_t * stops = walker->stops; + const pixman_gradient_stop_t * stops = walker->stops; static const pixman_color_t transparent_black = { 0, 0, 0, 0 }; @@ -150,7 +166,7 @@ _pixman_gradient_walker_reset (pixman_gradient_walker_t *walker, if ((int32_t)pos & 0x10000) { - pixman_color_t *tmp_c; + const pixman_color_t *tmp_c; int32_t tmp_x; tmp_x = 0x10000 - right_x; @@ -220,9 +236,9 @@ _pixman_gradient_walker_reset (pixman_gradient_walker_t *walker, /* the following assumes that PIXMAN_GRADIENT_WALKER_NEED_RESET(w,x) is FALSE */ -uint32_t +static uint32_t _pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker, - pixman_fixed_32_32_t x) + pixman_fixed_16_16_t x) { int dist, idist; uint32_t t1, t2, a, color; @@ -252,3 +268,37 @@ _pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker, return (color | (t1 & 0xff00ff) | (t2 & 0xff00)); } +uint32_t * +gradient_walker_get_scanline_narrow (uint32_t *buffer, + int width, + const uint32_t *mask, + const gradient_t *gradient) +{ + pixman_gradient_walker_t walker; + int i; + pixman_fixed_16_16_t t; + uint32_t old_c; + + _pixman_gradient_walker_init (&walker, gradient); + + t = -1; + for (i = 0; i < width; i++) + { + if (buffer[i] == (uint32_t) -1) + { + buffer[i] = 0; + } + else if (!mask || *mask++) + { + if (t != buffer[i]) + { + t = buffer[i]; + old_c = _pixman_gradient_walker_pixel (&walker, buffer[i]); + } + + buffer[i] = old_c; + } + } + + return buffer; +} |