[AdgTrail] Added localization
[adg.git] / demo / adg-demo.c
blob5e67450bb756a6ce8bc55e77941b78c36282daa9
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 AdgCanvas * alignment_canvas (void);
11 static void to_pdf (AdgWidget *widget,
12 GtkWidget *caller);
13 static void to_png (AdgWidget *widget,
14 GtkWidget *caller);
15 static void to_ps (AdgWidget *widget,
16 GtkWidget *caller);
19 int
20 main(gint argc, gchar **argv)
22 gchar *path;
23 GtkBuilder *builder;
24 GError *error;
25 GtkWidget *window;
26 GtkWidget *widget;
28 gtk_init(&argc, &argv);
29 //adg_switch_extents(TRUE);
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");
47 gtk_window_maximize(GTK_WINDOW(window));
49 widget = (GtkWidget *) gtk_builder_get_object(builder, "areaSample");
50 g_signal_connect_swapped(gtk_builder_get_object(builder, "btnPng"),
51 "clicked", G_CALLBACK(to_png), widget);
52 g_signal_connect_swapped(gtk_builder_get_object(builder, "btnPdf"),
53 "clicked", G_CALLBACK(to_pdf), widget);
54 g_signal_connect_swapped(gtk_builder_get_object(builder, "btnPs"),
55 "clicked", G_CALLBACK(to_ps), widget);
56 adg_widget_set_canvas(ADG_WIDGET(widget), sample_canvas());
58 widget = (GtkWidget *) gtk_builder_get_object(builder, "areaOperations");
59 adg_widget_set_canvas(ADG_WIDGET(widget), operations_canvas());
61 widget = (GtkWidget *) gtk_builder_get_object(builder, "areaMapping");
62 adg_widget_set_canvas(ADG_WIDGET(widget), mapping_canvas());
64 widget = (GtkWidget *) gtk_builder_get_object(builder, "areaAlignment");
65 adg_widget_set_canvas(ADG_WIDGET(widget), alignment_canvas());
67 /* Connect signals */
68 g_signal_connect(window, "delete-event",
69 G_CALLBACK(gtk_main_quit), NULL);
70 g_signal_connect(gtk_builder_get_object(builder, "btnQuit"),
71 "clicked", G_CALLBACK(gtk_main_quit), NULL);
73 g_object_unref(builder);
75 gtk_widget_show_all(window);
76 gtk_main();
78 return 0;
82 static AdgPath * non_trivial_model (void);
85 /**********************************************
86 * A sample mechanical part example
87 **********************************************/
89 #define SQRT3 1.732050808
90 #define CHAMFER 0.3
92 typedef struct _SampleData SampleData;
94 struct _SampleData {
95 gdouble A, B, C;
96 gdouble DHOLE, LHOLE;
97 gdouble D1, D2, D3, D4, D5, D6, D7;
98 gdouble RD34, RD56;
99 gdouble LD2, LD3, LD5, LD6, LD7;
102 static void sample_get (SampleData *data);
103 static AdgPath *sample_bottom_path (const SampleData *data,
104 gdouble height);
105 static AdgPath *sample_path (const SampleData *data);
106 static void sample_add_sheet (AdgCanvas *canvas);
107 static void sample_add_dimensions (AdgCanvas *canvas,
108 AdgModel *model);
109 static void sample_add_stuff (AdgCanvas *canvas,
110 AdgModel *model);
113 static AdgCanvas *
114 sample_canvas(void)
116 SampleData data;
117 AdgCanvas *canvas;
118 AdgContainer *container;
119 AdgPath *bottom, *shape;
120 AdgEdges *edges;
121 AdgEntity *entity;
122 AdgMatrix map;
124 sample_get(&data);
125 canvas = adg_canvas_new();
126 container = (AdgContainer *) canvas;
128 bottom = sample_bottom_path(&data, data.LHOLE + 2);
129 adg_path_reflect(bottom, NULL);
130 adg_path_close(bottom);
132 shape = sample_path(&data);
133 adg_path_reflect(shape, NULL);
134 adg_path_close(shape);
135 adg_path_move_to_explicit(shape, data.LHOLE + 2, data.D1 / 2);
136 adg_path_line_to_explicit(shape, data.LHOLE + 2, -data.D1 / 2);
138 edges = adg_edges_new_with_source(ADG_TRAIL(shape));
140 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(shape)));
141 adg_container_add(container, entity);
143 entity = ADG_ENTITY(adg_hatch_new(ADG_TRAIL(bottom)));
144 adg_container_add(container, entity);
146 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(edges)));
147 adg_container_add(container, entity);
149 sample_add_sheet(canvas);
150 sample_add_dimensions(canvas, ADG_MODEL(shape));
151 sample_add_stuff(canvas, ADG_MODEL(shape));
153 cairo_matrix_init_translate(&map, 110, 70);
154 cairo_matrix_scale(&map, 6.883, 6.883);
155 cairo_matrix_translate(&map, 0, 10);
156 adg_entity_set_local_map(ADG_ENTITY(container), &map);
158 return canvas;
161 static void
162 sample_get(SampleData *data)
164 data->A = 52.3;
165 data->B = 20.6;
166 data->C = 2;
167 data->DHOLE = 2;
168 data->LHOLE = 3;
169 data->D1 = 9.3;
170 data->D2 = 6.5;
171 data->D3 = 11.9;
172 data->D4 = 6.5;
173 data->D5 = 4.5;
174 data->D6 = 7.2;
175 data->D7 = 3;
176 data->RD34 = 1;
177 data->LD2 = 7;
178 data->LD3 = 3.5;
179 data->LD5 = 5;
180 data->LD6 = 1;
181 data->LD7 = 0.5;
184 static AdgPath *
185 sample_bottom_path(const SampleData *data, gdouble height)
187 AdgPath *path;
188 AdgModel *model;
189 AdgPair pair;
191 path = adg_path_new();
192 model = ADG_MODEL(path);
194 pair.x = data->LHOLE;
195 pair.y = 0;
196 adg_path_move_to(path, &pair);
197 adg_model_set_named_pair(model, "LHOLE", &pair);
199 pair.y = data->DHOLE / 2;
200 pair.x -= pair.y / SQRT3;
201 adg_path_line_to(path, &pair);
203 pair.x = 0;
204 adg_path_line_to(path, &pair);
205 adg_model_set_named_pair(model, "DHOLE", &pair);
207 pair.y = data->D1 / 2;
208 adg_path_line_to(path, &pair);
209 adg_model_set_named_pair(model, "D1I", &pair);
211 pair.x = height;
212 adg_path_line_to(path, &pair);
213 adg_model_set_named_pair(model, "D1F", &pair);
215 return path;
218 static AdgPath *
219 sample_path(const SampleData *data)
221 AdgPath *path;
222 AdgModel *model;
223 AdgPair pair, tmp;
224 const AdgPrimitive *primitive;
226 pair.x = data->A - data->B - data->LD2;
227 path = sample_bottom_path(data, pair.x);
228 model = ADG_MODEL(path);
230 pair.x += (data->D1 - data->D2) * SQRT3 / 2;
231 pair.y = data->D2 / 2;
232 adg_path_line_to(path, &pair);
233 adg_model_set_named_pair(model, "D2I", &pair);
235 pair.x = data->A - data->B;
236 adg_path_line_to(path, &pair);
237 adg_path_fillet(path, 0.4);
239 pair.x = data->A - data->B;
240 pair.y = data->D3 / 2;
241 adg_path_line_to(path, &pair);
242 adg_model_set_named_pair(model, "D3I", &pair);
244 pair.x = data->A;
245 adg_model_set_named_pair(model, "East", &pair);
247 adg_path_chamfer(path, CHAMFER, CHAMFER);
249 pair.x = data->A - data->B + data->LD3;
250 pair.y = data->D3 / 2;
251 adg_path_line_to(path, &pair);
253 primitive = adg_path_over_primitive(path);
254 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
255 adg_model_set_named_pair(model, "D3I_X", &tmp);
257 adg_path_chamfer(path, CHAMFER, CHAMFER);
259 pair.y = data->D4 / 2;
260 adg_path_line_to(path, &pair);
262 primitive = adg_path_over_primitive(path);
263 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
264 adg_model_set_named_pair(model, "D3F_Y", &tmp);
265 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, -1));
266 adg_model_set_named_pair(model, "D3F_X", &tmp);
268 adg_path_fillet(path, data->RD34);
270 pair.x = data->A - data->C - data->LD5;
271 adg_path_line_to(path, &pair);
272 adg_model_set_named_pair(model, "D4F", &pair);
274 primitive = adg_path_over_primitive(path);
275 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
276 tmp.x += data->RD34;
277 adg_model_set_named_pair(model, "RD34", &tmp);
279 tmp.x -= cos(G_PI_4) * data->RD34,
280 tmp.y -= sin(G_PI_4) * data->RD34,
281 adg_model_set_named_pair(model, "RD34_R", &tmp);
283 tmp.x += data->RD34,
284 tmp.y += data->RD34,
285 adg_model_set_named_pair(model, "RD34_XY", &tmp);
287 pair.x += (data->D4 - data->D5) / 2;
288 pair.y = data->D5 / 2;
289 adg_path_line_to(path, &pair);
291 pair.x = data->A - data->C;
292 adg_path_line_to(path, &pair);
294 adg_path_fillet(path, 0.2);
296 pair.y = data->D6 / 2;
297 adg_path_line_to(path, &pair);
299 primitive = adg_path_over_primitive(path);
300 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
301 adg_model_set_named_pair(model, "D5F", &tmp);
303 adg_path_fillet(path, 0.1);
305 pair.x += data->LD6;
306 adg_path_line_to(path, &pair);
307 adg_model_set_named_pair(model, "D6F", &pair);
309 primitive = adg_path_over_primitive(path);
310 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, -1));
311 adg_model_set_named_pair(model, "D6I_Y", &tmp);
313 pair.x = data->A - data->LD7;
314 pair.y -= (data->C - data->LD7 - data->LD6) / SQRT3;
315 adg_path_line_to(path, &pair);
316 adg_model_set_named_pair(model, "D67", &pair);
318 pair.y = data->D7 / 2;
319 adg_path_line_to(path, &pair);
321 pair.x = data->A;
322 adg_path_line_to(path, &pair);
323 adg_model_set_named_pair(model, "D7F", &pair);
325 return path;
328 static void
329 sample_add_sheet(AdgCanvas *canvas)
331 AdgTitleBlock *title_block;
332 AdgLogo *logo;
333 AdgMatrix map;
335 title_block = adg_title_block_new();
337 logo = adg_logo_new();
338 cairo_matrix_init_scale(&map, 2, 2);
339 adg_entity_set_global_map(ADG_ENTITY(logo), &map);
341 g_object_set(title_block,
342 "title", "SAMPLE DRAWING",
343 "author", "NtD",
344 "date", "",
345 "drawing", "TEST123",
346 "logo", logo,
347 "projection", adg_projection_new(ADG_PROJECTION_FIRST_ANGLE),
348 "scale", "NONE",
349 "size", "A4",
350 NULL);
352 cairo_matrix_init_translate(&map, 800, 600);
353 adg_entity_set_global_map(ADG_ENTITY(title_block), &map);
355 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(title_block));
358 static void
359 sample_add_dimensions(AdgCanvas *canvas, AdgModel *model)
361 AdgLDim *ldim;
362 AdgADim *adim;
363 AdgRDim *rdim;
365 /* NORTH */
367 ldim = adg_ldim_new_full_from_model(model, "-D1F", "-D3I_X", "-D3F_Y",
368 ADG_DIR_UP);
369 adg_dim_set_outside(ADG_DIM(ldim), ADG_THREE_STATE_OFF);
370 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
372 ldim = adg_ldim_new_full_from_model(model, "-D3I_X", "-D3F_X", "-D3F_Y",
373 ADG_DIR_UP);
374 adg_ldim_switch_extension1(ldim, FALSE);
375 adg_dim_set_outside(ADG_DIM(ldim), ADG_THREE_STATE_OFF);
376 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
378 /* SOUTH */
380 ldim = adg_ldim_new_full_from_model(model, "D1I", "LHOLE", "D3F_Y",
381 ADG_DIR_DOWN);
382 adg_ldim_switch_extension1(ldim, FALSE);
383 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
385 ldim = adg_ldim_new_full_from_model(model, "D3I_X", "D7F", "D3F_Y",
386 ADG_DIR_DOWN);
387 adg_dim_set_limits(ADG_DIM(ldim), NULL, "+0.1");
388 adg_ldim_switch_extension2(ldim, FALSE);
389 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
391 ldim = adg_ldim_new_full_from_model(model, "D1I", "D7F", "D3F_Y",
392 ADG_DIR_DOWN);
393 adg_dim_set_limits(ADG_DIM(ldim), "-0.05", "+0.05");
394 adg_dim_set_level(ADG_DIM(ldim), 2);
395 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
397 adim = adg_adim_new_full_from_model(model, "D6F", "D6I_Y", "D67",
398 "D6F", "D6F");
399 adg_dim_set_level(ADG_DIM(adim), 2);
400 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(adim));
402 rdim = adg_rdim_new_full_from_model(model, "RD34", "RD34_R", "RD34_XY");
403 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(rdim));
405 /* EAST */
407 ldim = adg_ldim_new_full_from_model(model, "D3F_Y", "-D3F_Y", "East",
408 ADG_DIR_RIGHT);
409 adg_dim_set_limits(ADG_DIM(ldim), "-0.25", NULL);
410 adg_dim_set_level(ADG_DIM(ldim), 5);
411 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
413 ldim = adg_ldim_new_full_from_model(model, "D6F", "-D6F", "-East",
414 ADG_DIR_RIGHT);
415 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
416 adg_dim_set_level(ADG_DIM(ldim), 4);
417 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
419 ldim = adg_ldim_new_full_from_model(model, "D4F", "-D4F", "East",
420 ADG_DIR_RIGHT);
421 adg_dim_set_level(ADG_DIM(ldim), 3);
422 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
424 ldim = adg_ldim_new_full_from_model(model, "D5F", "-D5F", "-East",
425 ADG_DIR_RIGHT);
426 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
427 adg_dim_set_level(ADG_DIM(ldim), 2);
428 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
430 ldim = adg_ldim_new_full_from_model(model, "D7F", "-D7F", "East",
431 ADG_DIR_RIGHT);
432 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
434 /* WEST */
436 ldim = adg_ldim_new_full_from_model(model, "D1I", "-D1I", "D1I",
437 ADG_DIR_LEFT);
438 adg_dim_set_limits(ADG_DIM(ldim), "+0.05", "-0.05");
439 adg_dim_set_level(ADG_DIM(ldim), 3);
440 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
442 ldim = adg_ldim_new_full_from_model(model, "D2I", "-D2I", "D1I",
443 ADG_DIR_LEFT);
444 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
445 adg_dim_set_level(ADG_DIM(ldim), 2);
446 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
448 ldim = adg_ldim_new_full_from_model(model, "DHOLE", "-DHOLE", "D1I",
449 ADG_DIR_LEFT);
450 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
453 static void
454 sample_add_stuff(AdgCanvas *canvas, AdgModel *model)
456 AdgToyText *toy_text;
457 AdgMatrix map;
458 const AdgPair *pair;
460 toy_text = adg_toy_text_new("Rotate the mouse wheel to zoom in and out");
461 pair = adg_model_get_named_pair(model, "D3I");
462 cairo_matrix_init_translate(&map, 0, pair->y);
463 adg_entity_set_local_map(ADG_ENTITY(toy_text), &map);
464 cairo_matrix_init_translate(&map, 10, 30 + 30 * 2);
465 adg_entity_set_global_map(ADG_ENTITY(toy_text), &map);
466 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(toy_text));
468 toy_text = adg_toy_text_new("Keep the wheel pressed while dragging the mouse to translate");
469 cairo_matrix_init_translate(&map, 0, pair->y);
470 adg_entity_set_local_map(ADG_ENTITY(toy_text), &map);
471 cairo_matrix_init_translate(&map, 10, 50 + 30 * 2);
472 adg_entity_set_global_map(ADG_ENTITY(toy_text), &map);
473 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(toy_text));
477 #if defined(CAIRO_HAS_PNG_FUNCTIONS) || defined(CAIRO_HAS_PDF_SURFACE) || defined(CAIRO_HAS_PS_SURFACE)
479 /* Only needed if there is at least one supported surface */
480 static void
481 file_generated(GtkWidget *caller, const gchar *file)
483 GtkWindow *window;
484 GtkWidget *dialog;
486 window = (GtkWindow *) gtk_widget_get_toplevel(caller);
487 dialog = gtk_message_dialog_new_with_markup(window, GTK_DIALOG_MODAL,
488 GTK_MESSAGE_INFO,
489 GTK_BUTTONS_CLOSE,
490 "The requested operation generated\n"
491 "<b>%s</b> in the current directory.",
492 file);
493 gtk_window_set_title(GTK_WINDOW(dialog), "Operation completed");
494 gtk_dialog_run(GTK_DIALOG(dialog));
495 gtk_widget_destroy(dialog);
498 #endif
500 #if !defined(CAIRO_HAS_PNG_FUNCTIONS) || !defined(CAIRO_HAS_PDF_SURFACE) || !defined(CAIRO_HAS_PS_SURFACE)
502 /* Only needed if there is a missing surface */
503 static void
504 missing_feature(GtkWidget *caller, const gchar *feature)
506 GtkWindow *window;
507 GtkWidget *dialog;
509 window = (GtkWindow *) gtk_widget_get_toplevel(caller);
510 dialog = gtk_message_dialog_new(window, GTK_DIALOG_MODAL,
511 GTK_MESSAGE_WARNING,
512 GTK_BUTTONS_OK,
513 "The provided cairo library\n"
514 "was compiled with no %s support!",
515 feature);
516 gtk_window_set_title(GTK_WINDOW(dialog), "Missing feature");
517 gtk_dialog_run(GTK_DIALOG(dialog));
518 gtk_widget_destroy(dialog);
521 #endif
524 #ifdef CAIRO_HAS_PNG_FUNCTIONS
526 static void
527 to_png(AdgWidget *widget, GtkWidget *caller)
529 cairo_surface_t *surface;
530 cairo_t *cr;
532 surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 800, 600);
533 cr = cairo_create(surface);
534 cairo_surface_destroy(surface);
536 /* Rendering process */
537 adg_entity_render(ADG_ENTITY(adg_widget_get_canvas(widget)), cr);
539 cairo_show_page(cr);
540 cairo_surface_write_to_png(surface, "test.png");
541 cairo_destroy(cr);
543 file_generated(caller, "test.png");
546 #else
548 static void
549 to_png(AdgWidget *widget, GtkWidget *caller)
551 missing_feature(caller, "PNG");
554 #endif
556 #ifdef CAIRO_HAS_PDF_SURFACE
558 #include <cairo-pdf.h>
560 static void
561 to_pdf(AdgWidget *widget, GtkWidget *caller)
563 cairo_surface_t *surface;
564 cairo_t *cr;
566 surface = cairo_pdf_surface_create("test.pdf", 841, 595);
567 cr = cairo_create(surface);
568 cairo_surface_destroy(surface);
570 adg_entity_render(ADG_ENTITY(adg_widget_get_canvas(widget)), cr);
572 cairo_show_page(cr);
573 cairo_destroy(cr);
575 file_generated(caller, "test.pdf");
578 #else
580 static void
581 to_pdf(AdgWidget *widget, GtkWidget *caller)
583 missing_feature(caller, "PDF");
586 #endif
588 #ifdef CAIRO_HAS_PS_SURFACE
590 #include <cairo-ps.h>
592 static void
593 to_ps(AdgWidget *widget, GtkWidget *caller)
595 cairo_surface_t *surface;
596 cairo_t *cr;
598 /* Surface creation: A4 size */
599 surface = cairo_ps_surface_create("test.ps", 841, 595);
600 cairo_ps_surface_dsc_comment(surface,
601 "%%Title: Automatic Drawing Generation (ADG) demo");
602 cairo_ps_surface_dsc_comment(surface,
603 "%%Copyright: Copyright (C) 2006-2009 Fontana Nicola");
604 cairo_ps_surface_dsc_comment(surface, "%%Orientation: Portrait");
606 cairo_ps_surface_dsc_begin_setup(surface);
608 cairo_ps_surface_dsc_begin_page_setup(surface);
609 cairo_ps_surface_dsc_comment(surface,
610 "%%IncludeFeature: *PageSize A4");
612 cr = cairo_create(surface);
613 cairo_surface_destroy(surface);
615 adg_entity_render(ADG_ENTITY(adg_widget_get_canvas(widget)), cr);
617 cairo_show_page(cr);
618 cairo_destroy(cr);
620 file_generated(caller, "test.ps");
623 #else
625 static void
626 to_ps(AdgWidget *widget, GtkWidget *caller)
628 missing_feature(caller, "PostScript");
631 #endif
634 /**********************************************
635 * Test case for basic operations,
636 * such as chamfer and fillet
637 **********************************************/
639 static AdgPath * operations_chamfer (const AdgPath *path,
640 gdouble delta1,
641 gdouble delta2);
642 static AdgPath * operations_fillet (const AdgPath *path,
643 gdouble radius);
645 static AdgCanvas *
646 operations_canvas(void)
648 AdgPath *path, *chamfer_path, *fillet_path;
649 AdgCanvas *canvas;
650 AdgContainer *container;
651 AdgEntity *entity;
652 AdgMatrix map;
654 path = non_trivial_model();
655 chamfer_path = operations_chamfer(path, 0.25, 0.25);
656 fillet_path = operations_fillet(path, 0.20);
657 canvas = adg_canvas_new();
659 /* Add the original shape */
660 container = adg_container_new();
661 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
663 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
664 adg_container_add(container, entity);
666 entity = ADG_ENTITY(adg_toy_text_new("Original shape"));
667 cairo_matrix_init_translate(&map, 5, 10);
668 adg_entity_set_local_map(entity, &map);
669 cairo_matrix_init_translate(&map, -50, 20);
670 adg_entity_set_global_map(entity, &map);
671 adg_container_add(ADG_CONTAINER(canvas), entity);
673 /* Add the shape with 0.25x0.25 chamfer */
674 container = adg_container_new();
675 cairo_matrix_init_translate(&map, 15, 0);
676 adg_entity_set_local_map(ADG_ENTITY(container), &map);
677 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
679 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(chamfer_path)));
680 adg_container_add(container, entity);
682 entity = ADG_ENTITY(adg_toy_text_new("Shape with 0.25x0.25 chamfer"));
683 cairo_matrix_init_translate(&map, 5, 10);
684 adg_entity_set_local_map(entity, &map);
685 cairo_matrix_init_translate(&map, -120, 20);
686 adg_entity_set_global_map(entity, &map);
687 adg_container_add(container, entity);
689 /* Add the shape with fillets with 0.20 of radius */
690 container = adg_container_new();
691 cairo_matrix_init_translate(&map, 30, 0);
692 adg_entity_set_local_map(ADG_ENTITY(container), &map);
693 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
695 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(fillet_path)));
696 adg_container_add(container, entity);
698 entity = ADG_ENTITY(adg_toy_text_new("Shape with R=0.20 fillet"));
699 cairo_matrix_init_translate(&map, 5, 10);
700 adg_entity_set_local_map(entity, &map);
701 cairo_matrix_init_translate(&map, -90, 20);
702 adg_entity_set_global_map(entity, &map);
703 adg_container_add(container, entity);
705 /* Set a decent start position and zoom */
706 cairo_matrix_init_translate(&map, 10, -140);
707 cairo_matrix_scale(&map, 15, 15);
708 cairo_matrix_translate(&map, 0, 10);
709 adg_entity_set_local_map(ADG_ENTITY(canvas), &map);
711 return canvas;
714 static AdgPath *
715 operations_chamfer(const AdgPath *model, gdouble delta1, gdouble delta2)
717 AdgPath *path;
718 CpmlSegment segment;
719 CpmlPrimitive primitive;
720 CpmlPair org;
722 path = adg_path_new();
723 adg_trail_put_segment(ADG_TRAIL(model), 1, &segment);
724 cpml_primitive_from_segment(&primitive, &segment);
725 cpml_pair_from_cairo(&org, primitive.org);
727 adg_path_move_to(path, &org);
729 do {
730 adg_path_append_primitive(path, &primitive);
731 adg_path_chamfer(path, delta1, delta2);
732 } while (cpml_primitive_next(&primitive));
734 return path;
737 static AdgPath *
738 operations_fillet(const AdgPath *model, gdouble radius)
740 AdgPath *path;
741 CpmlSegment segment;
742 CpmlPrimitive primitive;
743 CpmlPair org;
745 path = adg_path_new();
746 adg_trail_put_segment(ADG_TRAIL(model), 1, &segment);
747 cpml_primitive_from_segment(&primitive, &segment);
748 cpml_pair_from_cairo(&org, primitive.org);
750 adg_path_move_to(path, &org);
752 do {
753 adg_path_append_primitive(path, &primitive);
754 adg_path_fillet(path, radius);
755 } while (cpml_primitive_next(&primitive));
757 return path;
761 /**********************************************
762 * Test case for mapping transformations,
763 * either on the local and global map
764 **********************************************/
766 static AdgCanvas *
767 mapping_canvas(void)
769 AdgPath *path;
770 AdgCanvas *canvas;
771 AdgContainer *container;
772 AdgEntity *entity;
773 AdgMatrix map;
775 path = non_trivial_model();
776 canvas = adg_canvas_new();
778 /* Original shape */
779 container = adg_container_new();
780 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
782 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
783 adg_container_add(container, entity);
785 entity = ADG_ENTITY(adg_toy_text_new("Original shape"));
786 cairo_matrix_init_translate(&map, -50, 20);
787 adg_entity_set_global_map(entity, &map);
788 cairo_matrix_init_translate(&map, 5, 10);
789 adg_entity_set_local_map(entity, &map);
790 adg_container_add(ADG_CONTAINER(canvas), entity);
792 /* Global map rotated by 90 */
793 container = adg_container_new();
794 cairo_matrix_init_translate(&map, 0, -25);
795 adg_entity_set_local_map(ADG_ENTITY(container), &map);
796 cairo_matrix_init_rotate(&map, M_PI_2);
797 adg_entity_set_global_map(ADG_ENTITY(container), &map);
798 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
800 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
801 adg_container_add(container, entity);
803 entity = ADG_ENTITY(adg_toy_text_new("Global map rotated by 90"));
804 cairo_matrix_init_translate(&map, -100, 20);
805 adg_entity_set_global_map(entity, &map);
806 cairo_matrix_init_translate(&map, 5, 10);
807 adg_entity_set_local_map(entity, &map);
808 adg_container_add(container, entity);
810 /* Local map rotated by 90 */
811 container = adg_container_new();
812 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
813 cairo_matrix_init_translate(&map, 40, 0);
814 cairo_matrix_rotate(&map, M_PI_2);
815 adg_entity_set_local_map(ADG_ENTITY(container), &map);
817 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
818 adg_container_add(container, entity);
820 entity = ADG_ENTITY(adg_toy_text_new("Local map rotated by 90"));
821 cairo_matrix_init_translate(&map, -20, -100);
822 adg_entity_set_global_map(entity, &map);
823 cairo_matrix_init_translate(&map, 5, 10);
824 adg_entity_set_local_map(entity, &map);
825 adg_container_add(container, entity);
827 /* Global map scaled by 0.5 */
828 container = adg_container_new();
829 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
830 cairo_matrix_init_translate(&map, 5, 30);
831 adg_entity_set_local_map(ADG_ENTITY(container), &map);
832 cairo_matrix_init_scale(&map, 0.5, 0.5);
833 adg_entity_set_global_map(ADG_ENTITY(container), &map);
835 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
836 adg_container_add(container, entity);
838 entity = ADG_ENTITY(adg_toy_text_new("Global map scaled by 0.5"));
839 cairo_matrix_init_translate(&map, -80, 20);
840 adg_entity_set_global_map(entity, &map);
841 cairo_matrix_init_translate(&map, 5, 10);
842 adg_entity_set_local_map(entity, &map);
843 adg_container_add(container, entity);
845 /* Local map scaled by 0.5 */
846 container = adg_container_new();
847 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
848 cairo_matrix_init_translate(&map, 18, 15);
849 cairo_matrix_scale(&map, 0.5, 0.5);
850 adg_entity_set_local_map(ADG_ENTITY(container), &map);
852 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
853 adg_container_add(container, entity);
855 entity = ADG_ENTITY(adg_toy_text_new("Local map scaled by 0.5"));
856 cairo_matrix_init_translate(&map, -80, 20);
857 adg_entity_set_global_map(entity, &map);
858 cairo_matrix_init_translate(&map, 5, 10);
859 adg_entity_set_local_map(entity, &map);
860 adg_container_add(container, entity);
862 /* Global and local maps scaled by 0.5 */
863 container = adg_container_new();
864 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
865 cairo_matrix_init_translate(&map, 66, 30);
866 cairo_matrix_scale(&map, 0.5, 0.5);
867 adg_entity_set_local_map(ADG_ENTITY(container), &map);
868 cairo_matrix_init_scale(&map, 0.5, 0.5);
869 adg_entity_set_global_map(ADG_ENTITY(container), &map);
871 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
872 adg_container_add(container, entity);
874 entity = ADG_ENTITY(adg_toy_text_new("Local and global map scaled by 0.5"));
875 cairo_matrix_init_translate(&map, -140, 20);
876 adg_entity_set_global_map(entity, &map);
877 cairo_matrix_init_translate(&map, 5, 10);
878 adg_entity_set_local_map(entity, &map);
879 adg_container_add(container, entity);
881 /* Set a decent start position and zoom */
882 cairo_matrix_init_scale(&map, 15, 15);
883 adg_entity_set_local_map(ADG_ENTITY(canvas), &map);
884 cairo_matrix_init_translate(&map, 100, 100);
885 adg_entity_set_global_map(ADG_ENTITY(canvas), &map);
887 return canvas;
891 /**********************************************
892 * Test case for alignments of entities
893 * using different factors
894 **********************************************/
896 static AdgCanvas *
897 alignment_canvas(void)
899 AdgPath *path;
900 AdgCanvas *canvas;
901 AdgPath *axis;
902 AdgAlignment *alignment;
903 AdgStroke *stroke;
904 AdgMatrix map;
906 path = non_trivial_model();
907 canvas = adg_canvas_new();
908 cairo_matrix_init_scale(&map, 2, 2);
910 axis = adg_path_new();
911 adg_path_move_to_explicit(axis, -15, 0);
912 adg_path_line_to_explicit(axis, 15, 0);
913 adg_path_move_to_explicit(axis, 0, -15);
914 adg_path_line_to_explicit(axis, 0, 15);
916 /* Axis */
917 stroke = adg_stroke_new(ADG_TRAIL(axis));
918 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(stroke));
920 /* Original path */
921 alignment = adg_alignment_new_explicit(0, 0);
922 stroke = adg_stroke_new(ADG_TRAIL(path));
923 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
924 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
926 /* Path scaled in local space */
927 alignment = adg_alignment_new_explicit(0.5, 0.5);
928 stroke = adg_stroke_new(ADG_TRAIL(path));
929 adg_entity_set_local_map(ADG_ENTITY(stroke), &map);
930 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
931 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
933 alignment = adg_alignment_new_explicit(1, 1);
934 stroke = adg_stroke_new(ADG_TRAIL(path));
935 adg_entity_set_local_map(ADG_ENTITY(stroke), &map);
936 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
937 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
939 /* Path scaled in global space */
940 alignment = adg_alignment_new_explicit(0, 0);
941 stroke = adg_stroke_new(ADG_TRAIL(path));
942 cairo_matrix_init_scale(&map, 2, 2);
943 adg_entity_set_global_map(ADG_ENTITY(stroke), &map);
944 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
945 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
947 alignment = adg_alignment_new_explicit(-0.5, -0.5);
948 stroke = adg_stroke_new(ADG_TRAIL(path));
949 adg_entity_set_global_map(ADG_ENTITY(stroke), &map);
950 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
951 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
953 alignment = adg_alignment_new_explicit(-0.25, -0.25);
954 stroke = adg_stroke_new(ADG_TRAIL(path));
955 adg_entity_set_global_map(ADG_ENTITY(stroke), &map);
956 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
957 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
959 /* Set a decent start position and zoom */
960 cairo_matrix_init_scale(&map, 15, 15);
961 cairo_matrix_translate(&map, 20, 20);
962 adg_entity_set_local_map(ADG_ENTITY(canvas), &map);
964 cairo_matrix_init_translate(&map, 20, 20);
965 adg_entity_set_global_map(ADG_ENTITY(canvas), &map);
967 return canvas;
971 /**********************************************
972 * Non specific test related stuff
973 **********************************************/
975 static AdgPath *
976 non_trivial_model()
978 AdgPath *path = adg_path_new();
980 adg_path_move_to_explicit(path, 2, 0);
981 adg_path_line_to_explicit(path, 0, 5);
982 adg_path_line_to_explicit(path, 2, 2);
983 adg_path_line_to_explicit(path, 0, 8);
984 adg_path_line_to_explicit(path, 2, 8);
985 adg_path_line_to_explicit(path, 2, 10);
986 adg_path_line_to_explicit(path, 3, 10);
987 adg_path_line_to_explicit(path, 10, 9);
988 adg_path_line_to_explicit(path, 5, 5);
989 adg_path_line_to_explicit(path, 3, 0);
990 adg_path_close(path);
992 return path;