pixman: Branch 'master' - 3 commits

Søren Sandmann Pedersen sandmann at kemper.freedesktop.org
Wed Feb 16 03:08:28 PST 2011


 Makefile.am              |    2 
 configure.ac             |    1 
 demos/Makefile.am        |   34 ++++++++
 demos/alpha-test.c       |  117 +++++++++++++++++++++++++++
 demos/clip-in.c          |   50 +++++++++++
 demos/clip-test.c        |   97 +++++++++++++++++++++++
 demos/composite-test.c   |  191 +++++++++++++++++++++++++++++++++++++++++++++
 demos/convolution-test.c |   47 +++++++++++
 demos/gradient-test.c    |   89 +++++++++++++++++++++
 demos/gtk-utils.c        |  115 +++++++++++++++++++++++++++
 demos/gtk-utils.h        |   13 +++
 demos/radial-test.c      |  198 +++++++++++++++++++++++++++++++++++++++++++++++
 demos/screen-test.c      |   44 ++++++++++
 demos/trap-test.c        |   49 +++++++++++
 test/Makefile.am         |  104 ------------------------
 test/alpha-test.c        |  117 ---------------------------
 test/clip-in.c           |   50 -----------
 test/clip-test.c         |   97 -----------------------
 test/composite-test.c    |  191 ---------------------------------------------
 test/convolution-test.c  |   47 -----------
 test/gradient-test.c     |   89 ---------------------
 test/gtk-utils.c         |  115 ---------------------------
 test/gtk-utils.h         |   13 ---
 test/radial-test.c       |  198 -----------------------------------------------
 test/screen-test.c       |   44 ----------
 test/trap-test.c         |   49 -----------
 26 files changed, 1049 insertions(+), 1112 deletions(-)

New commits:
commit 1feaf6bea707a97db44643c5bfa6218afea9b6be
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Tue Jan 18 19:40:53 2011 -0500

    test/Makefile.am: Move all the TEST_LDADD into a new global LDADD.
    
    This gets rid of a bunch of replicated *_LDADD clauses

diff --git a/test/Makefile.am b/test/Makefile.am
index 0f03153..3ce466e 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,7 +1,6 @@
 AM_CFLAGS = @OPENMP_CFLAGS@
 AM_LDFLAGS = @OPENMP_CFLAGS@ @TESTPROGS_EXTRA_LDFLAGS@
-
-TEST_LDADD = $(top_builddir)/pixman/libpixman-1.la -lm
+LDADD = $(top_builddir)/pixman/libpixman-1.la -lm
 INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman
 
 TESTPROGRAMS =			\
@@ -22,46 +21,15 @@ TESTPROGRAMS =			\
 	affine-test		\
 	composite
 
-a1_trap_test_LDADD = $(TEST_LDADD)
-
-fetch_test_LDADD = $(TEST_LDADD)
-
-trap_crasher_LDADD = $(TEST_LDADD)
-
-oob_test_LDADD = $(TEST_LDADD)
-
-scaling_crash_test_LDADD = $(TEST_LDADD)
-
-region_translate_test_LDADD = $(TEST_LDADD)
-
-pdf_op_test_LDADD = $(TEST_LDADD)
 pdf_op_test_SOURCES = pdf-op-test.c utils.c utils.h
-
-region_test_LDADD = $(TEST_LDADD)
 region_test_SOURCES = region-test.c utils.c utils.h
-
-blitters_test_LDADD = $(TEST_LDADD)
 blitters_test_SOURCES = blitters-test.c utils.c utils.h
-
-scaling_test_LDADD = $(TEST_LDADD)
 scaling_test_SOURCES = scaling-test.c utils.c utils.h
-
-affine_test_LDADD = $(TEST_LDADD)
 affine_test_SOURCES = affine-test.c utils.c utils.h
-
-alphamap_LDADD = $(TEST_LDADD)
 alphamap_SOURCES = alphamap.c utils.c utils.h
-
-alpha_loop_LDADD = $(TEST_LDADD)
 alpha_loop_SOURCES = alpha-loop.c utils.c utils.h
-
-composite_LDADD = $(TEST_LDADD)
 composite_SOURCES = composite.c utils.c utils.h
-
-gradient_crash_test_LDADD = $(TEST_LDADD)
 gradient_crash_test_SOURCES = gradient-crash-test.c utils.c utils.h
-
-stress_test_LDADD = $(TEST_LDADD)
 stress_test_SOURCES = stress-test.c utils.c utils.h
 
 # Benchmarks
@@ -70,7 +38,6 @@ BENCHMARKS =			\
 	lowlevel-blt-bench
 
 lowlevel_blt_bench_SOURCES = lowlevel-blt-bench.c utils.c utils.h
-lowlevel_blt_bench_LDADD = $(TEST_LDADD)
 
 noinst_PROGRAMS = $(TESTPROGRAMS) $(BENCHMARKS)
 
commit 1237fd9bc84a27f232ceddf1c7b72645fcc99aec
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Tue Jan 18 19:20:18 2011 -0500

    Add @TESTPROGS_EXTRA_LDFLAGS@ to AM_LDFLAGS
    
    Instead of explicitly adding it to each test program.

diff --git a/test/Makefile.am b/test/Makefile.am
index 92ee8fd..0f03153 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,5 +1,5 @@
 AM_CFLAGS = @OPENMP_CFLAGS@
-AM_LDFLAGS = @OPENMP_CFLAGS@
+AM_LDFLAGS = @OPENMP_CFLAGS@ @TESTPROGS_EXTRA_LDFLAGS@
 
 TEST_LDADD = $(top_builddir)/pixman/libpixman-1.la -lm
 INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman
@@ -23,61 +23,45 @@ TESTPROGRAMS =			\
 	composite
 
 a1_trap_test_LDADD = $(TEST_LDADD)
-a1_trap_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 
 fetch_test_LDADD = $(TEST_LDADD)
-fetch_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 
 trap_crasher_LDADD = $(TEST_LDADD)
-trap_crasher_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 
 oob_test_LDADD = $(TEST_LDADD)
-oob_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 
 scaling_crash_test_LDADD = $(TEST_LDADD)
-scaling_crash_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 
 region_translate_test_LDADD = $(TEST_LDADD)
-region_translate_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 
 pdf_op_test_LDADD = $(TEST_LDADD)
-pdf_op_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 pdf_op_test_SOURCES = pdf-op-test.c utils.c utils.h
 
 region_test_LDADD = $(TEST_LDADD)
-region_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 region_test_SOURCES = region-test.c utils.c utils.h
 
 blitters_test_LDADD = $(TEST_LDADD)
-blitters_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 blitters_test_SOURCES = blitters-test.c utils.c utils.h
 
 scaling_test_LDADD = $(TEST_LDADD)
-scaling_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 scaling_test_SOURCES = scaling-test.c utils.c utils.h
 
 affine_test_LDADD = $(TEST_LDADD)
-affine_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 affine_test_SOURCES = affine-test.c utils.c utils.h
 
 alphamap_LDADD = $(TEST_LDADD)
-alphamap_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 alphamap_SOURCES = alphamap.c utils.c utils.h
 
 alpha_loop_LDADD = $(TEST_LDADD)
-alpha_loop_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 alpha_loop_SOURCES = alpha-loop.c utils.c utils.h
 
 composite_LDADD = $(TEST_LDADD)
-composite_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 composite_SOURCES = composite.c utils.c utils.h
 
 gradient_crash_test_LDADD = $(TEST_LDADD)
-gradient_crash_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 gradient_crash_test_SOURCES = gradient-crash-test.c utils.c utils.h
 
 stress_test_LDADD = $(TEST_LDADD)
-stress_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 stress_test_SOURCES = stress-test.c utils.c utils.h
 
 # Benchmarks
commit 7dfe845786920d50c6f93165ef6f539e6f4d1b53
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Tue Jan 18 19:16:39 2011 -0500

    Move all the GTK+ based test programs to a new subdir, "demos"
    
    This separates the test suite from the random gtk+ using test
    programs. "demos" is somewhat misleading because the programs there
    are not particularly exciting (with the possible exception of
    composite-test which shows off all the compositing operators).

diff --git a/Makefile.am b/Makefile.am
index 63b08c1..062c58a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = pixman test
+SUBDIRS = pixman test demos
 
 pkgconfigdir=$(libdir)/pkgconfig
 pkgconfig_DATA=pixman-1.pc
