7 static AdgCanvas
* ldim_canvas (void);
8 static void ldim_expose (GtkWidget
*widget
,
11 static AdgCanvas
* drawing_canvas (void);
12 static void drawing_expose (GtkWidget
*widget
,
13 GdkEventExpose
*event
,
15 static void to_pdf (AdgCanvas
*canvas
,
17 static void to_png (AdgCanvas
*canvas
,
19 static void to_ps (AdgCanvas
*canvas
,
24 main(gint argc
, gchar
**argv
)
30 AdgCanvas
*ldim
, *drawing
;
32 gtk_init(&argc
, &argv
);
34 /* Get the canvas populated by the examples */
36 drawing
= drawing_canvas();
38 /* User interface stuff */
39 path
= demo_find_data_file("adg-demo.ui");
41 g_print("adg-demo.ui not found!\n");
45 builder
= gtk_builder_new();
48 gtk_builder_add_from_file(builder
, path
, &error
);
50 g_print("%s\n", error
->message
);
54 window
= (GtkWidget
*) gtk_builder_get_object(builder
, "wndMain");
57 g_signal_connect(window
, "delete-event",
58 G_CALLBACK(gtk_main_quit
), NULL
);
59 g_signal_connect(gtk_builder_get_object(builder
, "btnQuit"),
60 "clicked", G_CALLBACK(gtk_main_quit
), NULL
);
62 g_signal_connect(gtk_builder_get_object(builder
, "areaLDim"),
63 "expose-event", G_CALLBACK(ldim_expose
), ldim
);
65 g_signal_connect(gtk_builder_get_object(builder
, "areaDrawing"),
66 "expose-event", G_CALLBACK(drawing_expose
), drawing
);
67 g_signal_connect_swapped(gtk_builder_get_object(builder
, "btnPng"),
68 "clicked", G_CALLBACK(to_png
), drawing
);
69 g_signal_connect_swapped(gtk_builder_get_object(builder
, "btnPdf"),
70 "clicked", G_CALLBACK(to_pdf
), drawing
);
71 g_signal_connect_swapped(gtk_builder_get_object(builder
, "btnPs"),
72 "clicked", G_CALLBACK(to_ps
), drawing
);
74 g_object_unref(builder
);
76 gtk_widget_show_all(window
);
83 /**********************************************
85 **********************************************/
94 /* Build the path model */
95 path
= (AdgPath
*) adg_path_new();
97 adg_path_move_to(path
, 0, 0);
98 adg_path_line_to(path
, 0, -5);
99 adg_path_line_to(path
, 2, -5);
100 adg_path_line_to(path
, 2, -10);
101 adg_path_line_to(path
, 8, -10);
102 adg_path_line_to(path
, 8, -5);
103 adg_path_line_to(path
, 10, -5);
104 adg_path_line_to(path
, 10, 0);
105 adg_path_close(path
);
107 /* Populate the canvas */
108 canvas
= adg_canvas_new();
110 entity
= adg_stroke_new(path
);
111 adg_container_add(ADG_CONTAINER(canvas
), entity
);
113 entity
= adg_ldim_new_full_explicit(2, -10, 8, -10, ADG_DIR_UP
, 0, -10);
114 adg_container_add(ADG_CONTAINER(canvas
), entity
);
116 entity
= adg_ldim_new_full_explicit(0, -5, 10, -5, ADG_DIR_UP
, 0, -10);
117 adg_dim_set_level(ADG_DIM(entity
), 2);
118 adg_container_add(ADG_CONTAINER(canvas
), entity
);
124 ldim_expose(GtkWidget
*widget
, GdkEventExpose
*event
, AdgCanvas
*canvas
)
128 double xscale
, yscale
, scale
;
131 cr
= gdk_cairo_create(widget
->window
);
132 width
= widget
->allocation
.width
;
133 height
= widget
->allocation
.height
;
135 /* Fit ldim in horizontal or vertical space keeping the aspect ratio:
136 * the lesser scale factor will be used */
137 xscale
= (double) (width
- 20) / 10;
138 yscale
= (double) (height
- 90) / 10;
145 cairo_matrix_init_translate(&matrix
, 10, 80);
146 cairo_matrix_scale(&matrix
, scale
, scale
);
147 cairo_matrix_translate(&matrix
, 0, 10);
148 adg_container_set_model_transformation(ADG_CONTAINER(canvas
), &matrix
);
150 /* Rendering process */
151 adg_entity_render(ADG_ENTITY(canvas
), cr
);
157 /**********************************************
158 * A more complex example
159 **********************************************/
161 #define SQRT3 1.732050808
164 typedef struct _DrawingData DrawingData
;
166 struct _DrawingData
{
168 gdouble D1
, D2
, D3
, D4
, D5
, D6
, D7
;
170 gdouble LD2
, LD3
, LD5
, LD6
, LD7
;
173 static void drawing_get (DrawingData
*data
);
174 static AdgPath
*drawing_path (const DrawingData
*data
);
175 static void drawing_add_dimensions (AdgCanvas
*canvas
,
176 const DrawingData
*data
);
177 static void drawing_add_stuff (AdgCanvas
*canvas
,
178 const DrawingData
*data
);
190 path
= drawing_path(&data
);
191 canvas
= adg_canvas_new();
193 entity
= adg_stroke_new(path
);
194 adg_container_add(ADG_CONTAINER(canvas
), entity
);
196 drawing_add_dimensions(canvas
, &data
);
197 drawing_add_stuff(canvas
, &data
);
203 drawing_expose(GtkWidget
*widget
, GdkEventExpose
*event
, AdgCanvas
*canvas
)
210 cr
= gdk_cairo_create(widget
->window
);
211 width
= widget
->allocation
.width
;
212 height
= widget
->allocation
.height
;
214 /* Hardcoding sizes is a really ugly way to scale a drawing but... */
215 scale
= (double) (width
- 100 - 180) / 52.3;
217 cairo_matrix_init_translate(&matrix
, 100, 70);
218 cairo_matrix_scale(&matrix
, scale
, scale
);
219 cairo_matrix_translate(&matrix
, 0, 6);
220 adg_container_set_model_transformation(ADG_CONTAINER(canvas
), &matrix
);
222 /* Rendering process */
223 adg_entity_render(ADG_ENTITY(canvas
), cr
);
229 drawing_get(DrawingData
*data
)
250 drawing_path(const DrawingData
*data
)
254 cairo_path_t
*cairo_path
;
256 cairo_matrix_t matrix
;
258 path
= (AdgPath
*) adg_path_new();
260 adg_path_move_to(path
, 0, data
->D1
/ 2);
261 adg_path_line_to(path
, data
->A
- data
->B
- data
->LD2
, data
->D1
/ 2);
262 y
= (data
->D1
- data
->D2
) / 2;
263 adg_path_line_to(path
, data
->A
- data
->B
- data
->LD2
+ y
* SQRT3
, data
->D1
/ 2 - y
);
264 adg_path_line_to(path
, data
->A
- data
->B
, data
->D2
/ 2);
265 adg_path_line_to(path
, data
->A
- data
->B
, data
->D3
/ 2 - CHAMFER
);
266 adg_path_line_to(path
, data
->A
- data
->B
+ CHAMFER
, data
->D3
/ 2);
267 adg_path_line_to(path
, data
->A
- data
->B
+ data
->LD3
- CHAMFER
, data
->D3
/ 2);
268 adg_path_line_to(path
, data
->A
- data
->B
+ data
->LD3
, data
->D3
/ 2 - CHAMFER
);
269 x
= data
->A
- data
->B
+ data
->LD3
+ data
->RD34
;
270 y
= data
->D4
/ 2 + data
->RD34
;
271 adg_path_arc(path
, x
, y
, data
->RD34
, G_PI
, -G_PI_2
);
272 adg_path_line_to(path
, data
->A
- data
->C
- data
->LD5
, data
->D4
/ 2);
273 y
= (data
->D4
- data
->D5
) / 2;
274 adg_path_line_to(path
, data
->A
- data
->C
- data
->LD5
+ y
, data
->D4
/ 2 - y
);
275 adg_path_line_to(path
, data
->A
- data
->C
, data
->D5
/ 2);
276 adg_path_line_to(path
, data
->A
- data
->C
, data
->D6
/ 2);
277 adg_path_line_to(path
, data
->A
- data
->C
+ data
->LD6
, data
->D6
/ 2);
278 x
= data
->C
- data
->LD7
- data
->LD6
;
280 adg_path_line_to(path
, data
->A
- data
->C
+ data
->LD6
+ x
, data
->D6
/ 2 - y
);
281 adg_path_line_to(path
, data
->A
- data
->LD7
, data
->D7
/ 2);
282 adg_path_line_to(path
, data
->A
, data
->D7
/ 2);
284 /* Build the shape by reflecting the current path, reversing the order
285 * and joining the result to the current path */
286 cairo_path
= adg_path_dup_cpml_path(path
);
288 cpml_segment_from_cairo(&segment
, cairo_path
);
289 cpml_segment_reverse(&segment
);
290 adg_matrix_init_reflection(&matrix
, 0);
291 cpml_segment_transform(&segment
, &matrix
);
292 cairo_path
->data
[0].header
.type
= CAIRO_PATH_LINE_TO
;
294 adg_path_append_cairo_path(path
, cairo_path
);
298 adg_path_close(path
);
303 drawing_add_dimensions(AdgCanvas
*canvas
, const DrawingData
*data
)
311 entity
= adg_ldim_new_full_explicit(data
->A
- data
->B
- data
->LD2
, -data
->D1
/ 2, data
->A
- data
->B
,
312 -data
->D3
/ 2 + CHAMFER
, ADG_DIR_UP
, 0,
314 adg_container_add(ADG_CONTAINER(canvas
), entity
);
317 entity
= adg_ldim_new_full_explicit(data
->A
- data
->B
, -data
->D3
/ 2 + CHAMFER
, data
->A
- data
->B
+ data
->LD3
,
318 -data
->D3
/ 2 + CHAMFER
, ADG_DIR_UP
, 0,
320 adg_container_add(ADG_CONTAINER(canvas
), entity
);
325 entity
= adg_ldim_new_full_explicit(data
->A
- data
->B
, data
->D3
/ 2 - CHAMFER
, data
->A
, data
->D7
/ 2,
326 ADG_DIR_DOWN
, 0, data
->D3
/ 2);
327 adg_dim_set_tolerances(ADG_DIM(entity
), "+0.1", NULL
);
328 adg_container_add(ADG_CONTAINER(canvas
), entity
);
331 entity
= adg_ldim_new_full_explicit(0, data
->D1
/ 2, data
->A
, data
->D7
/ 2,
332 ADG_DIR_DOWN
, 0, data
->D3
/ 2);
333 adg_dim_set_tolerances(ADG_DIM(entity
), "+0.05", "-0.05");
334 adg_dim_set_level(ADG_DIM(entity
), 2);
335 adg_container_add(ADG_CONTAINER(canvas
), entity
);
340 x
= data
->A
- data
->B
+ data
->LD3
- CHAMFER
;
341 entity
= adg_ldim_new_full_explicit(x
, -data
->D3
/ 2, x
, data
->D3
/ 2,
342 ADG_DIR_RIGHT
, data
->A
, 0);
343 adg_dim_set_tolerances(ADG_DIM(entity
), "-0.25", NULL
);
344 adg_dim_set_level(ADG_DIM(entity
), 5);
345 adg_container_add(ADG_CONTAINER(canvas
), entity
);
348 x
= data
->A
- data
->C
+ data
->LD6
;
349 entity
= adg_ldim_new_full_explicit(x
, -data
->D6
/ 2, x
, data
->D6
/ 2,
350 ADG_DIR_RIGHT
, data
->A
, 0);
351 adg_dim_set_tolerances(ADG_DIM(entity
), "-0.1", NULL
);
352 adg_dim_set_level(ADG_DIM(entity
), 4);
353 adg_container_add(ADG_CONTAINER(canvas
), entity
);
356 x
= data
->A
- data
->C
- data
->LD5
;
357 entity
= adg_ldim_new_full_explicit(x
, -data
->D4
/ 2, x
, data
->D4
/ 2,
358 ADG_DIR_RIGHT
, data
->A
, 0);
359 adg_dim_set_level(ADG_DIM(entity
), 3);
360 adg_container_add(ADG_CONTAINER(canvas
), entity
);
363 x
= data
->A
- data
->C
;
364 entity
= adg_ldim_new_full_explicit(x
, -data
->D5
/ 2, x
, data
->D5
/ 2,
365 ADG_DIR_RIGHT
, data
->A
, 0);
366 adg_dim_set_tolerances(ADG_DIM(entity
), "-0.1", NULL
);
367 adg_dim_set_level(ADG_DIM(entity
), 2);
368 adg_container_add(ADG_CONTAINER(canvas
), entity
);
371 entity
= adg_ldim_new_full_explicit(data
->A
, -data
->D7
/ 2, data
->A
, data
->D7
/ 2,
372 ADG_DIR_RIGHT
, data
->A
, 0);
373 adg_container_add(ADG_CONTAINER(canvas
), entity
);
378 entity
= adg_ldim_new_full_explicit(0, -data
->D1
/ 2, 0, data
->D1
/ 2,
380 adg_dim_set_tolerances(ADG_DIM(entity
), "+0.05", "-0.05");
381 adg_dim_set_level(ADG_DIM(entity
), 2);
382 adg_container_add(ADG_CONTAINER(canvas
), entity
);
385 y
= (data
->D1
- data
->D2
) / 2;
386 x
= data
->A
- data
->B
- data
->LD2
+ y
* SQRT3
;
387 entity
= adg_ldim_new_full_explicit(x
, -data
->D2
/ 2, x
, data
->D2
/ 2,
389 adg_dim_set_tolerances(ADG_DIM(entity
), "-0.1", NULL
);
390 adg_container_add(ADG_CONTAINER(canvas
), entity
);
394 drawing_add_stuff(AdgCanvas
*canvas
, const DrawingData
*data
)
398 toy_text
= adg_toy_text_new("Horizontal toy_text above the piston");
399 adg_translatable_set_origin_explicit(ADG_TRANSLATABLE(toy_text
),
402 adg_container_add(ADG_CONTAINER(canvas
), toy_text
);
404 toy_text
= adg_toy_text_new("toy_text");
405 adg_translatable_set_origin_explicit(ADG_TRANSLATABLE(toy_text
),
408 adg_rotable_set_angle(ADG_ROTABLE(toy_text
), M_PI
* 3./2.);
409 adg_container_add(ADG_CONTAINER(canvas
), toy_text
);
413 #if defined(CAIRO_HAS_PNG_FUNCTIONS) || defined(CAIRO_HAS_PDF_SURFACE) || defined(CAIRO_HAS_PS_SURFACE)
415 /* Only needed if there is at least one supported surface */
417 file_generated(GtkWidget
*caller
, const gchar
*file
)
422 window
= (GtkWindow
*) gtk_widget_get_toplevel(caller
);
423 dialog
= gtk_message_dialog_new_with_markup(window
, GTK_DIALOG_MODAL
,
426 "The requested operation generated\n"
427 "<b>%s</b> in the current directory.",
429 gtk_window_set_title(GTK_WINDOW(dialog
), "Operation completed");
430 gtk_dialog_run(GTK_DIALOG(dialog
));
431 gtk_widget_destroy(dialog
);
436 #if !defined(CAIRO_HAS_PNG_FUNCTIONS) || !defined(CAIRO_HAS_PDF_SURFACE) || !defined(CAIRO_HAS_PS_SURFACE)
438 /* Only needed if there is a missing surface */
440 missing_feature(GtkWidget
*caller
, const gchar
*feature
)
445 window
= (GtkWindow
*) gtk_widget_get_toplevel(caller
);
446 dialog
= gtk_message_dialog_new(window
, GTK_DIALOG_MODAL
,
449 "The provided cairo library\n"
450 "was compiled with no %s support!",
452 gtk_window_set_title(GTK_WINDOW(dialog
), "Missing feature");
453 gtk_dialog_run(GTK_DIALOG(dialog
));
454 gtk_widget_destroy(dialog
);
460 #ifdef CAIRO_HAS_PNG_FUNCTIONS
463 to_png(AdgCanvas
*canvas
, GtkWidget
*caller
)
465 cairo_surface_t
*surface
;
468 surface
= cairo_image_surface_create(CAIRO_FORMAT_ARGB32
, 800, 600);
469 cr
= cairo_create(surface
);
470 cairo_surface_destroy(surface
);
472 /* Rendering process */
473 adg_entity_render(ADG_ENTITY(canvas
), cr
);
476 cairo_surface_write_to_png(surface
, "test.png");
479 file_generated(caller
, "test.png");
485 to_png(AdgCanvas
*canvas
, GtkWidget
*caller
)
487 missing_feature(caller
, "PNG");
492 #ifdef CAIRO_HAS_PDF_SURFACE
494 #include <cairo-pdf.h>
497 to_pdf(AdgCanvas
*canvas
, GtkWidget
*caller
)
499 cairo_surface_t
*surface
;
502 surface
= cairo_pdf_surface_create("test.pdf", 841, 595);
503 cr
= cairo_create(surface
);
504 cairo_surface_destroy(surface
);
506 adg_entity_render(ADG_ENTITY(canvas
), cr
);
511 file_generated(caller
, "test.pdf");
517 to_pdf(AdgCanvas
*canvas
, GtkWidget
*caller
)
519 missing_feature(caller
, "PDF");
524 #ifdef CAIRO_HAS_PS_SURFACE
526 #include <cairo-ps.h>
529 to_ps(AdgCanvas
*canvas
, GtkWidget
*caller
)
531 cairo_surface_t
*surface
;
534 /* Surface creation: A4 size */
535 surface
= cairo_ps_surface_create("test.ps", 841, 595);
536 cairo_ps_surface_dsc_comment(surface
,
537 "%%Title: Automatic Drawing Generation (Adg) demo");
538 cairo_ps_surface_dsc_comment(surface
,
539 "%%Copyright: Copyright (C) 2006 Fontana Nicola");
540 cairo_ps_surface_dsc_comment(surface
, "%%Orientation: Portrait");
542 cairo_ps_surface_dsc_begin_setup(surface
);
544 cairo_ps_surface_dsc_begin_page_setup(surface
);
545 cairo_ps_surface_dsc_comment(surface
,
546 "%%IncludeFeature: *PageSize A4");
548 cr
= cairo_create(surface
);
549 cairo_surface_destroy(surface
);
551 adg_entity_render(ADG_ENTITY(canvas
), cr
);
556 file_generated(caller
, "test.ps");
562 to_ps(AdgCanvas
*canvas
, GtkWidget
*caller
)
564 missing_feature(caller
, "PostScript");