11176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <gtk/gtk.h>
21176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <stdlib.h>
31176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <stdio.h>
41176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "pixman.h"
51176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "gtk-utils.h"
61176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "parrot.c"
71176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
81176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define WIDTH	80
91176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define HEIGHT	80
101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
111176bdada62cabc6ec4b0308a930e83b679d5d36John Recktypedef struct {
121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    const char *name;
131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_op_t op;
141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} operator_t;
151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
161176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic const operator_t operators[] = {
171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "CLEAR",		PIXMAN_OP_CLEAR },
181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "SRC",		PIXMAN_OP_SRC },
191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "DST",		PIXMAN_OP_DST },
201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "OVER",		PIXMAN_OP_OVER },
211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "OVER_REVERSE",	PIXMAN_OP_OVER_REVERSE },
221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "IN",		PIXMAN_OP_IN },
231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "IN_REVERSE",	PIXMAN_OP_IN_REVERSE },
241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "OUT",		PIXMAN_OP_OUT },
251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "OUT_REVERSE",	PIXMAN_OP_OUT_REVERSE },
261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "ATOP",		PIXMAN_OP_ATOP },
271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "ATOP_REVERSE",	PIXMAN_OP_ATOP_REVERSE },
281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "XOR",		PIXMAN_OP_XOR },
291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "ADD",		PIXMAN_OP_ADD },
301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "SATURATE",	PIXMAN_OP_SATURATE },
311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "MULTIPLY",	PIXMAN_OP_MULTIPLY },
331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "SCREEN",		PIXMAN_OP_SCREEN },
341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "OVERLAY",	PIXMAN_OP_OVERLAY },
351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "DARKEN",		PIXMAN_OP_DARKEN },
361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "LIGHTEN",	PIXMAN_OP_LIGHTEN },
371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "COLOR_DODGE",	PIXMAN_OP_COLOR_DODGE },
381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "COLOR_BURN",	PIXMAN_OP_COLOR_BURN },
391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "HARD_LIGHT",	PIXMAN_OP_HARD_LIGHT },
401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "SOFT_LIGHT",	PIXMAN_OP_SOFT_LIGHT },
411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "DIFFERENCE",	PIXMAN_OP_DIFFERENCE },
421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "EXCLUSION",	PIXMAN_OP_EXCLUSION },
431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "HSL_HUE",	PIXMAN_OP_HSL_HUE },
441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "HSL_SATURATION",	PIXMAN_OP_HSL_SATURATION },
451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "HSL_COLOR",	PIXMAN_OP_HSL_COLOR },
461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    { "HSL_LUMINOSITY",	PIXMAN_OP_HSL_LUMINOSITY },
471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck};
481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
491176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic uint32_t
501176bdada62cabc6ec4b0308a930e83b679d5d36John Reckreader (const void *src, int size)
511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    switch (size)
531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case 1:
551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return *(uint8_t *)src;
561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case 2:
571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return *(uint16_t *)src;
581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case 4:
591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	return *(uint32_t *)src;
601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    default:
611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	g_assert_not_reached();
621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
651176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic void
661176bdada62cabc6ec4b0308a930e83b679d5d36John Reckwriter (void *src, uint32_t value, int size)
671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    switch (size)
691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case 1:
711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	*(uint8_t *)src = value;
721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case 2:
751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	*(uint16_t *)src = value;
761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case 4:
791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	*(uint32_t *)src = value;
801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    default:
831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        break;
841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
871176bdada62cabc6ec4b0308a930e83b679d5d36John Reckint
881176bdada62cabc6ec4b0308a930e83b679d5d36John Reckmain (int argc, char **argv)
891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define d2f pixman_double_to_fixed
911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    GtkWidget *window, *swindow;
931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    GtkWidget *table;
941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    uint32_t *dest = malloc (WIDTH * HEIGHT * 4);
951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    uint32_t *src = malloc (WIDTH * HEIGHT * 4);
961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_image_t *gradient, *parrot;
971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_image_t *dest_img;
981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_point_fixed_t p1 = { -10 << 16, 10 << 16 };
991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_point_fixed_t p2 = { (WIDTH + 10) << 16, (HEIGHT - 10) << 16 };
1001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    uint16_t alpha = 0xdddd;
1011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_gradient_stop_t stops[6] =
1021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
1031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{ d2f (0.0), { 0xf2f2, 0x8787, 0x7d7d, alpha } },
1041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{ d2f (0.22), { 0xf3f3, 0xeaea, 0x8383, alpha } },
1051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{ d2f (0.42), { 0x6b6b, 0xc0c0, 0x7777, alpha } },
1061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{ d2f (0.57), { 0x4b4b, 0xc9c9, 0xf5f5, alpha } },
1071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{ d2f (0.75), { 0x6a6a, 0x7f7f, 0xbebe, alpha } },
1081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{ d2f (1.0), { 0xeded, 0x8282, 0xb0b0, alpha } },
1091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    };
1101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    int i;
1121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    gtk_init (&argc, &argv);
1141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);
1181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    g_signal_connect (window, "delete-event",
1201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		      G_CALLBACK (gtk_main_quit),
1211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		      NULL);
1221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    table = gtk_table_new (G_N_ELEMENTS (operators) / 6, 6, TRUE);
1231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    gradient = pixman_image_create_linear_gradient (&p1, &p2, stops, G_N_ELEMENTS (stops));
1251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    parrot = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, (uint32_t *)parrot_bits, WIDTH * 4);
1261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_image_set_repeat (gradient, PIXMAN_REPEAT_PAD);
1281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
1301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					 WIDTH, HEIGHT,
1311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					 NULL,
1321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck					 WIDTH * 4);
1331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_image_set_accessors (dest_img, reader, writer);
1341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    for (i = 0; i < G_N_ELEMENTS (operators); ++i)
1361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
1371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	GtkWidget *image;
1381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	GdkPixbuf *pixbuf;
1391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	GtkWidget *vbox;
1401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	GtkWidget *label;
1411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	vbox = gtk_vbox_new (FALSE, 0);
1431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	label = gtk_label_new (operators[i].name);
1451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 6);
1461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	gtk_widget_show (label);
1471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_image_composite (PIXMAN_OP_SRC, gradient, NULL, dest_img,
1491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
1501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_image_composite (operators[i].op, parrot, NULL, dest_img,
1511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
1521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixbuf = pixbuf_from_argb32 (pixman_image_get_data (dest_img),
1531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				     WIDTH, HEIGHT, WIDTH * 4);
1541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	image = gtk_image_new_from_pixbuf (pixbuf);
1551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	gtk_box_pack_start (GTK_BOX (vbox), image, FALSE, FALSE, 0);
1561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	gtk_widget_show (image);
1571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	gtk_table_attach_defaults (GTK_TABLE (table), vbox,
1591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				   i % 6, (i % 6) + 1, i / 6, (i / 6) + 1);
1601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	gtk_widget_show (vbox);
1611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	g_object_unref (pixbuf);
1631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
1641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_image_unref (gradient);
1661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    free (src);
1671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_image_unref (dest_img);
1681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    free (dest);
1691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    swindow = gtk_scrolled_window_new (NULL, NULL);
1711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
1721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				    GTK_POLICY_AUTOMATIC,
1731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				    GTK_POLICY_AUTOMATIC);
1741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (swindow), table);
1761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    gtk_widget_show (table);
1771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    gtk_container_add (GTK_CONTAINER (window), swindow);
1791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    gtk_widget_show (swindow);
1801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    gtk_widget_show (window);
1821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    gtk_main ();
1841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return 0;
1861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
187