diff --git a/configure.ac b/configure.ac
index ab2ecde..5242799 100644
--- a/configure.ac
+++ b/configure.ac
@@ -794,6 +794,7 @@ AC_OUTPUT([pixman-1.pc
            Makefile
 	   pixman/Makefile
 	   pixman/pixman-version.h
+	   demos/Makefile
 	   test/Makefile])
 
 m4_if(m4_eval(pixman_minor % 2), [1], [
diff --git a/demos/Makefile.am b/demos/Makefile.am
new file mode 100644
index 0000000..2dcdfd3
--- /dev/null
+++ b/demos/Makefile.am
@@ -0,0 +1,34 @@
+if HAVE_GTK
+
+AM_CFLAGS = @OPENMP_CFLAGS@
+AM_LDFLAGS = @OPENMP_CFLAGS@
+
+LDADD = $(GTK_LIBS) $(top_builddir)/pixman/libpixman-1.la -lm 
+INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman $(GTK_CFLAGS)
+
+GTK_UTILS = gtk-utils.c gtk-utils.h
+
+DEMOS =				\
+	clip-test		\
+	clip-in			\
+	composite-test		\
+	gradient-test		\
+	radial-test		\
+	alpha-test		\
+	screen-test		\
+	convolution-test	\
+	trap-test
+
+gradient_test_SOURCES = gradient-test.c $(GTK_UTILS)
+alpha_test_SOURCES = alpha-test.c $(GTK_UTILS)
+composite_test_SOURCES = composite-test.c $(GTK_UTILS)
+clip_test_SOURCES = clip-test.c $(GTK_UTILS)
+clip_in_SOURCES = clip-in.c $(GTK_UTILS)
+trap_test_SOURCES = trap-test.c $(GTK_UTILS)
+screen_test_SOURCES = screen-test.c $(GTK_UTILS)
+convolution_test_SOURCES = convolution-test.c $(GTK_UTILS)
+radial_test_SOURCES = radial-test.c ../test/utils.c ../test/utils.h $(GTK_UTILS)
+
+noinst_PROGRAMS = $(DEMOS)
+
+endif
diff --git a/demos/alpha-test.c b/demos/alpha-test.c
new file mode 100644
index 0000000..92c2081
--- /dev/null
+++ b/demos/alpha-test.c
@@ -0,0 +1,117 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "pixman.h"
+#include "gtk-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 *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) };
+#if 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) } 
+	}
+    };
+#else
+    pixman_transform_t trans = {
+	{ { pixman_fixed_1, 0, 0 },
+	  { 0, pixman_fixed_1, 0 },
+	  { 0, 0, pixman_fixed_1 } }
+    };
+#endif
+
+    pixman_point_fixed_t c_inner;
+    pixman_point_fixed_t c_outer;
+    pixman_fixed_t r_inner;
+    pixman_fixed_t r_outer;
+    
+    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, &trans);
+    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;
+}
diff --git a/demos/clip-in.c b/demos/clip-in.c
new file mode 100644
index 0000000..5157981
--- /dev/null
+++ b/demos/clip-in.c
@@ -0,0 +1,50 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "pixman.h"
+#include "gtk-utils.h"
+
+/* This test demonstrates that clipping is done totally different depending
+ * on whether the source is transformed or not.
+ */
+int
+main (int argc, char **argv)
+{
+#define WIDTH 200
+#define HEIGHT 200
+
+#define SMALL 25
+    
+    uint32_t *sbits = malloc (SMALL * SMALL * 4);
+    uint32_t *bits = malloc (WIDTH * HEIGHT * 4);
+    pixman_transform_t trans = {
+    {
+	{ pixman_double_to_fixed (1.0), pixman_double_to_fixed (0), pixman_double_to_fixed (-0.1), },
+	{ pixman_double_to_fixed (0), pixman_double_to_fixed (1), pixman_double_to_fixed (-0.1), },
+	{ pixman_double_to_fixed (0), pixman_double_to_fixed (0), pixman_double_to_fixed (1.0) }
+    } };
+	  
+    pixman_image_t *src_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, SMALL, SMALL, sbits, 4 * SMALL);
+    pixman_image_t *dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, bits, 4 * WIDTH);
+
+    memset (bits, 0xff, WIDTH * HEIGHT * 4);
+    memset (sbits, 0x00, SMALL * SMALL * 4);
+
+    pixman_image_composite (PIXMAN_OP_IN,
+			    src_img, NULL, dest_img,
+			    0, 0, 0, 0, SMALL, SMALL, 200, 200);
+    
+    pixman_image_set_transform (src_img, &trans);
+    
+    pixman_image_composite (PIXMAN_OP_IN,
+			    src_img, NULL, dest_img,
+			    0, 0, 0, 0, SMALL * 2, SMALL * 2, 200, 200);
+    
+    show_image (dest_img);
+    
+    pixman_image_unref (src_img);
+    pixman_image_unref (dest_img);
+    free (bits);
+    
+    return 0;
+}
diff --git a/demos/clip-test.c b/demos/clip-test.c
new file mode 100644
index 0000000..aa0df44
--- /dev/null
+++ b/demos/clip-test.c
@@ -0,0 +1,97 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "pixman.h"
+#include "gtk-utils.h"
+
+#define WIDTH 200
+#define HEIGHT 200
+    
+static pixman_image_t *
+create_solid_bits (uint32_t pixel)
+{
+    uint32_t *pixels = malloc (WIDTH * HEIGHT * 4);
+    int i;
+    
+    for (i = 0; i < WIDTH * HEIGHT; ++i)
+	pixels[i] = pixel;
+
+    return pixman_image_create_bits (PIXMAN_a8r8g8b8,
+				     WIDTH, HEIGHT, 
+				     pixels,
+				     WIDTH * 4);
+}
+
+int
+main (int argc, char **argv)
+{
+    pixman_image_t *gradient_img;
+    pixman_image_t *src_img, *dst_img;
+    pixman_gradient_stop_t stops[2] =
+	{
+	    { pixman_int_to_fixed (0), { 0xffff, 0x0000, 0x0000, 0xffff } },
+	    { pixman_int_to_fixed (1), { 0xffff, 0xffff, 0x0000, 0xffff } }
+	};
+#if 0
+    pixman_point_fixed_t p1 = { 0, 0 };
+    pixman_point_fixed_t p2 = { pixman_int_to_fixed (WIDTH),
+				pixman_int_to_fixed (HEIGHT) };
+#endif
+    pixman_point_fixed_t c_inner;
+    pixman_point_fixed_t c_outer;
+    pixman_fixed_t r_inner;
+    pixman_fixed_t r_outer;
+    pixman_region32_t clip_region;
+    pixman_transform_t trans = {
+	{ { pixman_double_to_fixed (1.3), pixman_double_to_fixed (0), pixman_double_to_fixed (-0.5), },
+	  { pixman_double_to_fixed (0), pixman_double_to_fixed (1), pixman_double_to_fixed (-0.5), },
+	  { pixman_double_to_fixed (0), pixman_double_to_fixed (0), pixman_double_to_fixed (1.0) } 
+	}
+    };
+    
+    src_img = create_solid_bits (0xff0000ff);
+    
+    c_inner.x = pixman_double_to_fixed (100.0);
+    c_inner.y = pixman_double_to_fixed (100.0);
+    c_outer.x = pixman_double_to_fixed (100.0);
+    c_outer.y = pixman_double_to_fixed (100.0);
+    r_inner = 0;
+    r_outer = pixman_double_to_fixed (100.0);
+    
+    gradient_img = pixman_image_create_radial_gradient (&c_inner, &c_outer,
+							r_inner, r_outer,
+							stops, 2);
+
+#if 0
+    gradient_img = pixman_image_create_linear_gradient  (&p1, &p2,
+							 stops, 2);
+    
+#endif
+
+    pixman_image_composite (PIXMAN_OP_OVER, gradient_img, NULL, src_img,
+			    0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
+    
+    pixman_region32_init_rect (&clip_region, 50, 0, 100, 200);
+    pixman_image_set_clip_region32 (src_img, &clip_region);
+    pixman_image_set_source_clipping (src_img, TRUE);
+    pixman_image_set_has_client_clip (src_img, TRUE);
+    pixman_image_set_transform (src_img, &trans);
+    pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL);
+    
+    dst_img = create_solid_bits (0xffff0000);
+    pixman_image_composite (PIXMAN_OP_OVER, src_img, NULL, dst_img,
+			    0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
+    
+
+#if 0
+    printf ("0, 0: %x\n", src[0]);
+    printf ("10, 10: %x\n", src[10 * 10 + 10]);
+    printf ("w, h: %x\n", src[(HEIGHT - 1) * 100 + (WIDTH - 1)]);
+#endif
+    
+    show_image (dst_img);
+    
+    pixman_image_unref (gradient_img);
+    pixman_image_unref (src_img);
+    
+    return 0;
+}
diff --git a/demos/composite-test.c b/demos/composite-test.c
new file mode 100644
index 0000000..f5f352f
--- /dev/null
+++ b/demos/composite-test.c
@@ -0,0 +1,191 @@
+#include <gtk/gtk.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "pixman.h"
+#include "gtk-utils.h"
+
+#define WIDTH	60
+#define HEIGHT	60
+
+typedef struct {
+    const char *name;
+    pixman_op_t op;
+} operator_t;
+
+static const operator_t operators[] = {
+    { "CLEAR",		PIXMAN_OP_CLEAR },
+    { "SRC",		PIXMAN_OP_SRC },
+    { "DST",		PIXMAN_OP_DST },
+    { "OVER",		PIXMAN_OP_OVER },
+    { "OVER_REVERSE",	PIXMAN_OP_OVER_REVERSE },
+    { "IN",		PIXMAN_OP_IN },
+    { "IN_REVERSE",	PIXMAN_OP_IN_REVERSE },
+    { "OUT",		PIXMAN_OP_OUT },
+    { "OUT_REVERSE",	PIXMAN_OP_OUT_REVERSE },
+    { "ATOP",		PIXMAN_OP_ATOP },
+    { "ATOP_REVERSE",	PIXMAN_OP_ATOP_REVERSE },
+    { "XOR",		PIXMAN_OP_XOR },
+    { "ADD",		PIXMAN_OP_ADD },
+    { "SATURATE",	PIXMAN_OP_SATURATE },
+
+    { "MULTIPLY",	PIXMAN_OP_MULTIPLY },
+    { "SCREEN",		PIXMAN_OP_SCREEN },
+    { "OVERLAY",	PIXMAN_OP_OVERLAY },
+    { "DARKEN",		PIXMAN_OP_DARKEN },
+    { "LIGHTEN",	PIXMAN_OP_LIGHTEN },
+    { "COLOR_DODGE",	PIXMAN_OP_COLOR_DODGE },
+    { "COLOR_BURN",	PIXMAN_OP_COLOR_BURN },
+    { "HARD_LIGHT",	PIXMAN_OP_HARD_LIGHT },
+    { "SOFT_LIGHT",	PIXMAN_OP_SOFT_LIGHT },
+    { "DIFFERENCE",	PIXMAN_OP_DIFFERENCE },
+    { "EXCLUSION",	PIXMAN_OP_EXCLUSION },
+    { "HSL_HUE",	PIXMAN_OP_HSL_HUE },
+    { "HSL_SATURATION",	PIXMAN_OP_HSL_SATURATION },
+    { "HSL_COLOR",	PIXMAN_OP_HSL_COLOR },
+    { "HSL_LUMINOSITY",	PIXMAN_OP_HSL_LUMINOSITY },
+};
+
+static uint32_t
+reader (const void *src, int size)
+{
+    switch (size)
+    {
+    case 1:
+	return *(uint8_t *)src;
+    case 2:
+	return *(uint16_t *)src;
+    case 4:
+	return *(uint32_t *)src;
+    default:
+	g_assert_not_reached();
+    }
+}
+
+static void
+writer (void *src, uint32_t value, int size)
+{
+    switch (size)
+    {
+    case 1:
+	*(uint8_t *)src = value;
+	break;
+
+    case 2:
+	*(uint16_t *)src = value;
+	break;
+
+    case 4:
+	*(uint32_t *)src = value;
+	break;
+
+    default:
+        break;
+    }
+}
+
+int
+main (int argc, char **argv)
+{
+#define d2f pixman_double_to_fixed
+    
+    GtkWidget *window, *swindow;
+    GtkWidget *table;
+    uint32_t *dest = malloc (WIDTH * HEIGHT * 4);
+    uint32_t *src = malloc (WIDTH * HEIGHT * 4);
+    pixman_image_t *src_img;
+    pixman_image_t *dest_img;
+    pixman_point_fixed_t p1 = { -10 << 0, 0 };
+    pixman_point_fixed_t p2 = { WIDTH << 16, (HEIGHT - 10) << 16 };
+    uint16_t full = 0xcfff;
+    uint16_t low  = 0x5000;
+    uint16_t alpha = 0xffff;
+    pixman_gradient_stop_t stops[6] =
+    {
+	{ d2f (0.0), { full, low, low, alpha } },
+	{ d2f (0.25), { full, full, low, alpha } },
+	{ d2f (0.4), { low, full, low, alpha } },
+	{ d2f (0.6), { low, full, full, alpha } },
+	{ d2f (0.8), { low, low, full, alpha } },
+	{ d2f (1.0), { full, low, full, alpha } },
+    };
+
+    int i;
+
+    gtk_init (&argc, &argv);
+
+    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+    gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);
+    
+    g_signal_connect (window, "delete-event",
+		      G_CALLBACK (gtk_main_quit),
+		      NULL);
+    table = gtk_table_new (G_N_ELEMENTS (operators) / 6, 6, TRUE);
+
+    src_img = pixman_image_create_linear_gradient (&p1, &p2, stops,
+						   sizeof (stops) / sizeof (stops[0]));
+
+    pixman_image_set_repeat (src_img, PIXMAN_REPEAT_PAD);
+    
+    dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
+					 WIDTH, HEIGHT,
+					 dest,
+					 WIDTH * 4);
+    pixman_image_set_accessors (dest_img, reader, writer);
+
+    for (i = 0; i < G_N_ELEMENTS (operators); ++i)
+    {
+	GtkWidget *image;
+	GdkPixbuf *pixbuf;
+	GtkWidget *vbox;
+	GtkWidget *label;
+	int j, k;
+
+	vbox = gtk_vbox_new (FALSE, 0);
+
+	label = gtk_label_new (operators[i].name);
+	gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 6);
+	gtk_widget_show (label);
+
+	for (j = 0; j < HEIGHT; ++j)
+	{
+	    for (k = 0; k < WIDTH; ++k)
+		dest[j * WIDTH + k] = 0x7f6f6f00;
+	}
+	pixman_image_composite (operators[i].op, src_img, NULL, dest_img,
+				0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
+	pixbuf = pixbuf_from_argb32 (pixman_image_get_data (dest_img), TRUE,
+				     WIDTH, HEIGHT, WIDTH * 4);
+	image = gtk_image_new_from_pixbuf (pixbuf);
+	gtk_box_pack_start (GTK_BOX (vbox), image, FALSE, FALSE, 0);
+	gtk_widget_show (image);
+
+	gtk_table_attach_defaults (GTK_TABLE (table), vbox,
+				   i % 6, (i % 6) + 1, i / 6, (i / 6) + 1);
+	gtk_widget_show (vbox);
+
+	g_object_unref (pixbuf);
+    }
+
+    pixman_image_unref (src_img);
+    free (src);
+    pixman_image_unref (dest_img);
+    free (dest);
+
+    swindow = gtk_scrolled_window_new (NULL, NULL);
+    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
+				    GTK_POLICY_AUTOMATIC,
+				    GTK_POLICY_AUTOMATIC);
+    
+    gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (swindow), table);
+    gtk_widget_show (table);
+
+    gtk_container_add (GTK_CONTAINER (window), swindow);
+    gtk_widget_show (swindow);
+
+    gtk_widget_show (window);
+
+    gtk_main ();
+
+    return 0;
+}
diff --git a/demos/convolution-test.c b/demos/convolution-test.c
new file mode 100644
index 0000000..da284af
--- /dev/null
+++ b/demos/convolution-test.c
@@ -0,0 +1,47 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "pixman.h"
+#include "gtk-utils.h"
+
+int
+main (int argc, char **argv)
+{
+#define WIDTH 200
+#define HEIGHT 200
+
+#define d2f pixman_double_to_fixed
+    
+    uint32_t *src = malloc (WIDTH * HEIGHT * 4);
+    uint32_t *mask = malloc (WIDTH * HEIGHT * 4);
+    uint32_t *dest = malloc (WIDTH * HEIGHT * 4);
+    pixman_fixed_t convolution[] =
+    {
+	d2f (3), d2f (3),
+	d2f (0.5), d2f (0.5), d2f (0.5),
+	d2f (0.5), d2f (0.5), d2f (0.5),
+	d2f (0.5), d2f (0.5), d2f (0.5),
+    };
+    pixman_image_t *simg, *mimg, *dimg;
+
+    int i;
+
+    for (i = 0; i < WIDTH * HEIGHT; ++i)
+    {
+	src[i] = 0x7f007f00;
+	mask[i] = (i % 256) * 0x01000000;
+	dest[i] = 0;
+    }
+
+    simg = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, src, WIDTH * 4);
+    mimg = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, mask, WIDTH * 4);
+    dimg = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, dest, WIDTH * 4);
+
+    pixman_image_set_filter (mimg, PIXMAN_FILTER_CONVOLUTION,
+			     convolution, 11);
+
+    pixman_image_composite (PIXMAN_OP_OVER, simg, mimg, dimg, 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
+
+    show_image (dimg);
+    
+    return 0;
+}
diff --git a/demos/gradient-test.c b/demos/gradient-test.c
new file mode 100644
index 0000000..fc84844
--- /dev/null
+++ b/demos/gradient-test.c
@@ -0,0 +1,89 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "pixman.h"
+#include "gtk-utils.h"
+
+int
+main (int argc, char **argv)
+{
+#define WIDTH 400
+#define HEIGHT 200
+    
+    uint32_t *dest = malloc (WIDTH * HEIGHT * 4);
+    pixman_image_t *src_img;
+    pixman_image_t *dest_img;
+    int i;
+    pixman_gradient_stop_t stops[2] =
+	{
+	    { pixman_int_to_fixed (0), { 0xffff, 0xeeee, 0xeeee, 0xeeee } },
+	    { pixman_int_to_fixed (1), { 0xffff, 0x1111, 0x1111, 0x1111 } }
+	};
+    pixman_point_fixed_t p1 = { pixman_double_to_fixed (0), 0 };
+    pixman_point_fixed_t p2 = { pixman_double_to_fixed (WIDTH / 8.),
+				pixman_int_to_fixed (0) };
+#if 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) } 
+	}
+    };
+#else
+    pixman_transform_t trans = {
+	{ { pixman_fixed_1, 0, 0 },
+	  { 0, pixman_fixed_1, 0 },
+	  { 0, 0, pixman_fixed_1 } }
+    };
+#endif
+
+    pixman_point_fixed_t c_inner;
+    pixman_point_fixed_t c_outer;
+    pixman_fixed_t r_inner;
+    pixman_fixed_t r_outer;
+    
+    for (i = 0; i < WIDTH * HEIGHT; ++i)
+	dest[i] = 0x4f00004f; /* pale blue */
+    
+    dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
+					 WIDTH, HEIGHT, 
+					 dest,
+					 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);
+    
+    src_img = pixman_image_create_conical_gradient (&c_inner, r_inner,
+						    stops, 2);
+#if 0
+    src_img = pixman_image_create_conical_gradient (&c_inner, r_inner,
+						    stops, 2);
+    src_img = pixman_image_create_linear_gradient (&c_inner, &c_outer,
+						   r_inner, r_outer,
+						   stops, 2);
+#endif
+    
+    src_img = pixman_image_create_linear_gradient  (&p1, &p2,
+						    stops, 2);
+    
+    pixman_image_set_transform (src_img, &trans);
+    pixman_image_set_repeat (src_img, PIXMAN_REPEAT_PAD);
+    
+    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 (dest_img);
+    free (dest);
+    
+    return 0;
+}
diff --git a/demos/gtk-utils.c b/demos/gtk-utils.c
new file mode 100644
index 0000000..0e7cb5c
--- /dev/null
+++ b/demos/gtk-utils.c
@@ -0,0 +1,115 @@
+#include <gtk/gtk.h>
+#include <config.h>
+#include "pixman-private.h"	/* For image->bits.format
+				 * FIXME: there should probably be public API for this
+				 */
+#include "gtk-utils.h"
+
+GdkPixbuf *
+pixbuf_from_argb32 (uint32_t *bits,
+		    gboolean has_alpha,
+		    int width,
+		    int height,
+		    int stride)
+{
+    GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE,
+					8, width, height);
+    int p_stride = gdk_pixbuf_get_rowstride (pixbuf);
+    guint32 *p_bits = (guint32 *)gdk_pixbuf_get_pixels (pixbuf);
+    int w, h;
+    
+    for (h = 0; h < height; ++h)
+    {
+	for (w = 0; w < width; ++w)
+	{
+	    uint32_t argb = bits[h * (stride / 4) + w];
+	    guint r, g, b, a;
+	    char *pb = (char *)p_bits;
+
+	    pb += h * p_stride + w * 4;
+
+	    r = (argb & 0x00ff0000) >> 16;
+	    g = (argb & 0x0000ff00) >> 8;
+	    b = (argb & 0x000000ff) >> 0;
+	    a = has_alpha? (argb & 0xff000000) >> 24 : 0xff;
+
+	    if (a)
+	    {
+		r = (r * 255) / a;
+		g = (g * 255) / a;
+		b = (b * 255) / a;
+	    }
+
+	    if (r > 255) r = 255;
+	    if (g > 255) g = 255;
+	    if (b > 255) b = 255;
+	    
+	    pb[0] = r;
+	    pb[1] = g;
+	    pb[2] = b;
+	    pb[3] = a;
+	}
+    }
+    
+    return pixbuf;
+}
+
+
+static gboolean
+on_expose (GtkWidget *widget, GdkEventExpose *expose, gpointer data)
+{
+    GdkPixbuf *pixbuf = data;
+    
+    gdk_draw_pixbuf (widget->window, NULL,
+		     pixbuf, 0, 0, 0, 0,
+		     gdk_pixbuf_get_width (pixbuf),
+		     gdk_pixbuf_get_height (pixbuf),
+		     GDK_RGB_DITHER_NONE,
+		     0, 0);
+    
+    return TRUE;
+}
+
+void
+show_image (pixman_image_t *image)
+{
+    GtkWidget *window;
+    GdkPixbuf *pixbuf;
+    int width, height, stride;
+    int argc;
+    char **argv;
+    char *arg0 = g_strdup ("pixman-test-program");
+    gboolean has_alpha;
+    pixman_format_code_t format;
+
+    argc = 1;
+    argv = (char **)&arg0;
+
+    gtk_init (&argc, &argv);
+    
+    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    width = pixman_image_get_width (image);
+    height = pixman_image_get_height (image);
+    stride = pixman_image_get_stride (image);
+
+    gtk_window_set_default_size (GTK_WINDOW (window), width, height);
+    
+    format = image->bits.format;
+    
+    if (format == PIXMAN_a8r8g8b8)
+	has_alpha = TRUE;
+    else if (format == PIXMAN_x8r8g8b8)
+	has_alpha = FALSE;
+    else
+	g_error ("Can't deal with this format: %x\n", format);
+    
+    pixbuf = pixbuf_from_argb32 (pixman_image_get_data (image), has_alpha,
+				 width, height, stride);
+    
+    g_signal_connect (window, "expose_event", G_CALLBACK (on_expose), pixbuf);
+    g_signal_connect (window, "delete_event", G_CALLBACK (gtk_main_quit), NULL);
+    
+    gtk_widget_show (window);
+    
+    gtk_main ();
+}
diff --git a/demos/gtk-utils.h b/demos/gtk-utils.h
new file mode 100644
index 0000000..2cb13bc
--- /dev/null
+++ b/demos/gtk-utils.h
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+#include "pixman.h"
+
+void show_image (pixman_image_t *image);
+
+GdkPixbuf *pixbuf_from_argb32 (uint32_t *bits,
+		               gboolean has_alpha,
+                               int width,
+                               int height,
+                               int stride);
diff --git a/demos/radial-test.c b/demos/radial-test.c
new file mode 100644
index 0000000..35e90d7
--- /dev/null
+++ b/demos/radial-test.c
@@ -0,0 +1,198 @@
+#include "../test/utils.h"
+#include "gtk-utils.h"
+
+#define NUM_GRADIENTS 7
+#define NUM_STOPS 3
+#define NUM_REPEAT 4
+#define SIZE 128
+#define WIDTH (SIZE * NUM_GRADIENTS)
+#define HEIGHT (SIZE * NUM_REPEAT)
+
+/*
+ * We want to test all the possible relative positions of the start
+ * and end circle:
+ *
+ *  - The start circle can be smaller/equal/bigger than the end
+ *    circle. A radial gradient can be classified in one of these
+ *    three cases depending on the sign of dr.
+ *
+ *  - The smaller circle can be completely inside/internally
+ *    tangent/outside (at least in part) of the bigger circle. This
+ *    classification is the same as the one which can be computed by
+ *    examining the sign of a = (dx^2 + dy^2 - dr^2).
+ *
+ *  - If the two circles have the same size, neither can be inside or
+ *    internally tangent
+ *
+ * This test draws radial gradients whose circles always have the same
+ * centers (0, 0) and (1, 0), but with different radiuses. From left
+ * to right:
+ *
+ * - Small start circle completely inside the end circle
+ *     0.25 -> 1.75; dr =  1.5 > 0; a = 1 - 1.50^2 < 0
+ *
+ * - Small start circle internally tangent to the end circle
+ *     0.50 -> 1.50; dr =  1.0 > 0; a = 1 - 1.00^2 = 0
+ *
+ * - Small start circle outside of the end circle
+ *     0.50 -> 1.00; dr =  0.5 > 0; a = 1 - 0.50^2 > 0
+ *
+ * - Start circle with the same size as the end circle
+ *     1.00 -> 1.00; dr =  0.0 = 0; a = 1 - 0.00^2 > 0
+ *
+ * - Small end circle outside of the start circle
+ *     1.00 -> 0.50; dr = -0.5 > 0; a = 1 - 0.50^2 > 0
+ *
+ * - Small end circle internally tangent to the start circle
+ *     1.50 -> 0.50; dr = -1.0 > 0; a = 1 - 1.00^2 = 0
+ *
+ * - Small end circle completely inside the start circle
+ *     1.75 -> 0.25; dr = -1.5 > 0; a = 1 - 1.50^2 < 0
+ *
+ */
+
+const static double radiuses[NUM_GRADIENTS] = {
+    0.25,
+    0.50,
+    0.50,
+    1.00,
+    1.00,
+    1.50,
+    1.75
+};
+
+#define double_to_color(x)					\
+    (((uint32_t) ((x)*65536)) - (((uint32_t) ((x)*65536)) >> 16))
+
+#define PIXMAN_STOP(offset,r,g,b,a)		\
+    { pixman_double_to_fixed (offset),		\
+	{					\
+	double_to_color (r),			\
+	double_to_color (g),			\
+	double_to_color (b),			\
+	double_to_color (a)			\
+	}					\
+    }
+
+static const pixman_gradient_stop_t stops[NUM_STOPS] = {
+    PIXMAN_STOP (0.0,        1, 0, 0, 0.75),
+    PIXMAN_STOP (0.70710678, 0, 1, 0, 0),
+    PIXMAN_STOP (1.0,        0, 0, 1, 1)
+};
+
+static pixman_image_t *
+create_radial (int index)
+{
+    pixman_point_fixed_t p0, p1;
+    pixman_fixed_t r0, r1;
+    double x0, x1, radius0, radius1, left, right, center;
+
+    x0 = 0;
+    x1 = 1;
+    radius0 = radiuses[index];
+    radius1 = radiuses[NUM_GRADIENTS - index - 1];
+
+    /* center the gradient */
+    left = MIN (x0 - radius0, x1 - radius1);
+    right = MAX (x0 + radius0, x1 + radius1);
+    center = (left + right) * 0.5;
+    x0 -= center;
+    x1 -= center;
+
+    /* scale to make it fit within a 1x1 rect centered in (0,0) */
+    x0 *= 0.25;
+    x1 *= 0.25;
+    radius0 *= 0.25;
+    radius1 *= 0.25;
+
+    p0.x = pixman_double_to_fixed (x0);
+    p0.y = pixman_double_to_fixed (0);
+
+    p1.x = pixman_double_to_fixed (x1);
+    p1.y = pixman_double_to_fixed (0);
+
+    r0 = pixman_double_to_fixed (radius0);
+    r1 = pixman_double_to_fixed (radius1);
+
+    return pixman_image_create_radial_gradient (&p0, &p1,
+						r0, r1,
+						stops, NUM_STOPS);
+}
+
+static const pixman_repeat_t repeat[NUM_REPEAT] = {
+    PIXMAN_REPEAT_NONE,
+    PIXMAN_REPEAT_NORMAL,
+    PIXMAN_REPEAT_REFLECT,
+    PIXMAN_REPEAT_PAD
+};
+
+int
+main (int argc, char **argv)
+{
+    pixman_transform_t transform;
+    pixman_image_t *src_img, *dest_img;
+    int i, j;
+
+    enable_fp_exceptions ();
+
+    dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
+					 WIDTH, HEIGHT,
+					 NULL, 0);
+
+    pixman_transform_init_identity (&transform);
+
+    /*
+     * The create_radial() function returns gradients centered in the
+     * origin and whose interesting part fits a 1x1 square. We want to
+     * paint these gradients on a SIZExSIZE square and to make things
+     * easier we want the origin in the top-left corner of the square
+     * we want to see.
+     */
+    pixman_transform_translate (NULL, &transform,
+				pixman_double_to_fixed (0.5),
+				pixman_double_to_fixed (0.5));
+
+    pixman_transform_scale (NULL, &transform,
+			    pixman_double_to_fixed (SIZE),
+			    pixman_double_to_fixed (SIZE));
+
+    /*
+     * Gradients are evaluated at the center of each pixel, so we need
+     * to translate by half a pixel to trigger some interesting
+     * cornercases. In particular, the original implementation of PDF
+     * radial gradients tried to divide by 0 when using this transform
+     * on the "tangent circles" cases.
+     */
+    pixman_transform_translate (NULL, &transform,
+				pixman_double_to_fixed (0.5),
+				pixman_double_to_fixed (0.5));
+
+    for (i = 0; i < NUM_GRADIENTS; i++)
+    {
+	src_img = create_radial (i);
+	pixman_image_set_transform (src_img, &transform);
+
+	for (j = 0; j < NUM_REPEAT; j++)
+	{
+	    pixman_image_set_repeat (src_img, repeat[j]);
+
+	    pixman_image_composite32 (PIXMAN_OP_OVER,
+				      src_img,
+				      NULL,
+				      dest_img,
+				      0, 0,
+				      0, 0,
+				      i * SIZE, j * SIZE,
+				      SIZE, SIZE);
+
+	}
+
+	pixman_image_unref (src_img);
+    }
+
+    show_image (dest_img);
+
+    pixman_image_unref (dest_img);
+
+    return 0;
+}
diff --git a/demos/screen-test.c b/demos/screen-test.c
new file mode 100644
index 0000000..e69dba3
--- /dev/null
+++ b/demos/screen-test.c
@@ -0,0 +1,44 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "pixman.h"
+#include "gtk-utils.h"
+
+int
+main (int argc, char **argv)
+{
+#define WIDTH 40
+#define HEIGHT 40
+    
+    uint32_t *src1 = malloc (WIDTH * HEIGHT * 4);
+    uint32_t *src2 = malloc (WIDTH * HEIGHT * 4);
+    uint32_t *src3 = malloc (WIDTH * HEIGHT * 4);
+    uint32_t *dest = malloc (3 * WIDTH * 2 * HEIGHT * 4);
+    pixman_image_t *simg1, *simg2, *simg3, *dimg;
+
+    int i;
+
+    for (i = 0; i < WIDTH * HEIGHT; ++i)
+    {
+	src1[i] = 0x7ff00000;
+	src2[i] = 0x7f00ff00;
+	src3[i] = 0x7f0000ff;
+    }
+
+    for (i = 0; i < 3 * WIDTH * 2 * HEIGHT; ++i)
+    {
+	dest[i] = 0x0;
+    }
+
+    simg1 = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, src1, WIDTH * 4);
+    simg2 = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, src2, WIDTH * 4);
+    simg3 = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, src3, WIDTH * 4);
+    dimg  = pixman_image_create_bits (PIXMAN_a8r8g8b8, 3 * WIDTH, 2 * HEIGHT, dest, 3 * WIDTH * 4);
+
+    pixman_image_composite (PIXMAN_OP_SCREEN, simg1, NULL, dimg, 0, 0, 0, 0, WIDTH, HEIGHT / 4, WIDTH, HEIGHT);
+    pixman_image_composite (PIXMAN_OP_SCREEN, simg2, NULL, dimg, 0, 0, 0, 0, (WIDTH/2), HEIGHT / 4 + HEIGHT / 2, WIDTH, HEIGHT);
+    pixman_image_composite (PIXMAN_OP_SCREEN, simg3, NULL, dimg, 0, 0, 0, 0, (4 * WIDTH) / 3, HEIGHT, WIDTH, HEIGHT);
+
+    show_image (dimg);
+    
+    return 0;
+}
diff --git a/demos/trap-test.c b/demos/trap-test.c
new file mode 100644
index 0000000..19295e7
--- /dev/null
+++ b/demos/trap-test.c
@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "pixman.h"
+#include "gtk-utils.h"
+
+int
+main (int argc, char **argv)
+{
+#define WIDTH 200
+#define HEIGHT 200
+
+    pixman_image_t *src_img;
+    pixman_image_t *mask_img;
+    pixman_image_t *dest_img;
+    pixman_trap_t trap;
+    pixman_color_t white = { 0x0000, 0xffff, 0x0000, 0xffff };
+    uint32_t *bits = malloc (WIDTH * HEIGHT * 4);
+    uint32_t *mbits = malloc (WIDTH * HEIGHT);
+
+    memset (mbits, 0, WIDTH * HEIGHT);
+    memset (bits, 0xff, WIDTH * HEIGHT * 4);
+    
+    trap.top.l = pixman_int_to_fixed (50) + 0x8000;
+    trap.top.r = pixman_int_to_fixed (150) + 0x8000;
+    trap.top.y = pixman_int_to_fixed (30);
+
+    trap.bot.l = pixman_int_to_fixed (50) + 0x8000;
+    trap.bot.r = pixman_int_to_fixed (150) + 0x8000;
+    trap.bot.y = pixman_int_to_fixed (150);
+
+    mask_img = pixman_image_create_bits (PIXMAN_a8, WIDTH, HEIGHT, mbits, WIDTH);
+    src_img = pixman_image_create_solid_fill (&white);
+    dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, bits, WIDTH * 4);
+    
+    pixman_add_traps (mask_img, 0, 0, 1, &trap);
+
+    pixman_image_composite (PIXMAN_OP_OVER,
+			    src_img, mask_img, dest_img,
+			    0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
+    
+    show_image (dest_img);
+    
+    pixman_image_unref (src_img);
+    pixman_image_unref (dest_img);
+    free (bits);
+    
+    return 0;
+}
diff --git a/test/Makefile.am b/test/Makefile.am
index 8d8471d..92ee8fd 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -80,55 +80,6 @@ stress_test_LDADD = $(TEST_LDADD)
 stress_test_LDFLAGS = @TESTPROGS_EXTRA_LDFLAGS@
 stress_test_SOURCES = stress-test.c utils.c utils.h
 
