pixman: Branch 'master'

Søren Sandmann Pedersen sandmann at kemper.freedesktop.org
Thu May 21 15:28:25 PDT 2009


 pixman/pixman-compute-region.c |    8 +-
 test/Makefile.am               |    4 +
 test/alpha-test.c              |  117 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 125 insertions(+), 4 deletions(-)

New commits:
commit 85b390cadf8c60808ed17df95885e72c082ad180
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Wed May 20 10:45:29 2009 -0400

    Fix alpha map computation in pixman_compute_composite_region()
    
    According to the RENDER spec, the origin of the alpha map is
    interpreted relative to the origin of the drawable of the image, not
    the origin of the drawable of the alpha map.
    
    This commit fixes that and adds an alpha-test.c test program.
    
    The only use of alpha maps I have been able to find is in Qt and they
    don't use a non-zero alpha origin.

diff --git a/pixman/pixman-compute-region.c b/pixman/pixman-compute-region.c
index 55bca18..31eaee8 100644
--- a/pixman/pixman-compute-region.c
+++ b/pixman/pixman-compute-region.c
@@ -178,8 +178,8 @@ pixman_compute_composite_region32 (pixman_region32_t *	pRegion,
     if (pSrc->common.alpha_map)
     {
 	if (!miClipPictureSrc (pRegion, (pixman_image_t *)pSrc->common.alpha_map,
-			       xDst - (xSrc + pSrc->common.alpha_origin.x),
-			       yDst - (ySrc + pSrc->common.alpha_origin.y)))
+			       xDst - (xSrc - pSrc->common.alpha_origin.x),
+			       yDst - (ySrc - pSrc->common.alpha_origin.y)))
 	{
 	    pixman_region32_fini (pRegion);
 	    return FALSE;
@@ -196,8 +196,8 @@ pixman_compute_composite_region32 (pixman_region32_t *	pRegion,
 	if (pMask->common.alpha_map)
 	{
 	    if (!miClipPictureSrc (pRegion, (pixman_image_t *)pMask->common.alpha_map,
-				   xDst - (xMask + pMask->common.alpha_origin.x),
-				   yDst - (yMask + pMask->common.alpha_origin.y)))
+				   xDst - (xMask - pMask->common.alpha_origin.x),
+				   yDst - (yMask - pMask->common.alpha_origin.y)))
 	    {
 		pixman_region32_fini (pRegion);
 		return FALSE;
diff --git a/test/Makefile.am b/test/Makefile.am
index cb8a5ef..be76dc8 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -23,6 +23,7 @@ TESTPROGRAMS +=			\
 	clip-in			\
 	composite-test		\
 	gradient-test		\
+	alpha-test		\
 	trap-test
 
 noinst_PROGRAMS = $(TESTPROGRAMS)
@@ -32,6 +33,9 @@ INCLUDES += $(GTK_CFLAGS)
 gradient_test_LDADD = $(GTK_LDADD)
 gradient_test_SOURCES = gradient-test.c utils.c utils.h
 
+alpha_test_LDADD = $(GTK_LDADD)
+alpha_test_SOURCES = alpha-test.c utils.c utils.h
+
 composite_test_LDADD = $(GTK_LDADD)
 composite_test_SOURCES = composite-test.c utils.c utils.h
 
diff --git a/test/alpha-test.c b/test/alpha-test.c
new file mode 100644
index 0000000..e2b97c7
--- /dev/null
+++ b/test/alpha-test.c
@@ -0,0 +1,117 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "pixman.h"
+#include "utils.h"
+
+int
+main (int argc, char **argv)
+{
+#define WIDTH 400
+#define HEIGHT 200
+    
+    uint32_t *alpha = malloc (WIDTH * HEIGHT * 4);
+    uint32_t *dest = malloc (WIDTH * HEIGHT * 4);
+    uint32_t *src = malloc (WIDTH * HEIGHT * 4);
+    pixman_image_t *grad_img;
+    pixman_image_t *alpha_img;
+    pixman_image_t *solid_img;
+    pixman_image_t *dest_img;
+    pixman_image_t *src_img;
+    int i;
+    pixman_gradient_stop_t stops[2] =
+	{
+	    { pixman_int_to_fixed (0), { 0x0000, 0x0000, 0x0000, 0x0000 } },
+	    { pixman_int_to_fixed (1), { 0xffff, 0x0000, 0x1111, 0xffff } }
+	};
+    pixman_point_fixed_t p1 = { pixman_double_to_fixed (0), 0 };
+    pixman_point_fixed_t p2 = { pixman_double_to_fixed (WIDTH),
+				pixman_int_to_fixed (0) };
+    pixman_transform_t trans = {
+	{ { pixman_double_to_fixed (2), pixman_double_to_fixed (0.5), pixman_double_to_fixed (-100), },
+	  { pixman_double_to_fixed (0), pixman_double_to_fixed (3), pixman_double_to_fixed (0), },
+	  { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), pixman_double_to_fixed (1.0) } 
+	}
+    };
+
+    pixman_transform_t id = {
+	{ { pixman_fixed_1, 0, 0 },
+	  { 0, pixman_fixed_1, 0 },
+	  { 0, 0, pixman_fixed_1 } }
+    };
+
+    pixman_point_fixed_t c_inner;
+    pixman_point_fixed_t c_outer;
+    pixman_fixed_t r_inner;
+    pixman_fixed_t r_outer;
+    pixman_color_t red = { 0xffff, 0x0000, 0x0000, 0xffff };
+    
+    for (i = 0; i < WIDTH * HEIGHT; ++i)
+	alpha[i] = 0x4f00004f; /* pale blue */
+    
+    alpha_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
+					 WIDTH, HEIGHT, 
+					  alpha,
+					 WIDTH * 4);
+
+    for (i = 0; i < WIDTH * HEIGHT; ++i)
+	dest[i] = 0xffffff00;		/* yellow */
+    
+    dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
+					 WIDTH, HEIGHT, 
+					 dest,
+					 WIDTH * 4);
+
+    for (i = 0; i < WIDTH * HEIGHT; ++i)
+	src[i] = 0xffff0000;
+
+    src_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
+					WIDTH, HEIGHT,
+					src,
+					WIDTH * 4);
+    
+    c_inner.x = pixman_double_to_fixed (50.0);
+    c_inner.y = pixman_double_to_fixed (50.0);
+    c_outer.x = pixman_double_to_fixed (50.0);
+    c_outer.y = pixman_double_to_fixed (50.0);
+    r_inner = 0;
+    r_outer = pixman_double_to_fixed (50.0);
+    
+#if 0
+    grad_img = pixman_image_create_conical_gradient (&c_inner, r_inner,
+						    stops, 2);
+#endif
+#if 0
+    grad_img = pixman_image_create_conical_gradient (&c_inner, r_inner,
+						    stops, 2);
+    grad_img = pixman_image_create_linear_gradient (&c_inner, &c_outer,
+						   r_inner, r_outer,
+						   stops, 2);
+#endif
+    
+    grad_img = pixman_image_create_linear_gradient  (&p1, &p2,
+						    stops, 2);
+
+    pixman_image_set_transform (grad_img, &id);
+    pixman_image_set_repeat (grad_img, PIXMAN_REPEAT_PAD);
+    
+    pixman_image_composite (PIXMAN_OP_OVER, grad_img, NULL, alpha_img,
+			    0, 0, 0, 0, 0, 0, 10 * WIDTH, HEIGHT);
+
+    pixman_image_set_alpha_map (src_img, alpha_img, 10, 10);
+    
+    pixman_image_composite (PIXMAN_OP_OVER, src_img, NULL, dest_img,
+			    0, 0, 0, 0, 0, 0, 10 * WIDTH, HEIGHT);
+    
+    printf ("0, 0: %x\n", dest[0]);
+    printf ("10, 10: %x\n", dest[10 * 10 + 10]);
+    printf ("w, h: %x\n", dest[(HEIGHT - 1) * 100 + (WIDTH - 1)]);
+    
+    show_image (dest_img);
+
+    pixman_image_unref (src_img);
+    pixman_image_unref (grad_img);
+    pixman_image_unref (alpha_img);
+    free (dest);
+    
+    return 0;
+}


More information about the xorg-commit mailing list