summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <sandmann@redhat.com>2009-05-20 12:44:55 -0400
committerSøren Sandmann Pedersen <sandmann@redhat.com>2009-06-02 16:54:08 -0400
commit2557931bac461d8a0274ad638c12687afbe26145 (patch)
treef8a6d5f69857e4418361360b257ceb1b65c4abee
parent72ae714b7400db7282aa0f92cc740bc106685e54 (diff)
Handle alpha maps in _pixman_image_fetch_pixels()
-rw-r--r--pixman/pixman-bits-image.c124
-rw-r--r--pixman/pixman-transformed.c14
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;