-# GTK using test programs
-
-if HAVE_GTK
-
-GTK_LDADD = $(TEST_LDADD) $(GTK_LIBS)
-GTK_UTILS = gtk-utils.c gtk-utils.h
-
-TESTPROGRAMS_GTK =		\
-	clip-test		\
-	clip-in			\
-	composite-test		\
-	gradient-test		\
-	radial-test		\
-	alpha-test		\
-	screen-test		\
-	convolution-test	\
-	trap-test
-
-INCLUDES += $(GTK_CFLAGS)
-
-gradient_test_LDADD = $(GTK_LDADD)
-gradient_test_SOURCES = gradient-test.c $(GTK_UTILS)
-
-radial_test_LDADD = $(GTK_LDADD)
-radial_test_SOURCES = radial-test.c utils.c utils.h $(GTK_UTILS)
-
-alpha_test_LDADD = $(GTK_LDADD)
-alpha_test_SOURCES = alpha-test.c $(GTK_UTILS)
-
-composite_test_LDADD = $(GTK_LDADD)
-composite_test_SOURCES = composite-test.c $(GTK_UTILS)
-
-clip_test_LDADD = $(GTK_LDADD)
-clip_test_SOURCES = clip-test.c $(GTK_UTILS)
-
-clip_in_LDADD = $(GTK_LDADD)
-clip_in_SOURCES = clip-in.c $(GTK_UTILS)
-
-trap_test_LDADD = $(GTK_LDADD)
-trap_test_SOURCES = trap-test.c $(GTK_UTILS)
-
-screen_test_LDADD = $(GTK_LDADD)
-screen_test_SOURCES = screen-test.c $(GTK_UTILS)
-
-convolution_test_LDADD = $(GTK_LDADD)
-convolution_test_SOURCES = convolution-test.c $(GTK_UTILS)
-
-endif
-
 # Benchmarks
 
 BENCHMARKS =			\
