1 /* test_gradient.c */
2
3 #include <math.h>
4 #include <gtk/gtk.h>
5 #include "art_point.h"
6 #include "art_misc.h"
7 #include "art_affine.h"
8 #include "art_svp.h"
9 #include "art_svp_vpath.h"
10 #include "art_rgb.h"
11 #include "art_rgb_svp.h"
12 #include "art_render.h"
13 #include "art_render_gradient.h"
14
15 GtkWidget *drawing_area;
16 static art_u8 *rgbdata = NULL;
17 int width, height;
18
19 double pos_x[2], pos_y[2];
20 int pos_nr = 0;
21
22 double a = 1/32.0;
23 double b = -1/33.00000;
24 double c = -1/3.0;
25 ArtGradientSpread spread = ART_GRADIENT_REPEAT;
26
27 ArtVpath *
randstar(int n)28 randstar (int n)
29 {
30 ArtVpath *vec;
31 int i;
32 double r, th;
33
34 vec = art_new (ArtVpath, n + 2);
35 for (i = 0; i < n; i++)
36 {
37 vec[i].code = i ? ART_LINETO : ART_MOVETO;
38 r = rand () * (250.0 / RAND_MAX);
39 th = i * 2 * M_PI / n;
40 vec[i].x = 250 + r * cos (th);
41 vec[i].y = 250 - r * sin (th);
42 }
43 vec[i].code = ART_LINETO;
44 vec[i].x = vec[0].x;
45 vec[i].y = vec[0].y;
46 i++;
47 vec[i].code = ART_END;
48 vec[i].x = 0;
49 vec[i].y = 0;
50 return vec;
51 }
52
53 ArtVpath *
rect(void)54 rect (void)
55 {
56 ArtVpath *vec;
57 int i;
58 double r, th;
59
60 #define START 0
61
62 vec = art_new (ArtVpath, 6);
63 vec[0].code = ART_MOVETO;
64 vec[0].x = START;
65 vec[0].y = START;
66 vec[1].code = ART_LINETO;
67 vec[1].x = START;
68 vec[1].y = 512-START;
69 vec[2].code = ART_LINETO;
70 vec[2].x = 512-START;
71 vec[2].y = 512-START;
72 vec[3].code = ART_LINETO;
73 vec[3].x = 512-START;
74 vec[3].y = START;
75 vec[4].code = ART_LINETO;
76 vec[4].x = START;
77 vec[4].y = START;
78 vec[5].code = ART_END;
79 vec[5].x = 0;
80 vec[5].y = 0;
81
82 return vec;
83 }
84
85
86 static void
draw_test()87 draw_test()
88 {
89 static ArtVpath *vpath = NULL;
90 static ArtSVP *svp = NULL;
91 ArtRender *render;
92 ArtPixMaxDepth color[3] = {0x0000, 0x0000, 0x8000 };
93 ArtGradientLinear gradient;
94 ArtGradientStop stops[3] = {
95 { 0.02, { 0x7fff, 0x0000, 0x0000, 0x7fff }},
96 { 0.5, { 0x0000, 0x0000, 0x0000, 0x1000 }},
97 { 0.98, { 0x0000, 0x7fff, 0x0000, 0x7fff }}
98 };
99
100 if (!vpath) {
101 vpath = rect ();
102 svp = art_svp_from_vpath (vpath);
103 }
104
105 gradient.a = a;
106 gradient.b = b;
107 gradient.c = c;
108 gradient.spread = spread;
109
110 gradient.n_stops = sizeof(stops) / sizeof(stops[0]);
111 gradient.stops = stops;
112
113 render = art_render_new (0, 0,
114 width, height,
115 rgbdata, width * 3,
116 3, 8, ART_ALPHA_NONE,
117 NULL);
118 art_render_clear_rgb (render, 0xfff0c0);
119 art_render_svp (render, svp);
120 art_render_gradient_linear (render, &gradient, ART_FILTER_NEAREST);
121 // art_render_image_solid (render, color);
122 art_render_invoke (render);
123 }
124
125 /* Create a new backing pixmap of the appropriate size */
configure_event(GtkWidget * widget,GdkEventConfigure * event)126 static gint configure_event( GtkWidget *widget,
127 GdkEventConfigure *event )
128 {
129 if (rgbdata)
130 free(rgbdata);
131
132 rgbdata = malloc(3*widget->allocation.width*widget->allocation.height);
133 width = widget->allocation.width;
134 height = widget->allocation.height;
135
136 draw_test();
137
138 return TRUE;
139 }
140
141 /* Redraw the screen from the backing pixmap */
expose_event(GtkWidget * widget,GdkEventExpose * event)142 static gint expose_event( GtkWidget *widget,
143 GdkEventExpose *event )
144 {
145 static GdkGC *copy_gc = NULL;
146
147 if (copy_gc == NULL) {
148 copy_gc = gdk_gc_new(widget->window);
149 }
150
151 gdk_draw_rgb_image(widget->window,
152 copy_gc,
153 event->area.x, event->area.y,
154 event->area.width, event->area.height,
155 GDK_RGB_DITHER_NONE,
156 rgbdata + event->area.x*3+event->area.y*3*width,
157 width*3 );
158
159 return FALSE;
160 }
161
button_press_event(GtkWidget * widget,GdkEventButton * event)162 static gint button_press_event( GtkWidget *widget,
163 GdkEventButton *event )
164 {
165 static GdkGC *copy_gc = NULL;
166 int x, y;
167
168 x = event->x;
169 y = event->y;
170
171 pos_x[pos_nr] = (double) x;
172 pos_y[pos_nr] = (double) y;
173
174 pos_nr = (pos_nr+1) % 2;
175
176 draw_test();
177
178 if (copy_gc == NULL) {
179 copy_gc = gdk_gc_new(widget->window);
180 }
181
182 gdk_draw_rgb_image(widget->window,
183 copy_gc,
184 0, 0,
185 width, height,
186 GDK_RGB_DITHER_NONE,
187 rgbdata, width*3 );
188
189 return TRUE;
190 }
191
motion_notify_event(GtkWidget * widget,GdkEventMotion * event)192 static gint motion_notify_event( GtkWidget *widget,
193 GdkEventMotion *event )
194 {
195 static GdkGC *copy_gc = NULL;
196 int x, y;
197 GdkModifierType state;
198
199 if (event->is_hint) {
200 gdk_window_get_pointer (event->window, &x, &y, &state);
201 } else {
202 x = event->x;
203 y = event->y;
204 state = event->state;
205 }
206
207 if (state & GDK_BUTTON1_MASK && rgbdata != NULL) {
208
209 pos_x[(pos_nr+1) % 2] = (double) x;
210 pos_y[(pos_nr+1) % 2] = (double) y;
211
212 draw_test();
213
214 if (copy_gc == NULL) {
215 copy_gc = gdk_gc_new(widget->window);
216 }
217
218 gdk_draw_rgb_image(widget->window,
219 copy_gc,
220 0, 0,
221 width, height,
222 GDK_RGB_DITHER_NONE,
223 rgbdata, width*3 );
224 }
225
226 return TRUE;
227 }
228
quit()229 void quit ()
230 {
231 gtk_exit (0);
232 }
233
234 static void
change_gradient(GtkEntry * entry,double * ptr)235 change_gradient (GtkEntry *entry,
236 double *ptr)
237 {
238 double d;
239 d = g_ascii_strtod (gtk_entry_get_text (entry), NULL);
240 if (d != 0.0)
241 *ptr = 1.0/d;
242 else
243 *ptr = 0.0;
244 draw_test();
245 gtk_widget_queue_draw (drawing_area);
246 }
247
248 static void
change_spread(GtkEntry * entry,int * ptr)249 change_spread (GtkEntry *entry,
250 int *ptr)
251 {
252 double d;
253 d = g_ascii_strtod (gtk_entry_get_text (entry), NULL);
254 *ptr = (int)d;
255 draw_test();
256 gtk_widget_queue_draw (drawing_area);
257 }
258
259
main(int argc,char * argv[])260 int main( int argc,
261 char *argv[] )
262 {
263 GtkWidget *window;
264 GtkWidget *vbox;
265 char buf[G_ASCII_DTOSTR_BUF_SIZE];
266
267 GtkWidget *button;
268 GtkWidget *entry;
269
270 gtk_init (&argc, &argv);
271
272 gdk_rgb_init();
273
274 pos_x[0] = 100;
275 pos_y[0] = 100;
276 pos_x[1] = 300;
277 pos_y[1] = 300;
278
279 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
280 gtk_widget_set_name (window, "Test Input");
281
282 vbox = gtk_vbox_new (FALSE, 0);
283 gtk_container_add (GTK_CONTAINER (window), vbox);
284 gtk_widget_show (vbox);
285
286 gtk_signal_connect (GTK_OBJECT (window), "destroy",
287 GTK_SIGNAL_FUNC (quit), NULL);
288
289 /* Create the drawing area */
290
291 drawing_area = gtk_drawing_area_new ();
292 gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_area), 512, 512);
293 gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0);
294
295 gtk_widget_show (drawing_area);
296
297 /* Signals used to handle backing pixmap */
298
299 gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
300 (GtkSignalFunc) expose_event, NULL);
301 gtk_signal_connect (GTK_OBJECT(drawing_area),"configure_event",
302 (GtkSignalFunc) configure_event, NULL);
303
304 /* Event signals */
305
306 gtk_signal_connect (GTK_OBJECT (drawing_area), "motion_notify_event",
307 (GtkSignalFunc) motion_notify_event, NULL);
308 gtk_signal_connect (GTK_OBJECT (drawing_area), "button_press_event",
309 (GtkSignalFunc) button_press_event, NULL);
310
311 gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK
312 | GDK_LEAVE_NOTIFY_MASK
313 | GDK_BUTTON_PRESS_MASK
314 | GDK_POINTER_MOTION_MASK
315 | GDK_POINTER_MOTION_HINT_MASK);
316
317
318 entry = gtk_entry_new ();
319 gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
320
321 gtk_signal_connect (GTK_OBJECT (entry), "activate",
322 GTK_SIGNAL_FUNC (change_gradient),
323 &a);
324 gtk_entry_set_text (GTK_ENTRY (entry),
325 g_ascii_dtostr (buf, G_ASCII_DTOSTR_BUF_SIZE,
326 1.0/a));
327 gtk_widget_show (entry);
328
329 entry = gtk_entry_new ();
330 gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
331
332 gtk_signal_connect (GTK_OBJECT (entry), "activate",
333 GTK_SIGNAL_FUNC (change_gradient),
334 &b);
335 gtk_entry_set_text (GTK_ENTRY (entry),
336 g_ascii_dtostr (buf, G_ASCII_DTOSTR_BUF_SIZE,
337 1.0/b));
338 gtk_widget_show (entry);
339
340 entry = gtk_entry_new ();
341 gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
342
343 gtk_signal_connect (GTK_OBJECT (entry), "activate",
344 GTK_SIGNAL_FUNC (change_gradient),
345 &c);
346 gtk_entry_set_text (GTK_ENTRY (entry),
347 g_ascii_dtostr (buf, G_ASCII_DTOSTR_BUF_SIZE,
348 1.0/c));
349 gtk_widget_show (entry);
350
351 entry = gtk_entry_new ();
352 gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
353
354 gtk_signal_connect (GTK_OBJECT (entry), "activate",
355 GTK_SIGNAL_FUNC (change_spread),
356 &spread);
357 gtk_entry_set_text (GTK_ENTRY (entry),
358 g_strdup_printf ("%d", spread));
359 gtk_widget_show (entry);
360
361
362 /* .. And a quit button */
363 button = gtk_button_new_with_label ("Quit");
364 gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
365
366 gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
367 GTK_SIGNAL_FUNC (gtk_widget_destroy),
368 GTK_OBJECT (window));
369 gtk_widget_show (button);
370
371 gtk_widget_show (window);
372
373 gtk_main ();
374
375 return 0;
376 }
377