8 #define G_SQRT3 1.732050808
15 typedef struct _Piston Piston
;
19 gdouble D1
, D2
, D3
, D4
, D5
, D6
, D7
;
21 gdouble LD2
, LD3
, LD5
, LD6
, LD7
;
25 static void ldim_path (AdgEntity
*entity
,
28 static void ldim_expose (GtkWidget
*widget
,
29 GdkEventExpose
*event
,
32 static void drawing_fill_model (Piston
*piston
);
33 static void drawing_add_dimensions (AdgCanvas
*canvas
,
35 static void drawing_add_stuff (AdgCanvas
*canvas
);
36 static void drawing_path (AdgEntity
*entity
,
39 static void drawing_expose (GtkWidget
*widget
,
40 GdkEventExpose
*event
,
43 static void to_pdf (AdgCanvas
*canvas
,
45 static void to_png (AdgCanvas
*canvas
,
47 static void to_ps (AdgCanvas
*canvas
,
54 main(gint argc
, gchar
**argv
)
60 AdgCanvas
*ldim_canvas
, *drawing_canvas
;
63 gtk_init(&argc
, &argv
);
67 ldim_canvas
= adg_canvas_new();
69 entity
= adg_stroke_new(ldim_path
, NULL
);
70 adg_container_add(ADG_CONTAINER(ldim_canvas
), entity
);
72 entity
= adg_ldim_new_full_explicit(2, -10, 8, -10, ADG_DIR_UP
, 0, -10);
73 adg_container_add(ADG_CONTAINER(ldim_canvas
), entity
);
75 entity
= adg_ldim_new_full_explicit(0, -5, 10, -5, ADG_DIR_UP
, 0, -10);
76 adg_dim_set_level(ADG_DIM(entity
), 2);
77 adg_container_add(ADG_CONTAINER(ldim_canvas
), entity
);
81 drawing_canvas
= adg_canvas_new();
83 drawing_fill_model(&model
);
85 entity
= adg_stroke_new(drawing_path
, NULL
);
86 adg_container_add(ADG_CONTAINER(drawing_canvas
), entity
);
88 drawing_add_dimensions(drawing_canvas
, &model
);
89 drawing_add_stuff(drawing_canvas
);
92 /* User interface stuff */
93 path
= demo_find_data_file("adg-demo.ui");
95 g_print("adg-demo.ui not found!\n");
99 builder
= gtk_builder_new();
102 gtk_builder_add_from_file(builder
, path
, &error
);
104 g_print("%s\n", error
->message
);
108 window
= (GtkWidget
*) gtk_builder_get_object(builder
, "wndMain");
110 /* Connect signals */
111 g_signal_connect(window
, "delete-event",
112 G_CALLBACK(gtk_main_quit
), NULL
);
113 g_signal_connect(gtk_builder_get_object(builder
, "btnQuit"),
114 "clicked", G_CALLBACK(gtk_main_quit
), NULL
);
116 g_signal_connect(gtk_builder_get_object(builder
, "areaLDim"),
117 "expose-event", G_CALLBACK(ldim_expose
), ldim_canvas
);
119 g_signal_connect(gtk_builder_get_object(builder
, "areaDrawing"),
120 "expose-event", G_CALLBACK(drawing_expose
), drawing_canvas
);
121 g_signal_connect_swapped(gtk_builder_get_object(builder
, "btnPng"),
122 "clicked", G_CALLBACK(to_png
), drawing_canvas
);
123 g_signal_connect_swapped(gtk_builder_get_object(builder
, "btnPdf"),
124 "clicked", G_CALLBACK(to_pdf
), drawing_canvas
);
125 g_signal_connect_swapped(gtk_builder_get_object(builder
, "btnPs"),
126 "clicked", G_CALLBACK(to_ps
), drawing_canvas
);
128 g_object_unref(builder
);
130 gtk_widget_show_all(window
);
138 ldim_path(AdgEntity
*entity
, cairo_t
*cr
, gpointer user_data
)
140 cairo_move_to(cr
, 0, 0);
141 cairo_line_to(cr
, 0, -5);
142 cairo_line_to(cr
, 2, -5);
143 cairo_line_to(cr
, 2, -10);
144 cairo_line_to(cr
, 8, -10);
145 cairo_line_to(cr
, 8, -5);
146 cairo_line_to(cr
, 10., -5);
147 cairo_line_to(cr
, 10., 0);
148 cairo_close_path(cr
);
152 ldim_expose(GtkWidget
*widget
, GdkEventExpose
*event
, AdgCanvas
*canvas
)
156 double xscale
, yscale
, scale
;
159 cr
= gdk_cairo_create(widget
->window
);
160 width
= widget
->allocation
.width
;
161 height
= widget
->allocation
.height
;
163 /* Fit ldim in horizontal or vertical space keeping the aspect ratio:
164 * the lesser scale factor will be used */
165 xscale
= (double) (width
- 20) / 10;
166 yscale
= (double) (height
- 90) / 10;
173 cairo_matrix_init_translate(&matrix
, 10, 80);
174 cairo_matrix_scale(&matrix
, scale
, scale
);
175 cairo_matrix_translate(&matrix
, 0, 10);
176 adg_container_set_model_transformation(ADG_CONTAINER(canvas
), &matrix
);
178 /* Rendering process */
179 adg_entity_render(ADG_ENTITY(canvas
), cr
);
186 drawing_fill_model(Piston
*piston
)
207 drawing_add_dimensions(AdgCanvas
*canvas
, Piston
*piston
)
210 double D1
, D2
, D3
, D4
, D5
, D6
, D7
;
211 double LD2
, LD3
, LD5
, LD6
, LD7
;
238 entity
= adg_ldim_new_full_explicit(A
- B
- LD2
, -D1
/ 2, A
- B
,
239 -D3
/ 2 + CHAMFER
, ADG_DIR_UP
, 0,
241 adg_container_add(ADG_CONTAINER(canvas
), entity
);
244 entity
= adg_ldim_new_full_explicit(A
- B
, -D3
/ 2 + CHAMFER
, A
- B
+ LD3
,
245 -D3
/ 2 + CHAMFER
, ADG_DIR_UP
, 0,
247 adg_container_add(ADG_CONTAINER(canvas
), entity
);
253 entity
= adg_ldim_new_full_explicit(A
- B
, D3
/ 2 - CHAMFER
, A
, D7
/ 2,
254 ADG_DIR_DOWN
, 0, D3
/ 2);
255 adg_dim_set_tolerances(ADG_DIM(entity
), "+0.1", NULL
);
256 adg_container_add(ADG_CONTAINER(canvas
), entity
);
259 entity
= adg_ldim_new_full_explicit(0, D1
/ 2, A
, D7
/ 2,
260 ADG_DIR_DOWN
, 0, D3
/ 2);
261 adg_dim_set_tolerances(ADG_DIM(entity
), "+0.05", "-0.05");
262 adg_dim_set_level(ADG_DIM(entity
), 2);
263 adg_container_add(ADG_CONTAINER(canvas
), entity
);
269 x
= A
- B
+ LD3
- CHAMFER
;
270 entity
= adg_ldim_new_full_explicit(x
, -D3
/ 2, x
, D3
/ 2,
271 ADG_DIR_RIGHT
, A
, 0);
272 adg_dim_set_tolerances(ADG_DIM(entity
), "-0.25", NULL
);
273 adg_dim_set_level(ADG_DIM(entity
), 5);
274 adg_container_add(ADG_CONTAINER(canvas
), entity
);
278 entity
= adg_ldim_new_full_explicit(x
, -D6
/ 2, x
, D6
/ 2,
279 ADG_DIR_RIGHT
, A
, 0);
280 adg_dim_set_tolerances(ADG_DIM(entity
), "-0.1", NULL
);
281 adg_dim_set_level(ADG_DIM(entity
), 4);
282 adg_container_add(ADG_CONTAINER(canvas
), entity
);
286 entity
= adg_ldim_new_full_explicit(x
, -D4
/ 2, x
, D4
/ 2,
287 ADG_DIR_RIGHT
, A
, 0);
288 adg_dim_set_level(ADG_DIM(entity
), 3);
289 adg_container_add(ADG_CONTAINER(canvas
), entity
);
293 entity
= adg_ldim_new_full_explicit(x
, -D5
/ 2, x
, D5
/ 2,
294 ADG_DIR_RIGHT
, A
, 0);
295 adg_dim_set_tolerances(ADG_DIM(entity
), "-0.1", NULL
);
296 adg_dim_set_level(ADG_DIM(entity
), 2);
297 adg_container_add(ADG_CONTAINER(canvas
), entity
);
300 entity
= adg_ldim_new_full_explicit(A
, -D7
/ 2, A
, D7
/ 2,
301 ADG_DIR_RIGHT
, A
, 0);
302 adg_container_add(ADG_CONTAINER(canvas
), entity
);
308 entity
= adg_ldim_new_full_explicit(0, -D1
/ 2, 0, D1
/ 2,
310 adg_dim_set_tolerances(ADG_DIM(entity
), "+0.05", "-0.05");
311 adg_dim_set_level(ADG_DIM(entity
), 2);
312 adg_container_add(ADG_CONTAINER(canvas
), entity
);
316 x
= A
- B
- LD2
+ y
* G_SQRT3
;
317 entity
= adg_ldim_new_full_explicit(x
, -D2
/ 2, x
, D2
/ 2,
319 adg_dim_set_tolerances(ADG_DIM(entity
), "-0.1", NULL
);
320 adg_container_add(ADG_CONTAINER(canvas
), entity
);
324 drawing_add_stuff(AdgCanvas
*canvas
)
328 toy_text
= adg_toy_text_new("Horizontal toy_text above the piston");
329 adg_translatable_set_origin_explicit(ADG_TRANSLATABLE(toy_text
),
332 adg_container_add(ADG_CONTAINER(canvas
), toy_text
);
334 toy_text
= adg_toy_text_new("toy_text");
335 adg_translatable_set_origin_explicit(ADG_TRANSLATABLE(toy_text
),
338 adg_rotable_set_angle(ADG_ROTABLE(toy_text
), M_PI
* 3./2.);
339 adg_container_add(ADG_CONTAINER(canvas
), toy_text
);
343 drawing_path(AdgEntity
*entity
, cairo_t
*cr
, gpointer user_data
)
347 double D1
, D2
, D3
, D4
, D5
, D6
, D7
;
348 double LD2
, LD3
, LD5
, LD6
, LD7
;
375 cairo_move_to(cr
, 0, D1
/ 2);
376 cairo_line_to(cr
, A
- B
- LD2
, D1
/ 2);
378 cairo_line_to(cr
, A
- B
- LD2
+ y
* G_SQRT3
, D1
/ 2 - y
);
379 cairo_line_to(cr
, A
- B
, D2
/ 2);
380 cairo_line_to(cr
, A
- B
, D3
/ 2 - CHAMFER
);
381 cairo_line_to(cr
, A
- B
+ CHAMFER
, D3
/ 2);
382 cairo_line_to(cr
, A
- B
+ LD3
- CHAMFER
, D3
/ 2);
383 cairo_line_to(cr
, A
- B
+ LD3
, D3
/ 2 - CHAMFER
);
384 x
= A
- B
+ LD3
+ RD34
;
386 cairo_arc(cr
, x
, y
, RD34
, G_PI
, 3 * G_PI_2
);
387 cairo_line_to(cr
, A
- C
- LD5
, D4
/ 2);
389 cairo_line_to(cr
, A
- C
- LD5
+ y
, D4
/ 2 - y
);
390 cairo_line_to(cr
, A
- C
, D5
/ 2);
391 cairo_line_to(cr
, A
- C
, D6
/ 2);
392 cairo_line_to(cr
, A
- C
+ LD6
, D6
/ 2);
395 cairo_line_to(cr
, A
- C
+ LD6
+ x
, D6
/ 2 - y
);
396 cairo_line_to(cr
, A
- LD7
, D7
/ 2);
397 cairo_line_to(cr
, A
, D7
/ 2);
399 /* Build the shape by reflecting the current path, reversing the order
400 * and joining the result to the current path */
401 path
= cairo_copy_path(cr
);
402 cpml_segment_from_cairo(&segment
, path
);
403 cpml_segment_reverse(&segment
);
404 adg_matrix_init_reflection(&matrix
, 0);
405 cpml_segment_transform(&segment
, &matrix
);
406 path
->data
[0].header
.type
= CAIRO_PATH_LINE_TO
;
407 cairo_append_path(cr
, path
);
408 cairo_path_destroy(path
);
409 cairo_close_path(cr
);
413 drawing_expose(GtkWidget
*widget
, GdkEventExpose
*event
, AdgCanvas
*canvas
)
420 cr
= gdk_cairo_create(widget
->window
);
421 width
= widget
->allocation
.width
;
422 height
= widget
->allocation
.height
;
424 /* Hardcoding sizes is a really ugly way to scale a drawing but... */
425 scale
= (double) (width
- 100 - 180) / 52.3;
427 cairo_matrix_init_translate(&matrix
, 100, 70);
428 cairo_matrix_scale(&matrix
, scale
, scale
);
429 cairo_matrix_translate(&matrix
, 0, 6);
430 adg_container_set_model_transformation(ADG_CONTAINER(canvas
), &matrix
);
432 /* Rendering process */
433 adg_entity_render(ADG_ENTITY(canvas
), cr
);
439 #if defined(CAIRO_HAS_PNG_FUNCTIONS) || defined(CAIRO_HAS_PDF_SURFACE) || defined(CAIRO_HAS_PS_SURFACE)
441 /* Only needed if there is at least one supported surface */
443 file_generated(GtkWidget
*caller
, const gchar
*file
)
448 window
= (GtkWindow
*) gtk_widget_get_toplevel(caller
);
449 dialog
= gtk_message_dialog_new_with_markup(window
, GTK_DIALOG_MODAL
,
452 "The requested operation generated\n"
453 "<b>%s</b> in the current directory.",
455 gtk_window_set_title(GTK_WINDOW(dialog
), "Operation completed");
456 gtk_dialog_run(GTK_DIALOG(dialog
));
457 gtk_widget_destroy(dialog
);
462 #if !defined(CAIRO_HAS_PNG_FUNCTIONS) || !defined(CAIRO_HAS_PDF_SURFACE) || !defined(CAIRO_HAS_PS_SURFACE)
464 /* Only needed if there is a missing surface */
466 missing_feature(GtkWidget
*caller
, const gchar
*feature
)
471 window
= (GtkWindow
*) gtk_widget_get_toplevel(caller
);
472 dialog
= gtk_message_dialog_new(window
, GTK_DIALOG_MODAL
,
475 "The provided cairo library\n"
476 "was compiled with no %s support!",
478 gtk_window_set_title(GTK_WINDOW(dialog
), "Missing feature");
479 gtk_dialog_run(GTK_DIALOG(dialog
));
480 gtk_widget_destroy(dialog
);
486 #ifdef CAIRO_HAS_PNG_FUNCTIONS
489 to_png(AdgCanvas
*canvas
, GtkWidget
*caller
)
491 cairo_surface_t
*surface
;
494 surface
= cairo_image_surface_create(CAIRO_FORMAT_ARGB32
, 800, 600);
495 cr
= cairo_create(surface
);
496 cairo_surface_destroy(surface
);
498 /* Rendering process */
499 adg_entity_render(ADG_ENTITY(canvas
), cr
);
502 cairo_surface_write_to_png(surface
, "test.png");
505 file_generated(caller
, "test.png");
511 to_png(AdgCanvas
*canvas
, GtkWidget
*caller
)
513 missing_feature(caller
, "PNG");
518 #ifdef CAIRO_HAS_PDF_SURFACE
520 #include <cairo-pdf.h>
523 to_pdf(AdgCanvas
*canvas
, GtkWidget
*caller
)
525 cairo_surface_t
*surface
;
528 surface
= cairo_pdf_surface_create("test.pdf", 841, 595);
529 cr
= cairo_create(surface
);
530 cairo_surface_destroy(surface
);
532 adg_entity_render(ADG_ENTITY(canvas
), cr
);
537 file_generated(caller
, "test.pdf");
543 to_pdf(AdgCanvas
*canvas
, GtkWidget
*caller
)
545 missing_feature(caller
, "PDF");
550 #ifdef CAIRO_HAS_PS_SURFACE
552 #include <cairo-ps.h>
555 to_ps(AdgCanvas
*canvas
, GtkWidget
*caller
)
557 cairo_surface_t
*surface
;
560 /* Surface creation: A4 size */
561 surface
= cairo_ps_surface_create("test.ps", 841, 595);
562 cairo_ps_surface_dsc_comment(surface
,
563 "%%Title: Automatic Drawing Generation (Adg) demo");
564 cairo_ps_surface_dsc_comment(surface
,
565 "%%Copyright: Copyright (C) 2006 Fontana Nicola");
566 cairo_ps_surface_dsc_comment(surface
, "%%Orientation: Portrait");
568 cairo_ps_surface_dsc_begin_setup(surface
);
570 cairo_ps_surface_dsc_begin_page_setup(surface
);
571 cairo_ps_surface_dsc_comment(surface
,
572 "%%IncludeFeature: *PageSize A4");
574 cr
= cairo_create(surface
);
575 cairo_surface_destroy(surface
);
577 adg_entity_render(ADG_ENTITY(canvas
), cr
);
582 file_generated(caller
, "test.ps");
588 to_ps(AdgCanvas
*canvas
, GtkWidget
*caller
)
590 missing_feature(caller
, "PostScript");