summaryrefslogtreecommitdiff
path: root/pixman/pixman-gradient-walker.c
diff options
context:
space:
mode:
Diffstat (limited to 'pixman/pixman-gradient-walker.c')
-rw-r--r--pixman/pixman-gradient-walker.c72
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;
+}