PageRenderTime 455ms CodeModel.GetById 120ms app.highlight 150ms RepoModel.GetById 172ms app.codeStats 7ms

/src/demos/demo_cairo.c

http://ftk.googlecode.com/
C | 405 lines | 321 code | 80 blank | 4 comment | 11 complexity | b1899c90fa3e8fc35d44a142d48c94f3 MD5 | raw file
  1#include <math.h>
  2#include "ftk_cairo.h"
  3
  4static cairo_t* cr = NULL;
  5
  6static void paint_clip_image(int x, int y, int width, int height)
  7{
  8	int              w, h;
  9	cairo_surface_t *image;
 10	char filename[FTK_MAX_PATH+1] = {0};
 11
 12	cairo_translate (cr, x, y);
 13	
 14	cairo_arc (cr, width/2, height/4, width/3, 0, 2*M_PI);
 15	cairo_clip (cr);
 16	cairo_new_path (cr); /* path not consumed by clip()*/
 17
 18	ftk_snprintf(filename, FTK_MAX_PATH, "%s/png3.png", 
 19		ftk_config_get_test_data_dir(ftk_default_config()));
 20	ftk_logd("%s:%s\n", __func__, filename);
 21	image = cairo_image_surface_create_from_png (filename);
 22
 23	w = cairo_image_surface_get_width (image);
 24	h = cairo_image_surface_get_height (image);
 25
 26//	cairo_scale (cr, 256.0/w, 256.0/h);
 27
 28	cairo_set_source_surface (cr, image, 0, 0);
 29	cairo_paint (cr);
 30
 31	cairo_surface_destroy (image);
 32
 33	return;
 34}
 35
 36static void paint_rect(int x, int y, int width, int height)
 37{
 38	/* a custom shape that could be wrapped in a function */
 39	double x0      = 25.6,   /* parameters like cairo_rectangle */
 40		   y0      = 25.6,
 41		   rect_width  = 204.8,
 42		   rect_height = 204.8,
 43		   radius = 102.4;   /* and an approximate curvature radius */
 44
 45	double x1,y1;
 46
 47	cairo_translate (cr, x, y);
 48	x1=x0+rect_width;
 49	y1=y0+rect_height;
 50	if (!rect_width || !rect_height)
 51		return;
 52	if (rect_width/2<radius) {
 53		if (rect_height/2<radius) {
 54			cairo_move_to  (cr, x0, (y0 + y1)/2);
 55			cairo_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0);
 56			cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1)/2);
 57			cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0)/2, y1);
 58			cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1)/2);
 59		} else {
 60			cairo_move_to  (cr, x0, y0 + radius);
 61			cairo_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0);
 62			cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
 63			cairo_line_to (cr, x1 , y1 - radius);
 64			cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0)/2, y1);
 65			cairo_curve_to (cr, x0, y1, x0, y1, x0, y1- radius);
 66		}
 67	} else {
 68		if (rect_height/2<radius) {
 69			cairo_move_to  (cr, x0, (y0 + y1)/2);
 70			cairo_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0);
 71			cairo_line_to (cr, x1 - radius, y0);
 72			cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1)/2);
 73			cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
 74			cairo_line_to (cr, x0 + radius, y1);
 75			cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1)/2);
 76		} else {
 77			cairo_move_to  (cr, x0, y0 + radius);
 78			cairo_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0);
 79			cairo_line_to (cr, x1 - radius, y0);
 80			cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
 81			cairo_line_to (cr, x1 , y1 - radius);
 82			cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
 83			cairo_line_to (cr, x0 + radius, y1);
 84			cairo_curve_to (cr, x0, y1, x0, y1, x0, y1- radius);
 85		}
 86	}
 87	cairo_close_path (cr);
 88
 89	cairo_set_source_rgb (cr, 0.5, 0.5, 1);
 90	cairo_fill_preserve (cr);
 91	cairo_set_source_rgba (cr, 0.5, 0, 0, 0.5);
 92	cairo_set_line_width (cr, 10.0);
 93	cairo_stroke (cr);
 94
 95	return;
 96}
 97
 98static void paint_pic(int x, int y, int width, int height)
 99{
100	int              w, h;
101	cairo_surface_t *image;
102	cairo_pattern_t *pattern;
103	cairo_matrix_t   matrix;
104	char filename[FTK_MAX_PATH+1] = {0};
105
106	cairo_translate (cr, x, y);
107	ftk_snprintf(filename, FTK_MAX_PATH, "%s/png3.png", 
108		ftk_config_get_test_data_dir(ftk_default_config()));
109	image = cairo_image_surface_create_from_png (filename);
110
111	w = cairo_image_surface_get_width (image);
112	h = cairo_image_surface_get_height (image);
113
114	pattern = cairo_pattern_create_for_surface (image);
115	cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
116
117	cairo_translate (cr, 128.0, 128.0);
118	cairo_rotate (cr, M_PI / 4);
119	cairo_scale (cr, 1 / sqrt (2), 1 / sqrt (2));
120	cairo_translate (cr, -128.0, -128.0);
121
122	cairo_matrix_init_scale (&matrix, w/256.0 * 5.0, h/256.0 * 5.0);
123	cairo_pattern_set_matrix (pattern, &matrix);
124
125	cairo_set_source (cr, pattern);
126
127	cairo_rectangle (cr, 0, 0, 256.0, 256.0);
128	cairo_fill (cr);
129
130	cairo_pattern_destroy (pattern);
131	cairo_surface_destroy (image);
132
133	return;
134}
135
136static void paint_arrow(int x, int y, int width, int height)
137{
138	cairo_translate (cr, x, y);
139	cairo_set_line_width (cr, 40.96);
140	cairo_move_to (cr, 76.8, 84.48);
141	cairo_rel_line_to (cr, 51.2, -51.2);
142	cairo_rel_line_to (cr, 51.2, 51.2);
143	cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER); /* default */
144	cairo_stroke (cr);
145
146	cairo_move_to (cr, 76.8, 161.28);
147	cairo_rel_line_to (cr, 51.2, -51.2);
148	cairo_rel_line_to (cr, 51.2, 51.2);
149	cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL);
150	cairo_stroke (cr);
151
152	cairo_move_to (cr, 76.8, 238.08);
153	cairo_rel_line_to (cr, 51.2, -51.2);
154	cairo_rel_line_to (cr, 51.2, 51.2);
155	cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
156	cairo_stroke (cr);
157
158	return;
159}
160
161static void paint_segments(int x, int y, int width, int height)
162{
163	cairo_translate (cr, x, y);
164	cairo_move_to (cr, 50.0, 75.0);
165	cairo_line_to (cr, 200.0, 75.0);
166
167	cairo_move_to (cr, 50.0, 125.0);
168	cairo_line_to (cr, 200.0, 125.0);
169
170	cairo_move_to (cr, 50.0, 175.0);
171	cairo_line_to (cr, 200.0, 175.0);
172
173	cairo_set_line_width (cr, 30.0);
174	cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
175	cairo_stroke (cr);
176
177	return;
178}
179
180static void paint_ball(int x, int y, int width, int height)
181{
182	cairo_pattern_t *pat;
183
184	pat = cairo_pattern_create_linear (0.0, 0.0,  0.0, height);
185	cairo_pattern_add_color_stop_rgba (pat, 1, 0, 0, 0, 1);
186	cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 1);
187	cairo_rectangle (cr, x, y, width, height);
188	cairo_set_source (cr, pat);
189	cairo_fill (cr);
190	cairo_pattern_destroy (pat);
191
192	pat = cairo_pattern_create_radial (x+115.2, y+102.4, 25.6,
193									   x+102.4,  y+102.4, 128.0);
194	cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 1);
195	cairo_pattern_add_color_stop_rgba (pat, 1, 0, 0, 0, 1);
196	cairo_set_source (cr, pat);
197	cairo_arc (cr, x+width/2, y+height/4, 76.8, 0, 2 * M_PI);
198	cairo_fill (cr);
199	cairo_pattern_destroy (pat);
200
201	return;
202}
203
204static void paint_sin(int x, int y, int width, int height)
205{
206	int i = 0;
207	int base_y = height/2;
208
209	cairo_translate (cr, x, y);
210	cairo_set_source_rgba (cr, 1.0, 0, 0, 1.0);
211	cairo_set_line_width (cr, 2);
212	cairo_move_to  (cr, 0, base_y);
213	cairo_line_to (cr, width, base_y);
214	cairo_stroke (cr);
215	
216	cairo_set_line_width (cr, 1);
217	cairo_move_to  (cr, 0, base_y);
218	cairo_set_source_rgba (cr, 0, 1.0, 0, 1.0);
219	for(i = 0; i < width; i++)
220	{
221		double r =  2 * 3.14 * i /(width >> 2);
222		int h = height/3 * sin(r);
223		cairo_line_to  (cr, i, base_y + h);
224	}
225
226	ftk_logd("%s:x=%d y=%d base_y=%d width=%d\n", __func__, x, y, base_y, width);
227	cairo_stroke (cr);
228
229	return;
230}
231
232static void paint_helloworld(int x, int y, int width, int height)
233{
234	cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
235								   CAIRO_FONT_WEIGHT_BOLD);
236	cairo_set_font_size (cr, 90.0);
237
238	cairo_move_to (cr, x+10.0, y+135.0);
239	cairo_show_text (cr, "Hello");
240
241	cairo_move_to (cr, x+70.0, y+165.0);
242	cairo_text_path (cr, "void");
243	cairo_set_source_rgb (cr, 0.5, 0.5, 1);
244	cairo_fill_preserve (cr);
245	cairo_set_source_rgb (cr, 0, 0, 0);
246	cairo_set_line_width (cr, 2.56);
247	cairo_stroke (cr);
248
249	/* draw helping lines */
250	cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6);
251	cairo_arc (cr, x+10.0, y+135.0, 5.12, 0, 2*M_PI);
252	cairo_close_path (cr);
253	cairo_arc (cr, x+70.0, y+165.0, 5.12, 0, 2*M_PI);
254	cairo_fill (cr);
255
256	return;
257}
258
259static void paint_car(int x, int y, int width, int height)
260{
261	cairo_set_line_width (cr, 6);
262	cairo_rectangle (cr, x+10, y+10, width-20, 70);
263	cairo_new_sub_path (cr); cairo_arc (cr, x+64, y+64, 40, 0, 2*M_PI);
264	cairo_new_sub_path (cr); cairo_arc_negative (cr, width-64, y+64, 40, 0, -2*M_PI);
265
266	cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
267	cairo_set_source_rgb (cr, 0, 0.7, 0); cairo_fill_preserve (cr);
268	cairo_set_source_rgb (cr, 0, 0, 0); cairo_stroke (cr);
269
270	cairo_translate (cr, x, height/2);
271	cairo_rectangle (cr, 10, 10, width-20, 70);
272	cairo_new_sub_path (cr); cairo_arc (cr, 64, 64, 40, 0, 2*M_PI);
273	cairo_new_sub_path (cr); cairo_arc_negative (cr, width-64, 64, 40, 0, -2*M_PI);
274
275	cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING);
276	cairo_set_source_rgb (cr, 0, 0, 0.9); cairo_fill_preserve (cr);
277	cairo_set_source_rgb (cr, 0, 0, 0); cairo_stroke (cr);
278
279	return;
280}
281
282typedef void (*PaintFunc)(int x, int y, int width, int height);
283
284static size_t g_index = 0;
285
286static const PaintFunc paints[] = 
287{
288	paint_car,
289	paint_sin,
290//	paint_helloworld,
291	paint_ball,
292	paint_segments,
293	paint_arrow,
294	paint_pic,
295	paint_rect,
296	paint_clip_image
297};
298
299static Ret on_paint(void* ctx, void* obj)
300{
301	FtkWidget* thiz = obj;
302	FTK_BEGIN_PAINT(x, y, width, height, canvas);
303
304	ftk_logd("%s:%d\n", __func__, __LINE__);
305	if(cr == NULL)
306	{
307		cairo_surface_t* surface = ftk_cairo_surface_create(thiz);
308		cr = cairo_create(surface);
309		cairo_surface_destroy(surface);
310	ftk_logd("%s:%d\n", __func__, __LINE__);
311	}
312	
313	cairo_save (cr);
314	cairo_reset_clip (cr);
315	cairo_identity_matrix (cr);
316	cairo_new_path (cr);
317	cairo_rectangle(cr, x, y, width, height);
318	cairo_clip (cr);
319
320	ftk_logd("%s:%d index=%d\n", __func__, __LINE__, g_index);
321	paints[g_index](x, y, width, height);
322	ftk_logd("%s:%d\n", __func__, __LINE__);
323
324	cairo_restore (cr);
325	
326	FTK_END_PAINT();
327	ftk_logd("%s:%d\n", __func__, __LINE__);
328
329	return RET_OK;
330}
331
332static Ret button_prev_clicked(void* ctx, void* obj)
333{
334	g_index = g_index > 0 ? g_index - 1 : 0;
335	ftk_widget_invalidate(ftk_widget_lookup(ctx, 100));
336
337	return RET_OK;
338}
339
340static Ret button_next_clicked(void* ctx, void* obj)
341{
342	g_index++;
343	g_index = g_index % (sizeof(paints)/sizeof(paints[0]));
344
345	ftk_widget_invalidate(ftk_widget_lookup(ctx, 100));
346
347	return RET_OK;
348}
349
350static Ret button_quit_clicked(void* ctx, void* obj)
351{
352	ftk_widget_unref(ctx);
353
354	return RET_OK;
355}
356
357#ifdef FTK_AS_PLUGIN
358#include "ftk_app_demo.h"
359FTK_HIDE int FTK_MAIN(int argc, char* argv[]);
360FtkApp* ftk_app_demo_cairo_create()
361{
362	return ftk_app_demo_create(_("cairo"), ftk_main);
363}
364#else
365#define FTK_HIDE extern
366#endif /*FTK_AS_PLUGIN*/
367
368FTK_HIDE int FTK_MAIN(int argc, char* argv[])
369{
370	int width = 0;
371	int height = 0;
372	FtkWidget* win = NULL;
373	FtkWidget* button = NULL;
374	FtkWidget* painter = NULL;
375	FTK_INIT(argc, argv);
376
377	win = ftk_app_window_create();
378	ftk_window_set_animation_hint(win, "app_main_window");
379	width = ftk_widget_width(win);
380	height = ftk_widget_height(win);
381
382	button = ftk_button_create(win, 0, 10, width/3, 60);
383	ftk_widget_set_text(button, "prev");
384	ftk_button_set_clicked_listener(button, button_prev_clicked, win);
385
386	button = ftk_button_create(win, width/3, 10, width/3, 60);
387	ftk_widget_set_text(button, "next");
388	ftk_button_set_clicked_listener(button, button_next_clicked, win);
389
390	button = ftk_button_create(win, width*2/3, 10, width/3, 60);
391	ftk_widget_set_text(button, "quit");
392	ftk_button_set_clicked_listener(button, button_quit_clicked, win);
393
394	painter = ftk_painter_create(win, 0, 70, width, height-80);
395	ftk_widget_set_id(painter, 100);
396	ftk_painter_set_paint_listener(painter, on_paint, NULL);
397
398	ftk_widget_set_text(win, "cairo demo");
399	ftk_widget_show_all(win, 1);
400	FTK_QUIT_WHEN_WIDGET_CLOSE(win);
401
402	FTK_RUN();
403
404	return 0;
405}