7 #define G_SQRT3 1.732050808
12 typedef struct _Piston Piston
;
16 gdouble D1
, D2
, D3
, D4
, D5
, D6
, D7
;
18 gdouble LD2
, LD3
, LD5
, LD6
, LD7
;
22 static void fill_piston_model (Piston
*piston
);
23 static void add_piston_dimensions (AdgCanvas
*canvas
,
25 static void add_sample_stuff (AdgCanvas
*canvas
);
26 static void piston_path_extern (AdgEntity
*entity
,
29 static void piston_expose (GtkWidget
*widget
,
30 GdkEventExpose
*event
,
32 static void to_pdf (AdgCanvas
*canvas
,
34 static void to_png (AdgCanvas
*canvas
,
36 static void to_ps (AdgCanvas
*canvas
,
38 static void missing_feature (GtkWidget
*caller
,
39 const gchar
*feature
);
40 static void file_generated (GtkWidget
*caller
,
47 main(gint argc
, gchar
**argv
)
51 GtkWidget
*button_box
;
56 gtk_init(&argc
, &argv
);
58 /* Fill the model structure with some data */
59 fill_piston_model(&model
);
61 /* Create the canvas and populate it */
62 canvas
= adg_canvas_new();
64 path
= adg_path_new(piston_path_extern
, NULL
);
65 adg_container_add(ADG_CONTAINER(canvas
), path
);
67 add_piston_dimensions(canvas
, &model
);
68 add_sample_stuff(canvas
);
70 /* User interface stuff */
71 window
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
72 g_signal_connect(window
, "delete-event", G_CALLBACK(gtk_main_quit
), NULL
);
74 vbox
= gtk_vbox_new(FALSE
, 0);
76 widget
= gtk_drawing_area_new();
77 gtk_widget_set_size_request(widget
, 790, 240);
78 g_signal_connect(widget
, "expose-event", G_CALLBACK(piston_expose
),
80 gtk_container_add(GTK_CONTAINER(vbox
), widget
);
82 button_box
= gtk_hbutton_box_new();
83 gtk_container_set_border_width(GTK_CONTAINER(button_box
), 5);
84 gtk_box_set_spacing(GTK_BOX(button_box
), 5);
85 gtk_button_box_set_layout(GTK_BUTTON_BOX(button_box
), GTK_BUTTONBOX_END
);
86 gtk_box_pack_end(GTK_BOX(vbox
), button_box
, FALSE
, TRUE
, 0);
88 widget
= gtk_button_new_with_mnemonic("P_NG image");
89 g_signal_connect_swapped(widget
, "clicked", G_CALLBACK(to_png
), canvas
);
90 gtk_container_add(GTK_CONTAINER(button_box
), widget
);
92 widget
= gtk_button_new_with_mnemonic("P_DF file");
93 g_signal_connect_swapped(widget
, "clicked", G_CALLBACK(to_pdf
), canvas
);
94 gtk_container_add(GTK_CONTAINER(button_box
), widget
);
96 widget
= gtk_button_new_with_mnemonic("_PostScript");
97 g_signal_connect_swapped(widget
, "clicked", G_CALLBACK(to_ps
), canvas
);
98 gtk_container_add(GTK_CONTAINER(button_box
), widget
);
100 widget
= gtk_button_new_from_stock(GTK_STOCK_QUIT
);
101 g_signal_connect(widget
, "clicked", G_CALLBACK(gtk_main_quit
), NULL
);
102 gtk_container_add(GTK_CONTAINER(button_box
), widget
);
104 gtk_container_add(GTK_CONTAINER(window
), vbox
);
105 gtk_widget_show_all(window
);
114 fill_piston_model(Piston
*piston
)
135 add_piston_dimensions(AdgCanvas
*canvas
, Piston
*piston
)
138 double D1
, D2
, D3
, D4
, D5
, D6
, D7
;
139 double LD2
, LD3
, LD5
, LD6
, LD7
;
167 adg_ldim_new_full_explicit(A
- B
- LD2
, -D1
/ 2.0, A
- B
,
168 -D3
/ 2.0 + CHAMFER
, CPML_DIR_UP
, 0.0,
170 adg_container_add(ADG_CONTAINER(canvas
), entity
);
174 adg_ldim_new_full_explicit(A
- B
, -D3
/ 2.0 + CHAMFER
, A
- B
+ LD3
,
175 -D3
/ 2.0 + CHAMFER
, CPML_DIR_UP
, 0.0,
177 adg_container_add(ADG_CONTAINER(canvas
), entity
);
184 adg_ldim_new_full_explicit(A
- B
, D3
/ 2.0 - CHAMFER
, A
, D7
/ 2.0,
185 CPML_DIR_DOWN
, 0.0, D3
/ 2.0);
186 adg_dim_set_tolerances(ADG_DIM(entity
), "+0.1", NULL
);
187 adg_container_add(ADG_CONTAINER(canvas
), entity
);
191 adg_ldim_new_full_explicit(0.0, D1
/ 2.0, A
, D7
/ 2.0,
192 CPML_DIR_DOWN
, 0.0, D3
/ 2.0);
193 adg_dim_set_tolerances(ADG_DIM(entity
), "+0.05", "-0.05");
194 adg_dim_set_level(ADG_DIM(entity
), 2.0);
195 adg_container_add(ADG_CONTAINER(canvas
), entity
);
201 x
= A
- B
+ LD3
- CHAMFER
;
203 adg_ldim_new_full_explicit(x
, -D3
/ 2.0, x
, D3
/ 2.0,
204 CPML_DIR_RIGHT
, A
, 0.0);
205 adg_dim_set_tolerances(ADG_DIM(entity
), "-0.25", NULL
);
206 adg_dim_set_level(ADG_DIM(entity
), 5.0);
207 adg_container_add(ADG_CONTAINER(canvas
), entity
);
212 adg_ldim_new_full_explicit(x
, -D6
/ 2.0, x
, D6
/ 2.0,
213 CPML_DIR_RIGHT
, A
, 0.0);
214 adg_dim_set_tolerances(ADG_DIM(entity
), "-0.1", NULL
);
215 adg_dim_set_level(ADG_DIM(entity
), 4.0);
216 adg_container_add(ADG_CONTAINER(canvas
), entity
);
221 adg_ldim_new_full_explicit(x
, -D4
/ 2.0, x
, D4
/ 2.0,
222 CPML_DIR_RIGHT
, A
, 0.0);
223 adg_dim_set_level(ADG_DIM(entity
), 3.0);
224 adg_container_add(ADG_CONTAINER(canvas
), entity
);
229 adg_ldim_new_full_explicit(x
, -D5
/ 2.0, x
, D5
/ 2.0,
230 CPML_DIR_RIGHT
, A
, 0.0);
231 adg_dim_set_tolerances(ADG_DIM(entity
), "-0.1", NULL
);
232 adg_dim_set_level(ADG_DIM(entity
), 2.0);
233 adg_container_add(ADG_CONTAINER(canvas
), entity
);
237 adg_ldim_new_full_explicit(A
, -D7
/ 2.0, A
, D7
/ 2.0,
238 CPML_DIR_RIGHT
, A
, 0.0);
239 adg_container_add(ADG_CONTAINER(canvas
), entity
);
246 adg_ldim_new_full_explicit(0.0, -D1
/ 2.0, 0.0, D1
/ 2.0,
247 CPML_DIR_LEFT
, 0.0, 0.0);
248 adg_dim_set_tolerances(ADG_DIM(entity
), "+0.05", "-0.05");
249 adg_dim_set_level(ADG_DIM(entity
), 2.0);
250 adg_container_add(ADG_CONTAINER(canvas
), entity
);
254 x
= A
- B
- LD2
+ y
* G_SQRT3
;
256 adg_ldim_new_full_explicit(x
, -D2
/ 2.0, x
, D2
/ 2.0,
257 CPML_DIR_LEFT
, 0.0, 0.0);
258 adg_dim_set_tolerances(ADG_DIM(entity
), "-0.1", NULL
);
259 adg_container_add(ADG_CONTAINER(canvas
), entity
);
263 add_sample_stuff(AdgCanvas
*canvas
)
267 toy_text
= adg_toy_text_new("Horizontal toy_text above the piston");
268 adg_translatable_set_origin_explicit(ADG_TRANSLATABLE(toy_text
),
271 adg_container_add(ADG_CONTAINER(canvas
), toy_text
);
273 toy_text
= adg_toy_text_new("toy_text");
274 adg_translatable_set_origin_explicit(ADG_TRANSLATABLE(toy_text
),
277 adg_rotable_set_angle(ADG_ROTABLE(toy_text
), M_PI
* 3./2.);
278 adg_container_add(ADG_CONTAINER(canvas
), toy_text
);
282 piston_path_extern(AdgEntity
*entity
, cairo_t
*cr
, gpointer user_data
)
286 double D1
, D2
, D3
, D4
, D5
, D6
, D7
;
287 double LD2
, LD3
, LD5
, LD6
, LD7
;
314 cairo_move_to(cr
, 0, D1
/ 2.0);
315 cairo_line_to(cr
, A
- B
- LD2
, D1
/ 2.0);
317 cairo_line_to(cr
, A
- B
- LD2
+ y
* G_SQRT3
, D1
/ 2.0 - y
);
318 cairo_line_to(cr
, A
- B
, D2
/ 2.0);
319 cairo_line_to(cr
, A
- B
, D3
/ 2.0 - CHAMFER
);
320 cairo_line_to(cr
, A
- B
+ CHAMFER
, D3
/ 2.0);
321 cairo_line_to(cr
, A
- B
+ LD3
- CHAMFER
, D3
/ 2.0);
322 cairo_line_to(cr
, A
- B
+ LD3
, D3
/ 2.0 - CHAMFER
);
323 x
= A
- B
+ LD3
+ RD34
;
325 cairo_arc(cr
, x
, y
, RD34
, G_PI
, 3.0 * G_PI_2
);
326 cairo_line_to(cr
, A
- C
- LD5
, D4
/ 2.0);
328 cairo_line_to(cr
, A
- C
- LD5
+ y
, D4
/ 2.0 - y
);
329 cairo_line_to(cr
, A
- C
, D5
/ 2.0);
330 cairo_line_to(cr
, A
- C
, D6
/ 2.0);
331 cairo_line_to(cr
, A
- C
+ LD6
, D6
/ 2.0);
334 cairo_line_to(cr
, A
- C
+ LD6
+ x
, D6
/ 2.0 - y
);
335 cairo_line_to(cr
, A
- LD7
, D7
/ 2.0);
336 cairo_line_to(cr
, A
, D7
/ 2.0);
338 /* Build the shape by reflecting the current path, reversing the order
339 * and joining the result to the current path */
340 path
= cairo_copy_path(cr
);
341 cpml_segment_init(&segment
, path
);
342 cpml_segment_reverse(&segment
);
343 adg_matrix_init_reflection(&matrix
, 0);
344 cpml_segment_transform(&segment
, &matrix
);
345 path
->data
[0].header
.type
= CAIRO_PATH_LINE_TO
;
346 cairo_append_path(cr
, path
);
347 cairo_path_destroy(path
);
348 cairo_close_path(cr
);
352 piston_expose(GtkWidget
*widget
, GdkEventExpose
*event
, AdgCanvas
*canvas
)
359 cr
= gdk_cairo_create(widget
->window
);
360 width
= widget
->allocation
.width
;
361 height
= widget
->allocation
.height
;
362 scale
= (double) (width
- 80.0) / 80.0;
364 cairo_matrix_init(&matrix
, scale
, 0.0, 0.0, scale
, scale
+ 71.0,
366 adg_container_set_model_transformation(ADG_CONTAINER(canvas
), &matrix
);
368 /* Rendering process */
369 adg_entity_render(ADG_ENTITY(canvas
), cr
);
375 #ifdef CAIRO_HAS_PNG_FUNCTIONS
378 to_png(AdgCanvas
*canvas
, GtkWidget
*caller
)
380 cairo_surface_t
*surface
;
383 surface
= cairo_image_surface_create(CAIRO_FORMAT_ARGB32
, 800, 600);
384 cr
= cairo_create(surface
);
385 cairo_surface_destroy(surface
);
387 /* Rendering process */
388 adg_entity_render(ADG_ENTITY(canvas
), cr
);
391 cairo_surface_write_to_png(surface
, "test.png");
394 file_generated(caller
, "test.png");
400 to_png(AdgCanvas
*canvas
, GtkWidget
*caller
)
402 missing_feature(caller
, "PNG");
408 #ifdef CAIRO_HAS_PDF_SURFACE
410 #include <cairo-pdf.h>
413 to_pdf(AdgCanvas
*canvas
, GtkWidget
*caller
)
415 cairo_surface_t
*surface
;
418 surface
= cairo_pdf_surface_create("test.pdf", 841, 595);
419 cr
= cairo_create(surface
);
420 cairo_surface_destroy(surface
);
422 adg_entity_render(ADG_ENTITY(canvas
), cr
);
427 file_generated(caller
, "test.pdf");
433 to_pdf(AdgCanvas
*canvas
, GtkWidget
*caller
)
435 missing_feature(caller
, "PDF");
441 #ifdef CAIRO_HAS_PS_SURFACE
443 #include <cairo-ps.h>
446 to_ps(AdgCanvas
*canvas
, GtkWidget
*caller
)
448 cairo_surface_t
*surface
;
451 /* Surface creation: A4 size */
452 surface
= cairo_ps_surface_create("test.ps", 841, 595);
453 cairo_ps_surface_dsc_comment(surface
,
454 "%%Title: Automatic Drawing Generation (Adg) demo");
455 cairo_ps_surface_dsc_comment(surface
,
456 "%%Copyright: Copyright (C) 2006 Fontana Nicola");
457 cairo_ps_surface_dsc_comment(surface
, "%%Orientation: Portrait");
459 cairo_ps_surface_dsc_begin_setup(surface
);
461 cairo_ps_surface_dsc_begin_page_setup(surface
);
462 cairo_ps_surface_dsc_comment(surface
,
463 "%%IncludeFeature: *PageSize A4");
465 cr
= cairo_create(surface
);
466 cairo_surface_destroy(surface
);
468 adg_entity_render(ADG_ENTITY(canvas
), cr
);
473 file_generated(caller
, "test.ps");
479 to_ps(AdgCanvas
*canvas
, GtkWidget
*caller
)
481 missing_feature(caller
, "PostScript");
488 missing_feature(GtkWidget
*caller
, const gchar
*feature
)
493 window
= (GtkWindow
*) gtk_widget_get_toplevel(caller
);
494 dialog
= gtk_message_dialog_new(window
, GTK_DIALOG_MODAL
,
497 "The provided cairo library\n"
498 "was compiled with no %s support!",
500 gtk_window_set_title(GTK_WINDOW(dialog
), "Missing feature");
501 gtk_dialog_run(GTK_DIALOG(dialog
));
502 gtk_widget_destroy(dialog
);
506 file_generated(GtkWidget
*caller
, const gchar
*file
)
511 window
= (GtkWindow
*) gtk_widget_get_toplevel(caller
);
512 dialog
= gtk_message_dialog_new_with_markup(window
, GTK_DIALOG_MODAL
,
515 "The requested operation generated\n"
516 "<b>%s</b> in the current directory.",
518 gtk_window_set_title(GTK_WINDOW(dialog
), "Operation completed");
519 gtk_dialog_run(GTK_DIALOG(dialog
));
520 gtk_widget_destroy(dialog
);