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
,
49 static void missing_feature (GtkWidget
*caller
,
50 const gchar
*feature
);
51 static void file_generated (GtkWidget
*caller
,
58 main(gint argc
, gchar
**argv
)
64 AdgCanvas
*ldim_canvas
, *drawing_canvas
;
67 gtk_init(&argc
, &argv
);
71 ldim_canvas
= adg_canvas_new();
73 entity
= adg_stroke_new(ldim_path
, NULL
);
74 adg_container_add(ADG_CONTAINER(ldim_canvas
), entity
);
76 entity
= adg_ldim_new_full_explicit(2, -10, 8, -10, ADG_DIR_UP
, 0, -10);
77 adg_container_add(ADG_CONTAINER(ldim_canvas
), entity
);
79 entity
= adg_ldim_new_full_explicit(0, -5, 10, -5, ADG_DIR_UP
, 0, -10);
80 adg_dim_set_level(ADG_DIM(entity
), 2);
81 adg_container_add(ADG_CONTAINER(ldim_canvas
), entity
);
85 drawing_canvas
= adg_canvas_new();
87 drawing_fill_model(&model
);
89 entity
= adg_stroke_new(drawing_path
, NULL
);
90 adg_container_add(ADG_CONTAINER(drawing_canvas
), entity
);
92 drawing_add_dimensions(drawing_canvas
, &model
);
93 drawing_add_stuff(drawing_canvas
);
96 /* User interface stuff */
97 path
= demo_find_data_file("adg-demo.ui");
99 g_print("adg-demo.ui not found!\n");
103 builder
= gtk_builder_new();
106 gtk_builder_add_from_file(builder
, path
, &error
);
108 g_print("%s\n", error
->message
);
112 window
= (GtkWidget
*) gtk_builder_get_object(builder
, "wndMain");
114 /* Connect signals */
115 g_signal_connect(window
, "delete-event",
116 G_CALLBACK(gtk_main_quit
), NULL
);
117 g_signal_connect(gtk_builder_get_object(builder
, "btnQuit"),
118 "clicked", G_CALLBACK(gtk_main_quit
), NULL
);
120 g_signal_connect(gtk_builder_get_object(builder
, "areaLDim"),
121 "expose-event", G_CALLBACK(ldim_expose
), ldim_canvas
);
123 g_signal_connect(gtk_builder_get_object(builder
, "areaDrawing"),
124 "expose-event", G_CALLBACK(drawing_expose
), drawing_canvas
);
125 g_signal_connect_swapped(gtk_builder_get_object(builder
, "btnPng"),
126 "clicked", G_CALLBACK(to_png
), drawing_canvas
);
127 g_signal_connect_swapped(gtk_builder_get_object(builder
, "btnPdf"),
128 "clicked", G_CALLBACK(to_pdf
), drawing_canvas
);
129 g_signal_connect_swapped(gtk_builder_get_object(builder
, "btnPs"),
130 "clicked", G_CALLBACK(to_ps
), drawing_canvas
);
132 g_object_unref(builder
);
134 gtk_widget_show_all(window
);
142 ldim_path(AdgEntity
*entity
, cairo_t
*cr
, gpointer user_data
)
144 cairo_move_to(cr
, 0, 0);
145 cairo_line_to(cr
, 0, -5);
146 cairo_line_to(cr
, 2, -5);
147 cairo_line_to(cr
, 2, -10);
148 cairo_line_to(cr
, 8, -10);
149 cairo_line_to(cr
, 8, -5);
150 cairo_line_to(cr
, 10., -5);
151 cairo_line_to(cr
, 10., 0);
152 cairo_close_path(cr
);
156 ldim_expose(GtkWidget
*widget
, GdkEventExpose
*event
, AdgCanvas
*canvas
)
160 double xscale
, yscale
, scale
;
163 cr
= gdk_cairo_create(widget
->window
);
164 width
= widget
->allocation
.width
;
165 height
= widget
->allocation
.height
;
167 /* Fit ldim in horizontal or vertical space keeping the aspect ratio:
168 * the lesser scale factor will be used */
169 xscale
= (double) (width
- 20) / 10;
170 yscale
= (double) (height
- 90) / 10;
177 cairo_matrix_init_translate(&matrix
, 10, 80);
178 cairo_matrix_scale(&matrix
, scale
, scale
);
179 cairo_matrix_translate(&matrix
, 0, 10);
180 adg_container_set_model_transformation(ADG_CONTAINER(canvas
), &matrix
);
182 /* Rendering process */
183 adg_entity_render(ADG_ENTITY(canvas
), cr
);
190 drawing_fill_model(Piston
*piston
)
211 drawing_add_dimensions(AdgCanvas
*canvas
, Piston
*piston
)
214 double D1
, D2
, D3
, D4
, D5
, D6
, D7
;
215 double LD2
, LD3
, LD5
, LD6
, LD7
;
242 entity
= adg_ldim_new_full_explicit(A
- B
- LD2
, -D1
/ 2, A
- B
,
243 -D3
/ 2 + CHAMFER
, ADG_DIR_UP
, 0,
245 adg_container_add(ADG_CONTAINER(canvas
), entity
);
248 entity
= adg_ldim_new_full_explicit(A
- B
, -D3
/ 2 + CHAMFER
, A
- B
+ LD3
,
249 -D3
/ 2 + CHAMFER
, ADG_DIR_UP
, 0,
251 adg_container_add(ADG_CONTAINER(canvas
), entity
);
257 entity
= adg_ldim_new_full_explicit(A
- B
, D3
/ 2 - CHAMFER
, A
, D7
/ 2,
258 ADG_DIR_DOWN
, 0, D3
/ 2);
259 adg_dim_set_tolerances(ADG_DIM(entity
), "+0.1", NULL
);
260 adg_container_add(ADG_CONTAINER(canvas
), entity
);
263 entity
= adg_ldim_new_full_explicit(0, D1
/ 2, A
, D7
/ 2,
264 ADG_DIR_DOWN
, 0, D3
/ 2);
265 adg_dim_set_tolerances(ADG_DIM(entity
), "+0.05", "-0.05");
266 adg_dim_set_level(ADG_DIM(entity
), 2);
267 adg_container_add(ADG_CONTAINER(canvas
), entity
);
273 x
= A
- B
+ LD3
- CHAMFER
;
274 entity
= adg_ldim_new_full_explicit(x
, -D3
/ 2, x
, D3
/ 2,
275 ADG_DIR_RIGHT
, A
, 0);
276 adg_dim_set_tolerances(ADG_DIM(entity
), "-0.25", NULL
);
277 adg_dim_set_level(ADG_DIM(entity
), 5);
278 adg_container_add(ADG_CONTAINER(canvas
), entity
);
282 entity
= adg_ldim_new_full_explicit(x
, -D6
/ 2, x
, D6
/ 2,
283 ADG_DIR_RIGHT
, A
, 0);
284 adg_dim_set_tolerances(ADG_DIM(entity
), "-0.1", NULL
);
285 adg_dim_set_level(ADG_DIM(entity
), 4);
286 adg_container_add(ADG_CONTAINER(canvas
), entity
);
290 entity
= adg_ldim_new_full_explicit(x
, -D4
/ 2, x
, D4
/ 2,
291 ADG_DIR_RIGHT
, A
, 0);
292 adg_dim_set_level(ADG_DIM(entity
), 3);
293 adg_container_add(ADG_CONTAINER(canvas
), entity
);
297 entity
= adg_ldim_new_full_explicit(x
, -D5
/ 2, x
, D5
/ 2,
298 ADG_DIR_RIGHT
, A
, 0);
299 adg_dim_set_tolerances(ADG_DIM(entity
), "-0.1", NULL
);
300 adg_dim_set_level(ADG_DIM(entity
), 2);
301 adg_container_add(ADG_CONTAINER(canvas
), entity
);
304 entity
= adg_ldim_new_full_explicit(A
, -D7
/ 2, A
, D7
/ 2,
305 ADG_DIR_RIGHT
, A
, 0);
306 adg_container_add(ADG_CONTAINER(canvas
), entity
);
312 entity
= adg_ldim_new_full_explicit(0, -D1
/ 2, 0, D1
/ 2,
314 adg_dim_set_tolerances(ADG_DIM(entity
), "+0.05", "-0.05");
315 adg_dim_set_level(ADG_DIM(entity
), 2);
316 adg_container_add(ADG_CONTAINER(canvas
), entity
);
320 x
= A
- B
- LD2
+ y
* G_SQRT3
;
321 entity
= adg_ldim_new_full_explicit(x
, -D2
/ 2, x
, D2
/ 2,
323 adg_dim_set_tolerances(ADG_DIM(entity
), "-0.1", NULL
);
324 adg_container_add(ADG_CONTAINER(canvas
), entity
);
328 drawing_add_stuff(AdgCanvas
*canvas
)
332 toy_text
= adg_toy_text_new("Horizontal toy_text above the piston");
333 adg_translatable_set_origin_explicit(ADG_TRANSLATABLE(toy_text
),
336 adg_container_add(ADG_CONTAINER(canvas
), toy_text
);
338 toy_text
= adg_toy_text_new("toy_text");
339 adg_translatable_set_origin_explicit(ADG_TRANSLATABLE(toy_text
),
342 adg_rotable_set_angle(ADG_ROTABLE(toy_text
), M_PI
* 3./2.);
343 adg_container_add(ADG_CONTAINER(canvas
), toy_text
);
347 drawing_path(AdgEntity
*entity
, cairo_t
*cr
, gpointer user_data
)
351 double D1
, D2
, D3
, D4
, D5
, D6
, D7
;
352 double LD2
, LD3
, LD5
, LD6
, LD7
;
379 cairo_move_to(cr
, 0, D1
/ 2);
380 cairo_line_to(cr
, A
- B
- LD2
, D1
/ 2);
382 cairo_line_to(cr
, A
- B
- LD2
+ y
* G_SQRT3
, D1
/ 2 - y
);
383 cairo_line_to(cr
, A
- B
, D2
/ 2);
384 cairo_line_to(cr
, A
- B
, D3
/ 2 - CHAMFER
);
385 cairo_line_to(cr
, A
- B
+ CHAMFER
, D3
/ 2);
386 cairo_line_to(cr
, A
- B
+ LD3
- CHAMFER
, D3
/ 2);
387 cairo_line_to(cr
, A
- B
+ LD3
, D3
/ 2 - CHAMFER
);
388 x
= A
- B
+ LD3
+ RD34
;
390 cairo_arc(cr
, x
, y
, RD34
, G_PI
, 3 * G_PI_2
);
391 cairo_line_to(cr
, A
- C
- LD5
, D4
/ 2);
393 cairo_line_to(cr
, A
- C
- LD5
+ y
, D4
/ 2 - y
);
394 cairo_line_to(cr
, A
- C
, D5
/ 2);
395 cairo_line_to(cr
, A
- C
, D6
/ 2);
396 cairo_line_to(cr
, A
- C
+ LD6
, D6
/ 2);
399 cairo_line_to(cr
, A
- C
+ LD6
+ x
, D6
/ 2 - y
);
400 cairo_line_to(cr
, A
- LD7
, D7
/ 2);
401 cairo_line_to(cr
, A
, D7
/ 2);
403 /* Build the shape by reflecting the current path, reversing the order
404 * and joining the result to the current path */
405 path
= cairo_copy_path(cr
);
406 cpml_segment_from_cairo(&segment
, path
);
407 cpml_segment_reverse(&segment
);
408 adg_matrix_init_reflection(&matrix
, 0);
409 cpml_segment_transform(&segment
, &matrix
);
410 path
->data
[0].header
.type
= CAIRO_PATH_LINE_TO
;
411 cairo_append_path(cr
, path
);
412 cairo_path_destroy(path
);
413 cairo_close_path(cr
);
417 drawing_expose(GtkWidget
*widget
, GdkEventExpose
*event
, AdgCanvas
*canvas
)
424 cr
= gdk_cairo_create(widget
->window
);
425 width
= widget
->allocation
.width
;
426 height
= widget
->allocation
.height
;
428 /* Hardcoding sizes is a really ugly way to scale a drawing but... */
429 scale
= (double) (width
- 100 - 180) / 52.3;
431 cairo_matrix_init_translate(&matrix
, 100, 70);
432 cairo_matrix_scale(&matrix
, scale
, scale
);
433 cairo_matrix_translate(&matrix
, 0, 6);
434 adg_container_set_model_transformation(ADG_CONTAINER(canvas
), &matrix
);
436 /* Rendering process */
437 adg_entity_render(ADG_ENTITY(canvas
), cr
);
443 #ifdef CAIRO_HAS_PNG_FUNCTIONS
446 to_png(AdgCanvas
*canvas
, GtkWidget
*caller
)
448 cairo_surface_t
*surface
;
451 surface
= cairo_image_surface_create(CAIRO_FORMAT_ARGB32
, 800, 600);
452 cr
= cairo_create(surface
);
453 cairo_surface_destroy(surface
);
455 /* Rendering process */
456 adg_entity_render(ADG_ENTITY(canvas
), cr
);
459 cairo_surface_write_to_png(surface
, "test.png");
462 file_generated(caller
, "test.png");
468 to_png(AdgCanvas
*canvas
, GtkWidget
*caller
)
470 missing_feature(caller
, "PNG");
476 #ifdef CAIRO_HAS_PDF_SURFACE
478 #include <cairo-pdf.h>
481 to_pdf(AdgCanvas
*canvas
, GtkWidget
*caller
)
483 cairo_surface_t
*surface
;
486 surface
= cairo_pdf_surface_create("test.pdf", 841, 595);
487 cr
= cairo_create(surface
);
488 cairo_surface_destroy(surface
);
490 adg_entity_render(ADG_ENTITY(canvas
), cr
);
495 file_generated(caller
, "test.pdf");
501 to_pdf(AdgCanvas
*canvas
, GtkWidget
*caller
)
503 missing_feature(caller
, "PDF");
509 #ifdef CAIRO_HAS_PS_SURFACE
511 #include <cairo-ps.h>
514 to_ps(AdgCanvas
*canvas
, GtkWidget
*caller
)
516 cairo_surface_t
*surface
;
519 /* Surface creation: A4 size */
520 surface
= cairo_ps_surface_create("test.ps", 841, 595);
521 cairo_ps_surface_dsc_comment(surface
,
522 "%%Title: Automatic Drawing Generation (Adg) demo");
523 cairo_ps_surface_dsc_comment(surface
,
524 "%%Copyright: Copyright (C) 2006 Fontana Nicola");
525 cairo_ps_surface_dsc_comment(surface
, "%%Orientation: Portrait");
527 cairo_ps_surface_dsc_begin_setup(surface
);
529 cairo_ps_surface_dsc_begin_page_setup(surface
);
530 cairo_ps_surface_dsc_comment(surface
,
531 "%%IncludeFeature: *PageSize A4");
533 cr
= cairo_create(surface
);
534 cairo_surface_destroy(surface
);
536 adg_entity_render(ADG_ENTITY(canvas
), cr
);
541 file_generated(caller
, "test.ps");
547 to_ps(AdgCanvas
*canvas
, GtkWidget
*caller
)
549 missing_feature(caller
, "PostScript");
556 missing_feature(GtkWidget
*caller
, const gchar
*feature
)
561 window
= (GtkWindow
*) gtk_widget_get_toplevel(caller
);
562 dialog
= gtk_message_dialog_new(window
, GTK_DIALOG_MODAL
,
565 "The provided cairo library\n"
566 "was compiled with no %s support!",
568 gtk_window_set_title(GTK_WINDOW(dialog
), "Missing feature");
569 gtk_dialog_run(GTK_DIALOG(dialog
));
570 gtk_widget_destroy(dialog
);
574 file_generated(GtkWidget
*caller
, const gchar
*file
)
579 window
= (GtkWindow
*) gtk_widget_get_toplevel(caller
);
580 dialog
= gtk_message_dialog_new_with_markup(window
, GTK_DIALOG_MODAL
,
583 "The requested operation generated\n"
584 "<b>%s</b> in the current directory.",
586 gtk_window_set_title(GTK_WINDOW(dialog
), "Operation completed");
587 gtk_dialog_run(GTK_DIALOG(dialog
));
588 gtk_widget_destroy(dialog
);