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