[AdgColorStyle] Added missing getters/setters
[adg.git] / demo / adg-demo.c
blobf84740723a323386ce9d537fa3b8d40da58d9111
1 #include <config.h>
2 #include <adg/adg.h>
3 #include <adg/adg-widget.h>
4 #include <math.h>
6 /* Required for i18n */
7 #undef G_LOG_DOMAIN
8 #include <adg/adg-internal.h>
10 #include "demo.h"
13 static void parse_args (gint *p_argc,
14 gchar **p_argv[],
15 gboolean *show_extents);
16 static AdgCanvas * sample_canvas (void);
17 static AdgCanvas * operations_canvas (void);
18 static AdgCanvas * mapping_canvas (void);
19 static AdgCanvas * alignment_canvas (void);
20 static void to_pdf (AdgWidget *widget,
21 GtkWidget *caller);
22 static void to_png (AdgWidget *widget,
23 GtkWidget *caller);
24 static void to_ps (AdgWidget *widget,
25 GtkWidget *caller);
27 int
28 main(gint argc, gchar **argv)
30 gboolean show_extents;
31 gchar *path;
32 GtkBuilder *builder;
33 GError *error;
34 GtkWidget *window;
35 GtkWidget *widget;
37 parse_args(&argc, &argv, &show_extents);
38 adg_switch_extents(show_extents);
40 path = demo_find_data_file("adg-demo.ui");
41 if (path == NULL) {
42 g_print("adg-demo.ui not found!\n");
43 return 1;
46 builder = gtk_builder_new();
47 error = NULL;
49 gtk_builder_add_from_file(builder, path, &error);
50 if (error != NULL) {
51 g_print("%s\n", error->message);
52 return 2;
55 window = (GtkWidget *) gtk_builder_get_object(builder, "wndMain");
56 gtk_window_maximize(GTK_WINDOW(window));
58 widget = (GtkWidget *) gtk_builder_get_object(builder, "areaSample");
59 g_signal_connect_swapped(gtk_builder_get_object(builder, "btnPng"),
60 "clicked", G_CALLBACK(to_png), widget);
61 g_signal_connect_swapped(gtk_builder_get_object(builder, "btnPdf"),
62 "clicked", G_CALLBACK(to_pdf), widget);
63 g_signal_connect_swapped(gtk_builder_get_object(builder, "btnPs"),
64 "clicked", G_CALLBACK(to_ps), widget);
65 adg_widget_set_canvas(ADG_WIDGET(widget), sample_canvas());
67 widget = (GtkWidget *) gtk_builder_get_object(builder, "areaOperations");
68 adg_widget_set_canvas(ADG_WIDGET(widget), operations_canvas());
70 widget = (GtkWidget *) gtk_builder_get_object(builder, "areaMapping");
71 adg_widget_set_canvas(ADG_WIDGET(widget), mapping_canvas());
73 widget = (GtkWidget *) gtk_builder_get_object(builder, "areaAlignment");
74 adg_widget_set_canvas(ADG_WIDGET(widget), alignment_canvas());
76 /* Connect signals */
77 g_signal_connect(window, "delete-event",
78 G_CALLBACK(gtk_main_quit), NULL);
79 g_signal_connect(gtk_builder_get_object(builder, "btnQuit"),
80 "clicked", G_CALLBACK(gtk_main_quit), NULL);
82 g_object_unref(builder);
84 gtk_widget_show_all(window);
85 gtk_main();
87 return 0;
91 /**********************************************
92 * Command line options parser
93 **********************************************/
95 static void
96 version(void)
98 g_print("adg-demo " PACKAGE_VERSION "\n");
99 exit(0);
102 static void
103 parse_args(gint *p_argc, gchar **p_argv[], gboolean *show_extents)
105 GError *error = NULL;
106 GOptionEntry entries[] = {
107 {"version", 'V', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, version,
108 "Display version information", NULL},
109 {"show-extents", 'E', 0, G_OPTION_ARG_NONE, NULL,
110 "Show the boundary boxes of every entity", NULL},
111 {NULL}
114 entries[1].arg_data = show_extents;
115 *show_extents = FALSE;
116 gtk_init_with_args(p_argc, p_argv, "- ADG demonstration program",
117 entries, GETTEXT_PACKAGE, &error);
119 if (error != NULL) {
120 gint error_code = error->code;
122 g_printerr("%s\n", error->message);
124 g_error_free(error);
125 exit(error_code);
130 /**********************************************
131 * A sample mechanical part example
132 **********************************************/
134 #define SQRT3 1.732050808
135 #define CHAMFER 0.3
137 typedef struct _SampleData SampleData;
139 struct _SampleData {
140 gdouble A, B, C;
141 gdouble DHOLE, LHOLE;
142 gdouble D1, D2, D3, D4, D5, D6, D7;
143 gdouble RD34, RD56;
144 gdouble LD2, LD3, LD5, LD6, LD7;
147 static AdgPath *non_trivial_model (void);
148 static void sample_get (SampleData *data);
149 static AdgPath *sample_bottom_path (const SampleData *data,
150 gdouble height);
151 static AdgPath *sample_path (const SampleData *data);
152 static void sample_add_sheet (AdgCanvas *canvas);
153 static void sample_add_dimensions (AdgCanvas *canvas,
154 AdgModel *model);
155 static void sample_add_stuff (AdgCanvas *canvas,
156 AdgModel *model);
159 static AdgCanvas *
160 sample_canvas(void)
162 SampleData data;
163 AdgCanvas *canvas;
164 AdgContainer *container;
165 AdgPath *bottom, *shape;
166 AdgEdges *edges;
167 AdgEntity *entity;
168 AdgMatrix map;
170 sample_get(&data);
171 canvas = adg_canvas_new();
172 container = (AdgContainer *) canvas;
174 bottom = sample_bottom_path(&data, data.LHOLE + 2);
175 adg_path_reflect(bottom, NULL);
176 adg_path_close(bottom);
178 shape = sample_path(&data);
179 adg_path_reflect(shape, NULL);
180 adg_path_close(shape);
181 adg_path_move_to_explicit(shape, data.LHOLE + 2, data.D1 / 2);
182 adg_path_line_to_explicit(shape, data.LHOLE + 2, -data.D1 / 2);
184 edges = adg_edges_new_with_source(ADG_TRAIL(shape));
186 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(shape)));
187 adg_container_add(container, entity);
189 entity = ADG_ENTITY(adg_hatch_new(ADG_TRAIL(bottom)));
190 adg_container_add(container, entity);
192 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(edges)));
193 adg_container_add(container, entity);
195 sample_add_sheet(canvas);
196 sample_add_dimensions(canvas, ADG_MODEL(shape));
197 sample_add_stuff(canvas, ADG_MODEL(shape));
199 cairo_matrix_init_translate(&map, 110, 70);
200 cairo_matrix_scale(&map, 6.883, 6.883);
201 cairo_matrix_translate(&map, 0, 10);
202 adg_entity_set_local_map(ADG_ENTITY(container), &map);
204 return canvas;
207 static void
208 sample_get(SampleData *data)
210 data->A = 52.3;
211 data->B = 20.6;
212 data->C = 2;
213 data->DHOLE = 2;
214 data->LHOLE = 3;
215 data->D1 = 9.3;
216 data->D2 = 6.5;
217 data->D3 = 11.9;
218 data->D4 = 6.5;
219 data->D5 = 4.5;
220 data->D6 = 7.2;
221 data->D7 = 3;
222 data->RD34 = 1;
223 data->LD2 = 7;
224 data->LD3 = 3.5;
225 data->LD5 = 5;
226 data->LD6 = 1;
227 data->LD7 = 0.5;
230 static AdgPath *
231 sample_bottom_path(const SampleData *data, gdouble height)
233 AdgPath *path;
234 AdgModel *model;
235 AdgPair pair;
237 path = adg_path_new();
238 model = ADG_MODEL(path);
240 pair.x = data->LHOLE;
241 pair.y = 0;
242 adg_path_move_to(path, &pair);
243 adg_model_set_named_pair(model, "LHOLE", &pair);
245 pair.y = data->DHOLE / 2;
246 pair.x -= pair.y / SQRT3;
247 adg_path_line_to(path, &pair);
249 pair.x = 0;
250 adg_path_line_to(path, &pair);
251 adg_model_set_named_pair(model, "DHOLE", &pair);
253 pair.y = data->D1 / 2;
254 adg_path_line_to(path, &pair);
255 adg_model_set_named_pair(model, "D1I", &pair);
257 pair.x = height;
258 adg_path_line_to(path, &pair);
259 adg_model_set_named_pair(model, "D1F", &pair);
261 return path;
264 static AdgPath *
265 sample_path(const SampleData *data)
267 AdgPath *path;
268 AdgModel *model;
269 AdgPair pair, tmp;
270 const AdgPrimitive *primitive;
272 pair.x = data->A - data->B - data->LD2;
273 path = sample_bottom_path(data, pair.x);
274 model = ADG_MODEL(path);
276 pair.x += (data->D1 - data->D2) * SQRT3 / 2;
277 pair.y = data->D2 / 2;
278 adg_path_line_to(path, &pair);
279 adg_model_set_named_pair(model, "D2I", &pair);
281 pair.x = data->A - data->B;
282 adg_path_line_to(path, &pair);
283 adg_path_fillet(path, 0.4);
285 pair.x = data->A - data->B;
286 pair.y = data->D3 / 2;
287 adg_path_line_to(path, &pair);
288 adg_model_set_named_pair(model, "D3I", &pair);
290 pair.x = data->A;
291 adg_model_set_named_pair(model, "East", &pair);
293 adg_path_chamfer(path, CHAMFER, CHAMFER);
295 pair.x = data->A - data->B + data->LD3;
296 pair.y = data->D3 / 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, "D3I_X", &tmp);
303 adg_path_chamfer(path, CHAMFER, CHAMFER);
305 pair.y = data->D4 / 2;
306 adg_path_line_to(path, &pair);
308 primitive = adg_path_over_primitive(path);
309 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
310 adg_model_set_named_pair(model, "D3F_Y", &tmp);
311 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, -1));
312 adg_model_set_named_pair(model, "D3F_X", &tmp);
314 adg_path_fillet(path, data->RD34);
316 pair.x = data->A - data->C - data->LD5;
317 adg_path_line_to(path, &pair);
318 adg_model_set_named_pair(model, "D4F", &pair);
320 primitive = adg_path_over_primitive(path);
321 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
322 tmp.x += data->RD34;
323 adg_model_set_named_pair(model, "RD34", &tmp);
325 tmp.x -= cos(G_PI_4) * data->RD34,
326 tmp.y -= sin(G_PI_4) * data->RD34,
327 adg_model_set_named_pair(model, "RD34_R", &tmp);
329 tmp.x += data->RD34,
330 tmp.y += data->RD34,
331 adg_model_set_named_pair(model, "RD34_XY", &tmp);
333 pair.x += (data->D4 - data->D5) / 2;
334 pair.y = data->D5 / 2;
335 adg_path_line_to(path, &pair);
337 pair.x = data->A - data->C;
338 adg_path_line_to(path, &pair);
340 adg_path_fillet(path, 0.2);
342 pair.y = data->D6 / 2;
343 adg_path_line_to(path, &pair);
345 primitive = adg_path_over_primitive(path);
346 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
347 adg_model_set_named_pair(model, "D5F", &tmp);
349 adg_path_fillet(path, 0.1);
351 pair.x += data->LD6;
352 adg_path_line_to(path, &pair);
353 adg_model_set_named_pair(model, "D6F", &pair);
355 primitive = adg_path_over_primitive(path);
356 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, -1));
357 adg_model_set_named_pair(model, "D6I_Y", &tmp);
359 pair.x = data->A - data->LD7;
360 pair.y -= (data->C - data->LD7 - data->LD6) / SQRT3;
361 adg_path_line_to(path, &pair);
362 adg_model_set_named_pair(model, "D67", &pair);
364 pair.y = data->D7 / 2;
365 adg_path_line_to(path, &pair);
367 pair.x = data->A;
368 adg_path_line_to(path, &pair);
369 adg_model_set_named_pair(model, "D7F", &pair);
371 return path;
374 static void
375 sample_add_sheet(AdgCanvas *canvas)
377 AdgTitleBlock *title_block;
378 AdgLogo *logo;
379 AdgMatrix map;
381 title_block = adg_title_block_new();
383 logo = adg_logo_new();
384 cairo_matrix_init_scale(&map, 2, 2);
385 adg_entity_set_global_map(ADG_ENTITY(logo), &map);
387 g_object_set(title_block,
388 "title", "SAMPLE DRAWING",
389 "author", "NtD",
390 "date", "",
391 "drawing", "TEST123",
392 "logo", logo,
393 "projection", adg_projection_new(ADG_PROJECTION_FIRST_ANGLE),
394 "scale", "NONE",
395 "size", "A4",
396 NULL);
398 cairo_matrix_init_translate(&map, 800, 600);
399 adg_entity_set_global_map(ADG_ENTITY(title_block), &map);
401 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(title_block));
404 static void
405 sample_add_dimensions(AdgCanvas *canvas, AdgModel *model)
407 AdgLDim *ldim;
408 AdgADim *adim;
409 AdgRDim *rdim;
411 /* NORTH */
413 ldim = adg_ldim_new_full_from_model(model, "-D1F", "-D3I_X", "-D3F_Y",
414 ADG_DIR_UP);
415 adg_dim_set_outside(ADG_DIM(ldim), ADG_THREE_STATE_OFF);
416 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
418 ldim = adg_ldim_new_full_from_model(model, "-D3I_X", "-D3F_X", "-D3F_Y",
419 ADG_DIR_UP);
420 adg_ldim_switch_extension1(ldim, FALSE);
421 adg_dim_set_outside(ADG_DIM(ldim), ADG_THREE_STATE_OFF);
422 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
424 /* SOUTH */
426 ldim = adg_ldim_new_full_from_model(model, "D1I", "LHOLE", "D3F_Y",
427 ADG_DIR_DOWN);
428 adg_ldim_switch_extension1(ldim, FALSE);
429 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
431 ldim = adg_ldim_new_full_from_model(model, "D3I_X", "D7F", "D3F_Y",
432 ADG_DIR_DOWN);
433 adg_dim_set_limits(ADG_DIM(ldim), NULL, "+0.1");
434 adg_ldim_switch_extension2(ldim, FALSE);
435 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
437 ldim = adg_ldim_new_full_from_model(model, "D1I", "D7F", "D3F_Y",
438 ADG_DIR_DOWN);
439 adg_dim_set_limits(ADG_DIM(ldim), "-0.05", "+0.05");
440 adg_dim_set_level(ADG_DIM(ldim), 2);
441 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
443 adim = adg_adim_new_full_from_model(model, "D6F", "D6I_Y", "D67",
444 "D6F", "D6F");
445 adg_dim_set_level(ADG_DIM(adim), 2);
446 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(adim));
448 rdim = adg_rdim_new_full_from_model(model, "RD34", "RD34_R", "RD34_XY");
449 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(rdim));
451 /* EAST */
453 ldim = adg_ldim_new_full_from_model(model, "D3F_Y", "-D3F_Y", "East",
454 ADG_DIR_RIGHT);
455 adg_dim_set_limits(ADG_DIM(ldim), "-0.25", NULL);
456 adg_dim_set_level(ADG_DIM(ldim), 5);
457 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
459 ldim = adg_ldim_new_full_from_model(model, "D6F", "-D6F", "-East",
460 ADG_DIR_RIGHT);
461 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
462 adg_dim_set_level(ADG_DIM(ldim), 4);
463 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
465 ldim = adg_ldim_new_full_from_model(model, "D4F", "-D4F", "East",
466 ADG_DIR_RIGHT);
467 adg_dim_set_level(ADG_DIM(ldim), 3);
468 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
470 ldim = adg_ldim_new_full_from_model(model, "D5F", "-D5F", "-East",
471 ADG_DIR_RIGHT);
472 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
473 adg_dim_set_level(ADG_DIM(ldim), 2);
474 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
476 ldim = adg_ldim_new_full_from_model(model, "D7F", "-D7F", "East",
477 ADG_DIR_RIGHT);
478 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
480 /* WEST */
482 ldim = adg_ldim_new_full_from_model(model, "D1I", "-D1I", "D1I",
483 ADG_DIR_LEFT);
484 adg_dim_set_limits(ADG_DIM(ldim), "+0.05", "-0.05");
485 adg_dim_set_level(ADG_DIM(ldim), 3);
486 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
488 ldim = adg_ldim_new_full_from_model(model, "D2I", "-D2I", "D1I",
489 ADG_DIR_LEFT);
490 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
491 adg_dim_set_level(ADG_DIM(ldim), 2);
492 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
494 ldim = adg_ldim_new_full_from_model(model, "DHOLE", "-DHOLE", "D1I",
495 ADG_DIR_LEFT);
496 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
499 static void
500 sample_add_stuff(AdgCanvas *canvas, AdgModel *model)
502 AdgToyText *toy_text;
503 AdgMatrix map;
504 const AdgPair *pair;
506 toy_text = adg_toy_text_new("Rotate the mouse wheel to zoom in and out");
507 pair = adg_model_get_named_pair(model, "D3I");
508 cairo_matrix_init_translate(&map, 0, pair->y);
509 adg_entity_set_local_map(ADG_ENTITY(toy_text), &map);
510 cairo_matrix_init_translate(&map, 10, 30 + 30 * 2);
511 adg_entity_set_global_map(ADG_ENTITY(toy_text), &map);
512 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(toy_text));
514 toy_text = adg_toy_text_new("Keep the wheel pressed while dragging the mouse to translate");
515 cairo_matrix_init_translate(&map, 0, pair->y);
516 adg_entity_set_local_map(ADG_ENTITY(toy_text), &map);
517 cairo_matrix_init_translate(&map, 10, 50 + 30 * 2);
518 adg_entity_set_global_map(ADG_ENTITY(toy_text), &map);
519 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(toy_text));
523 #if defined(CAIRO_HAS_PNG_FUNCTIONS) || defined(CAIRO_HAS_PDF_SURFACE) || defined(CAIRO_HAS_PS_SURFACE)
525 /* Only needed if there is at least one supported surface */
526 static void
527 file_generated(GtkWidget *caller, const gchar *file)
529 GtkWindow *window;
530 GtkWidget *dialog;
532 window = (GtkWindow *) gtk_widget_get_toplevel(caller);
533 dialog = gtk_message_dialog_new_with_markup(window, GTK_DIALOG_MODAL,
534 GTK_MESSAGE_INFO,
535 GTK_BUTTONS_CLOSE,
536 "The requested operation generated\n"
537 "<b>%s</b> in the current directory.",
538 file);
539 gtk_window_set_title(GTK_WINDOW(dialog), "Operation completed");
540 gtk_dialog_run(GTK_DIALOG(dialog));
541 gtk_widget_destroy(dialog);
544 #endif
546 #if !defined(CAIRO_HAS_PNG_FUNCTIONS) || !defined(CAIRO_HAS_PDF_SURFACE) || !defined(CAIRO_HAS_PS_SURFACE)
548 /* Only needed if there is a missing surface */
549 static void
550 missing_feature(GtkWidget *caller, const gchar *feature)
552 GtkWindow *window;
553 GtkWidget *dialog;
555 window = (GtkWindow *) gtk_widget_get_toplevel(caller);
556 dialog = gtk_message_dialog_new(window, GTK_DIALOG_MODAL,
557 GTK_MESSAGE_WARNING,
558 GTK_BUTTONS_OK,
559 "The provided cairo library\n"
560 "was compiled with no %s support!",
561 feature);
562 gtk_window_set_title(GTK_WINDOW(dialog), "Missing feature");
563 gtk_dialog_run(GTK_DIALOG(dialog));
564 gtk_widget_destroy(dialog);
567 #endif
570 #ifdef CAIRO_HAS_PNG_FUNCTIONS
572 static void
573 to_png(AdgWidget *widget, GtkWidget *caller)
575 cairo_surface_t *surface;
576 cairo_t *cr;
578 surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 800, 600);
579 cr = cairo_create(surface);
580 cairo_surface_destroy(surface);
582 /* Rendering process */
583 adg_entity_render(ADG_ENTITY(adg_widget_get_canvas(widget)), cr);
585 cairo_show_page(cr);
586 cairo_surface_write_to_png(surface, "test.png");
587 cairo_destroy(cr);
589 file_generated(caller, "test.png");
592 #else
594 static void
595 to_png(AdgWidget *widget, GtkWidget *caller)
597 missing_feature(caller, "PNG");
600 #endif
602 #ifdef CAIRO_HAS_PDF_SURFACE
604 #include <cairo-pdf.h>
606 static void
607 to_pdf(AdgWidget *widget, GtkWidget *caller)
609 cairo_surface_t *surface;
610 cairo_t *cr;
612 surface = cairo_pdf_surface_create("test.pdf", 841, 595);
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.pdf");
624 #else
626 static void
627 to_pdf(AdgWidget *widget, GtkWidget *caller)
629 missing_feature(caller, "PDF");
632 #endif
634 #ifdef CAIRO_HAS_PS_SURFACE
636 #include <cairo-ps.h>
638 static void
639 to_ps(AdgWidget *widget, GtkWidget *caller)
641 cairo_surface_t *surface;
642 cairo_t *cr;
644 /* Surface creation: A4 size */
645 surface = cairo_ps_surface_create("test.ps", 841, 595);
646 cairo_ps_surface_dsc_comment(surface,
647 "%%Title: Automatic Drawing Generation (ADG) demo");
648 cairo_ps_surface_dsc_comment(surface,
649 "%%Copyright: Copyright (C) 2006-2009 Fontana Nicola");
650 cairo_ps_surface_dsc_comment(surface, "%%Orientation: Portrait");
652 cairo_ps_surface_dsc_begin_setup(surface);
654 cairo_ps_surface_dsc_begin_page_setup(surface);
655 cairo_ps_surface_dsc_comment(surface,
656 "%%IncludeFeature: *PageSize A4");
658 cr = cairo_create(surface);
659 cairo_surface_destroy(surface);
661 adg_entity_render(ADG_ENTITY(adg_widget_get_canvas(widget)), cr);
663 cairo_show_page(cr);
664 cairo_destroy(cr);
666 file_generated(caller, "test.ps");
669 #else
671 static void
672 to_ps(AdgWidget *widget, GtkWidget *caller)
674 missing_feature(caller, "PostScript");
677 #endif
680 /**********************************************
681 * Test case for basic operations,
682 * such as chamfer and fillet
683 **********************************************/
685 static AdgPath * operations_chamfer (const AdgPath *path,
686 gdouble delta1,
687 gdouble delta2);
688 static AdgPath * operations_fillet (const AdgPath *path,
689 gdouble radius);
691 static AdgCanvas *
692 operations_canvas(void)
694 AdgPath *path, *chamfer_path, *fillet_path;
695 AdgCanvas *canvas;
696 AdgContainer *container;
697 AdgEntity *entity;
698 AdgMatrix map;
700 path = non_trivial_model();
701 chamfer_path = operations_chamfer(path, 0.25, 0.25);
702 fillet_path = operations_fillet(path, 0.20);
703 canvas = adg_canvas_new();
705 /* Add the original shape */
706 container = adg_container_new();
707 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
709 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
710 adg_container_add(container, entity);
712 entity = ADG_ENTITY(adg_toy_text_new("Original shape"));
713 cairo_matrix_init_translate(&map, 5, 10);
714 adg_entity_set_local_map(entity, &map);
715 cairo_matrix_init_translate(&map, -50, 20);
716 adg_entity_set_global_map(entity, &map);
717 adg_container_add(ADG_CONTAINER(canvas), entity);
719 /* Add the shape with 0.25x0.25 chamfer */
720 container = adg_container_new();
721 cairo_matrix_init_translate(&map, 15, 0);
722 adg_entity_set_local_map(ADG_ENTITY(container), &map);
723 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
725 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(chamfer_path)));
726 adg_container_add(container, entity);
728 entity = ADG_ENTITY(adg_toy_text_new("Shape with 0.25x0.25 chamfer"));
729 cairo_matrix_init_translate(&map, 5, 10);
730 adg_entity_set_local_map(entity, &map);
731 cairo_matrix_init_translate(&map, -120, 20);
732 adg_entity_set_global_map(entity, &map);
733 adg_container_add(container, entity);
735 /* Add the shape with fillets with 0.20 of radius */
736 container = adg_container_new();
737 cairo_matrix_init_translate(&map, 30, 0);
738 adg_entity_set_local_map(ADG_ENTITY(container), &map);
739 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
741 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(fillet_path)));
742 adg_container_add(container, entity);
744 entity = ADG_ENTITY(adg_toy_text_new("Shape with R=0.20 fillet"));
745 cairo_matrix_init_translate(&map, 5, 10);
746 adg_entity_set_local_map(entity, &map);
747 cairo_matrix_init_translate(&map, -90, 20);
748 adg_entity_set_global_map(entity, &map);
749 adg_container_add(container, entity);
751 /* Set a decent start position and zoom */
752 cairo_matrix_init_translate(&map, 10, -140);
753 cairo_matrix_scale(&map, 15, 15);
754 cairo_matrix_translate(&map, 0, 10);
755 adg_entity_set_local_map(ADG_ENTITY(canvas), &map);
757 return canvas;
760 static AdgPath *
761 operations_chamfer(const AdgPath *model, gdouble delta1, gdouble delta2)
763 AdgPath *path;
764 CpmlSegment segment;
765 CpmlPrimitive primitive;
766 CpmlPair org;
768 path = adg_path_new();
769 adg_trail_put_segment(ADG_TRAIL(model), 1, &segment);
770 cpml_primitive_from_segment(&primitive, &segment);
771 cpml_pair_from_cairo(&org, primitive.org);
773 adg_path_move_to(path, &org);
775 do {
776 adg_path_append_primitive(path, &primitive);
777 adg_path_chamfer(path, delta1, delta2);
778 } while (cpml_primitive_next(&primitive));
780 return path;
783 static AdgPath *
784 operations_fillet(const AdgPath *model, gdouble radius)
786 AdgPath *path;
787 CpmlSegment segment;
788 CpmlPrimitive primitive;
789 CpmlPair org;
791 path = adg_path_new();
792 adg_trail_put_segment(ADG_TRAIL(model), 1, &segment);
793 cpml_primitive_from_segment(&primitive, &segment);
794 cpml_pair_from_cairo(&org, primitive.org);
796 adg_path_move_to(path, &org);
798 do {
799 adg_path_append_primitive(path, &primitive);
800 adg_path_fillet(path, radius);
801 } while (cpml_primitive_next(&primitive));
803 return path;
807 /**********************************************
808 * Test case for mapping transformations,
809 * either on the local and global map
810 **********************************************/
812 static AdgCanvas *
813 mapping_canvas(void)
815 AdgPath *path;
816 AdgCanvas *canvas;
817 AdgContainer *container;
818 AdgEntity *entity;
819 AdgMatrix map;
821 path = non_trivial_model();
822 canvas = adg_canvas_new();
824 /* Original shape */
825 container = adg_container_new();
826 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
828 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
829 adg_container_add(container, entity);
831 entity = ADG_ENTITY(adg_toy_text_new("Original shape"));
832 cairo_matrix_init_translate(&map, -50, 20);
833 adg_entity_set_global_map(entity, &map);
834 cairo_matrix_init_translate(&map, 5, 10);
835 adg_entity_set_local_map(entity, &map);
836 adg_container_add(ADG_CONTAINER(canvas), entity);
838 /* Global map rotated by 90 */
839 container = adg_container_new();
840 cairo_matrix_init_translate(&map, 0, -25);
841 adg_entity_set_local_map(ADG_ENTITY(container), &map);
842 cairo_matrix_init_rotate(&map, M_PI_2);
843 adg_entity_set_global_map(ADG_ENTITY(container), &map);
844 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
846 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
847 adg_container_add(container, entity);
849 entity = ADG_ENTITY(adg_toy_text_new("Global map rotated by 90"));
850 cairo_matrix_init_translate(&map, -100, 20);
851 adg_entity_set_global_map(entity, &map);
852 cairo_matrix_init_translate(&map, 5, 10);
853 adg_entity_set_local_map(entity, &map);
854 adg_container_add(container, entity);
856 /* Local map rotated by 90 */
857 container = adg_container_new();
858 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
859 cairo_matrix_init_translate(&map, 40, 0);
860 cairo_matrix_rotate(&map, M_PI_2);
861 adg_entity_set_local_map(ADG_ENTITY(container), &map);
863 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
864 adg_container_add(container, entity);
866 entity = ADG_ENTITY(adg_toy_text_new("Local map rotated by 90"));
867 cairo_matrix_init_translate(&map, -20, -100);
868 adg_entity_set_global_map(entity, &map);
869 cairo_matrix_init_translate(&map, 5, 10);
870 adg_entity_set_local_map(entity, &map);
871 adg_container_add(container, entity);
873 /* Global map scaled by 0.5 */
874 container = adg_container_new();
875 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
876 cairo_matrix_init_translate(&map, 5, 30);
877 adg_entity_set_local_map(ADG_ENTITY(container), &map);
878 cairo_matrix_init_scale(&map, 0.5, 0.5);
879 adg_entity_set_global_map(ADG_ENTITY(container), &map);
881 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
882 adg_container_add(container, entity);
884 entity = ADG_ENTITY(adg_toy_text_new("Global map scaled by 0.5"));
885 cairo_matrix_init_translate(&map, -80, 20);
886 adg_entity_set_global_map(entity, &map);
887 cairo_matrix_init_translate(&map, 5, 10);
888 adg_entity_set_local_map(entity, &map);
889 adg_container_add(container, entity);
891 /* Local map scaled by 0.5 */
892 container = adg_container_new();
893 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
894 cairo_matrix_init_translate(&map, 18, 15);
895 cairo_matrix_scale(&map, 0.5, 0.5);
896 adg_entity_set_local_map(ADG_ENTITY(container), &map);
898 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
899 adg_container_add(container, entity);
901 entity = ADG_ENTITY(adg_toy_text_new("Local map scaled by 0.5"));
902 cairo_matrix_init_translate(&map, -80, 20);
903 adg_entity_set_global_map(entity, &map);
904 cairo_matrix_init_translate(&map, 5, 10);
905 adg_entity_set_local_map(entity, &map);
906 adg_container_add(container, entity);
908 /* Global and local maps scaled by 0.5 */
909 container = adg_container_new();
910 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(container));
911 cairo_matrix_init_translate(&map, 66, 30);
912 cairo_matrix_scale(&map, 0.5, 0.5);
913 adg_entity_set_local_map(ADG_ENTITY(container), &map);
914 cairo_matrix_init_scale(&map, 0.5, 0.5);
915 adg_entity_set_global_map(ADG_ENTITY(container), &map);
917 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(path)));
918 adg_container_add(container, entity);
920 entity = ADG_ENTITY(adg_toy_text_new("Local and global map scaled by 0.5"));
921 cairo_matrix_init_translate(&map, -140, 20);
922 adg_entity_set_global_map(entity, &map);
923 cairo_matrix_init_translate(&map, 5, 10);
924 adg_entity_set_local_map(entity, &map);
925 adg_container_add(container, entity);
927 /* Set a decent start position and zoom */
928 cairo_matrix_init_scale(&map, 15, 15);
929 adg_entity_set_local_map(ADG_ENTITY(canvas), &map);
930 cairo_matrix_init_translate(&map, 100, 100);
931 adg_entity_set_global_map(ADG_ENTITY(canvas), &map);
933 return canvas;
937 /**********************************************
938 * Test case for alignments of entities
939 * using different factors
940 **********************************************/
942 static AdgCanvas *
943 alignment_canvas(void)
945 AdgPath *path;
946 AdgCanvas *canvas;
947 AdgPath *axis;
948 AdgAlignment *alignment;
949 AdgStroke *stroke;
950 AdgMatrix map;
952 path = non_trivial_model();
953 canvas = adg_canvas_new();
954 cairo_matrix_init_scale(&map, 2, 2);
956 axis = adg_path_new();
957 adg_path_move_to_explicit(axis, -15, 0);
958 adg_path_line_to_explicit(axis, 15, 0);
959 adg_path_move_to_explicit(axis, 0, -15);
960 adg_path_line_to_explicit(axis, 0, 15);
962 /* Axis */
963 stroke = adg_stroke_new(ADG_TRAIL(axis));
964 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(stroke));
966 /* Original path */
967 alignment = adg_alignment_new_explicit(0, 0);
968 stroke = adg_stroke_new(ADG_TRAIL(path));
969 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
970 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
972 /* Path scaled in local space */
973 alignment = adg_alignment_new_explicit(0.5, 0.5);
974 stroke = adg_stroke_new(ADG_TRAIL(path));
975 adg_entity_set_local_map(ADG_ENTITY(stroke), &map);
976 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
977 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
979 alignment = adg_alignment_new_explicit(1, 1);
980 stroke = adg_stroke_new(ADG_TRAIL(path));
981 adg_entity_set_local_map(ADG_ENTITY(stroke), &map);
982 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
983 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
985 /* Path scaled in global space */
986 alignment = adg_alignment_new_explicit(0, 0);
987 stroke = adg_stroke_new(ADG_TRAIL(path));
988 cairo_matrix_init_scale(&map, 2, 2);
989 adg_entity_set_global_map(ADG_ENTITY(stroke), &map);
990 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
991 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
993 alignment = adg_alignment_new_explicit(-0.5, -0.5);
994 stroke = adg_stroke_new(ADG_TRAIL(path));
995 adg_entity_set_global_map(ADG_ENTITY(stroke), &map);
996 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
997 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
999 alignment = adg_alignment_new_explicit(-0.25, -0.25);
1000 stroke = adg_stroke_new(ADG_TRAIL(path));
1001 adg_entity_set_global_map(ADG_ENTITY(stroke), &map);
1002 adg_container_add(ADG_CONTAINER(alignment), ADG_ENTITY(stroke));
1003 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(alignment));
1005 /* Set a decent start position and zoom */
1006 cairo_matrix_init_scale(&map, 15, 15);
1007 cairo_matrix_translate(&map, 20, 20);
1008 adg_entity_set_local_map(ADG_ENTITY(canvas), &map);
1010 cairo_matrix_init_translate(&map, 20, 20);
1011 adg_entity_set_global_map(ADG_ENTITY(canvas), &map);
1013 return canvas;
1017 /**********************************************
1018 * Non specific test related stuff
1019 **********************************************/
1021 static AdgPath *
1022 non_trivial_model()
1024 AdgPath *path = adg_path_new();
1026 adg_path_move_to_explicit(path, 2, 0);
1027 adg_path_line_to_explicit(path, 0, 5);
1028 adg_path_line_to_explicit(path, 2, 2);
1029 adg_path_line_to_explicit(path, 0, 8);
1030 adg_path_line_to_explicit(path, 2, 8);
1031 adg_path_line_to_explicit(path, 2, 10);
1032 adg_path_line_to_explicit(path, 3, 10);
1033 adg_path_line_to_explicit(path, 10, 9);
1034 adg_path_line_to_explicit(path, 5, 5);
1035 adg_path_line_to_explicit(path, 3, 0);
1036 adg_path_close(path);
1038 return path;