@@ -137,6 +88,6 @@ BENCHMARKS =			\
 lowlevel_blt_bench_SOURCES = lowlevel-blt-bench.c utils.c utils.h
 lowlevel_blt_bench_LDADD = $(TEST_LDADD)
 
-noinst_PROGRAMS = $(TESTPROGRAMS) $(TESTPROGRAMS_GTK) $(BENCHMARKS)
+noinst_PROGRAMS = $(TESTPROGRAMS) $(BENCHMARKS)
 
 TESTS = $(TESTPROGRAMS)
diff --git a/test/alpha-test.c b/test/alpha-test.c
deleted file mode 100644
index 92c2081..0000000
--- a/test/alpha-test.c
+++ /dev/null
@@ -1,117 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include "pixman.h"
-#include "gtk-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 *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) };
-#if 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) } 
-	}
-    };
-#else
-    pixman_transform_t trans = {
-	{ { pixman_fixed_1, 0, 0 },
-	  { 0, pixman_fixed_1, 0 },
-	  { 0, 0, pixman_fixed_1 } }
-    };
-#endif
-
-    pixman_point_fixed_t c_inner;
-    pixman_point_fixed_t c_outer;
-    pixman_fixed_t r_inner;
-    pixman_fixed_t r_outer;
-    
-    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, &trans);
-    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;
-}
diff --git a/test/clip-in.c b/test/clip-in.c
deleted file mode 100644
index 5157981..0000000
--- a/test/clip-in.c
+++ /dev/null
@@ -1,50 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "pixman.h"
-#include "gtk-utils.h"
-
-/* This test demonstrates that clipping is done totally different depending
- * on whether the source is transformed or not.
- */
-int
-main (int argc, char **argv)
-{
-#define WIDTH 200
-#define HEIGHT 200
-
-#define SMALL 25
-    
-    uint32_t *sbits = malloc (SMALL * SMALL * 4);
-    uint32_t *bits = malloc (WIDTH * HEIGHT * 4);
-    pixman_transform_t trans = {
-    {
-	{ pixman_double_to_fixed (1.0), pixman_double_to_fixed (0), pixman_double_to_fixed (-0.1), },
-	{ pixman_double_to_fixed (0), pixman_double_to_fixed (1), pixman_double_to_fixed (-0.1), },
-	{ pixman_double_to_fixed (0), pixman_double_to_fixed (0), pixman_double_to_fixed (1.0) }
-    } };
-	  
-    pixman_image_t *src_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, SMALL, SMALL, sbits, 4 * SMALL);
-    pixman_image_t *dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, bits, 4 * WIDTH);
-
-    memset (bits, 0xff, WIDTH * HEIGHT * 4);
-    memset (sbits, 0x00, SMALL * SMALL * 4);
-
-    pixman_image_composite (PIXMAN_OP_IN,
-			    src_img, NULL, dest_img,
-			    0, 0, 0, 0, SMALL, SMALL, 200, 200);
-    
-    pixman_image_set_transform (src_img, &trans);
-    
-    pixman_image_composite (PIXMAN_OP_IN,
-			    src_img, NULL, dest_img,
-			    0, 0, 0, 0, SMALL * 2, SMALL * 2, 200, 200);
-    
-    show_image (dest_img);
-    
-    pixman_image_unref (src_img);
-    pixman_image_unref (dest_img);
-    free (bits);
-    
-    return 0;
-}
diff --git a/test/clip-test.c b/test/clip-test.c
deleted file mode 100644
index aa0df44..0000000
--- a/test/clip-test.c
+++ /dev/null
@@ -1,97 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include "pixman.h"
-#include "gtk-utils.h"
-
-#define WIDTH 200
-#define HEIGHT 200
-    
-static pixman_image_t *
-create_solid_bits (uint32_t pixel)
-{
-    uint32_t *pixels = malloc (WIDTH * HEIGHT * 4);
-    int i;
-    
-    for (i = 0; i < WIDTH * HEIGHT; ++i)
-	pixels[i] = pixel;
-
-    return pixman_image_create_bits (PIXMAN_a8r8g8b8,
-				     WIDTH, HEIGHT, 
-				     pixels,
-				     WIDTH * 4);
-}
-
-int
-main (int argc, char **argv)
-{
-    pixman_image_t *gradient_img;
-    pixman_image_t *src_img, *dst_img;
-    pixman_gradient_stop_t stops[2] =
-	{
-	    { pixman_int_to_fixed (0), { 0xffff, 0x0000, 0x0000, 0xffff } },
-	    { pixman_int_to_fixed (1), { 0xffff, 0xffff, 0x0000, 0xffff } }
-	};
-#if 0
-    pixman_point_fixed_t p1 = { 0, 0 };
-    pixman_point_fixed_t p2 = { pixman_int_to_fixed (WIDTH),
-				pixman_int_to_fixed (HEIGHT) };
-#endif
-    pixman_point_fixed_t c_inner;
-    pixman_point_fixed_t c_outer;
-    pixman_fixed_t r_inner;
-    pixman_fixed_t r_outer;
-    pixman_region32_t clip_region;
-    pixman_transform_t trans = {
-	{ { pixman_double_to_fixed (1.3), pixman_double_to_fixed (0), pixman_double_to_fixed (-0.5), },
-	  { pixman_double_to_fixed (0), pixman_double_to_fixed (1), pixman_double_to_fixed (-0.5), },
-	  { pixman_double_to_fixed (0), pixman_double_to_fixed (0), pixman_double_to_fixed (1.0) } 
-	}
-    };
-    
-    src_img = create_solid_bits (0xff0000ff);
-    
-    c_inner.x = pixman_double_to_fixed (100.0);
-    c_inner.y = pixman_double_to_fixed (100.0);
-    c_outer.x = pixman_double_to_fixed (100.0);
-    c_outer.y = pixman_double_to_fixed (100.0);
-    r_inner = 0;
-    r_outer = pixman_double_to_fixed (100.0);
-    
-    gradient_img = pixman_image_create_radial_gradient (&c_inner, &c_outer,
-							r_inner, r_outer,
-							stops, 2);
-
-#if 0
-    gradient_img = pixman_image_create_linear_gradient  (&p1, &p2,
-							 stops, 2);
-    
-#endif
-
-    pixman_image_composite (PIXMAN_OP_OVER, gradient_img, NULL, src_img,
-			    0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
-    
-    pixman_region32_init_rect (&clip_region, 50, 0, 100, 200);
-    pixman_image_set_clip_region32 (src_img, &clip_region);
-    pixman_image_set_source_clipping (src_img, TRUE);
-    pixman_image_set_has_client_clip (src_img, TRUE);
-    pixman_image_set_transform (src_img, &trans);
-    pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL);
-    
-    dst_img = create_solid_bits (0xffff0000);
-    pixman_image_composite (PIXMAN_OP_OVER, src_img, NULL, dst_img,
-			    0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
-    
-
-#if 0
-    printf ("0, 0: %x\n", src[0]);
-    printf ("10, 10: %x\n", src[10 * 10 + 10]);
-    printf ("w, h: %x\n", src[(HEIGHT - 1) * 100 + (WIDTH - 1)]);
-#endif
-    
-    show_image (dst_img);
-    
-    pixman_image_unref (gradient_img);
-    pixman_image_unref (src_img);
-    
-    return 0;
-}
diff --git a/test/composite-test.c b/test/composite-test.c
deleted file mode 100644
index f5f352f..0000000
--- a/test/composite-test.c
+++ /dev/null
@@ -1,191 +0,0 @@
-#include <gtk/gtk.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include "pixman.h"
-#include "gtk-utils.h"
-
-#define WIDTH	60
-#define HEIGHT	60
-
-typedef struct {
-    const char *name;
-    pixman_op_t op;
-} operator_t;
-
-static const operator_t operators[] = {
-    { "CLEAR",		PIXMAN_OP_CLEAR },
-    { "SRC",		PIXMAN_OP_SRC },
-    { "DST",		PIXMAN_OP_DST },
-    { "OVER",		PIXMAN_OP_OVER },
-    { "OVER_REVERSE",	PIXMAN_OP_OVER_REVERSE },
-    { "IN",		PIXMAN_OP_IN },
-    { "IN_REVERSE",	PIXMAN_OP_IN_REVERSE },
-    { "OUT",		PIXMAN_OP_OUT },
-    { "OUT_REVERSE",	PIXMAN_OP_OUT_REVERSE },
-    { "ATOP",		PIXMAN_OP_ATOP },
-    { "ATOP_REVERSE",	PIXMAN_OP_ATOP_REVERSE },
-    { "XOR",		PIXMAN_OP_XOR },
-    { "ADD",		PIXMAN_OP_ADD },
-    { "SATURATE",	PIXMAN_OP_SATURATE },
-
-    { "MULTIPLY",	PIXMAN_OP_MULTIPLY },
-    { "SCREEN",		PIXMAN_OP_SCREEN },
-    { "OVERLAY",	PIXMAN_OP_OVERLAY },
-    { "DARKEN",		PIXMAN_OP_DARKEN },
-    { "LIGHTEN",	PIXMAN_OP_LIGHTEN },
-    { "COLOR_DODGE",	PIXMAN_OP_COLOR_DODGE },
-    { "COLOR_BURN",	PIXMAN_OP_COLOR_BURN },
-    { "HARD_LIGHT",	PIXMAN_OP_HARD_LIGHT },
-    { "SOFT_LIGHT",	PIXMAN_OP_SOFT_LIGHT },
-    { "DIFFERENCE",	PIXMAN_OP_DIFFERENCE },
-    { "EXCLUSION",	PIXMAN_OP_EXCLUSION },
-    { "HSL_HUE",	PIXMAN_OP_HSL_HUE },
-    { "HSL_SATURATION",	PIXMAN_OP_HSL_SATURATION },
-    { "HSL_COLOR",	PIXMAN_OP_HSL_COLOR },
-    { "HSL_LUMINOSITY",	PIXMAN_OP_HSL_LUMINOSITY },
-};
-
-static uint32_t
-reader (const void *src, int size)
-{
-    switch (size)
-    {
-    case 1:
-	return *(uint8_t *)src;
-    case 2:
-	return *(uint16_t *)src;
-    case 4:
-	return *(uint32_t *)src;
-    default:
-	g_assert_not_reached();
-    }
-}
-
-static void
-writer (void *src, uint32_t value, int size)
-{
-    switch (size)
-    {
-    case 1:
-	*(uint8_t *)src = value;
-	break;
-
-    case 2:
-	*(uint16_t *)src = value;
-	break;
-
-    case 4:
-	*(uint32_t *)src = value;
-	break;
-
-    default:
-        break;
-    }
-}
-
-int
-main (int argc, char **argv)
-{
-#define d2f pixman_double_to_fixed
-    
-    GtkWidget *window, *swindow;
-    GtkWidget *table;
-    uint32_t *dest = malloc (WIDTH * HEIGHT * 4);
-    uint32_t *src = malloc (WIDTH * HEIGHT * 4);
-    pixman_image_t *src_img;
-    pixman_image_t *dest_img;
-    pixman_point_fixed_t p1 = { -10 << 0, 0 };
-    pixman_point_fixed_t p2 = { WIDTH << 16, (HEIGHT - 10) << 16 };
-    uint16_t full = 0xcfff;
-    uint16_t low  = 0x5000;
-    uint16_t alpha = 0xffff;
-    pixman_gradient_stop_t stops[6] =
-    {
-	{ d2f (0.0), { full, low, low, alpha } },
-	{ d2f (0.25), { full, full, low, alpha } },
-	{ d2f (0.4), { low, full, low, alpha } },
-	{ d2f (0.6), { low, full, full, alpha } },
-	{ d2f (0.8), { low, low, full, alpha } },
-	{ d2f (1.0), { full, low, full, alpha } },
-    };
-
-    int i;
-
-    gtk_init (&argc, &argv);
-
-    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-
-    gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);
-    
-    g_signal_connect (window, "delete-event",
-		      G_CALLBACK (gtk_main_quit),
-		      NULL);
-    table = gtk_table_new (G_N_ELEMENTS (operators) / 6, 6, TRUE);
-
-    src_img = pixman_image_create_linear_gradient (&p1, &p2, stops,
-						   sizeof (stops) / sizeof (stops[0]));
-
-    pixman_image_set_repeat (src_img, PIXMAN_REPEAT_PAD);
-    
-    dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
-					 WIDTH, HEIGHT,
-					 dest,
-					 WIDTH * 4);
-    pixman_image_set_accessors (dest_img, reader, writer);
-
-    for (i = 0; i < G_N_ELEMENTS (operators); ++i)
-    {
-	GtkWidget *image;
-	GdkPixbuf *pixbuf;
-	GtkWidget *vbox;
-	GtkWidget *label;
-	int j, k;
-
-	vbox = gtk_vbox_new (FALSE, 0);
-
-	label = gtk_label_new (operators[i].name);
-	gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 6);
-	gtk_widget_show (label);
-
-	for (j = 0; j < HEIGHT; ++j)
-	{
-	    for (k = 0; k < WIDTH; ++k)
-		dest[j * WIDTH + k] = 0x7f6f6f00;
-	}
-	pixman_image_composite (operators[i].op, src_img, NULL, dest_img,
-				0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
-	pixbuf = pixbuf_from_argb32 (pixman_image_get_data (dest_img), TRUE,
-				     WIDTH, HEIGHT, WIDTH * 4);
-	image = gtk_image_new_from_pixbuf (pixbuf);
-	gtk_box_pack_start (GTK_BOX (vbox), image, FALSE, FALSE, 0);
-	gtk_widget_show (image);
-
-	gtk_table_attach_defaults (GTK_TABLE (table), vbox,
-				   i % 6, (i % 6) + 1, i / 6, (i / 6) + 1);
-	gtk_widget_show (vbox);
-
-	g_object_unref (pixbuf);
-    }
-
-    pixman_image_unref (src_img);
-    free (src);
-    pixman_image_unref (dest_img);
-    free (dest);
-
-    swindow = gtk_scrolled_window_new (NULL, NULL);
-    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
-				    GTK_POLICY_AUTOMATIC,
-				    GTK_POLICY_AUTOMATIC);
-    
-    gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (swindow), table);
-    gtk_widget_show (table);
-
-    gtk_container_add (GTK_CONTAINER (window), swindow);
-    gtk_widget_show (swindow);
-
-    gtk_widget_show (window);
-
-    gtk_main ();
-
-    return 0;
-}
diff --git a/test/convolution-test.c b/test/convolution-test.c
deleted file mode 100644
index da284af..0000000
--- a/test/convolution-test.c
+++ /dev/null
@@ -1,47 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include "pixman.h"
-#include "gtk-utils.h"
-
-int
-main (int argc, char **argv)
-{
-#define WIDTH 200
-#define HEIGHT 200
-
-#define d2f pixman_double_to_fixed
-    
-    uint32_t *src = malloc (WIDTH * HEIGHT * 4);
-    uint32_t *mask = malloc (WIDTH * HEIGHT * 4);
-    uint32_t *dest = malloc (WIDTH * HEIGHT * 4);
-    pixman_fixed_t convolution[] =
-    {
-	d2f (3), d2f (3),
-	d2f (0.5), d2f (0.5), d2f (0.5),
-	d2f (0.5), d2f (0.5), d2f (0.5),
-	d2f (0.5), d2f (0.5), d2f (0.5),
-    };
-    pixman_image_t *simg, *mimg, *dimg;
-
-    int i;
-
-    for (i = 0; i < WIDTH * HEIGHT; ++i)
-    {
-	src[i] = 0x7f007f00;
-	mask[i] = (i % 256) * 0x01000000;
-	dest[i] = 0;
-    }
-
-    simg = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, src, WIDTH * 4);
-    mimg = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, mask, WIDTH * 4);
-    dimg = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, dest, WIDTH * 4);
-
-    pixman_image_set_filter (mimg, PIXMAN_FILTER_CONVOLUTION,
-			     convolution, 11);
-
-    pixman_image_composite (PIXMAN_OP_OVER, simg, mimg, dimg, 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
-
-    show_image (dimg);
-    
-    return 0;
-}
diff --git a/test/gradient-test.c b/test/gradient-test.c
deleted file mode 100644
index fc84844..0000000
--- a/test/gradient-test.c
+++ /dev/null
@@ -1,89 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include "pixman.h"
-#include "gtk-utils.h"
-
-int
-main (int argc, char **argv)
-{
-#define WIDTH 400
-#define HEIGHT 200
-    
-    uint32_t *dest = malloc (WIDTH * HEIGHT * 4);
-    pixman_image_t *src_img;
-    pixman_image_t *dest_img;
-    int i;
-    pixman_gradient_stop_t stops[2] =
-	{
-	    { pixman_int_to_fixed (0), { 0xffff, 0xeeee, 0xeeee, 0xeeee } },
-	    { pixman_int_to_fixed (1), { 0xffff, 0x1111, 0x1111, 0x1111 } }
-	};
-    pixman_point_fixed_t p1 = { pixman_double_to_fixed (0), 0 };
-    pixman_point_fixed_t p2 = { pixman_double_to_fixed (WIDTH / 8.),
-				pixman_int_to_fixed (0) };
-#if 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) } 
-	}
-    };
-#else
-    pixman_transform_t trans = {
-	{ { pixman_fixed_1, 0, 0 },
-	  { 0, pixman_fixed_1, 0 },
-	  { 0, 0, pixman_fixed_1 } }
-    };
-#endif
-
-    pixman_point_fixed_t c_inner;
-    pixman_point_fixed_t c_outer;
-    pixman_fixed_t r_inner;
-    pixman_fixed_t r_outer;
-    
-    for (i = 0; i < WIDTH * HEIGHT; ++i)
-	dest[i] = 0x4f00004f; /* pale blue */
-    
-    dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
-					 WIDTH, HEIGHT, 
-					 dest,
-					 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);
-    
-    src_img = pixman_image_create_conical_gradient (&c_inner, r_inner,
-						    stops, 2);
-#if 0
-    src_img = pixman_image_create_conical_gradient (&c_inner, r_inner,
-						    stops, 2);
-    src_img = pixman_image_create_linear_gradient (&c_inner, &c_outer,
-						   r_inner, r_outer,
-						   stops, 2);
-#endif
-    
-    src_img = pixman_image_create_linear_gradient  (&p1, &p2,
-						    stops, 2);
-    
-    pixman_image_set_transform (src_img, &trans);
-    pixman_image_set_repeat (src_img, PIXMAN_REPEAT_PAD);
-    
-    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 (dest_img);
-    free (dest);
-    
-    return 0;
-}
diff --git a/test/gtk-utils.c b/test/gtk-utils.c
deleted file mode 100644
index 0e7cb5c..0000000
--- a/test/gtk-utils.c
+++ /dev/null
@@ -1,115 +0,0 @@
-#include <gtk/gtk.h>
-#include <config.h>
-#include "pixman-private.h"	/* For image->bits.format
-				 * FIXME: there should probably be public API for this
-				 */
-#include "gtk-utils.h"
-
-GdkPixbuf *
-pixbuf_from_argb32 (uint32_t *bits,
-		    gboolean has_alpha,
-		    int width,
-		    int height,
-		    int stride)
-{
-    GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE,
-					8, width, height);
-    int p_stride = gdk_pixbuf_get_rowstride (pixbuf);
-    guint32 *p_bits = (guint32 *)gdk_pixbuf_get_pixels (pixbuf);
-    int w, h;
-    
-    for (h = 0; h < height; ++h)
-    {
-	for (w = 0; w < width; ++w)
-	{
-	    uint32_t argb = bits[h * (stride / 4) + w];
-	    guint r, g, b, a;
-	    char *pb = (char *)p_bits;
-
-	    pb += h * p_stride + w * 4;
-
-	    r = (argb & 0x00ff0000) >> 16;
-	    g = (argb & 0x0000ff00) >> 8;
-	    b = (argb & 0x000000ff) >> 0;
-	    a = has_alpha? (argb & 0xff000000) >> 24 : 0xff;
-
-	    if (a)
-	    {
-		r = (r * 255) / a;
-		g = (g * 255) / a;
-		b = (b * 255) / a;
-	    }
-
-	    if (r > 255) r = 255;
-	    if (g > 255) g = 255;
-	    if (b > 255) b = 255;
-	    
-	    pb[0] = r;
-	    pb[1] = g;
-	    pb[2] = b;
-	    pb[3] = a;
-	}
-    }
-    
-    return pixbuf;
-}
-
-
-static gboolean
-on_expose (GtkWidget *widget, GdkEventExpose *expose, gpointer data)
-{
-    GdkPixbuf *pixbuf = data;
-    
-    gdk_draw_pixbuf (widget->window, NULL,
-		     pixbuf, 0, 0, 0, 0,
-		     gdk_pixbuf_get_width (pixbuf),
-		     gdk_pixbuf_get_height (pixbuf),
-		     GDK_RGB_DITHER_NONE,
-		     0, 0);
-    
-    return TRUE;
-}
-
-void
-show_image (pixman_image_t *image)
-{
-    GtkWidget *window;
-    GdkPixbuf *pixbuf;
-    int width, height, stride;
-    int argc;
-    char **argv;
-    char *arg0 = g_strdup ("pixman-test-program");
-    gboolean has_alpha;
-    pixman_format_code_t format;
-
-    argc = 1;
-    argv = (char **)&arg0;
-
-    gtk_init (&argc, &argv);
-    
-    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-    width = pixman_image_get_width (image);
-    height = pixman_image_get_height (image);
-    stride = pixman_image_get_stride (image);
-
-    gtk_window_set_default_size (GTK_WINDOW (window), width, height);
-    
-    format = image->bits.format;
-    
-    if (format == PIXMAN_a8r8g8b8)
-	has_alpha = TRUE;
-    else if (format == PIXMAN_x8r8g8b8)
-	has_alpha = FALSE;
-    else
-	g_error ("Can't deal with this format: %x\n", format);
-    
-    pixbuf = pixbuf_from_argb32 (pixman_image_get_data (image), has_alpha,
-				 width, height, stride);
-    
-    g_signal_connect (window, "expose_event", G_CALLBACK (on_expose), pixbuf);
-    g_signal_connect (window, "delete_event", G_CALLBACK (gtk_main_quit), NULL);
-    
-    gtk_widget_show (window);
-    
-    gtk_main ();
-}
diff --git a/test/gtk-utils.h b/test/gtk-utils.h
deleted file mode 100644
index 2cb13bc..0000000
--- a/test/gtk-utils.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <glib.h>
-#include <gtk/gtk.h>
-#include "pixman.h"
-
-void show_image (pixman_image_t *image);
-
-GdkPixbuf *pixbuf_from_argb32 (uint32_t *bits,
-		               gboolean has_alpha,
-                               int width,
-                               int height,
-                               int stride);
diff --git a/test/radial-test.c b/test/radial-test.c
deleted file mode 100644
index 5d716c3..0000000
--- a/test/radial-test.c
+++ /dev/null
@@ -1,198 +0,0 @@
-#include "utils.h"
-#include "gtk-utils.h"
-
-#define NUM_GRADIENTS 7
-#define NUM_STOPS 3
-#define NUM_REPEAT 4
-#define SIZE 128
-#define WIDTH (SIZE * NUM_GRADIENTS)
-#define HEIGHT (SIZE * NUM_REPEAT)
-
-/*
- * We want to test all the possible relative positions of the start
- * and end circle:
- *
- *  - The start circle can be smaller/equal/bigger than the end
- *    circle. A radial gradient can be classified in one of these
- *    three cases depending on the sign of dr.
- *
- *  - The smaller circle can be completely inside/internally
- *    tangent/outside (at least in part) of the bigger circle. This
- *    classification is the same as the one which can be computed by
- *    examining the sign of a = (dx^2 + dy^2 - dr^2).
- *
- *  - If the two circles have the same size, neither can be inside or
- *    internally tangent
- *
- * This test draws radial gradients whose circles always have the same
- * centers (0, 0) and (1, 0), but with different radiuses. From left
- * to right:
- *
- * - Small start circle completely inside the end circle
- *     0.25 -> 1.75; dr =  1.5 > 0; a = 1 - 1.50^2 < 0
- *
- * - Small start circle internally tangent to the end circle
- *     0.50 -> 1.50; dr =  1.0 > 0; a = 1 - 1.00^2 = 0
- *
- * - Small start circle outside of the end circle
- *     0.50 -> 1.00; dr =  0.5 > 0; a = 1 - 0.50^2 > 0
- *
- * - Start circle with the same size as the end circle
- *     1.00 -> 1.00; dr =  0.0 = 0; a = 1 - 0.00^2 > 0
- *
- * - Small end circle outside of the start circle
- *     1.00 -> 0.50; dr = -0.5 > 0; a = 1 - 0.50^2 > 0
- *
- * - Small end circle internally tangent to the start circle
- *     1.50 -> 0.50; dr = -1.0 > 0; a = 1 - 1.00^2 = 0
- *
- * - Small end circle completely inside the start circle
- *     1.75 -> 0.25; dr = -1.5 > 0; a = 1 - 1.50^2 < 0
- *
- */
-
-const static double radiuses[NUM_GRADIENTS] = {
-    0.25,
-    0.50,
-    0.50,
-    1.00,
-    1.00,
-    1.50,
-    1.75
-};
-
-#define double_to_color(x)					\
-    (((uint32_t) ((x)*65536)) - (((uint32_t) ((x)*65536)) >> 16))
-
-#define PIXMAN_STOP(offset,r,g,b,a)		\
-    { pixman_double_to_fixed (offset),		\
-	{					\
-	double_to_color (r),			\
-	double_to_color (g),			\
-	double_to_color (b),			\
-	double_to_color (a)			\
-	}					\
-    }
-
-static const pixman_gradient_stop_t stops[NUM_STOPS] = {
-    PIXMAN_STOP (0.0,        1, 0, 0, 0.75),
-    PIXMAN_STOP (0.70710678, 0, 1, 0, 0),
-    PIXMAN_STOP (1.0,        0, 0, 1, 1)
-};
-
-static pixman_image_t *
-create_radial (int index)
-{
-    pixman_point_fixed_t p0, p1;
-    pixman_fixed_t r0, r1;
-    double x0, x1, radius0, radius1, left, right, center;
-
-    x0 = 0;
-    x1 = 1;
-    radius0 = radiuses[index];
-    radius1 = radiuses[NUM_GRADIENTS - index - 1];
-
-    /* center the gradient */
-    left = MIN (x0 - radius0, x1 - radius1);
-    right = MAX (x0 + radius0, x1 + radius1);
-    center = (left + right) * 0.5;
-    x0 -= center;
-    x1 -= center;
-
-    /* scale to make it fit within a 1x1 rect centered in (0,0) */
-    x0 *= 0.25;
-    x1 *= 0.25;
-    radius0 *= 0.25;
-    radius1 *= 0.25;
-
-    p0.x = pixman_double_to_fixed (x0);
-    p0.y = pixman_double_to_fixed (0);
-
-    p1.x = pixman_double_to_fixed (x1);
-    p1.y = pixman_double_to_fixed (0);
-
-    r0 = pixman_double_to_fixed (radius0);
-    r1 = pixman_double_to_fixed (radius1);
-
-    return pixman_image_create_radial_gradient (&p0, &p1,
-						r0, r1,
-						stops, NUM_STOPS);
-}
-
-static const pixman_repeat_t repeat[NUM_REPEAT] = {
-    PIXMAN_REPEAT_NONE,
-    PIXMAN_REPEAT_NORMAL,
-    PIXMAN_REPEAT_REFLECT,
-    PIXMAN_REPEAT_PAD
-};
-
-int
-main (int argc, char **argv)
-{
-    pixman_transform_t transform;
-    pixman_image_t *src_img, *dest_img;
-    int i, j;
-
-    enable_fp_exceptions ();
-
-    dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
-					 WIDTH, HEIGHT,
-					 NULL, 0);
-
-    pixman_transform_init_identity (&transform);
-
-    /*
-     * The create_radial() function returns gradients centered in the
-     * origin and whose interesting part fits a 1x1 square. We want to
-     * paint these gradients on a SIZExSIZE square and to make things
-     * easier we want the origin in the top-left corner of the square
-     * we want to see.
-     */
-    pixman_transform_translate (NULL, &transform,
-				pixman_double_to_fixed (0.5),
-				pixman_double_to_fixed (0.5));
-
-    pixman_transform_scale (NULL, &transform,
-			    pixman_double_to_fixed (SIZE),
-			    pixman_double_to_fixed (SIZE));
-
-    /*
-     * Gradients are evaluated at the center of each pixel, so we need
-     * to translate by half a pixel to trigger some interesting
-     * cornercases. In particular, the original implementation of PDF
-     * radial gradients tried to divide by 0 when using this transform
-     * on the "tangent circles" cases.
-     */
-    pixman_transform_translate (NULL, &transform,
-				pixman_double_to_fixed (0.5),
-				pixman_double_to_fixed (0.5));
-
-    for (i = 0; i < NUM_GRADIENTS; i++)
-    {
-	src_img = create_radial (i);
-	pixman_image_set_transform (src_img, &transform);
-
-	for (j = 0; j < NUM_REPEAT; j++)
-	{
-	    pixman_image_set_repeat (src_img, repeat[j]);
-
-	    pixman_image_composite32 (PIXMAN_OP_OVER,
-				      src_img,
-				      NULL,
-				      dest_img,
-				      0, 0,
-				      0, 0,
-				      i * SIZE, j * SIZE,
-				      SIZE, SIZE);
-
-	}
-
-	pixman_image_unref (src_img);
-    }
-
-    show_image (dest_img);
-
-    pixman_image_unref (dest_img);
-
-    return 0;
-}
diff --git a/test/screen-test.c b/test/screen-test.c
deleted file mode 100644
index e69dba3..0000000
--- a/test/screen-test.c
+++ /dev/null
@@ -1,44 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include "pixman.h"
-#include "gtk-utils.h"
-
-int
-main (int argc, char **argv)
-{
-#define WIDTH 40
-#define HEIGHT 40
-    
-    uint32_t *src1 = malloc (WIDTH * HEIGHT * 4);
-    uint32_t *src2 = malloc (WIDTH * HEIGHT * 4);
-    uint32_t *src3 = malloc (WIDTH * HEIGHT * 4);
-    uint32_t *dest = malloc (3 * WIDTH * 2 * HEIGHT * 4);
-    pixman_image_t *simg1, *simg2, *simg3, *dimg;
-
-    int i;
-
-    for (i = 0; i < WIDTH * HEIGHT; ++i)
-    {
-	src1[i] = 0x7ff00000;
-	src2[i] = 0x7f00ff00;
-	src3[i] = 0x7f0000ff;
-    }
-
-    for (i = 0; i < 3 * WIDTH * 2 * HEIGHT; ++i)
-    {
-	dest[i] = 0x0;
-    }
-
-    simg1 = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, src1, WIDTH * 4);
-    simg2 = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, src2, WIDTH * 4);
-    simg3 = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, src3, WIDTH * 4);
-    dimg  = pixman_image_create_bits (PIXMAN_a8r8g8b8, 3 * WIDTH, 2 * HEIGHT, dest, 3 * WIDTH * 4);
-
-    pixman_image_composite (PIXMAN_OP_SCREEN, simg1, NULL, dimg, 0, 0, 0, 0, WIDTH, HEIGHT / 4, WIDTH, HEIGHT);
-    pixman_image_composite (PIXMAN_OP_SCREEN, simg2, NULL, dimg, 0, 0, 0, 0, (WIDTH/2), HEIGHT / 4 + HEIGHT / 2, WIDTH, HEIGHT);
-    pixman_image_composite (PIXMAN_OP_SCREEN, simg3, NULL, dimg, 0, 0, 0, 0, (4 * WIDTH) / 3, HEIGHT, WIDTH, HEIGHT);
-
-    show_image (dimg);
-    
-    return 0;
-}
diff --git a/test/trap-test.c b/test/trap-test.c
deleted file mode 100644
index 19295e7..0000000
--- a/test/trap-test.c
+++ /dev/null
@@ -1,49 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "pixman.h"
-#include "gtk-utils.h"
-
-int
-main (int argc, char **argv)
-{
-#define WIDTH 200
-#define HEIGHT 200
-
-    pixman_image_t *src_img;
-    pixman_image_t *mask_img;
-    pixman_image_t *dest_img;
-    pixman_trap_t trap;
-    pixman_color_t white = { 0x0000, 0xffff, 0x0000, 0xffff };
-    uint32_t *bits = malloc (WIDTH * HEIGHT * 4);
-    uint32_t *mbits = malloc (WIDTH * HEIGHT);
-
-    memset (mbits, 0, WIDTH * HEIGHT);
-    memset (bits, 0xff, WIDTH * HEIGHT * 4);
-    
-    trap.top.l = pixman_int_to_fixed (50) + 0x8000;
-    trap.top.r = pixman_int_to_fixed (150) + 0x8000;
-    trap.top.y = pixman_int_to_fixed (30);
-
-    trap.bot.l = pixman_int_to_fixed (50) + 0x8000;
-    trap.bot.r = pixman_int_to_fixed (150) + 0x8000;
-    trap.bot.y = pixman_int_to_fixed (150);
-
-    mask_img = pixman_image_create_bits (PIXMAN_a8, WIDTH, HEIGHT, mbits, WIDTH);
-    src_img = pixman_image_create_solid_fill (&white);
-    dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, bits, WIDTH * 4);
-    
-    pixman_add_traps (mask_img, 0, 0, 1, &trap);
-
-    pixman_image_composite (PIXMAN_OP_OVER,
-			    src_img, mask_img, dest_img,
-			    0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
-    
-    show_image (dest_img);
-    
-    pixman_image_unref (src_img);
-    pixman_image_unref (dest_img);
-    free (bits);
-    
-    return 0;
-}


More information about the xorg-commit mailing list