diff options
author | Søren Sandmann Pedersen <sandmann@redhat.com> | 2009-05-20 12:44:55 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <sandmann@redhat.com> | 2009-06-02 16:54:08 -0400 |
commit | 2557931bac461d8a0274ad638c12687afbe26145 (patch) | |
tree | f8a6d5f69857e4418361360b257ceb1b65c4abee | |
parent | 72ae714b7400db7282aa0f92cc740bc106685e54 (diff) |
Handle alpha maps in _pixman_image_fetch_pixels()
-rw-r--r-- | pixman/pixman-bits-image.c | 124 | ||||
-rw-r--r-- | pixman/pixman-transformed.c | 14 |
2 files changed, 111 insertions, 27 deletions
diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c index a3642b7..c7b2cab 100644 --- a/pixman/pixman-bits-image.c +++ b/pixman/pixman-bits-image.c @@ -22,6 +22,7 @@ #include <config.h> #include <stdlib.h> +#include <string.h> #include "pixman-private.h" @@ -111,6 +112,103 @@ fbStore64 (bits_image_t * image, int x, int y, int width, uint64_t *buffer) store((pixman_image_t *)image, bits, buffer, x, width, indexed); } +/* On entry, @buffer should contain @n_pixels (x, y) coordinate pairs, where + * x and y are both uint32_ts. On exit, buffer will contain the corresponding + * pixels. + */ +static void +_pixman_image_fetch_raw_pixels (bits_image_t *image, uint32_t *buffer, int n_pixels) +{ + uint32_t *coords; + int i; + + coords = buffer; + + for (i = 0; i < n_pixels; ++i) + { + uint32_t x = *coords++; + uint32_t y = *coords++; + + if (x == 0xffffffff || y == 0xffffffff) + buffer[i] = 0; + else + buffer[i] = image->fetch_pixel (image, x, y); + } +} + +#define Alpha(x) ((x) >> 24) +#define Red(x) (((x) >> 16) & 0xff) +#define Green(x) (((x) >> 8) & 0xff) +#define Blue(x) ((x) & 0xff) + +void +_pixman_image_fetch_pixels (bits_image_t *image, uint32_t *buffer, int n_pixels) +{ +#define N_ALPHA_PIXELS 256 + + uint32_t alpha_pixels[N_ALPHA_PIXELS * 2]; + int i; + + if (!image->common.alpha_map) + { + _pixman_image_fetch_raw_pixels (image, buffer, n_pixels); + return; + } + + i = 0; + while (i < n_pixels) + { + int tmp_n_pixels = MIN (N_ALPHA_PIXELS, n_pixels - i); + int j; + int32_t *coords; + + memcpy (alpha_pixels, buffer + 2 * i, tmp_n_pixels * 2 * sizeof (int32_t)); + coords = (int32_t *)alpha_pixels; + for (j = 0; j < tmp_n_pixels; ++j) + { + int32_t x = coords[0]; + int32_t y = coords[1]; + + if (x != 0xffffffff) + { + x -= image->common.alpha_origin.x; + + if (x < 0 || x >= image->common.alpha_map->width) + x = 0xffffffff; + } + + if (y != 0xffffffff) + { + y -= image->common.alpha_origin.y; + + if (y < 0 || y >= image->common.alpha_map->height) + y = 0xffffffff; + } + + coords[0] = x; + coords[1] = y; + + coords += 2; + } + + _pixman_image_fetch_raw_pixels (image->common.alpha_map, alpha_pixels, tmp_n_pixels); + _pixman_image_fetch_raw_pixels (image, buffer + 2 * i, tmp_n_pixels); + + for (j = 0; j < tmp_n_pixels; ++j) + { + int a = alpha_pixels[j] >> 24; + + buffer[i] = + (a << 24) | + div_255 (Red (buffer[2 * i - j]) * a) << 16 | + div_255 (Green (buffer[2 * i - j]) * a) << 8 | + div_255 (Blue (buffer[2 * i - j]) * a); + + i++; + } + } +} + static void fbStoreExternalAlpha (bits_image_t * image, int x, int y, int width, uint32_t *buffer) @@ -196,7 +294,7 @@ bits_image_property_changed (pixman_image_t *image) image->common.get_scanline_64 = (scanFetchProc)_pixman_image_get_scanline_64_generic; image->common.get_scanline_32 = - (scanFetchProc)READ_ACCESS(fbFetchExternalAlpha); + (scanFetchProc)READ_ACCESS(fbFetchTransformed); } else if ((bits->common.repeat != PIXMAN_REPEAT_NONE) && bits->width == 1 && @@ -235,30 +333,6 @@ bits_image_property_changed (pixman_image_t *image) } } -/* On entry, @buffer should contain @n_pixels (x, y) coordinate pairs, where - * x and y are both uint32_ts. On exit, buffer will contain the corresponding - * pixels. - */ -void -_pixman_image_fetch_pixels (bits_image_t *image, uint32_t *buffer, int n_pixels) -{ - uint32_t *coords; - int i; - - coords = buffer; - - for (i = 0; i < n_pixels; ++i) - { - uint32_t x = *coords++; - uint32_t y = *coords++; - - if (x == 0xffffffff || y == 0xffffffff) - buffer[i] = 0; - else - buffer[i] = image->fetch_pixel (image, x, y); - } -} - void _pixman_image_store_scanline_32 (bits_image_t *image, int x, int y, int width, uint32_t *buffer) diff --git a/pixman/pixman-transformed.c b/pixman/pixman-transformed.c index 2b95a2e..dd0d7a2 100644 --- a/pixman/pixman-transformed.c +++ b/pixman/pixman-transformed.c @@ -111,6 +111,7 @@ fetch_pixels_src_clip (bits_image_t *image, uint32_t *buffer, int n_pixels) _pixman_image_fetch_pixels (image, buffer, n_pixels); } +/* Buffer contains list of integers on input, list of pixels on output */ static void fetch_extended (bits_image_t *image, uint32_t *buffer, int n_pixels) { @@ -183,7 +184,9 @@ fetch_extended (bits_image_t *image, uint32_t *buffer, int n_pixels) fetch_pixels_src_clip (image, buffer, n_pixels); } -/* Converts a list of fixed-point coordinates into a list of pixel values */ +/* Buffer contains list of fixed-point coordinates on input, + * a list of pixels on output + */ static void fetch_nearest_pixels (bits_image_t *image, uint32_t *buffer, int n_pixels) { @@ -266,6 +269,9 @@ fetch_nearest (bits_image_t *pict, } } +/* Buffer contains list of fixed-point coordinates on input, + * a list of pixels on output + */ static void fetch_bilinear_pixels (bits_image_t *image, uint32_t *buffer, int n_pixels) { @@ -463,6 +469,9 @@ fetch_bilinear (bits_image_t *pict, } } +/* Buffer contains list of fixed-point coordinates on input, + * a list of pixels on output + */ static void fetch_convolution_pixels (bits_image_t *image, uint32_t *buffer, int n_pixels) { @@ -577,7 +586,8 @@ fetch_convolution_pixels (bits_image_t *image, uint32_t *buffer, int n_pixels) } static void -fbFetchTransformed_Convolution(bits_image_t * pict, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits, +fbFetchTransformed_Convolution(bits_image_t * pict, int width, uint32_t *buffer, + uint32_t *mask, uint32_t maskBits, pixman_bool_t affine, pixman_vector_t v, pixman_vector_t unit) { fetchPixelProc32 fetch; |