[AdgLDim] Added construction with named pairs
[adg.git] / demo / adg-demo.c
blob38382c52d5c38c6c14d834f68a990a89b2426d45
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 D1, D2, D3, D4, D5, D6, D7;
93 gdouble RD34, RD56;
94 gdouble LD2, LD3, LD5, LD6, LD7;
97 static void sample_get (SampleData *data);
98 static AdgPath *sample_path (const SampleData *data);
99 static void sample_add_dimensions (AdgCanvas *canvas,
100 AdgModel *model,
101 const SampleData *data);
102 static void sample_add_stuff (AdgCanvas *canvas,
103 const SampleData *data);
106 static AdgCanvas *
107 sample_canvas(void)
109 SampleData data;
110 AdgCanvas *canvas;
111 AdgContainer *container;
112 AdgTrail *shape, *edges;
113 AdgEntity *entity;
114 AdgMatrix map;
116 sample_get(&data);
117 canvas = adg_canvas_new();
118 container = (AdgContainer *) canvas;
119 shape = ADG_TRAIL(sample_path(&data));
120 edges = ADG_TRAIL(adg_edges_new_with_source(shape));
122 entity = ADG_ENTITY(adg_stroke_new(shape));
123 adg_container_add(container, entity);
125 entity = ADG_ENTITY(adg_hatch_new(shape));
126 adg_container_add(container, entity);
128 entity = ADG_ENTITY(adg_stroke_new(edges));
129 adg_container_add(container, entity);
131 sample_add_dimensions(canvas, ADG_MODEL(shape), &data);
132 sample_add_stuff(canvas, &data);
134 cairo_matrix_init_translate(&map, 100, 70);
135 cairo_matrix_scale(&map, 6.883, 6.883);
136 cairo_matrix_translate(&map, 0, 10);
137 adg_entity_set_local_map(ADG_ENTITY(container), &map);
139 return canvas;
142 static void
143 sample_get(SampleData *data)
145 data->A = 52.3;
146 data->B = 20.6;
147 data->C = 2;
148 data->D1 = 9.3;
149 data->D2 = 6.5;
150 data->D3 = 11.9;
151 data->D4 = 6.5;
152 data->D5 = 4.5;
153 data->D6 = 7.2;
154 data->D7 = 3;
155 data->RD34 = 1;
156 data->LD2 = 7;
157 data->LD3 = 3.5;
158 data->LD5 = 5;
159 data->LD6 = 1;
160 data->LD7 = 0.5;
163 static AdgPath *
164 sample_path(const SampleData *data)
166 AdgPath *path;
167 AdgPair pair;
168 double x, y;
169 AdgSegment segment;
170 AdgSegment *dup_segment;
171 cairo_matrix_t matrix;
173 path = adg_path_new();
175 pair.x = 0;
176 pair.y = data->D1 / 2;
177 adg_path_move_to(path, pair.x, pair.y);
178 adg_model_set_named_pair(ADG_MODEL(path), "D1I", &pair);
180 adg_path_line_to(path, data->A - data->B - data->LD2, data->D1 / 2);
181 y = (data->D1 - data->D2) / 2;
182 adg_path_line_to(path, data->A - data->B - data->LD2 + y * SQRT3, data->D1 / 2 - y);
183 adg_path_line_to(path, data->A - data->B, data->D2 / 2);
184 adg_path_fillet(path, 0.4);
185 adg_path_line_to(path, data->A - data->B, data->D3 / 2);
186 adg_path_chamfer(path, CHAMFER, CHAMFER);
188 pair.x = data->A - data->B + data->LD3;
189 pair.y = data->D3 / 2;
190 adg_path_line_to(path, pair.x, pair.y);
191 adg_model_set_named_pair(ADG_MODEL(path), "D3F", &pair);
193 adg_path_chamfer(path, CHAMFER, CHAMFER);
194 adg_path_line_to(path, data->A - data->B + data->LD3, data->D4 / 2);
195 adg_path_fillet(path, data->RD34);
196 adg_path_line_to(path, data->A - data->C - data->LD5, data->D4 / 2);
197 y = (data->D4 - data->D5) / 2;
198 adg_path_line_to(path, data->A - data->C - data->LD5 + y, data->D4 / 2 - y);
199 adg_path_line_to(path, data->A - data->C, data->D5 / 2);
200 adg_path_fillet(path, 0.2);
201 adg_path_line_to(path, data->A - data->C, data->D6 / 2);
202 adg_path_fillet(path, 0.1);
203 adg_path_line_to(path, data->A - data->C + data->LD6, data->D6 / 2);
204 x = data->C - data->LD7 - data->LD6;
205 y = x / SQRT3;
206 adg_path_line_to(path, data->A - data->C + data->LD6 + x, data->D6 / 2 - y);
207 adg_path_line_to(path, data->A - data->LD7, data->D7 / 2);
209 pair.x = data->A;
210 pair.y = data->D7 / 2;
211 adg_path_line_to(path, pair.x, pair.y);
212 adg_model_set_named_pair(ADG_MODEL(path), "D7F", &pair);
214 /* Reflect the shape by duplicating the first segment of
215 * the current path, applying a -1 y scale (that is
216 * mirroring it on the y=0 axis), reversing the resulting
217 * path and appending it to the original one */
218 adg_trail_get_segment(ADG_TRAIL(path), &segment, 1);
219 dup_segment = adg_segment_deep_dup(&segment);
220 cpml_segment_reverse(dup_segment);
221 cairo_matrix_init(&matrix, 1, 0, 0, -1, 0, 0);
222 cpml_segment_transform(dup_segment, &matrix);
223 dup_segment->data[0].header.type = CAIRO_PATH_LINE_TO;
225 adg_path_append_segment(path, dup_segment);
227 g_free(dup_segment);
229 adg_path_close(path);
230 return path;
233 static void
234 sample_add_dimensions(AdgCanvas *canvas, AdgModel *model,
235 const SampleData *data)
237 AdgLDim *ldim;
238 AdgADim *adim;
239 AdgRDim *rdim;
240 double x, y;
242 /* NORTH */
244 /* LD2 */
245 ldim = adg_ldim_new_full_explicit(data->A - data->B - data->LD2, -data->D1 / 2,
246 data->A - data->B, -data->D3 / 2 + CHAMFER,
247 0, -data->D3 / 2,
248 ADG_DIR_UP);
249 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
251 /* LD3 */
252 ldim = adg_ldim_new_full_explicit(data->A - data->B, -data->D3 / 2 + CHAMFER,
253 data->A - data->B + data->LD3,
254 -data->D3 / 2 + CHAMFER,
255 0, -data->D3 / 2,
256 ADG_DIR_UP);
257 adg_ldim_switch_extension1(ldim, FALSE);
258 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
260 /* SOUTH */
262 /* B */
263 ldim = adg_ldim_new_full_explicit(data->A - data->B, data->D3 / 2 - CHAMFER,
264 data->A, data->D7 / 2,
265 0, data->D3 / 2,
266 ADG_DIR_DOWN);
267 adg_dim_set_limits(ADG_DIM(ldim), NULL, "+0.1");
268 adg_ldim_switch_extension2(ldim, FALSE);
269 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
271 /* A */
272 ldim = adg_ldim_new();
273 adg_ldim_set_direction(ldim, ADG_DIR_DOWN);
274 adg_dim_set_ref_from_model(ADG_DIM(ldim), model, "D1I", "D7F");
275 adg_dim_set_pos_from_model(ADG_DIM(ldim), model, "D3F");
276 adg_dim_set_limits(ADG_DIM(ldim), "-0.05", "+0.05");
277 adg_dim_set_level(ADG_DIM(ldim), 2);
278 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
280 /* Angular D6+ */
281 x = data->A - data->C;
282 y = data->D6 / 2 - (data->C - data->LD6 - data->LD7) / SQRT3;
283 adim = adg_adim_new_full_explicit(x + data->LD6, data->D6 / 2,
284 x + 0.1, data->D6 / 2,
285 data->A - data->LD7, y,
286 x + data->LD6, data->D6 / 2,
287 x + data->LD6, data->D6 / 2);
288 adg_dim_set_level(ADG_DIM(adim), 2);
289 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(adim));
291 /* Radial RD34 */
292 x = data->A - data->B + data->LD3 + data->RD34;
293 y = data->D4 / 2 + data->RD34;
294 rdim = adg_rdim_new_full_explicit(x, y,
295 x - cos(G_PI_4) * data->RD34,
296 y - sin(G_PI_4) * data->RD34,
297 x + cos(G_PI_4) * data->RD34,
298 y + sin(G_PI_4) * data->RD34);
299 adg_dim_set_level(ADG_DIM(rdim), 1);
300 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(rdim));
302 /* EAST */
304 /* D3 */
305 x = data->A - data->B + data->LD3 - CHAMFER;
306 ldim = adg_ldim_new_full_explicit(x, -data->D3 / 2,
307 x, data->D3 / 2,
308 data->A, 0,
309 ADG_DIR_RIGHT);
310 adg_dim_set_limits(ADG_DIM(ldim), "-0.25", NULL);
311 adg_dim_set_level(ADG_DIM(ldim), 5);
312 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
314 /* D6 */
315 x = data->A - data->C + data->LD6;
316 ldim = adg_ldim_new_full_explicit(x, -data->D6 / 2,
317 x, data->D6 / 2,
318 data->A, 0,
319 ADG_DIR_RIGHT);
320 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
321 adg_dim_set_level(ADG_DIM(ldim), 4);
322 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
324 /* D4 */
325 x = data->A - data->C - data->LD5;
326 ldim = adg_ldim_new_full_explicit(x, -data->D4 / 2,
327 x, data->D4 / 2,
328 data->A, 0,
329 ADG_DIR_RIGHT);
330 adg_dim_set_level(ADG_DIM(ldim), 3);
331 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
333 /* D5 */
334 x = data->A - data->C - 0.2;
335 ldim = adg_ldim_new_full_explicit(x, -data->D5 / 2,
336 x, data->D5 / 2,
337 data->A, 0,
338 ADG_DIR_RIGHT);
339 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
340 adg_dim_set_level(ADG_DIM(ldim), 2);
341 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
343 /* D7 */
344 ldim = adg_ldim_new_full_explicit(data->A, -data->D7 / 2,
345 data->A, data->D7 / 2,
346 data->A, 0,
347 ADG_DIR_RIGHT);
348 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
350 /* WEST */
352 /* D1 */
353 ldim = adg_ldim_new_full_explicit(0, -data->D1 / 2,
354 0, data->D1 / 2,
355 0, 0,
356 ADG_DIR_LEFT);
357 adg_dim_set_limits(ADG_DIM(ldim), "+0.05", "-0.05");
358 adg_dim_set_level(ADG_DIM(ldim), 2);
359 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
361 /* D2 */
362 y = (data->D1 - data->D2) / 2;
363 x = data->A - data->B - data->LD2 + y * SQRT3;
364 ldim = adg_ldim_new_full_explicit(x, -data->D2 / 2,
365 x, data->D2 / 2,
366 0, 0,
367 ADG_DIR_LEFT);
368 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
369 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
372 static void
373 sample_add_stuff(AdgCanvas *canvas, const SampleData *data)
375 AdgToyText *toy_text;
376 AdgMatrix map;
378 toy_text = adg_toy_text_new("Rotate the mouse wheel to zoom in and out");
379 cairo_matrix_init_translate(&map, 0, data->D3 / 2);
380 adg_entity_set_local_map(ADG_ENTITY(toy_text), &map);
381 cairo_matrix_translate(&map, 10, 30 + 30 * 2);
382 adg_entity_set_global_map(ADG_ENTITY(toy_text), &map);
383 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(toy_text));
385 toy_text = adg_toy_text_new("Keep the wheel pressed while dragging the mouse to translate");
386 cairo_matrix_init_translate(&map, 0, data->D3 / 2);
387 adg_entity_set_local_map(ADG_ENTITY(toy_text), &map);
388 cairo_matrix_init_translate(&map, 10, 50 + 30 * 2);
389 adg_entity_set_global_map(ADG_ENTITY(toy_text), &map);
390 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(toy_text));
394 #if defined(CAIRO_HAS_PNG_FUNCTIONS) || defined(CAIRO_HAS_PDF_SURFACE) || defined(CAIRO_HAS_PS_SURFACE)
396 /* Only needed if there is at least one supported surface */
397 static void
398 file_generated(GtkWidget *caller, const gchar *file)
400 GtkWindow *window;
401 GtkWidget *dialog;
403 window = (GtkWindow *) gtk_widget_get_toplevel(caller);
404 dialog = gtk_message_dialog_new_with_markup(window, GTK_DIALOG_MODAL,
405 GTK_MESSAGE_INFO,
406 GTK_BUTTONS_CLOSE,
407 "The requested operation generated\n"
408 "<b>%s</b> in the current directory.",
409 file);
410 gtk_window_set_title(GTK_WINDOW(dialog), "Operation completed");
411 gtk_dialog_run(GTK_DIALOG(dialog));
412 gtk_widget_destroy(dialog);
415 #endif
417 #if !defined(CAIRO_HAS_PNG_FUNCTIONS) || !defined(CAIRO_HAS_PDF_SURFACE) || !defined(CAIRO_HAS_PS_SURFACE)
419 /* Only needed if there is a missing surface */
420 static void
421 missing_feature(GtkWidget *caller, const gchar *feature)
423 GtkWindow *window;
424 GtkWidget *dialog;
426 window = (GtkWindow *) gtk_widget_get_toplevel(caller);
427 dialog = gtk_message_dialog_new(window, GTK_DIALOG_MODAL,
428 GTK_MESSAGE_WARNING,
429 GTK_BUTTONS_OK,
430 "The provided cairo library\n"
431 "was compiled with no %s support!",
432 feature);
433 gtk_window_set_title(GTK_WINDOW(dialog), "Missing feature");
434 gtk_dialog_run(GTK_DIALOG(dialog));
435 gtk_widget_destroy(dialog);
438 #endif
441 #ifdef CAIRO_HAS_PNG_FUNCTIONS
443 static void
444 to_png(AdgWidget *widget, GtkWidget *caller)
446 cairo_surface_t *surface;
447 cairo_t *cr;
449 surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 800, 600);
450 cr = cairo_create(surface);
451 cairo_surface_destroy(surface);
453 /* Rendering process */
454 adg_entity_render(ADG_ENTITY(adg_widget_get_canvas(widget)), cr);
456 cairo_show_page(cr);
457 cairo_surface_write_to_png(surface, "test.png");
458 cairo_destroy(cr);
460 file_generated(caller, "test.png");
463 #else
465 static void
466 to_png(AdgWidget *widget, GtkWidget *caller)
468 missing_feature(caller, "PNG");
471 #endif
473 #ifdef CAIRO_HAS_PDF_SURFACE
475 #include <cairo-pdf.h>
477 static void
478 to_pdf(AdgWidget *widget, GtkWidget *caller)
480 cairo_surface_t *surface;
481 cairo_t *cr;
483 surface = cairo_pdf_surface_create("test.pdf", 841, 595);
484 cr = cairo_create(surface);
485 cairo_surface_destroy(surface);
487 adg_entity_render(ADG_ENTITY(adg_widget_get_canvas(widget)), cr);
489 cairo_show_page(cr);
490 cairo_destroy(cr);
492 file_generated(caller, "test.pdf");
495 #else
497 static void
498 to_pdf(AdgWidget *widget, GtkWidget *caller)
500 missing_feature(caller, "PDF");
503 #endif
505 #ifdef CAIRO_HAS_PS_SURFACE
507 #include <cairo-ps.h>
509 static void
510 to_ps(AdgWidget *widget, GtkWidget *caller)
512 cairo_surface_t *surface;
513 cairo_t *cr;
515 /* Surface creation: A4 size */
516 surface = cairo_ps_surface_create("test.ps", 841, 595);
517 cairo_ps_surface_dsc_comment(surface,
518 "%%Title: Automatic Drawing Generation (ADG) demo");
519 cairo_ps_surface_dsc_comment(surface,
520 "%%Copyright: Copyright (C) 2006-2009 Fontana Nicola");
521 cairo_ps_surface_dsc_comment(surface, "%%Orientation: Portrait");
523 cairo_ps_surface_dsc_begin_setup(surface);
525 cairo_ps_surface_dsc_begin_page_setup(surface);
526 cairo_ps_surface_dsc_comment(surface,
527 "%%IncludeFeature: *PageSize A4");
529 cr = cairo_create(surface);
530 cairo_surface_destroy(surface);
532 adg_entity_render(ADG_ENTITY(adg_widget_get_canvas(widget)), cr);
534 cairo_show_page(cr);
535 cairo_destroy(cr);
537 file_generated(caller, "test.ps");
540 #else
542 static void
543 to_ps(AdgWidget *widget, GtkWidget *caller)
545 missing_feature(caller, "PostScript");
548 #endif
551 /**********************************************
552 * Test case for basic operations,
553 * such as chamfer and fillet
554 **********************************************/
556 static AdgPath * operations_chamfer (const AdgPath *path,
557 gdouble delta1,
558 gdouble delta2);
559 static AdgPath * operations_fillet (const AdgPath *path,
560 gdouble radius);
562 static AdgCanvas *
563 operations_canvas(void)
565 AdgPath *path, *chamfer_path, *fillet_path;
566 AdgCanvas *canvas;
567 AdgContainer *container;
568 AdgEntity *entity;
569 AdgMatrix map;
571 path = non_trivial_model();
572 chamfer_path = operations_chamfer(path, 0.25, 0.25);
573 fillet_path = operations_fillet(path, 0.20);
574 canvas = adg_canvas_new();
576 /* Add the original shape */
577 container = adg_container_new();
578 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
580 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
581 adg_container_add(container, entity);
583 entity = ADG_ENTITY(adg_toy_text_new("Original shape"));
584 cairo_matrix_init_translate(&map, 5, 10);
585 adg_entity_set_local_map(entity, &map);
586 cairo_matrix_init_translate(&map, -50, 20);
587 adg_entity_set_global_map(entity, &map);
588 adg_container_add(ADG_CONTAINER(canvas), entity);
590 /* Add the shape with 0.25x0.25 chamfer */
591 container = adg_container_new();
592 cairo_matrix_init_translate(&map, 15, 0);
593 adg_entity_set_local_map(ADG_ENTITY(container), &map);
594 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
596 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(chamfer_path)));
597 adg_container_add(container, entity);
599 entity = ADG_ENTITY(adg_toy_text_new("Shape with 0.25x0.25 chamfer"));
600 cairo_matrix_init_translate(&map, 5, 10);
601 adg_entity_set_local_map(entity, &map);
602 cairo_matrix_init_translate(&map, -120, 20);
603 adg_entity_set_global_map(entity, &map);
604 adg_container_add(container, entity);
606 /* Add the shape with fillets with 0.20 of radius */
607 container = adg_container_new();
608 cairo_matrix_init_translate(&map, 30, 0);
609 adg_entity_set_local_map(ADG_ENTITY(container), &map);
610 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
612 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(fillet_path)));
613 adg_container_add(container, entity);
615 entity = ADG_ENTITY(adg_toy_text_new("Shape with R=20 fillet"));
616 cairo_matrix_init_translate(&map, 5, 10);
617 adg_entity_set_local_map(entity, &map);
618 cairo_matrix_init_translate(&map, -90, 20);
619 adg_entity_set_global_map(entity, &map);
620 adg_container_add(container, entity);
622 /* Set a decent start position and zoom */
623 cairo_matrix_init_translate(&map, 10, -140);
624 cairo_matrix_scale(&map, 15, 15);
625 cairo_matrix_translate(&map, 0, 10);
626 adg_entity_set_local_map(ADG_ENTITY(canvas), &map);
628 return canvas;
631 static AdgPath *
632 operations_chamfer(const AdgPath *model, gdouble delta1, gdouble delta2)
634 AdgPath *path;
635 CpmlSegment segment;
636 CpmlPrimitive primitive;
638 path = adg_path_new();
639 adg_trail_get_segment(ADG_TRAIL(model), &segment, 1);
640 cpml_primitive_from_segment(&primitive, &segment);
642 adg_path_move_to(path, (primitive.org)->point.x, (primitive.org)->point.y);
644 do {
645 adg_path_append_primitive(path, &primitive);
646 if (primitive.data[0].header.type == CAIRO_PATH_LINE_TO)
647 adg_path_chamfer(path, delta1, delta2);
648 } while (cpml_primitive_next(&primitive));
650 return path;
653 static AdgPath *
654 operations_fillet(const AdgPath *model, gdouble radius)
656 AdgPath *path;
657 CpmlSegment segment;
658 CpmlPrimitive primitive;
660 path = adg_path_new();
661 adg_trail_get_segment(ADG_TRAIL(model), &segment, 1);
662 cpml_primitive_from_segment(&primitive, &segment);
664 adg_path_move_to(path, (primitive.org)->point.x, (primitive.org)->point.y);
666 do {
667 adg_path_append_primitive(path, &primitive);
668 if (primitive.data[0].header.type == CAIRO_PATH_LINE_TO)
669 adg_path_fillet(path, radius);
670 } while (cpml_primitive_next(&primitive));
672 return path;
676 /**********************************************
677 * Test case for mapping transformations,
678 * either on the local and global map
679 **********************************************/
681 static AdgCanvas *
682 mapping_canvas(void)
684 AdgPath *path;
685 AdgCanvas *canvas;
686 AdgContainer *container;
687 AdgEntity *entity;
688 AdgMatrix map;
690 path = non_trivial_model();
691 canvas = adg_canvas_new();
693 /* Add the original shape */
694 container = adg_container_new();
695 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
697 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
698 adg_container_add(container, entity);
700 entity = ADG_ENTITY(adg_toy_text_new("Original shape"));
701 cairo_matrix_init_translate(&map, -50, 20);
702 adg_entity_set_global_map(entity, &map);
703 cairo_matrix_init_translate(&map, 5, 10);
704 adg_entity_set_local_map(entity, &map);
705 adg_container_add(ADG_CONTAINER(canvas), entity);
707 /* Original shape with global rotated by 90 and local translated x+=10 */
708 container = adg_container_new();
709 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
710 cairo_matrix_init_translate(&map, 15, 0);
711 adg_entity_set_local_map(ADG_ENTITY(container), &map);
713 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
714 cairo_matrix_init_rotate(&map, M_PI_2);
715 adg_entity_set_global_map(entity, &map);
716 cairo_matrix_init_translate(&map, 10, 0);
717 adg_entity_set_local_map(entity, &map);
718 adg_container_add(container, entity);
720 entity = ADG_ENTITY(adg_toy_text_new("Global map rotated by 90"));
721 cairo_matrix_init_translate(&map, -120, 20);
722 adg_entity_set_global_map(entity, &map);
723 cairo_matrix_init_translate(&map, 5, 10);
724 adg_entity_set_local_map(entity, &map);
725 adg_container_add(container, entity);
727 /* Original shape with local translated x+=10 and rotated by 90 */
728 container = adg_container_new();
729 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
730 cairo_matrix_init_translate(&map, 30, 0);
731 adg_entity_set_local_map(ADG_ENTITY(container), &map);
733 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
734 cairo_matrix_init_translate(&map, 10, 0);
735 cairo_matrix_rotate(&map, M_PI_2);
736 adg_entity_set_local_map(entity, &map);
737 adg_container_add(container, entity);
739 entity = ADG_ENTITY(adg_toy_text_new("Local map rotated by 90"));
740 cairo_matrix_init_translate(&map, -120, 20);
741 adg_entity_set_global_map(entity, &map);
742 cairo_matrix_init_translate(&map, 5, 10);
743 adg_entity_set_local_map(entity, &map);
744 adg_container_add(container, entity);
746 /* Original shape with global map scaled by 0.5 */
747 container = adg_container_new();
748 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
749 cairo_matrix_init_translate(&map, 3.5, 15);
750 adg_entity_set_local_map(ADG_ENTITY(container), &map);
752 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
753 cairo_matrix_init_scale(&map, 0.5, 0.5);
754 adg_entity_set_global_map(entity, &map);
755 adg_container_add(container, entity);
757 entity = ADG_ENTITY(adg_toy_text_new("Global map scaled by 0.5"));
758 cairo_matrix_init_translate(&map, -100, 20);
759 adg_entity_set_global_map(entity, &map);
760 cairo_matrix_init_translate(&map, 2.5, 5);
761 adg_entity_set_local_map(entity, &map);
762 adg_container_add(container, entity);
764 /* Original shape with local map scaled by 0.5 */
765 container = adg_container_new();
766 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
767 cairo_matrix_init_translate(&map, 18, 15);
768 adg_entity_set_local_map(ADG_ENTITY(container), &map);
770 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
771 cairo_matrix_init_scale(&map, 0.5, 0.5);
772 adg_entity_set_local_map(entity, &map);
773 adg_container_add(container, entity);
775 entity = ADG_ENTITY(adg_toy_text_new("Local map scaled by 0.5"));
776 cairo_matrix_init_translate(&map, -100, 20);
777 adg_entity_set_global_map(entity, &map);
778 cairo_matrix_init_translate(&map, 2.5, 5);
779 adg_entity_set_local_map(entity, &map);
780 adg_container_add(container, entity);
782 /* Original shape with global and local maps scaled by 0.5 */
783 container = adg_container_new();
784 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
785 cairo_matrix_init_translate(&map, 33, 15);
786 adg_entity_set_local_map(ADG_ENTITY(container), &map);
788 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
789 cairo_matrix_init_scale(&map, 0.5, 0.5);
790 adg_entity_set_global_map(entity, &map);
791 adg_entity_set_local_map(entity, &map);
792 adg_container_add(container, entity);
794 entity = ADG_ENTITY(adg_toy_text_new("Local&global scaled by 0.5"));
795 cairo_matrix_init_translate(&map, -130, 20);
796 adg_entity_set_global_map(entity, &map);
797 cairo_matrix_init_translate(&map, 2.5, 5);
798 adg_entity_set_local_map(entity, &map);
799 adg_container_add(container, entity);
801 /* Set a decent start position and zoom */
802 cairo_matrix_init_translate(&map, 10, -140);
803 cairo_matrix_scale(&map, 15, 15);
804 cairo_matrix_translate(&map, 0, 10);
805 adg_entity_set_local_map(ADG_ENTITY(canvas), &map);
807 return canvas;
811 /**********************************************
812 * Non specific test related stuff
813 **********************************************/
815 static AdgPath *
816 non_trivial_model()
818 AdgPath *path = adg_path_new();
820 adg_path_move_to(path, 2, 0);
821 adg_path_line_to(path, 0, 5);
822 adg_path_line_to(path, 2, 2);
823 adg_path_line_to(path, 0, 8);
824 adg_path_line_to(path, 2, 8);
825 adg_path_line_to(path, 2, 10);
826 adg_path_line_to(path, 3, 10);
827 adg_path_line_to(path, 10, 9);
828 adg_path_line_to(path, 5, 5);
829 adg_path_line_to(path, 3, 0);
830 adg_path_close(path);
832 return path;