[build] Bumped version to 0.5.3
[adg.git] / demo / adg-demo.c
bloba037c380bb3e2f35e9db194eae2f750b987f997c
1 #include <adg/adg.h>
2 #include <math.h>
4 #include "demo.h"
7 static AdgCanvas * sample_canvas (void);
8 static AdgCanvas * operations_canvas (void);
9 static AdgCanvas * mapping_canvas (void);
10 static void to_pdf (AdgWidget *widget,
11 GtkWidget *caller);
12 static void to_png (AdgWidget *widget,
13 GtkWidget *caller);
14 static void to_ps (AdgWidget *widget,
15 GtkWidget *caller);
18 int
19 main(gint argc, gchar **argv)
21 gchar *path;
22 GtkBuilder *builder;
23 GError *error;
24 GtkWidget *window;
25 GtkWidget *sample;
26 GtkWidget *operations;
27 GtkWidget *mapping;
29 gtk_init(&argc, &argv);
31 path = demo_find_data_file("adg-demo.ui");
32 if (path == NULL) {
33 g_print("adg-demo.ui not found!\n");
34 return 1;
37 builder = gtk_builder_new();
38 error = NULL;
40 gtk_builder_add_from_file(builder, path, &error);
41 if (error != NULL) {
42 g_print("%s\n", error->message);
43 return 2;
46 window = (GtkWidget *) gtk_builder_get_object(builder, "wndMain");
48 sample = (GtkWidget *) gtk_builder_get_object(builder, "areaSample");
49 adg_widget_set_canvas(ADG_WIDGET(sample), sample_canvas());
51 operations = (GtkWidget *) gtk_builder_get_object(builder, "areaOperations");
52 adg_widget_set_canvas(ADG_WIDGET(operations), operations_canvas());
54 mapping = (GtkWidget *) gtk_builder_get_object(builder, "areaMapping");
55 adg_widget_set_canvas(ADG_WIDGET(mapping), mapping_canvas());
57 /* Connect signals */
58 g_signal_connect(window, "delete-event",
59 G_CALLBACK(gtk_main_quit), NULL);
60 g_signal_connect(gtk_builder_get_object(builder, "btnQuit"),
61 "clicked", G_CALLBACK(gtk_main_quit), NULL);
62 g_signal_connect_swapped(gtk_builder_get_object(builder, "btnPng"),
63 "clicked", G_CALLBACK(to_png), sample);
64 g_signal_connect_swapped(gtk_builder_get_object(builder, "btnPdf"),
65 "clicked", G_CALLBACK(to_pdf), sample);
66 g_signal_connect_swapped(gtk_builder_get_object(builder, "btnPs"),
67 "clicked", G_CALLBACK(to_ps), sample);
69 g_object_unref(builder);
71 gtk_widget_show_all(window);
72 gtk_main();
74 return 0;
78 static AdgPath * non_trivial_model (void);
81 /**********************************************
82 * A sample mechanical part example
83 **********************************************/
85 #define SQRT3 1.732050808
86 #define CHAMFER 0.3
88 typedef struct _SampleData SampleData;
90 struct _SampleData {
91 gdouble A, B, C;
92 gdouble DHOLE, LHOLE;
93 gdouble D1, D2, D3, D4, D5, D6, D7;
94 gdouble RD34, RD56;
95 gdouble LD2, LD3, LD5, LD6, LD7;
98 static void sample_get (SampleData *data);
99 static AdgPath *sample_bottom_path (const SampleData *data,
100 gdouble height);
101 static AdgPath *sample_path (const SampleData *data);
102 static void sample_add_dimensions (AdgCanvas *canvas,
103 AdgModel *model,
104 const SampleData *data);
105 static void sample_add_stuff (AdgCanvas *canvas,
106 const SampleData *data);
109 static AdgCanvas *
110 sample_canvas(void)
112 SampleData data;
113 AdgCanvas *canvas;
114 AdgContainer *container;
115 AdgPath *bottom, *shape;
116 AdgEdges *edges;
117 AdgEntity *entity;
118 AdgMatrix map;
120 sample_get(&data);
121 canvas = adg_canvas_new();
122 container = (AdgContainer *) canvas;
124 bottom = sample_bottom_path(&data, data.LHOLE + 2);
125 adg_path_reflect(bottom, NULL);
126 adg_path_close(bottom);
128 shape = sample_path(&data);
129 adg_path_reflect(shape, NULL);
130 adg_path_close(shape);
131 adg_path_move_to_explicit(shape, data.LHOLE + 2, data.D1 / 2);
132 adg_path_line_to_explicit(shape, data.LHOLE + 2, -data.D1 / 2);
134 edges = adg_edges_new_with_source(ADG_TRAIL(shape));
136 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(shape)));
137 adg_container_add(container, entity);
139 entity = ADG_ENTITY(adg_hatch_new(ADG_TRAIL(bottom)));
140 adg_container_add(container, entity);
142 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(edges)));
143 adg_container_add(container, entity);
145 sample_add_dimensions(canvas, ADG_MODEL(shape), &data);
146 sample_add_stuff(canvas, &data);
148 cairo_matrix_init_translate(&map, 110, 70);
149 cairo_matrix_scale(&map, 6.883, 6.883);
150 cairo_matrix_translate(&map, 0, 10);
151 adg_entity_set_local_map(ADG_ENTITY(container), &map);
153 return canvas;
156 static void
157 sample_get(SampleData *data)
159 data->A = 52.3;
160 data->B = 20.6;
161 data->C = 2;
162 data->DHOLE = 2;
163 data->LHOLE = 3;
164 data->D1 = 9.3;
165 data->D2 = 6.5;
166 data->D3 = 11.9;
167 data->D4 = 6.5;
168 data->D5 = 4.5;
169 data->D6 = 7.2;
170 data->D7 = 3;
171 data->RD34 = 1;
172 data->LD2 = 7;
173 data->LD3 = 3.5;
174 data->LD5 = 5;
175 data->LD6 = 1;
176 data->LD7 = 0.5;
179 static AdgPath *
180 sample_bottom_path(const SampleData *data, gdouble height)
182 AdgPath *path;
183 AdgModel *model;
184 AdgPair pair;
186 path = adg_path_new();
187 model = ADG_MODEL(path);
189 pair.x = data->LHOLE;
190 pair.y = 0;
191 adg_path_move_to(path, &pair);
192 adg_model_set_named_pair(model, "LHOLE", &pair);
194 pair.y = data->DHOLE / 2;
195 pair.x -= pair.y / SQRT3;
196 adg_path_line_to(path, &pair);
198 pair.x = 0;
199 adg_path_line_to(path, &pair);
200 adg_model_set_named_pair(model, "DHOLE", &pair);
202 pair.y = data->D1 / 2;
203 adg_path_line_to(path, &pair);
204 adg_model_set_named_pair(model, "D1I", &pair);
206 pair.x = height;
207 adg_path_line_to(path, &pair);
208 adg_model_set_named_pair(model, "D1F", &pair);
210 return path;
213 static AdgPath *
214 sample_path(const SampleData *data)
216 AdgPath *path;
217 AdgModel *model;
218 AdgPair pair, tmp;
219 const AdgPrimitive *primitive;
221 pair.x = data->A - data->B - data->LD2;
222 path = sample_bottom_path(data, pair.x);
223 model = ADG_MODEL(path);
225 pair.x += (data->D1 - data->D2) * SQRT3 / 2;
226 pair.y = data->D2 / 2;
227 adg_path_line_to(path, &pair);
228 adg_model_set_named_pair(model, "D2I", &pair);
230 pair.x = data->A - data->B;
231 adg_path_line_to(path, &pair);
232 adg_path_fillet(path, 0.4);
234 pair.x = data->A - data->B;
235 pair.y = data->D3 / 2;
236 adg_path_line_to(path, &pair);
237 adg_model_set_named_pair(model, "D3I", &pair);
239 adg_path_chamfer(path, CHAMFER, CHAMFER);
241 pair.x = data->A - data->B + data->LD3;
242 pair.y = data->D3 / 2;
243 adg_path_line_to(path, &pair);
245 primitive = adg_path_over_primitive(path);
246 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
247 adg_model_set_named_pair(model, "D3I_X", &tmp);
249 adg_path_chamfer(path, CHAMFER, CHAMFER);
251 pair.y = data->D4 / 2;
252 adg_path_line_to(path, &pair);
254 primitive = adg_path_over_primitive(path);
255 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
256 adg_model_set_named_pair(model, "D3F_Y", &tmp);
257 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, -1));
258 adg_model_set_named_pair(model, "D3F_X", &tmp);
260 adg_path_fillet(path, data->RD34);
262 pair.x = data->A - data->C - data->LD5;
263 adg_path_line_to(path, &pair);
264 adg_model_set_named_pair(model, "D4F", &pair);
266 primitive = adg_path_over_primitive(path);
267 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
268 tmp.x += data->RD34;
269 adg_model_set_named_pair(model, "RD34", &tmp);
271 tmp.x -= cos(G_PI_4) * data->RD34,
272 tmp.y -= sin(G_PI_4) * data->RD34,
273 adg_model_set_named_pair(model, "RD34_R", &tmp);
275 tmp.x += data->RD34,
276 tmp.y += data->RD34,
277 adg_model_set_named_pair(model, "RD34_XY", &tmp);
279 pair.x += (data->D4 - data->D5) / 2;
280 pair.y = data->D5 / 2;
281 adg_path_line_to(path, &pair);
283 pair.x = data->A - data->C;
284 adg_path_line_to(path, &pair);
286 adg_path_fillet(path, 0.2);
288 pair.y = data->D6 / 2;
289 adg_path_line_to(path, &pair);
291 primitive = adg_path_over_primitive(path);
292 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
293 adg_model_set_named_pair(model, "D5F", &tmp);
295 adg_path_fillet(path, 0.1);
297 pair.x += data->LD6;
298 adg_path_line_to(path, &pair);
299 adg_model_set_named_pair(model, "D6F", &pair);
301 primitive = adg_path_over_primitive(path);
302 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, -1));
303 adg_model_set_named_pair(model, "D6I_Y", &tmp);
305 pair.x = data->A - data->LD7;
306 pair.y -= (data->C - data->LD7 - data->LD6) / SQRT3;
307 adg_path_line_to(path, &pair);
308 adg_model_set_named_pair(model, "D67", &pair);
310 pair.y = data->D7 / 2;
311 adg_path_line_to(path, &pair);
313 pair.x = data->A;
314 adg_path_line_to(path, &pair);
315 adg_model_set_named_pair(model, "D7F", &pair);
317 return path;
320 static void
321 sample_add_dimensions(AdgCanvas *canvas, AdgModel *model,
322 const SampleData *data)
324 AdgLDim *ldim;
325 AdgADim *adim;
326 AdgRDim *rdim;
328 /* NORTH */
330 ldim = adg_ldim_new_full_from_model(model, "-D1F", "-D3I_X", "-D3F_Y",
331 ADG_DIR_UP);
332 adg_dim_set_outside(ADG_DIM(ldim), ADG_THREE_STATE_OFF);
333 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
335 ldim = adg_ldim_new_full_from_model(model, "-D3I_X", "-D3F_X", "-D3F_Y",
336 ADG_DIR_UP);
337 adg_ldim_switch_extension1(ldim, FALSE);
338 adg_dim_set_outside(ADG_DIM(ldim), ADG_THREE_STATE_OFF);
339 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
341 /* SOUTH */
343 ldim = adg_ldim_new_full_from_model(model, "D1I", "LHOLE", "D3F_Y",
344 ADG_DIR_DOWN);
345 adg_ldim_switch_extension1(ldim, FALSE);
346 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
348 ldim = adg_ldim_new_full_from_model(model, "D3I_X", "D7F", "D3F_Y",
349 ADG_DIR_DOWN);
350 adg_dim_set_limits(ADG_DIM(ldim), NULL, "+0.1");
351 adg_ldim_switch_extension2(ldim, FALSE);
352 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
354 ldim = adg_ldim_new_full_from_model(model, "D1I", "D7F", "D3F_Y",
355 ADG_DIR_DOWN);
356 adg_dim_set_limits(ADG_DIM(ldim), "-0.05", "+0.05");
357 adg_dim_set_level(ADG_DIM(ldim), 2);
358 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
360 adim = adg_adim_new_full_from_model(model, "D6F", "D6I_Y", "D67",
361 "D6F", "D6F");
362 adg_dim_set_level(ADG_DIM(adim), 2);
363 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(adim));
365 rdim = adg_rdim_new_full_from_model(model, "RD34", "RD34_R", "RD34_XY");
366 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(rdim));
368 /* EAST */
370 ldim = adg_ldim_new_full_from_model(model, "D3F_Y", "-D3F_Y", "D7F",
371 ADG_DIR_RIGHT);
372 adg_dim_set_limits(ADG_DIM(ldim), "-0.25", NULL);
373 adg_dim_set_level(ADG_DIM(ldim), 5);
374 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
376 ldim = adg_ldim_new_full_from_model(model, "D6F", "-D6F", "D7F",
377 ADG_DIR_RIGHT);
378 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
379 adg_dim_set_level(ADG_DIM(ldim), 4);
380 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
382 ldim = adg_ldim_new_full_from_model(model, "D4F", "-D4F", "D7F",
383 ADG_DIR_RIGHT);
384 adg_dim_set_level(ADG_DIM(ldim), 3);
385 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
387 ldim = adg_ldim_new_full_from_model(model, "D5F", "-D5F", "D7F",
388 ADG_DIR_RIGHT);
389 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
390 adg_dim_set_level(ADG_DIM(ldim), 2);
391 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
393 ldim = adg_ldim_new_full_from_model(model, "D7F", "-D7F", "D7F",
394 ADG_DIR_RIGHT);
395 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
397 /* WEST */
399 ldim = adg_ldim_new_full_from_model(model, "D1I", "-D1I", "D1I",
400 ADG_DIR_LEFT);
401 adg_dim_set_limits(ADG_DIM(ldim), "+0.05", "-0.05");
402 adg_dim_set_level(ADG_DIM(ldim), 3);
403 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
405 ldim = adg_ldim_new_full_from_model(model, "D2I", "-D2I", "D1I",
406 ADG_DIR_LEFT);
407 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
408 adg_dim_set_level(ADG_DIM(ldim), 2);
409 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
411 ldim = adg_ldim_new_full_from_model(model, "DHOLE", "-DHOLE", "D1I",
412 ADG_DIR_LEFT);
413 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
416 static void
417 sample_add_stuff(AdgCanvas *canvas, const SampleData *data)
419 AdgToyText *toy_text;
420 AdgMatrix map;
422 toy_text = adg_toy_text_new("Rotate the mouse wheel to zoom in and out");
423 cairo_matrix_init_translate(&map, 0, data->D3 / 2);
424 adg_entity_set_local_map(ADG_ENTITY(toy_text), &map);
425 cairo_matrix_translate(&map, 10, 30 + 30 * 2);
426 adg_entity_set_global_map(ADG_ENTITY(toy_text), &map);
427 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(toy_text));
429 toy_text = adg_toy_text_new("Keep the wheel pressed while dragging the mouse to translate");
430 cairo_matrix_init_translate(&map, 0, data->D3 / 2);
431 adg_entity_set_local_map(ADG_ENTITY(toy_text), &map);
432 cairo_matrix_init_translate(&map, 10, 50 + 30 * 2);
433 adg_entity_set_global_map(ADG_ENTITY(toy_text), &map);
434 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(toy_text));
438 #if defined(CAIRO_HAS_PNG_FUNCTIONS) || defined(CAIRO_HAS_PDF_SURFACE) || defined(CAIRO_HAS_PS_SURFACE)
440 /* Only needed if there is at least one supported surface */
441 static void
442 file_generated(GtkWidget *caller, const gchar *file)
444 GtkWindow *window;
445 GtkWidget *dialog;
447 window = (GtkWindow *) gtk_widget_get_toplevel(caller);
448 dialog = gtk_message_dialog_new_with_markup(window, GTK_DIALOG_MODAL,
449 GTK_MESSAGE_INFO,
450 GTK_BUTTONS_CLOSE,
451 "The requested operation generated\n"
452 "<b>%s</b> in the current directory.",
453 file);
454 gtk_window_set_title(GTK_WINDOW(dialog), "Operation completed");
455 gtk_dialog_run(GTK_DIALOG(dialog));
456 gtk_widget_destroy(dialog);
459 #endif
461 #if !defined(CAIRO_HAS_PNG_FUNCTIONS) || !defined(CAIRO_HAS_PDF_SURFACE) || !defined(CAIRO_HAS_PS_SURFACE)
463 /* Only needed if there is a missing surface */
464 static void
465 missing_feature(GtkWidget *caller, const gchar *feature)
467 GtkWindow *window;
468 GtkWidget *dialog;
470 window = (GtkWindow *) gtk_widget_get_toplevel(caller);
471 dialog = gtk_message_dialog_new(window, GTK_DIALOG_MODAL,
472 GTK_MESSAGE_WARNING,
473 GTK_BUTTONS_OK,
474 "The provided cairo library\n"
475 "was compiled with no %s support!",
476 feature);
477 gtk_window_set_title(GTK_WINDOW(dialog), "Missing feature");
478 gtk_dialog_run(GTK_DIALOG(dialog));
479 gtk_widget_destroy(dialog);
482 #endif
485 #ifdef CAIRO_HAS_PNG_FUNCTIONS
487 static void
488 to_png(AdgWidget *widget, GtkWidget *caller)
490 cairo_surface_t *surface;
491 cairo_t *cr;
493 surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 800, 600);
494 cr = cairo_create(surface);
495 cairo_surface_destroy(surface);
497 /* Rendering process */
498 adg_entity_render(ADG_ENTITY(adg_widget_get_canvas(widget)), cr);
500 cairo_show_page(cr);
501 cairo_surface_write_to_png(surface, "test.png");
502 cairo_destroy(cr);
504 file_generated(caller, "test.png");
507 #else
509 static void
510 to_png(AdgWidget *widget, GtkWidget *caller)
512 missing_feature(caller, "PNG");
515 #endif
517 #ifdef CAIRO_HAS_PDF_SURFACE
519 #include <cairo-pdf.h>
521 static void
522 to_pdf(AdgWidget *widget, GtkWidget *caller)
524 cairo_surface_t *surface;
525 cairo_t *cr;
527 surface = cairo_pdf_surface_create("test.pdf", 841, 595);
528 cr = cairo_create(surface);
529 cairo_surface_destroy(surface);
531 adg_entity_render(ADG_ENTITY(adg_widget_get_canvas(widget)), cr);
533 cairo_show_page(cr);
534 cairo_destroy(cr);
536 file_generated(caller, "test.pdf");
539 #else
541 static void
542 to_pdf(AdgWidget *widget, GtkWidget *caller)
544 missing_feature(caller, "PDF");
547 #endif
549 #ifdef CAIRO_HAS_PS_SURFACE
551 #include <cairo-ps.h>
553 static void
554 to_ps(AdgWidget *widget, GtkWidget *caller)
556 cairo_surface_t *surface;
557 cairo_t *cr;
559 /* Surface creation: A4 size */
560 surface = cairo_ps_surface_create("test.ps", 841, 595);
561 cairo_ps_surface_dsc_comment(surface,
562 "%%Title: Automatic Drawing Generation (ADG) demo");
563 cairo_ps_surface_dsc_comment(surface,
564 "%%Copyright: Copyright (C) 2006-2009 Fontana Nicola");
565 cairo_ps_surface_dsc_comment(surface, "%%Orientation: Portrait");
567 cairo_ps_surface_dsc_begin_setup(surface);
569 cairo_ps_surface_dsc_begin_page_setup(surface);
570 cairo_ps_surface_dsc_comment(surface,
571 "%%IncludeFeature: *PageSize A4");
573 cr = cairo_create(surface);
574 cairo_surface_destroy(surface);
576 adg_entity_render(ADG_ENTITY(adg_widget_get_canvas(widget)), cr);
578 cairo_show_page(cr);
579 cairo_destroy(cr);
581 file_generated(caller, "test.ps");
584 #else
586 static void
587 to_ps(AdgWidget *widget, GtkWidget *caller)
589 missing_feature(caller, "PostScript");
592 #endif
595 /**********************************************
596 * Test case for basic operations,
597 * such as chamfer and fillet
598 **********************************************/
600 static AdgPath * operations_chamfer (const AdgPath *path,
601 gdouble delta1,
602 gdouble delta2);
603 static AdgPath * operations_fillet (const AdgPath *path,
604 gdouble radius);
606 static AdgCanvas *
607 operations_canvas(void)
609 AdgPath *path, *chamfer_path, *fillet_path;
610 AdgCanvas *canvas;
611 AdgContainer *container;
612 AdgEntity *entity;
613 AdgMatrix map;
615 path = non_trivial_model();
616 chamfer_path = operations_chamfer(path, 0.25, 0.25);
617 fillet_path = operations_fillet(path, 0.20);
618 canvas = adg_canvas_new();
620 /* Add the original shape */
621 container = adg_container_new();
622 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
624 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
625 adg_container_add(container, entity);
627 entity = ADG_ENTITY(adg_toy_text_new("Original shape"));
628 cairo_matrix_init_translate(&map, 5, 10);
629 adg_entity_set_local_map(entity, &map);
630 cairo_matrix_init_translate(&map, -50, 20);
631 adg_entity_set_global_map(entity, &map);
632 adg_container_add(ADG_CONTAINER(canvas), entity);
634 /* Add the shape with 0.25x0.25 chamfer */
635 container = adg_container_new();
636 cairo_matrix_init_translate(&map, 15, 0);
637 adg_entity_set_local_map(ADG_ENTITY(container), &map);
638 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
640 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(chamfer_path)));
641 adg_container_add(container, entity);
643 entity = ADG_ENTITY(adg_toy_text_new("Shape with 0.25x0.25 chamfer"));
644 cairo_matrix_init_translate(&map, 5, 10);
645 adg_entity_set_local_map(entity, &map);
646 cairo_matrix_init_translate(&map, -120, 20);
647 adg_entity_set_global_map(entity, &map);
648 adg_container_add(container, entity);
650 /* Add the shape with fillets with 0.20 of radius */
651 container = adg_container_new();
652 cairo_matrix_init_translate(&map, 30, 0);
653 adg_entity_set_local_map(ADG_ENTITY(container), &map);
654 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
656 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(fillet_path)));
657 adg_container_add(container, entity);
659 entity = ADG_ENTITY(adg_toy_text_new("Shape with R=20 fillet"));
660 cairo_matrix_init_translate(&map, 5, 10);
661 adg_entity_set_local_map(entity, &map);
662 cairo_matrix_init_translate(&map, -90, 20);
663 adg_entity_set_global_map(entity, &map);
664 adg_container_add(container, entity);
666 /* Set a decent start position and zoom */
667 cairo_matrix_init_translate(&map, 10, -140);
668 cairo_matrix_scale(&map, 15, 15);
669 cairo_matrix_translate(&map, 0, 10);
670 adg_entity_set_local_map(ADG_ENTITY(canvas), &map);
672 return canvas;
675 static AdgPath *
676 operations_chamfer(const AdgPath *model, gdouble delta1, gdouble delta2)
678 AdgPath *path;
679 CpmlSegment segment;
680 CpmlPrimitive primitive;
681 CpmlPair org;
683 path = adg_path_new();
684 adg_trail_get_segment(ADG_TRAIL(model), &segment, 1);
685 cpml_primitive_from_segment(&primitive, &segment);
686 cpml_pair_from_cairo(&org, primitive.org);
688 adg_path_move_to(path, &org);
690 do {
691 adg_path_append_primitive(path, &primitive);
692 if (primitive.data[0].header.type == CAIRO_PATH_LINE_TO)
693 adg_path_chamfer(path, delta1, delta2);
694 } while (cpml_primitive_next(&primitive));
696 return path;
699 static AdgPath *
700 operations_fillet(const AdgPath *model, gdouble radius)
702 AdgPath *path;
703 CpmlSegment segment;
704 CpmlPrimitive primitive;
705 CpmlPair org;
707 path = adg_path_new();
708 adg_trail_get_segment(ADG_TRAIL(model), &segment, 1);
709 cpml_primitive_from_segment(&primitive, &segment);
710 cpml_pair_from_cairo(&org, primitive.org);
712 adg_path_move_to(path, &org);
714 do {
715 adg_path_append_primitive(path, &primitive);
716 if (primitive.data[0].header.type == CAIRO_PATH_LINE_TO)
717 adg_path_fillet(path, radius);
718 } while (cpml_primitive_next(&primitive));
720 return path;
724 /**********************************************
725 * Test case for mapping transformations,
726 * either on the local and global map
727 **********************************************/
729 static AdgCanvas *
730 mapping_canvas(void)
732 AdgPath *path;
733 AdgCanvas *canvas;
734 AdgContainer *container;
735 AdgEntity *entity;
736 AdgMatrix map;
738 path = non_trivial_model();
739 canvas = adg_canvas_new();
741 /* Add the original shape */
742 container = adg_container_new();
743 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
745 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
746 adg_container_add(container, entity);
748 entity = ADG_ENTITY(adg_toy_text_new("Original shape"));
749 cairo_matrix_init_translate(&map, -50, 20);
750 adg_entity_set_global_map(entity, &map);
751 cairo_matrix_init_translate(&map, 5, 10);
752 adg_entity_set_local_map(entity, &map);
753 adg_container_add(ADG_CONTAINER(canvas), entity);
755 /* Original shape with global rotated by 90 and local translated x+=10 */
756 container = adg_container_new();
757 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
758 cairo_matrix_init_translate(&map, 15, 0);
759 adg_entity_set_local_map(ADG_ENTITY(container), &map);
761 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
762 cairo_matrix_init_rotate(&map, M_PI_2);
763 adg_entity_set_global_map(entity, &map);
764 cairo_matrix_init_translate(&map, 10, 0);
765 adg_entity_set_local_map(entity, &map);
766 adg_container_add(container, entity);
768 entity = ADG_ENTITY(adg_toy_text_new("Global map rotated by 90"));
769 cairo_matrix_init_translate(&map, -120, 20);
770 adg_entity_set_global_map(entity, &map);
771 cairo_matrix_init_translate(&map, 5, 10);
772 adg_entity_set_local_map(entity, &map);
773 adg_container_add(container, entity);
775 /* Original shape with local translated x+=10 and rotated by 90 */
776 container = adg_container_new();
777 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
778 cairo_matrix_init_translate(&map, 30, 0);
779 adg_entity_set_local_map(ADG_ENTITY(container), &map);
781 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
782 cairo_matrix_init_translate(&map, 10, 0);
783 cairo_matrix_rotate(&map, M_PI_2);
784 adg_entity_set_local_map(entity, &map);
785 adg_container_add(container, entity);
787 entity = ADG_ENTITY(adg_toy_text_new("Local map rotated by 90"));
788 cairo_matrix_init_translate(&map, -120, 20);
789 adg_entity_set_global_map(entity, &map);
790 cairo_matrix_init_translate(&map, 5, 10);
791 adg_entity_set_local_map(entity, &map);
792 adg_container_add(container, entity);
794 /* Original shape with global map scaled by 0.5 */
795 container = adg_container_new();
796 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
797 cairo_matrix_init_translate(&map, 3.5, 15);
798 adg_entity_set_local_map(ADG_ENTITY(container), &map);
800 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
801 cairo_matrix_init_scale(&map, 0.5, 0.5);
802 adg_entity_set_global_map(entity, &map);
803 adg_container_add(container, entity);
805 entity = ADG_ENTITY(adg_toy_text_new("Global map scaled by 0.5"));
806 cairo_matrix_init_translate(&map, -100, 20);
807 adg_entity_set_global_map(entity, &map);
808 cairo_matrix_init_translate(&map, 2.5, 5);
809 adg_entity_set_local_map(entity, &map);
810 adg_container_add(container, entity);
812 /* Original shape with local map scaled by 0.5 */
813 container = adg_container_new();
814 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
815 cairo_matrix_init_translate(&map, 18, 15);
816 adg_entity_set_local_map(ADG_ENTITY(container), &map);
818 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
819 cairo_matrix_init_scale(&map, 0.5, 0.5);
820 adg_entity_set_local_map(entity, &map);
821 adg_container_add(container, entity);
823 entity = ADG_ENTITY(adg_toy_text_new("Local map scaled by 0.5"));
824 cairo_matrix_init_translate(&map, -100, 20);
825 adg_entity_set_global_map(entity, &map);
826 cairo_matrix_init_translate(&map, 2.5, 5);
827 adg_entity_set_local_map(entity, &map);
828 adg_container_add(container, entity);
830 /* Original shape with global and local maps scaled by 0.5 */
831 container = adg_container_new();
832 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
833 cairo_matrix_init_translate(&map, 33, 15);
834 adg_entity_set_local_map(ADG_ENTITY(container), &map);
836 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
837 cairo_matrix_init_scale(&map, 0.5, 0.5);
838 adg_entity_set_global_map(entity, &map);
839 adg_entity_set_local_map(entity, &map);
840 adg_container_add(container, entity);
842 entity = ADG_ENTITY(adg_toy_text_new("Local&global scaled by 0.5"));
843 cairo_matrix_init_translate(&map, -130, 20);
844 adg_entity_set_global_map(entity, &map);
845 cairo_matrix_init_translate(&map, 2.5, 5);
846 adg_entity_set_local_map(entity, &map);
847 adg_container_add(container, entity);
849 /* Set a decent start position and zoom */
850 cairo_matrix_init_translate(&map, 10, -140);
851 cairo_matrix_scale(&map, 15, 15);
852 cairo_matrix_translate(&map, 0, 10);
853 adg_entity_set_local_map(ADG_ENTITY(canvas), &map);
855 return canvas;
859 /**********************************************
860 * Non specific test related stuff
861 **********************************************/
863 static AdgPath *
864 non_trivial_model()
866 AdgPath *path = adg_path_new();
868 adg_path_move_to_explicit(path, 2, 0);
869 adg_path_line_to_explicit(path, 0, 5);
870 adg_path_line_to_explicit(path, 2, 2);
871 adg_path_line_to_explicit(path, 0, 8);
872 adg_path_line_to_explicit(path, 2, 8);
873 adg_path_line_to_explicit(path, 2, 10);
874 adg_path_line_to_explicit(path, 3, 10);
875 adg_path_line_to_explicit(path, 10, 9);
876 adg_path_line_to_explicit(path, 5, 5);
877 adg_path_line_to_explicit(path, 3, 0);
878 adg_path_close(path);
880 return path;