1#include <gtk/gtk.h>
2#include <stdlib.h>
3#include <stdio.h>
4#include "pixman.h"
5#include "gtk-utils.h"
6#include "parrot.c"
7
8#define WIDTH	80
9#define HEIGHT	80
10
11typedef struct {
12    const char *name;
13    pixman_op_t op;
14} operator_t;
15
16static const operator_t operators[] = {
17    { "CLEAR",		PIXMAN_OP_CLEAR },
18    { "SRC",		PIXMAN_OP_SRC },
19    { "DST",		PIXMAN_OP_DST },
20    { "OVER",		PIXMAN_OP_OVER },
21    { "OVER_REVERSE",	PIXMAN_OP_OVER_REVERSE },
22    { "IN",		PIXMAN_OP_IN },
23    { "IN_REVERSE",	PIXMAN_OP_IN_REVERSE },
24    { "OUT",		PIXMAN_OP_OUT },
25    { "OUT_REVERSE",	PIXMAN_OP_OUT_REVERSE },
26    { "ATOP",		PIXMAN_OP_ATOP },
27    { "ATOP_REVERSE",	PIXMAN_OP_ATOP_REVERSE },
28    { "XOR",		PIXMAN_OP_XOR },
29    { "ADD",		PIXMAN_OP_ADD },
30    { "SATURATE",	PIXMAN_OP_SATURATE },
31
32    { "MULTIPLY",	PIXMAN_OP_MULTIPLY },
33    { "SCREEN",		PIXMAN_OP_SCREEN },
34    { "OVERLAY",	PIXMAN_OP_OVERLAY },
35    { "DARKEN",		PIXMAN_OP_DARKEN },
36    { "LIGHTEN",	PIXMAN_OP_LIGHTEN },
37    { "COLOR_DODGE",	PIXMAN_OP_COLOR_DODGE },
38    { "COLOR_BURN",	PIXMAN_OP_COLOR_BURN },
39    { "HARD_LIGHT",	PIXMAN_OP_HARD_LIGHT },
40    { "SOFT_LIGHT",	PIXMAN_OP_SOFT_LIGHT },
41    { "DIFFERENCE",	PIXMAN_OP_DIFFERENCE },
42    { "EXCLUSION",	PIXMAN_OP_EXCLUSION },
43    { "HSL_HUE",	PIXMAN_OP_HSL_HUE },
44    { "HSL_SATURATION",	PIXMAN_OP_HSL_SATURATION },
45    { "HSL_COLOR",	PIXMAN_OP_HSL_COLOR },
46    { "HSL_LUMINOSITY",	PIXMAN_OP_HSL_LUMINOSITY },
47};
48
49static uint32_t
50reader (const void *src, int size)
51{
52    switch (size)
53    {
54    case 1:
55	return *(uint8_t *)src;
56    case 2:
57	return *(uint16_t *)src;
58    case 4:
59	return *(uint32_t *)src;
60    default:
61	g_assert_not_reached();
62    }
63}
64
65static void
66writer (void *src, uint32_t value, int size)
67{
68    switch (size)
69    {
70    case 1:
71	*(uint8_t *)src = value;
72	break;
73
74    case 2:
75	*(uint16_t *)src = value;
76	break;
77
78    case 4:
79	*(uint32_t *)src = value;
80	break;
81
82    default:
83        break;
84    }
85}
86
87int
88main (int argc, char **argv)
89{
90#define d2f pixman_double_to_fixed
91
92    GtkWidget *window, *swindow;
93    GtkWidget *table;
94    uint32_t *dest = malloc (WIDTH * HEIGHT * 4);
95    uint32_t *src = malloc (WIDTH * HEIGHT * 4);
96    pixman_image_t *gradient, *parrot;
97    pixman_image_t *dest_img;
98    pixman_point_fixed_t p1 = { -10 << 16, 10 << 16 };
99    pixman_point_fixed_t p2 = { (WIDTH + 10) << 16, (HEIGHT - 10) << 16 };
100    uint16_t alpha = 0xdddd;
101    pixman_gradient_stop_t stops[6] =
102    {
103	{ d2f (0.0), { 0xf2f2, 0x8787, 0x7d7d, alpha } },
104	{ d2f (0.22), { 0xf3f3, 0xeaea, 0x8383, alpha } },
105	{ d2f (0.42), { 0x6b6b, 0xc0c0, 0x7777, alpha } },
106	{ d2f (0.57), { 0x4b4b, 0xc9c9, 0xf5f5, alpha } },
107	{ d2f (0.75), { 0x6a6a, 0x7f7f, 0xbebe, alpha } },
108	{ d2f (1.0), { 0xeded, 0x8282, 0xb0b0, alpha } },
109    };
110
111    int i;
112
113    gtk_init (&argc, &argv);
114
115    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
116
117    gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);
118
119    g_signal_connect (window, "delete-event",
120		      G_CALLBACK (gtk_main_quit),
121		      NULL);
122    table = gtk_table_new (G_N_ELEMENTS (operators) / 6, 6, TRUE);
123
124    gradient = pixman_image_create_linear_gradient (&p1, &p2, stops, G_N_ELEMENTS (stops));
125    parrot = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, (uint32_t *)parrot_bits, WIDTH * 4);
126
127    pixman_image_set_repeat (gradient, PIXMAN_REPEAT_PAD);
128
129    dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
130					 WIDTH, HEIGHT,
131					 NULL,
132					 WIDTH * 4);
133    pixman_image_set_accessors (dest_img, reader, writer);
134
135    for (i = 0; i < G_N_ELEMENTS (operators); ++i)
136    {
137	GtkWidget *image;
138	GdkPixbuf *pixbuf;
139	GtkWidget *vbox;
140	GtkWidget *label;
141
142	vbox = gtk_vbox_new (FALSE, 0);
143
144	label = gtk_label_new (operators[i].name);
145	gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 6);
146	gtk_widget_show (label);
147
148	pixman_image_composite (PIXMAN_OP_SRC, gradient, NULL, dest_img,
149				0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
150	pixman_image_composite (operators[i].op, parrot, NULL, dest_img,
151				0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
152	pixbuf = pixbuf_from_argb32 (pixman_image_get_data (dest_img),
153				     WIDTH, HEIGHT, WIDTH * 4);
154	image = gtk_image_new_from_pixbuf (pixbuf);
155	gtk_box_pack_start (GTK_BOX (vbox), image, FALSE, FALSE, 0);
156	gtk_widget_show (image);
157
158	gtk_table_attach_defaults (GTK_TABLE (table), vbox,
159				   i % 6, (i % 6) + 1, i / 6, (i / 6) + 1);
160	gtk_widget_show (vbox);
161
162	g_object_unref (pixbuf);
163    }
164
165    pixman_image_unref (gradient);
166    free (src);
167    pixman_image_unref (dest_img);
168    free (dest);
169
170    swindow = gtk_scrolled_window_new (NULL, NULL);
171    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
172				    GTK_POLICY_AUTOMATIC,
173				    GTK_POLICY_AUTOMATIC);
174
175    gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (swindow), table);
176    gtk_widget_show (table);
177
178    gtk_container_add (GTK_CONTAINER (window), swindow);
179    gtk_widget_show (swindow);
180
181    gtk_widget_show (window);
182
183    gtk_main ();
184
185    return 0;
186}
187