[AdgColorStyle] s/_get_rgb/_put_rgb/
[adg.git] / demo / adg-demo.c
blob26abe6db9ebd9b24478e78d6494130b384c23ca4
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 adg_path_chamfer(path, CHAMFER, CHAMFER);
246 pair.x = data->A - data->B + data->LD3;
247 pair.y = data->D3 / 2;
248 adg_path_line_to(path, &pair);
250 primitive = adg_path_over_primitive(path);
251 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
252 adg_model_set_named_pair(model, "D3I_X", &tmp);
254 adg_path_chamfer(path, CHAMFER, CHAMFER);
256 pair.y = data->D4 / 2;
257 adg_path_line_to(path, &pair);
259 primitive = adg_path_over_primitive(path);
260 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
261 adg_model_set_named_pair(model, "D3F_Y", &tmp);
262 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, -1));
263 adg_model_set_named_pair(model, "D3F_X", &tmp);
265 adg_path_fillet(path, data->RD34);
267 pair.x = data->A - data->C - data->LD5;
268 adg_path_line_to(path, &pair);
269 adg_model_set_named_pair(model, "D4F", &pair);
271 primitive = adg_path_over_primitive(path);
272 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
273 tmp.x += data->RD34;
274 adg_model_set_named_pair(model, "RD34", &tmp);
276 tmp.x -= cos(G_PI_4) * data->RD34,
277 tmp.y -= sin(G_PI_4) * data->RD34,
278 adg_model_set_named_pair(model, "RD34_R", &tmp);
280 tmp.x += data->RD34,
281 tmp.y += data->RD34,
282 adg_model_set_named_pair(model, "RD34_XY", &tmp);
284 pair.x += (data->D4 - data->D5) / 2;
285 pair.y = data->D5 / 2;
286 adg_path_line_to(path, &pair);
288 pair.x = data->A - data->C;
289 adg_path_line_to(path, &pair);
291 adg_path_fillet(path, 0.2);
293 pair.y = data->D6 / 2;
294 adg_path_line_to(path, &pair);
296 primitive = adg_path_over_primitive(path);
297 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
298 adg_model_set_named_pair(model, "D5F", &tmp);
300 adg_path_fillet(path, 0.1);
302 pair.x += data->LD6;
303 adg_path_line_to(path, &pair);
304 adg_model_set_named_pair(model, "D6F", &pair);
306 primitive = adg_path_over_primitive(path);
307 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, -1));
308 adg_model_set_named_pair(model, "D6I_Y", &tmp);
310 pair.x = data->A - data->LD7;
311 pair.y -= (data->C - data->LD7 - data->LD6) / SQRT3;
312 adg_path_line_to(path, &pair);
313 adg_model_set_named_pair(model, "D67", &pair);
315 pair.y = data->D7 / 2;
316 adg_path_line_to(path, &pair);
318 pair.x = data->A;
319 adg_path_line_to(path, &pair);
320 adg_model_set_named_pair(model, "D7F", &pair);
322 return path;
325 static void
326 sample_add_sheet(AdgCanvas *canvas)
328 AdgTitleBlock *title_block;
329 AdgLogo *logo;
330 AdgMatrix map;
332 title_block = adg_title_block_new();
334 logo = adg_logo_new();
335 cairo_matrix_init_scale(&map, 2, 2);
336 adg_entity_set_global_map(ADG_ENTITY(logo), &map);
338 g_object_set(title_block,
339 "title", "SAMPLE DRAWING",
340 "author", "NtD",
341 "date", "",
342 "drawing", "TEST123",
343 "logo", logo,
344 "projection", adg_projection_new(ADG_PROJECTION_FIRST_ANGLE),
345 "scale", "NONE",
346 "size", "A4",
347 NULL);
349 cairo_matrix_init_translate(&map, 800, 600);
350 adg_entity_set_global_map(ADG_ENTITY(title_block), &map);
352 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(title_block));
355 static void
356 sample_add_dimensions(AdgCanvas *canvas, AdgModel *model)
358 AdgLDim *ldim;
359 AdgADim *adim;
360 AdgRDim *rdim;
362 /* NORTH */
364 ldim = adg_ldim_new_full_from_model(model, "-D1F", "-D3I_X", "-D3F_Y",
365 ADG_DIR_UP);
366 adg_dim_set_outside(ADG_DIM(ldim), ADG_THREE_STATE_OFF);
367 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
369 ldim = adg_ldim_new_full_from_model(model, "-D3I_X", "-D3F_X", "-D3F_Y",
370 ADG_DIR_UP);
371 adg_ldim_switch_extension1(ldim, FALSE);
372 adg_dim_set_outside(ADG_DIM(ldim), ADG_THREE_STATE_OFF);
373 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
375 /* SOUTH */
377 ldim = adg_ldim_new_full_from_model(model, "D1I", "LHOLE", "D3F_Y",
378 ADG_DIR_DOWN);
379 adg_ldim_switch_extension1(ldim, FALSE);
380 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
382 ldim = adg_ldim_new_full_from_model(model, "D3I_X", "D7F", "D3F_Y",
383 ADG_DIR_DOWN);
384 adg_dim_set_limits(ADG_DIM(ldim), NULL, "+0.1");
385 adg_ldim_switch_extension2(ldim, FALSE);
386 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
388 ldim = adg_ldim_new_full_from_model(model, "D1I", "D7F", "D3F_Y",
389 ADG_DIR_DOWN);
390 adg_dim_set_limits(ADG_DIM(ldim), "-0.05", "+0.05");
391 adg_dim_set_level(ADG_DIM(ldim), 2);
392 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
394 adim = adg_adim_new_full_from_model(model, "D6F", "D6I_Y", "D67",
395 "D6F", "D6F");
396 adg_dim_set_level(ADG_DIM(adim), 2);
397 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(adim));
399 rdim = adg_rdim_new_full_from_model(model, "RD34", "RD34_R", "RD34_XY");
400 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(rdim));
402 /* EAST */
404 ldim = adg_ldim_new_full_from_model(model, "D3F_Y", "-D3F_Y", "D7F",
405 ADG_DIR_RIGHT);
406 adg_dim_set_limits(ADG_DIM(ldim), "-0.25", NULL);
407 adg_dim_set_level(ADG_DIM(ldim), 5);
408 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
410 ldim = adg_ldim_new_full_from_model(model, "D6F", "-D6F", "D7F",
411 ADG_DIR_RIGHT);
412 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
413 adg_dim_set_level(ADG_DIM(ldim), 4);
414 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
416 ldim = adg_ldim_new_full_from_model(model, "D4F", "-D4F", "D7F",
417 ADG_DIR_RIGHT);
418 adg_dim_set_level(ADG_DIM(ldim), 3);
419 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
421 ldim = adg_ldim_new_full_from_model(model, "D5F", "-D5F", "D7F",
422 ADG_DIR_RIGHT);
423 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
424 adg_dim_set_level(ADG_DIM(ldim), 2);
425 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
427 ldim = adg_ldim_new_full_from_model(model, "D7F", "-D7F", "D7F",
428 ADG_DIR_RIGHT);
429 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
431 /* WEST */
433 ldim = adg_ldim_new_full_from_model(model, "D1I", "-D1I", "D1I",
434 ADG_DIR_LEFT);
435 adg_dim_set_limits(ADG_DIM(ldim), "+0.05", "-0.05");
436 adg_dim_set_level(ADG_DIM(ldim), 3);
437 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
439 ldim = adg_ldim_new_full_from_model(model, "D2I", "-D2I", "D1I",
440 ADG_DIR_LEFT);
441 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
442 adg_dim_set_level(ADG_DIM(ldim), 2);
443 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
445 ldim = adg_ldim_new_full_from_model(model, "DHOLE", "-DHOLE", "D1I",
446 ADG_DIR_LEFT);
447 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
450 static void
451 sample_add_stuff(AdgCanvas *canvas, AdgModel *model)
453 AdgToyText *toy_text;
454 AdgMatrix map;
455 const AdgPair *pair;
457 toy_text = adg_toy_text_new("Rotate the mouse wheel to zoom in and out");
458 pair = adg_model_named_pair(model, "D3I");
459 cairo_matrix_init_translate(&map, 0, pair->y);
460 adg_entity_set_local_map(ADG_ENTITY(toy_text), &map);
461 cairo_matrix_init_translate(&map, 10, 30 + 30 * 2);
462 adg_entity_set_global_map(ADG_ENTITY(toy_text), &map);
463 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(toy_text));
465 toy_text = adg_toy_text_new("Keep the wheel pressed while dragging the mouse to translate");
466 cairo_matrix_init_translate(&map, 0, pair->y);
467 adg_entity_set_local_map(ADG_ENTITY(toy_text), &map);
468 cairo_matrix_init_translate(&map, 10, 50 + 30 * 2);
469 adg_entity_set_global_map(ADG_ENTITY(toy_text), &map);
470 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(toy_text));
474 #if defined(CAIRO_HAS_PNG_FUNCTIONS) || defined(CAIRO_HAS_PDF_SURFACE) || defined(CAIRO_HAS_PS_SURFACE)
476 /* Only needed if there is at least one supported surface */
477 static void
478 file_generated(GtkWidget *caller, const gchar *file)
480 GtkWindow *window;
481 GtkWidget *dialog;
483 window = (GtkWindow *) gtk_widget_get_toplevel(caller);
484 dialog = gtk_message_dialog_new_with_markup(window, GTK_DIALOG_MODAL,
485 GTK_MESSAGE_INFO,
486 GTK_BUTTONS_CLOSE,
487 "The requested operation generated\n"
488 "<b>%s</b> in the current directory.",
489 file);
490 gtk_window_set_title(GTK_WINDOW(dialog), "Operation completed");
491 gtk_dialog_run(GTK_DIALOG(dialog));
492 gtk_widget_destroy(dialog);
495 #endif
497 #if !defined(CAIRO_HAS_PNG_FUNCTIONS) || !defined(CAIRO_HAS_PDF_SURFACE) || !defined(CAIRO_HAS_PS_SURFACE)
499 /* Only needed if there is a missing surface */
500 static void
501 missing_feature(GtkWidget *caller, const gchar *feature)
503 GtkWindow *window;
504 GtkWidget *dialog;
506 window = (GtkWindow *) gtk_widget_get_toplevel(caller);
507 dialog = gtk_message_dialog_new(window, GTK_DIALOG_MODAL,
508 GTK_MESSAGE_WARNING,
509 GTK_BUTTONS_OK,
510 "The provided cairo library\n"
511 "was compiled with no %s support!",
512 feature);
513 gtk_window_set_title(GTK_WINDOW(dialog), "Missing feature");
514 gtk_dialog_run(GTK_DIALOG(dialog));
515 gtk_widget_destroy(dialog);
518 #endif
521 #ifdef CAIRO_HAS_PNG_FUNCTIONS
523 static void
524 to_png(AdgWidget *widget, GtkWidget *caller)
526 cairo_surface_t *surface;
527 cairo_t *cr;
529 surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 800, 600);
530 cr = cairo_create(surface);
531 cairo_surface_destroy(surface);
533 /* Rendering process */
534 adg_entity_render(ADG_ENTITY(adg_widget_get_canvas(widget)), cr);
536 cairo_show_page(cr);
537 cairo_surface_write_to_png(surface, "test.png");
538 cairo_destroy(cr);
540 file_generated(caller, "test.png");
543 #else
545 static void
546 to_png(AdgWidget *widget, GtkWidget *caller)
548 missing_feature(caller, "PNG");
551 #endif
553 #ifdef CAIRO_HAS_PDF_SURFACE
555 #include <cairo-pdf.h>
557 static void
558 to_pdf(AdgWidget *widget, GtkWidget *caller)
560 cairo_surface_t *surface;
561 cairo_t *cr;
563 surface = cairo_pdf_surface_create("test.pdf", 841, 595);
564 cr = cairo_create(surface);
565 cairo_surface_destroy(surface);
567 adg_entity_render(ADG_ENTITY(adg_widget_get_canvas(widget)), cr);
569 cairo_show_page(cr);
570 cairo_destroy(cr);
572 file_generated(caller, "test.pdf");
575 #else
577 static void
578 to_pdf(AdgWidget *widget, GtkWidget *caller)
580 missing_feature(caller, "PDF");
583 #endif
585 #ifdef CAIRO_HAS_PS_SURFACE
587 #include <cairo-ps.h>
589 static void
590 to_ps(AdgWidget *widget, GtkWidget *caller)
592 cairo_surface_t *surface;
593 cairo_t *cr;
595 /* Surface creation: A4 size */
596 surface = cairo_ps_surface_create("test.ps", 841, 595);
597 cairo_ps_surface_dsc_comment(surface,
598 "%%Title: Automatic Drawing Generation (ADG) demo");
599 cairo_ps_surface_dsc_comment(surface,
600 "%%Copyright: Copyright (C) 2006-2009 Fontana Nicola");
601 cairo_ps_surface_dsc_comment(surface, "%%Orientation: Portrait");
603 cairo_ps_surface_dsc_begin_setup(surface);
605 cairo_ps_surface_dsc_begin_page_setup(surface);
606 cairo_ps_surface_dsc_comment(surface,
607 "%%IncludeFeature: *PageSize A4");
609 cr = cairo_create(surface);
610 cairo_surface_destroy(surface);
612 adg_entity_render(ADG_ENTITY(adg_widget_get_canvas(widget)), cr);
614 cairo_show_page(cr);
615 cairo_destroy(cr);
617 file_generated(caller, "test.ps");
620 #else
622 static void
623 to_ps(AdgWidget *widget, GtkWidget *caller)
625 missing_feature(caller, "PostScript");
628 #endif
631 /**********************************************
632 * Test case for basic operations,
633 * such as chamfer and fillet
634 **********************************************/
636 static AdgPath * operations_chamfer (const AdgPath *path,
637 gdouble delta1,
638 gdouble delta2);
639 static AdgPath * operations_fillet (const AdgPath *path,
640 gdouble radius);
642 static AdgCanvas *
643 operations_canvas(void)
645 AdgPath *path, *chamfer_path, *fillet_path;
646 AdgCanvas *canvas;
647 AdgContainer *container;
648 AdgEntity *entity;
649 AdgMatrix map;
651 path = non_trivial_model();
652 chamfer_path = operations_chamfer(path, 0.25, 0.25);
653 fillet_path = operations_fillet(path, 0.20);
654 canvas = adg_canvas_new();
656 /* Add the original shape */
657 container = adg_container_new();
658 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
660 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
661 adg_container_add(container, entity);
663 entity = ADG_ENTITY(adg_toy_text_new("Original shape"));
664 cairo_matrix_init_translate(&map, 5, 10);
665 adg_entity_set_local_map(entity, &map);
666 cairo_matrix_init_translate(&map, -50, 20);
667 adg_entity_set_global_map(entity, &map);
668 adg_container_add(ADG_CONTAINER(canvas), entity);
670 /* Add the shape with 0.25x0.25 chamfer */
671 container = adg_container_new();
672 cairo_matrix_init_translate(&map, 15, 0);
673 adg_entity_set_local_map(ADG_ENTITY(container), &map);
674 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
676 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(chamfer_path)));
677 adg_container_add(container, entity);
679 entity = ADG_ENTITY(adg_toy_text_new("Shape with 0.25x0.25 chamfer"));
680 cairo_matrix_init_translate(&map, 5, 10);
681 adg_entity_set_local_map(entity, &map);
682 cairo_matrix_init_translate(&map, -120, 20);
683 adg_entity_set_global_map(entity, &map);
684 adg_container_add(container, entity);
686 /* Add the shape with fillets with 0.20 of radius */
687 container = adg_container_new();
688 cairo_matrix_init_translate(&map, 30, 0);
689 adg_entity_set_local_map(ADG_ENTITY(container), &map);
690 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
692 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(fillet_path)));
693 adg_container_add(container, entity);
695 entity = ADG_ENTITY(adg_toy_text_new("Shape with R=0.20 fillet"));
696 cairo_matrix_init_translate(&map, 5, 10);
697 adg_entity_set_local_map(entity, &map);
698 cairo_matrix_init_translate(&map, -90, 20);
699 adg_entity_set_global_map(entity, &map);
700 adg_container_add(container, entity);
702 /* Set a decent start position and zoom */
703 cairo_matrix_init_translate(&map, 10, -140);
704 cairo_matrix_scale(&map, 15, 15);
705 cairo_matrix_translate(&map, 0, 10);
706 adg_entity_set_local_map(ADG_ENTITY(canvas), &map);
708 return canvas;
711 static AdgPath *
712 operations_chamfer(const AdgPath *model, gdouble delta1, gdouble delta2)
714 AdgPath *path;
715 CpmlSegment segment;
716 CpmlPrimitive primitive;
717 CpmlPair org;
719 path = adg_path_new();
720 adg_trail_get_segment(ADG_TRAIL(model), &segment, 1);
721 cpml_primitive_from_segment(&primitive, &segment);
722 cpml_pair_from_cairo(&org, primitive.org);
724 adg_path_move_to(path, &org);
726 do {
727 adg_path_append_primitive(path, &primitive);
728 adg_path_chamfer(path, delta1, delta2);
729 } while (cpml_primitive_next(&primitive));
731 return path;
734 static AdgPath *
735 operations_fillet(const AdgPath *model, gdouble radius)
737 AdgPath *path;
738 CpmlSegment segment;
739 CpmlPrimitive primitive;
740 CpmlPair org;
742 path = adg_path_new();
743 adg_trail_get_segment(ADG_TRAIL(model), &segment, 1);
744 cpml_primitive_from_segment(&primitive, &segment);
745 cpml_pair_from_cairo(&org, primitive.org);
747 adg_path_move_to(path, &org);
749 do {
750 adg_path_append_primitive(path, &primitive);
751 adg_path_fillet(path, radius);
752 } while (cpml_primitive_next(&primitive));
754 return path;
758 /**********************************************
759 * Test case for mapping transformations,
760 * either on the local and global map
761 **********************************************/
763 static AdgCanvas *
764 mapping_canvas(void)
766 AdgPath *path;
767 AdgCanvas *canvas;
768 AdgContainer *container;
769 AdgEntity *entity;
770 AdgMatrix map;
772 path = non_trivial_model();
773 canvas = adg_canvas_new();
775 /* Original shape */
776 container = adg_container_new();
777 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
779 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
780 adg_container_add(container, entity);
782 entity = ADG_ENTITY(adg_toy_text_new("Original shape"));
783 cairo_matrix_init_translate(&map, -50, 20);
784 adg_entity_set_global_map(entity, &map);
785 cairo_matrix_init_translate(&map, 5, 10);
786 adg_entity_set_local_map(entity, &map);
787 adg_container_add(ADG_CONTAINER(canvas), entity);
789 /* Global map rotated by 90 */
790 container = adg_container_new();
791 cairo_matrix_init_translate(&map, 0, -25);
792 adg_entity_set_local_map(ADG_ENTITY(container), &map);
793 cairo_matrix_init_rotate(&map, M_PI_2);
794 adg_entity_set_global_map(ADG_ENTITY(container), &map);
795 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
797 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
798 adg_container_add(container, entity);
800 entity = ADG_ENTITY(adg_toy_text_new("Global map rotated by 90"));
801 cairo_matrix_init_translate(&map, -100, 20);
802 adg_entity_set_global_map(entity, &map);
803 cairo_matrix_init_translate(&map, 5, 10);
804 adg_entity_set_local_map(entity, &map);
805 adg_container_add(container, entity);
807 /* Local map rotated by 90 */
808 container = adg_container_new();
809 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
810 cairo_matrix_init_translate(&map, 40, 0);
811 cairo_matrix_rotate(&map, M_PI_2);
812 adg_entity_set_local_map(ADG_ENTITY(container), &map);
814 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
815 adg_container_add(container, entity);
817 entity = ADG_ENTITY(adg_toy_text_new("Local map rotated by 90"));
818 cairo_matrix_init_translate(&map, -20, -100);
819 adg_entity_set_global_map(entity, &map);
820 cairo_matrix_init_translate(&map, 5, 10);
821 adg_entity_set_local_map(entity, &map);
822 adg_container_add(container, entity);
824 /* Global map scaled by 0.5 */
825 container = adg_container_new();
826 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
827 cairo_matrix_init_translate(&map, 5, 30);
828 adg_entity_set_local_map(ADG_ENTITY(container), &map);
829 cairo_matrix_init_scale(&map, 0.5, 0.5);
830 adg_entity_set_global_map(ADG_ENTITY(container), &map);
832 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
833 adg_container_add(container, entity);
835 entity = ADG_ENTITY(adg_toy_text_new("Global map scaled by 0.5"));
836 cairo_matrix_init_translate(&map, -80, 20);
837 adg_entity_set_global_map(entity, &map);
838 cairo_matrix_init_translate(&map, 5, 10);
839 adg_entity_set_local_map(entity, &map);
840 adg_container_add(container, entity);
842 /* Local map scaled by 0.5 */
843 container = adg_container_new();
844 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
845 cairo_matrix_init_translate(&map, 18, 15);
846 cairo_matrix_scale(&map, 0.5, 0.5);
847 adg_entity_set_local_map(ADG_ENTITY(container), &map);
849 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
850 adg_container_add(container, entity);
852 entity = ADG_ENTITY(adg_toy_text_new("Local map scaled by 0.5"));
853 cairo_matrix_init_translate(&map, -80, 20);
854 adg_entity_set_global_map(entity, &map);
855 cairo_matrix_init_translate(&map, 5, 10);
856 adg_entity_set_local_map(entity, &map);
857 adg_container_add(container, entity);
859 /* Global and local maps scaled by 0.5 */
860 container = adg_container_new();
861 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
862 cairo_matrix_init_translate(&map, 66, 30);
863 cairo_matrix_scale(&map, 0.5, 0.5);
864 adg_entity_set_local_map(ADG_ENTITY(container), &map);
865 cairo_matrix_init_scale(&map, 0.5, 0.5);
866 adg_entity_set_global_map(ADG_ENTITY(container), &map);
868 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
869 adg_container_add(container, entity);
871 entity = ADG_ENTITY(adg_toy_text_new("Local and global map scaled by 0.5"));
872 cairo_matrix_init_translate(&map, -140, 20);
873 adg_entity_set_global_map(entity, &map);
874 cairo_matrix_init_translate(&map, 5, 10);
875 adg_entity_set_local_map(entity, &map);
876 adg_container_add(container, entity);
878 /* Set a decent start position and zoom */
879 cairo_matrix_init_scale(&map, 15, 15);
880 adg_entity_set_local_map(ADG_ENTITY(canvas), &map);
881 cairo_matrix_init_translate(&map, 100, 100);
882 adg_entity_set_global_map(ADG_ENTITY(canvas), &map);
884 return canvas;
888 /**********************************************
889 * Test case for alignments of entities
890 * using different factors
891 **********************************************/
893 static AdgCanvas *
894 alignment_canvas(void)
896 AdgPath *path;
897 AdgCanvas *canvas;
898 AdgPath *axis;
899 AdgAlignment *alignment;
900 AdgStroke *stroke;
901 AdgMatrix map;
903 path = non_trivial_model();
904 canvas = adg_canvas_new();
905 cairo_matrix_init_scale(&map, 2, 2);
907 axis = adg_path_new();
908 adg_path_move_to_explicit(axis, -15, 0);
909 adg_path_line_to_explicit(axis, 15, 0);
910 adg_path_move_to_explicit(axis, 0, -15);
911 adg_path_line_to_explicit(axis, 0, 15);
913 /* Axis */
914 stroke = adg_stroke_new(ADG_TRAIL(axis));
915 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(stroke));
917 /* Original path */
918 alignment = adg_alignment_new_explicit(0, 0);
919 stroke = adg_stroke_new(ADG_TRAIL(path));
920 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
921 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
923 /* Path scaled in local space */
924 alignment = adg_alignment_new_explicit(0.5, 0.5);
925 stroke = adg_stroke_new(ADG_TRAIL(path));
926 adg_entity_set_local_map(ADG_ENTITY(stroke), &map);
927 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
928 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
930 alignment = adg_alignment_new_explicit(1, 1);
931 stroke = adg_stroke_new(ADG_TRAIL(path));
932 adg_entity_set_local_map(ADG_ENTITY(stroke), &map);
933 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
934 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
936 /* Path scaled in global space */
937 alignment = adg_alignment_new_explicit(0, 0);
938 stroke = adg_stroke_new(ADG_TRAIL(path));
939 cairo_matrix_init_scale(&map, 2, 2);
940 adg_entity_set_global_map(ADG_ENTITY(stroke), &map);
941 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
942 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
944 alignment = adg_alignment_new_explicit(-0.5, -0.5);
945 stroke = adg_stroke_new(ADG_TRAIL(path));
946 adg_entity_set_global_map(ADG_ENTITY(stroke), &map);
947 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
948 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
950 alignment = adg_alignment_new_explicit(-0.25, -0.25);
951 stroke = adg_stroke_new(ADG_TRAIL(path));
952 adg_entity_set_global_map(ADG_ENTITY(stroke), &map);
953 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
954 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
956 /* Set a decent start position and zoom */
957 cairo_matrix_init_scale(&map, 15, 15);
958 cairo_matrix_translate(&map, 20, 20);
959 adg_entity_set_local_map(ADG_ENTITY(canvas), &map);
961 cairo_matrix_init_translate(&map, 20, 20);
962 adg_entity_set_global_map(ADG_ENTITY(canvas), &map);
964 return canvas;
968 /**********************************************
969 * Non specific test related stuff
970 **********************************************/
972 static AdgPath *
973 non_trivial_model()
975 AdgPath *path = adg_path_new();
977 adg_path_move_to_explicit(path, 2, 0);
978 adg_path_line_to_explicit(path, 0, 5);
979 adg_path_line_to_explicit(path, 2, 2);
980 adg_path_line_to_explicit(path, 0, 8);
981 adg_path_line_to_explicit(path, 2, 8);
982 adg_path_line_to_explicit(path, 2, 10);
983 adg_path_line_to_explicit(path, 3, 10);
984 adg_path_line_to_explicit(path, 10, 9);
985 adg_path_line_to_explicit(path, 5, 5);
986 adg_path_line_to_explicit(path, 3, 0);
987 adg_path_close(path);
989 return path;