[CPML] s/npoint/n_point/
[adg.git] / demo / adg-demo.c
blob124905f88f8114046538cc55ca02c67d8af86d3a
1 #include <adg/adg.h>
2 #include <adg/adg-widget.h>
3 #include <math.h>
5 #include "demo.h"
8 static AdgCanvas * sample_canvas (void);
9 static AdgCanvas * operations_canvas (void);
10 static AdgCanvas * mapping_canvas (void);
11 static AdgCanvas * alignment_canvas (void);
12 static void to_pdf (AdgWidget *widget,
13 GtkWidget *caller);
14 static void to_png (AdgWidget *widget,
15 GtkWidget *caller);
16 static void to_ps (AdgWidget *widget,
17 GtkWidget *caller);
20 int
21 main(gint argc, gchar **argv)
23 gchar *path;
24 GtkBuilder *builder;
25 GError *error;
26 GtkWidget *window;
27 GtkWidget *widget;
29 gtk_init(&argc, &argv);
30 //adg_switch_extents(TRUE);
32 path = demo_find_data_file("adg-demo.ui");
33 if (path == NULL) {
34 g_print("adg-demo.ui not found!\n");
35 return 1;
38 builder = gtk_builder_new();
39 error = NULL;
41 gtk_builder_add_from_file(builder, path, &error);
42 if (error != NULL) {
43 g_print("%s\n", error->message);
44 return 2;
47 window = (GtkWidget *) gtk_builder_get_object(builder, "wndMain");
48 gtk_window_maximize(GTK_WINDOW(window));
50 widget = (GtkWidget *) gtk_builder_get_object(builder, "areaSample");
51 g_signal_connect_swapped(gtk_builder_get_object(builder, "btnPng"),
52 "clicked", G_CALLBACK(to_png), widget);
53 g_signal_connect_swapped(gtk_builder_get_object(builder, "btnPdf"),
54 "clicked", G_CALLBACK(to_pdf), widget);
55 g_signal_connect_swapped(gtk_builder_get_object(builder, "btnPs"),
56 "clicked", G_CALLBACK(to_ps), widget);
57 adg_widget_set_canvas(ADG_WIDGET(widget), sample_canvas());
59 widget = (GtkWidget *) gtk_builder_get_object(builder, "areaOperations");
60 adg_widget_set_canvas(ADG_WIDGET(widget), operations_canvas());
62 widget = (GtkWidget *) gtk_builder_get_object(builder, "areaMapping");
63 adg_widget_set_canvas(ADG_WIDGET(widget), mapping_canvas());
65 widget = (GtkWidget *) gtk_builder_get_object(builder, "areaAlignment");
66 adg_widget_set_canvas(ADG_WIDGET(widget), alignment_canvas());
68 /* Connect signals */
69 g_signal_connect(window, "delete-event",
70 G_CALLBACK(gtk_main_quit), NULL);
71 g_signal_connect(gtk_builder_get_object(builder, "btnQuit"),
72 "clicked", G_CALLBACK(gtk_main_quit), NULL);
74 g_object_unref(builder);
76 gtk_widget_show_all(window);
77 gtk_main();
79 return 0;
83 static AdgPath * non_trivial_model (void);
86 /**********************************************
87 * A sample mechanical part example
88 **********************************************/
90 #define SQRT3 1.732050808
91 #define CHAMFER 0.3
93 typedef struct _SampleData SampleData;
95 struct _SampleData {
96 gdouble A, B, C;
97 gdouble DHOLE, LHOLE;
98 gdouble D1, D2, D3, D4, D5, D6, D7;
99 gdouble RD34, RD56;
100 gdouble LD2, LD3, LD5, LD6, LD7;
103 static void sample_get (SampleData *data);
104 static AdgPath *sample_bottom_path (const SampleData *data,
105 gdouble height);
106 static AdgPath *sample_path (const SampleData *data);
107 static void sample_add_sheet (AdgCanvas *canvas);
108 static void sample_add_dimensions (AdgCanvas *canvas,
109 AdgModel *model);
110 static void sample_add_stuff (AdgCanvas *canvas,
111 AdgModel *model);
114 static AdgCanvas *
115 sample_canvas(void)
117 SampleData data;
118 AdgCanvas *canvas;
119 AdgContainer *container;
120 AdgPath *bottom, *shape;
121 AdgEdges *edges;
122 AdgEntity *entity;
123 AdgMatrix map;
125 sample_get(&data);
126 canvas = adg_canvas_new();
127 container = (AdgContainer *) canvas;
129 bottom = sample_bottom_path(&data, data.LHOLE + 2);
130 adg_path_reflect(bottom, NULL);
131 adg_path_close(bottom);
133 shape = sample_path(&data);
134 adg_path_reflect(shape, NULL);
135 adg_path_close(shape);
136 adg_path_move_to_explicit(shape, data.LHOLE + 2, data.D1 / 2);
137 adg_path_line_to_explicit(shape, data.LHOLE + 2, -data.D1 / 2);
139 edges = adg_edges_new_with_source(ADG_TRAIL(shape));
141 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(shape)));
142 adg_container_add(container, entity);
144 entity = ADG_ENTITY(adg_hatch_new(ADG_TRAIL(bottom)));
145 adg_container_add(container, entity);
147 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(edges)));
148 adg_container_add(container, entity);
150 sample_add_sheet(canvas);
151 sample_add_dimensions(canvas, ADG_MODEL(shape));
152 sample_add_stuff(canvas, ADG_MODEL(shape));
154 cairo_matrix_init_translate(&map, 110, 70);
155 cairo_matrix_scale(&map, 6.883, 6.883);
156 cairo_matrix_translate(&map, 0, 10);
157 adg_entity_set_local_map(ADG_ENTITY(container), &map);
159 return canvas;
162 static void
163 sample_get(SampleData *data)
165 data->A = 52.3;
166 data->B = 20.6;
167 data->C = 2;
168 data->DHOLE = 2;
169 data->LHOLE = 3;
170 data->D1 = 9.3;
171 data->D2 = 6.5;
172 data->D3 = 11.9;
173 data->D4 = 6.5;
174 data->D5 = 4.5;
175 data->D6 = 7.2;
176 data->D7 = 3;
177 data->RD34 = 1;
178 data->LD2 = 7;
179 data->LD3 = 3.5;
180 data->LD5 = 5;
181 data->LD6 = 1;
182 data->LD7 = 0.5;
185 static AdgPath *
186 sample_bottom_path(const SampleData *data, gdouble height)
188 AdgPath *path;
189 AdgModel *model;
190 AdgPair pair;
192 path = adg_path_new();
193 model = ADG_MODEL(path);
195 pair.x = data->LHOLE;
196 pair.y = 0;
197 adg_path_move_to(path, &pair);
198 adg_model_set_named_pair(model, "LHOLE", &pair);
200 pair.y = data->DHOLE / 2;
201 pair.x -= pair.y / SQRT3;
202 adg_path_line_to(path, &pair);
204 pair.x = 0;
205 adg_path_line_to(path, &pair);
206 adg_model_set_named_pair(model, "DHOLE", &pair);
208 pair.y = data->D1 / 2;
209 adg_path_line_to(path, &pair);
210 adg_model_set_named_pair(model, "D1I", &pair);
212 pair.x = height;
213 adg_path_line_to(path, &pair);
214 adg_model_set_named_pair(model, "D1F", &pair);
216 return path;
219 static AdgPath *
220 sample_path(const SampleData *data)
222 AdgPath *path;
223 AdgModel *model;
224 AdgPair pair, tmp;
225 const AdgPrimitive *primitive;
227 pair.x = data->A - data->B - data->LD2;
228 path = sample_bottom_path(data, pair.x);
229 model = ADG_MODEL(path);
231 pair.x += (data->D1 - data->D2) * SQRT3 / 2;
232 pair.y = data->D2 / 2;
233 adg_path_line_to(path, &pair);
234 adg_model_set_named_pair(model, "D2I", &pair);
236 pair.x = data->A - data->B;
237 adg_path_line_to(path, &pair);
238 adg_path_fillet(path, 0.4);
240 pair.x = data->A - data->B;
241 pair.y = data->D3 / 2;
242 adg_path_line_to(path, &pair);
243 adg_model_set_named_pair(model, "D3I", &pair);
245 pair.x = data->A;
246 adg_model_set_named_pair(model, "East", &pair);
248 adg_path_chamfer(path, CHAMFER, CHAMFER);
250 pair.x = data->A - data->B + data->LD3;
251 pair.y = data->D3 / 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, "D3I_X", &tmp);
258 adg_path_chamfer(path, CHAMFER, CHAMFER);
260 pair.y = data->D4 / 2;
261 adg_path_line_to(path, &pair);
263 primitive = adg_path_over_primitive(path);
264 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
265 adg_model_set_named_pair(model, "D3F_Y", &tmp);
266 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, -1));
267 adg_model_set_named_pair(model, "D3F_X", &tmp);
269 adg_path_fillet(path, data->RD34);
271 pair.x = data->A - data->C - data->LD5;
272 adg_path_line_to(path, &pair);
273 adg_model_set_named_pair(model, "D4F", &pair);
275 primitive = adg_path_over_primitive(path);
276 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
277 tmp.x += data->RD34;
278 adg_model_set_named_pair(model, "RD34", &tmp);
280 tmp.x -= cos(G_PI_4) * data->RD34,
281 tmp.y -= sin(G_PI_4) * data->RD34,
282 adg_model_set_named_pair(model, "RD34_R", &tmp);
284 tmp.x += data->RD34,
285 tmp.y += data->RD34,
286 adg_model_set_named_pair(model, "RD34_XY", &tmp);
288 pair.x += (data->D4 - data->D5) / 2;
289 pair.y = data->D5 / 2;
290 adg_path_line_to(path, &pair);
292 pair.x = data->A - data->C;
293 adg_path_line_to(path, &pair);
295 adg_path_fillet(path, 0.2);
297 pair.y = data->D6 / 2;
298 adg_path_line_to(path, &pair);
300 primitive = adg_path_over_primitive(path);
301 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
302 adg_model_set_named_pair(model, "D5F", &tmp);
304 adg_path_fillet(path, 0.1);
306 pair.x += data->LD6;
307 adg_path_line_to(path, &pair);
308 adg_model_set_named_pair(model, "D6F", &pair);
310 primitive = adg_path_over_primitive(path);
311 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, -1));
312 adg_model_set_named_pair(model, "D6I_Y", &tmp);
314 pair.x = data->A - data->LD7;
315 pair.y -= (data->C - data->LD7 - data->LD6) / SQRT3;
316 adg_path_line_to(path, &pair);
317 adg_model_set_named_pair(model, "D67", &pair);
319 pair.y = data->D7 / 2;
320 adg_path_line_to(path, &pair);
322 pair.x = data->A;
323 adg_path_line_to(path, &pair);
324 adg_model_set_named_pair(model, "D7F", &pair);
326 return path;
329 static void
330 sample_add_sheet(AdgCanvas *canvas)
332 AdgTitleBlock *title_block;
333 AdgLogo *logo;
334 AdgMatrix map;
336 title_block = adg_title_block_new();
338 logo = adg_logo_new();
339 cairo_matrix_init_scale(&map, 2, 2);
340 adg_entity_set_global_map(ADG_ENTITY(logo), &map);
342 g_object_set(title_block,
343 "title", "SAMPLE DRAWING",
344 "author", "NtD",
345 "date", "",
346 "drawing", "TEST123",
347 "logo", logo,
348 "projection", adg_projection_new(ADG_PROJECTION_FIRST_ANGLE),
349 "scale", "NONE",
350 "size", "A4",
351 NULL);
353 cairo_matrix_init_translate(&map, 800, 600);
354 adg_entity_set_global_map(ADG_ENTITY(title_block), &map);
356 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(title_block));
359 static void
360 sample_add_dimensions(AdgCanvas *canvas, AdgModel *model)
362 AdgLDim *ldim;
363 AdgADim *adim;
364 AdgRDim *rdim;
366 /* NORTH */
368 ldim = adg_ldim_new_full_from_model(model, "-D1F", "-D3I_X", "-D3F_Y",
369 ADG_DIR_UP);
370 adg_dim_set_outside(ADG_DIM(ldim), ADG_THREE_STATE_OFF);
371 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
373 ldim = adg_ldim_new_full_from_model(model, "-D3I_X", "-D3F_X", "-D3F_Y",
374 ADG_DIR_UP);
375 adg_ldim_switch_extension1(ldim, FALSE);
376 adg_dim_set_outside(ADG_DIM(ldim), ADG_THREE_STATE_OFF);
377 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
379 /* SOUTH */
381 ldim = adg_ldim_new_full_from_model(model, "D1I", "LHOLE", "D3F_Y",
382 ADG_DIR_DOWN);
383 adg_ldim_switch_extension1(ldim, FALSE);
384 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
386 ldim = adg_ldim_new_full_from_model(model, "D3I_X", "D7F", "D3F_Y",
387 ADG_DIR_DOWN);
388 adg_dim_set_limits(ADG_DIM(ldim), NULL, "+0.1");
389 adg_ldim_switch_extension2(ldim, FALSE);
390 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
392 ldim = adg_ldim_new_full_from_model(model, "D1I", "D7F", "D3F_Y",
393 ADG_DIR_DOWN);
394 adg_dim_set_limits(ADG_DIM(ldim), "-0.05", "+0.05");
395 adg_dim_set_level(ADG_DIM(ldim), 2);
396 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
398 adim = adg_adim_new_full_from_model(model, "D6F", "D6I_Y", "D67",
399 "D6F", "D6F");
400 adg_dim_set_level(ADG_DIM(adim), 2);
401 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(adim));
403 rdim = adg_rdim_new_full_from_model(model, "RD34", "RD34_R", "RD34_XY");
404 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(rdim));
406 /* EAST */
408 ldim = adg_ldim_new_full_from_model(model, "D3F_Y", "-D3F_Y", "East",
409 ADG_DIR_RIGHT);
410 adg_dim_set_limits(ADG_DIM(ldim), "-0.25", NULL);
411 adg_dim_set_level(ADG_DIM(ldim), 5);
412 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
414 ldim = adg_ldim_new_full_from_model(model, "D6F", "-D6F", "-East",
415 ADG_DIR_RIGHT);
416 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
417 adg_dim_set_level(ADG_DIM(ldim), 4);
418 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
420 ldim = adg_ldim_new_full_from_model(model, "D4F", "-D4F", "East",
421 ADG_DIR_RIGHT);
422 adg_dim_set_level(ADG_DIM(ldim), 3);
423 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
425 ldim = adg_ldim_new_full_from_model(model, "D5F", "-D5F", "-East",
426 ADG_DIR_RIGHT);
427 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
428 adg_dim_set_level(ADG_DIM(ldim), 2);
429 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
431 ldim = adg_ldim_new_full_from_model(model, "D7F", "-D7F", "East",
432 ADG_DIR_RIGHT);
433 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
435 /* WEST */
437 ldim = adg_ldim_new_full_from_model(model, "D1I", "-D1I", "D1I",
438 ADG_DIR_LEFT);
439 adg_dim_set_limits(ADG_DIM(ldim), "+0.05", "-0.05");
440 adg_dim_set_level(ADG_DIM(ldim), 3);
441 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
443 ldim = adg_ldim_new_full_from_model(model, "D2I", "-D2I", "D1I",
444 ADG_DIR_LEFT);
445 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
446 adg_dim_set_level(ADG_DIM(ldim), 2);
447 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
449 ldim = adg_ldim_new_full_from_model(model, "DHOLE", "-DHOLE", "D1I",
450 ADG_DIR_LEFT);
451 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
454 static void
455 sample_add_stuff(AdgCanvas *canvas, AdgModel *model)
457 AdgToyText *toy_text;
458 AdgMatrix map;
459 const AdgPair *pair;
461 toy_text = adg_toy_text_new("Rotate the mouse wheel to zoom in and out");
462 pair = adg_model_get_named_pair(model, "D3I");
463 cairo_matrix_init_translate(&map, 0, pair->y);
464 adg_entity_set_local_map(ADG_ENTITY(toy_text), &map);
465 cairo_matrix_init_translate(&map, 10, 30 + 30 * 2);
466 adg_entity_set_global_map(ADG_ENTITY(toy_text), &map);
467 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(toy_text));
469 toy_text = adg_toy_text_new("Keep the wheel pressed while dragging the mouse to translate");
470 cairo_matrix_init_translate(&map, 0, pair->y);
471 adg_entity_set_local_map(ADG_ENTITY(toy_text), &map);
472 cairo_matrix_init_translate(&map, 10, 50 + 30 * 2);
473 adg_entity_set_global_map(ADG_ENTITY(toy_text), &map);
474 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(toy_text));
478 #if defined(CAIRO_HAS_PNG_FUNCTIONS) || defined(CAIRO_HAS_PDF_SURFACE) || defined(CAIRO_HAS_PS_SURFACE)
480 /* Only needed if there is at least one supported surface */
481 static void
482 file_generated(GtkWidget *caller, const gchar *file)
484 GtkWindow *window;
485 GtkWidget *dialog;
487 window = (GtkWindow *) gtk_widget_get_toplevel(caller);
488 dialog = gtk_message_dialog_new_with_markup(window, GTK_DIALOG_MODAL,
489 GTK_MESSAGE_INFO,
490 GTK_BUTTONS_CLOSE,
491 "The requested operation generated\n"
492 "<b>%s</b> in the current directory.",
493 file);
494 gtk_window_set_title(GTK_WINDOW(dialog), "Operation completed");
495 gtk_dialog_run(GTK_DIALOG(dialog));
496 gtk_widget_destroy(dialog);
499 #endif
501 #if !defined(CAIRO_HAS_PNG_FUNCTIONS) || !defined(CAIRO_HAS_PDF_SURFACE) || !defined(CAIRO_HAS_PS_SURFACE)
503 /* Only needed if there is a missing surface */
504 static void
505 missing_feature(GtkWidget *caller, const gchar *feature)
507 GtkWindow *window;
508 GtkWidget *dialog;
510 window = (GtkWindow *) gtk_widget_get_toplevel(caller);
511 dialog = gtk_message_dialog_new(window, GTK_DIALOG_MODAL,
512 GTK_MESSAGE_WARNING,
513 GTK_BUTTONS_OK,
514 "The provided cairo library\n"
515 "was compiled with no %s support!",
516 feature);
517 gtk_window_set_title(GTK_WINDOW(dialog), "Missing feature");
518 gtk_dialog_run(GTK_DIALOG(dialog));
519 gtk_widget_destroy(dialog);
522 #endif
525 #ifdef CAIRO_HAS_PNG_FUNCTIONS
527 static void
528 to_png(AdgWidget *widget, GtkWidget *caller)
530 cairo_surface_t *surface;
531 cairo_t *cr;
533 surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 800, 600);
534 cr = cairo_create(surface);
535 cairo_surface_destroy(surface);
537 /* Rendering process */
538 adg_entity_render(ADG_ENTITY(adg_widget_get_canvas(widget)), cr);
540 cairo_show_page(cr);
541 cairo_surface_write_to_png(surface, "test.png");
542 cairo_destroy(cr);
544 file_generated(caller, "test.png");
547 #else
549 static void
550 to_png(AdgWidget *widget, GtkWidget *caller)
552 missing_feature(caller, "PNG");
555 #endif
557 #ifdef CAIRO_HAS_PDF_SURFACE
559 #include <cairo-pdf.h>
561 static void
562 to_pdf(AdgWidget *widget, GtkWidget *caller)
564 cairo_surface_t *surface;
565 cairo_t *cr;
567 surface = cairo_pdf_surface_create("test.pdf", 841, 595);
568 cr = cairo_create(surface);
569 cairo_surface_destroy(surface);
571 adg_entity_render(ADG_ENTITY(adg_widget_get_canvas(widget)), cr);
573 cairo_show_page(cr);
574 cairo_destroy(cr);
576 file_generated(caller, "test.pdf");
579 #else
581 static void
582 to_pdf(AdgWidget *widget, GtkWidget *caller)
584 missing_feature(caller, "PDF");
587 #endif
589 #ifdef CAIRO_HAS_PS_SURFACE
591 #include <cairo-ps.h>
593 static void
594 to_ps(AdgWidget *widget, GtkWidget *caller)
596 cairo_surface_t *surface;
597 cairo_t *cr;
599 /* Surface creation: A4 size */
600 surface = cairo_ps_surface_create("test.ps", 841, 595);
601 cairo_ps_surface_dsc_comment(surface,
602 "%%Title: Automatic Drawing Generation (ADG) demo");
603 cairo_ps_surface_dsc_comment(surface,
604 "%%Copyright: Copyright (C) 2006-2009 Fontana Nicola");
605 cairo_ps_surface_dsc_comment(surface, "%%Orientation: Portrait");
607 cairo_ps_surface_dsc_begin_setup(surface);
609 cairo_ps_surface_dsc_begin_page_setup(surface);
610 cairo_ps_surface_dsc_comment(surface,
611 "%%IncludeFeature: *PageSize A4");
613 cr = cairo_create(surface);
614 cairo_surface_destroy(surface);
616 adg_entity_render(ADG_ENTITY(adg_widget_get_canvas(widget)), cr);
618 cairo_show_page(cr);
619 cairo_destroy(cr);
621 file_generated(caller, "test.ps");
624 #else
626 static void
627 to_ps(AdgWidget *widget, GtkWidget *caller)
629 missing_feature(caller, "PostScript");
632 #endif
635 /**********************************************
636 * Test case for basic operations,
637 * such as chamfer and fillet
638 **********************************************/
640 static AdgPath * operations_chamfer (const AdgPath *path,
641 gdouble delta1,
642 gdouble delta2);
643 static AdgPath * operations_fillet (const AdgPath *path,
644 gdouble radius);
646 static AdgCanvas *
647 operations_canvas(void)
649 AdgPath *path, *chamfer_path, *fillet_path;
650 AdgCanvas *canvas;
651 AdgContainer *container;
652 AdgEntity *entity;
653 AdgMatrix map;
655 path = non_trivial_model();
656 chamfer_path = operations_chamfer(path, 0.25, 0.25);
657 fillet_path = operations_fillet(path, 0.20);
658 canvas = adg_canvas_new();
660 /* Add the original shape */
661 container = adg_container_new();
662 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
664 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
665 adg_container_add(container, entity);
667 entity = ADG_ENTITY(adg_toy_text_new("Original shape"));
668 cairo_matrix_init_translate(&map, 5, 10);
669 adg_entity_set_local_map(entity, &map);
670 cairo_matrix_init_translate(&map, -50, 20);
671 adg_entity_set_global_map(entity, &map);
672 adg_container_add(ADG_CONTAINER(canvas), entity);
674 /* Add the shape with 0.25x0.25 chamfer */
675 container = adg_container_new();
676 cairo_matrix_init_translate(&map, 15, 0);
677 adg_entity_set_local_map(ADG_ENTITY(container), &map);
678 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
680 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(chamfer_path)));
681 adg_container_add(container, entity);
683 entity = ADG_ENTITY(adg_toy_text_new("Shape with 0.25x0.25 chamfer"));
684 cairo_matrix_init_translate(&map, 5, 10);
685 adg_entity_set_local_map(entity, &map);
686 cairo_matrix_init_translate(&map, -120, 20);
687 adg_entity_set_global_map(entity, &map);
688 adg_container_add(container, entity);
690 /* Add the shape with fillets with 0.20 of radius */
691 container = adg_container_new();
692 cairo_matrix_init_translate(&map, 30, 0);
693 adg_entity_set_local_map(ADG_ENTITY(container), &map);
694 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
696 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(fillet_path)));
697 adg_container_add(container, entity);
699 entity = ADG_ENTITY(adg_toy_text_new("Shape with R=0.20 fillet"));
700 cairo_matrix_init_translate(&map, 5, 10);
701 adg_entity_set_local_map(entity, &map);
702 cairo_matrix_init_translate(&map, -90, 20);
703 adg_entity_set_global_map(entity, &map);
704 adg_container_add(container, entity);
706 /* Set a decent start position and zoom */
707 cairo_matrix_init_translate(&map, 10, -140);
708 cairo_matrix_scale(&map, 15, 15);
709 cairo_matrix_translate(&map, 0, 10);
710 adg_entity_set_local_map(ADG_ENTITY(canvas), &map);
712 return canvas;
715 static AdgPath *
716 operations_chamfer(const AdgPath *model, gdouble delta1, gdouble delta2)
718 AdgPath *path;
719 CpmlSegment segment;
720 CpmlPrimitive primitive;
721 CpmlPair org;
723 path = adg_path_new();
724 adg_trail_put_segment(ADG_TRAIL(model), 1, &segment);
725 cpml_primitive_from_segment(&primitive, &segment);
726 cpml_pair_from_cairo(&org, primitive.org);
728 adg_path_move_to(path, &org);
730 do {
731 adg_path_append_primitive(path, &primitive);
732 adg_path_chamfer(path, delta1, delta2);
733 } while (cpml_primitive_next(&primitive));
735 return path;
738 static AdgPath *
739 operations_fillet(const AdgPath *model, gdouble radius)
741 AdgPath *path;
742 CpmlSegment segment;
743 CpmlPrimitive primitive;
744 CpmlPair org;
746 path = adg_path_new();
747 adg_trail_put_segment(ADG_TRAIL(model), 1, &segment);
748 cpml_primitive_from_segment(&primitive, &segment);
749 cpml_pair_from_cairo(&org, primitive.org);
751 adg_path_move_to(path, &org);
753 do {
754 adg_path_append_primitive(path, &primitive);
755 adg_path_fillet(path, radius);
756 } while (cpml_primitive_next(&primitive));
758 return path;
762 /**********************************************
763 * Test case for mapping transformations,
764 * either on the local and global map
765 **********************************************/
767 static AdgCanvas *
768 mapping_canvas(void)
770 AdgPath *path;
771 AdgCanvas *canvas;
772 AdgContainer *container;
773 AdgEntity *entity;
774 AdgMatrix map;
776 path = non_trivial_model();
777 canvas = adg_canvas_new();
779 /* Original shape */
780 container = adg_container_new();
781 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
783 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
784 adg_container_add(container, entity);
786 entity = ADG_ENTITY(adg_toy_text_new("Original shape"));
787 cairo_matrix_init_translate(&map, -50, 20);
788 adg_entity_set_global_map(entity, &map);
789 cairo_matrix_init_translate(&map, 5, 10);
790 adg_entity_set_local_map(entity, &map);
791 adg_container_add(ADG_CONTAINER(canvas), entity);
793 /* Global map rotated by 90 */
794 container = adg_container_new();
795 cairo_matrix_init_translate(&map, 0, -25);
796 adg_entity_set_local_map(ADG_ENTITY(container), &map);
797 cairo_matrix_init_rotate(&map, M_PI_2);
798 adg_entity_set_global_map(ADG_ENTITY(container), &map);
799 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
801 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
802 adg_container_add(container, entity);
804 entity = ADG_ENTITY(adg_toy_text_new("Global map rotated by 90"));
805 cairo_matrix_init_translate(&map, -100, 20);
806 adg_entity_set_global_map(entity, &map);
807 cairo_matrix_init_translate(&map, 5, 10);
808 adg_entity_set_local_map(entity, &map);
809 adg_container_add(container, entity);
811 /* Local map rotated by 90 */
812 container = adg_container_new();
813 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
814 cairo_matrix_init_translate(&map, 40, 0);
815 cairo_matrix_rotate(&map, M_PI_2);
816 adg_entity_set_local_map(ADG_ENTITY(container), &map);
818 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
819 adg_container_add(container, entity);
821 entity = ADG_ENTITY(adg_toy_text_new("Local map rotated by 90"));
822 cairo_matrix_init_translate(&map, -20, -100);
823 adg_entity_set_global_map(entity, &map);
824 cairo_matrix_init_translate(&map, 5, 10);
825 adg_entity_set_local_map(entity, &map);
826 adg_container_add(container, entity);
828 /* Global map scaled by 0.5 */
829 container = adg_container_new();
830 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
831 cairo_matrix_init_translate(&map, 5, 30);
832 adg_entity_set_local_map(ADG_ENTITY(container), &map);
833 cairo_matrix_init_scale(&map, 0.5, 0.5);
834 adg_entity_set_global_map(ADG_ENTITY(container), &map);
836 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
837 adg_container_add(container, entity);
839 entity = ADG_ENTITY(adg_toy_text_new("Global map scaled by 0.5"));
840 cairo_matrix_init_translate(&map, -80, 20);
841 adg_entity_set_global_map(entity, &map);
842 cairo_matrix_init_translate(&map, 5, 10);
843 adg_entity_set_local_map(entity, &map);
844 adg_container_add(container, entity);
846 /* Local map scaled by 0.5 */
847 container = adg_container_new();
848 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
849 cairo_matrix_init_translate(&map, 18, 15);
850 cairo_matrix_scale(&map, 0.5, 0.5);
851 adg_entity_set_local_map(ADG_ENTITY(container), &map);
853 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
854 adg_container_add(container, entity);
856 entity = ADG_ENTITY(adg_toy_text_new("Local map scaled by 0.5"));
857 cairo_matrix_init_translate(&map, -80, 20);
858 adg_entity_set_global_map(entity, &map);
859 cairo_matrix_init_translate(&map, 5, 10);
860 adg_entity_set_local_map(entity, &map);
861 adg_container_add(container, entity);
863 /* Global and local maps scaled by 0.5 */
864 container = adg_container_new();
865 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
866 cairo_matrix_init_translate(&map, 66, 30);
867 cairo_matrix_scale(&map, 0.5, 0.5);
868 adg_entity_set_local_map(ADG_ENTITY(container), &map);
869 cairo_matrix_init_scale(&map, 0.5, 0.5);
870 adg_entity_set_global_map(ADG_ENTITY(container), &map);
872 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
873 adg_container_add(container, entity);
875 entity = ADG_ENTITY(adg_toy_text_new("Local and global map scaled by 0.5"));
876 cairo_matrix_init_translate(&map, -140, 20);
877 adg_entity_set_global_map(entity, &map);
878 cairo_matrix_init_translate(&map, 5, 10);
879 adg_entity_set_local_map(entity, &map);
880 adg_container_add(container, entity);
882 /* Set a decent start position and zoom */
883 cairo_matrix_init_scale(&map, 15, 15);
884 adg_entity_set_local_map(ADG_ENTITY(canvas), &map);
885 cairo_matrix_init_translate(&map, 100, 100);
886 adg_entity_set_global_map(ADG_ENTITY(canvas), &map);
888 return canvas;
892 /**********************************************
893 * Test case for alignments of entities
894 * using different factors
895 **********************************************/
897 static AdgCanvas *
898 alignment_canvas(void)
900 AdgPath *path;
901 AdgCanvas *canvas;
902 AdgPath *axis;
903 AdgAlignment *alignment;
904 AdgStroke *stroke;
905 AdgMatrix map;
907 path = non_trivial_model();
908 canvas = adg_canvas_new();
909 cairo_matrix_init_scale(&map, 2, 2);
911 axis = adg_path_new();
912 adg_path_move_to_explicit(axis, -15, 0);
913 adg_path_line_to_explicit(axis, 15, 0);
914 adg_path_move_to_explicit(axis, 0, -15);
915 adg_path_line_to_explicit(axis, 0, 15);
917 /* Axis */
918 stroke = adg_stroke_new(ADG_TRAIL(axis));
919 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(stroke));
921 /* Original path */
922 alignment = adg_alignment_new_explicit(0, 0);
923 stroke = adg_stroke_new(ADG_TRAIL(path));
924 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
925 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
927 /* Path scaled in local space */
928 alignment = adg_alignment_new_explicit(0.5, 0.5);
929 stroke = adg_stroke_new(ADG_TRAIL(path));
930 adg_entity_set_local_map(ADG_ENTITY(stroke), &map);
931 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
932 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
934 alignment = adg_alignment_new_explicit(1, 1);
935 stroke = adg_stroke_new(ADG_TRAIL(path));
936 adg_entity_set_local_map(ADG_ENTITY(stroke), &map);
937 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
938 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
940 /* Path scaled in global space */
941 alignment = adg_alignment_new_explicit(0, 0);
942 stroke = adg_stroke_new(ADG_TRAIL(path));
943 cairo_matrix_init_scale(&map, 2, 2);
944 adg_entity_set_global_map(ADG_ENTITY(stroke), &map);
945 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
946 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
948 alignment = adg_alignment_new_explicit(-0.5, -0.5);
949 stroke = adg_stroke_new(ADG_TRAIL(path));
950 adg_entity_set_global_map(ADG_ENTITY(stroke), &map);
951 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
952 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
954 alignment = adg_alignment_new_explicit(-0.25, -0.25);
955 stroke = adg_stroke_new(ADG_TRAIL(path));
956 adg_entity_set_global_map(ADG_ENTITY(stroke), &map);
957 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
958 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
960 /* Set a decent start position and zoom */
961 cairo_matrix_init_scale(&map, 15, 15);
962 cairo_matrix_translate(&map, 20, 20);
963 adg_entity_set_local_map(ADG_ENTITY(canvas), &map);
965 cairo_matrix_init_translate(&map, 20, 20);
966 adg_entity_set_global_map(ADG_ENTITY(canvas), &map);
968 return canvas;
972 /**********************************************
973 * Non specific test related stuff
974 **********************************************/
976 static AdgPath *
977 non_trivial_model()
979 AdgPath *path = adg_path_new();
981 adg_path_move_to_explicit(path, 2, 0);
982 adg_path_line_to_explicit(path, 0, 5);
983 adg_path_line_to_explicit(path, 2, 2);
984 adg_path_line_to_explicit(path, 0, 8);
985 adg_path_line_to_explicit(path, 2, 8);
986 adg_path_line_to_explicit(path, 2, 10);
987 adg_path_line_to_explicit(path, 3, 10);
988 adg_path_line_to_explicit(path, 10, 9);
989 adg_path_line_to_explicit(path, 5, 5);
990 adg_path_line_to_explicit(path, 3, 0);
991 adg_path_close(path);
993 return path;