1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007-2021 Nicola Fontana <ntd at entidi.it>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
26 _adg_method_get_current_point(void)
32 g_assert_null(adg_path_get_current_point(NULL
));
34 path
= adg_path_new();
35 g_assert_null(adg_path_get_current_point(path
));
37 adg_path_move_to_explicit(path
, 1, 2);
38 cp
= adg_path_get_current_point(path
);
40 adg_assert_isapprox(cp
->x
, 1);
41 adg_assert_isapprox(cp
->y
, 2);
43 adg_path_line_to_explicit(path
, 3, 4);
44 cp
= adg_path_get_current_point(path
);
46 adg_assert_isapprox(cp
->x
, 3);
47 adg_assert_isapprox(cp
->y
, 4);
49 adg_path_arc_to_explicit(path
, 5, 6, 7, 8);
50 cp
= adg_path_get_current_point(path
);
52 adg_assert_isapprox(cp
->x
, 7);
53 adg_assert_isapprox(cp
->y
, 8);
55 adg_path_curve_to_explicit(path
, 9, 10, 11, 12, 13, 14);
56 cp
= adg_path_get_current_point(path
);
58 adg_assert_isapprox(cp
->x
, 13);
59 adg_assert_isapprox(cp
->y
, 14);
62 g_assert_null(adg_path_get_current_point(path
));
68 _adg_method_has_current_point(void)
73 g_assert_false(adg_path_has_current_point(NULL
));
75 path
= adg_path_new();
76 g_assert_false(adg_path_has_current_point(path
));
78 adg_path_move_to_explicit(path
, 0, 0);
79 g_assert_true(adg_path_has_current_point(path
));
81 g_assert_false(adg_path_has_current_point(path
));
83 adg_path_line_to_explicit(path
, 0, 0);
84 g_assert_true(adg_path_has_current_point(path
));
90 _adg_method_last_primitive(void)
93 const CpmlPrimitive
*primitive
;
96 g_assert_null(adg_path_last_primitive(NULL
));
98 path
= adg_path_new();
99 g_assert_null(adg_path_last_primitive(path
));
101 adg_path_move_to_explicit(path
, 1, 2);
102 g_assert_null(adg_path_last_primitive(path
));
104 adg_path_line_to_explicit(path
, 3, 4);
105 primitive
= adg_path_last_primitive(path
);
106 g_assert_nonnull(primitive
);
107 g_assert_cmpint(primitive
->data
->header
.type
, ==, CPML_LINE
);
108 g_assert_cmpint(primitive
->data
->header
.length
, ==, 2);
109 adg_assert_isapprox(primitive
->org
->point
.x
, 1);
110 adg_assert_isapprox(primitive
->org
->point
.y
, 2);
111 adg_assert_isapprox(primitive
->data
[1].point
.x
, 3);
112 adg_assert_isapprox(primitive
->data
[1].point
.y
, 4);
114 adg_path_arc_to_explicit(path
, 5, 6, 7, 8);
115 primitive
= adg_path_last_primitive(path
);
116 g_assert_nonnull(primitive
);
117 g_assert_cmpint(primitive
->data
->header
.type
, ==, CPML_ARC
);
118 g_assert_cmpint(primitive
->data
->header
.length
, ==, 3);
119 adg_assert_isapprox(primitive
->org
->point
.x
, 3);
120 adg_assert_isapprox(primitive
->org
->point
.y
, 4);
121 adg_assert_isapprox(primitive
->data
[1].point
.x
, 5);
122 adg_assert_isapprox(primitive
->data
[1].point
.y
, 6);
123 adg_assert_isapprox(primitive
->data
[2].point
.x
, 7);
124 adg_assert_isapprox(primitive
->data
[2].point
.y
, 8);
126 adg_path_move_to_explicit(path
, 0, 0);
127 primitive
= adg_path_last_primitive(path
);
128 g_assert_nonnull(primitive
);
129 g_assert_cmpint(primitive
->data
->header
.type
, ==, CPML_ARC
);
131 adg_path_move_to_explicit(path
, 1, 1);
132 primitive
= adg_path_last_primitive(path
);
133 g_assert_nonnull(primitive
);
134 g_assert_cmpint(primitive
->data
->header
.type
, ==, CPML_ARC
);
136 adg_path_curve_to_explicit(path
, 9, 10, 11, 12, 13, 14);
137 primitive
= adg_path_last_primitive(path
);
138 g_assert_nonnull(primitive
);
139 g_assert_cmpint(primitive
->data
->header
.type
, ==, CPML_CURVE
);
140 g_assert_cmpint(primitive
->data
->header
.length
, ==, 4);
141 adg_assert_isapprox(primitive
->org
->point
.x
, 1);
142 adg_assert_isapprox(primitive
->org
->point
.y
, 1);
143 adg_assert_isapprox(primitive
->data
[1].point
.x
, 9);
144 adg_assert_isapprox(primitive
->data
[1].point
.y
, 10);
145 adg_assert_isapprox(primitive
->data
[2].point
.x
, 11);
146 adg_assert_isapprox(primitive
->data
[2].point
.y
, 12);
147 adg_assert_isapprox(primitive
->data
[3].point
.x
, 13);
148 adg_assert_isapprox(primitive
->data
[3].point
.y
, 14);
150 adg_path_close(path
);
151 primitive
= adg_path_last_primitive(path
);
152 g_assert_nonnull(primitive
);
153 g_assert_cmpint(primitive
->data
->header
.type
, ==, CPML_CLOSE
);
154 g_assert_cmpint(primitive
->data
->header
.length
, ==, 1);
155 adg_assert_isapprox(primitive
->org
->point
.x
, 13);
156 adg_assert_isapprox(primitive
->org
->point
.y
, 14);
158 /* This line is invalid because there is no current point */
159 adg_path_line_to_explicit(path
, 15, 16);
160 g_assert_null(adg_path_last_primitive(path
));
162 g_object_unref(path
);
166 _adg_method_over_primitive(void)
169 const CpmlPrimitive
*primitive
;
172 g_assert_null(adg_path_over_primitive(NULL
));
174 path
= adg_path_new();
175 g_assert_null(adg_path_over_primitive(path
));
177 adg_path_move_to_explicit(path
, 1, 2);
178 g_assert_null(adg_path_over_primitive(path
));
180 adg_path_line_to_explicit(path
, 3, 4);
181 g_assert_null(adg_path_over_primitive(path
));
183 adg_path_arc_to_explicit(path
, 5, 6, 7, 8);
184 primitive
= adg_path_over_primitive(path
);
185 g_assert_nonnull(primitive
);
186 g_assert_cmpint(primitive
->data
->header
.type
, ==, CPML_LINE
);
187 g_assert_cmpint(primitive
->data
->header
.length
, ==, 2);
188 adg_assert_isapprox(primitive
->org
->point
.x
, 1);
189 adg_assert_isapprox(primitive
->org
->point
.y
, 2);
190 adg_assert_isapprox(primitive
->data
[1].point
.x
, 3);
191 adg_assert_isapprox(primitive
->data
[1].point
.y
, 4);
193 adg_path_curve_to_explicit(path
, 9, 10, 11, 12, 13, 14);
194 primitive
= adg_path_over_primitive(path
);
195 g_assert_nonnull(primitive
);
196 g_assert_cmpint(primitive
->data
->header
.type
, ==, CPML_ARC
);
197 g_assert_cmpint(primitive
->data
->header
.length
, ==, 3);
198 adg_assert_isapprox(primitive
->org
->point
.x
, 3);
199 adg_assert_isapprox(primitive
->org
->point
.y
, 4);
200 adg_assert_isapprox(primitive
->data
[1].point
.x
, 5);
201 adg_assert_isapprox(primitive
->data
[1].point
.y
, 6);
202 adg_assert_isapprox(primitive
->data
[2].point
.x
, 7);
203 adg_assert_isapprox(primitive
->data
[2].point
.y
, 8);
205 adg_path_close(path
);
206 primitive
= adg_path_over_primitive(path
);
207 g_assert_nonnull(primitive
);
208 g_assert_cmpint(primitive
->data
->header
.type
, ==, CPML_CURVE
);
209 g_assert_cmpint(primitive
->data
->header
.length
, ==, 4);
210 adg_assert_isapprox(primitive
->org
->point
.x
, 7);
211 adg_assert_isapprox(primitive
->org
->point
.y
, 8);
212 adg_assert_isapprox(primitive
->data
[1].point
.x
, 9);
213 adg_assert_isapprox(primitive
->data
[1].point
.y
, 10);
214 adg_assert_isapprox(primitive
->data
[2].point
.x
, 11);
215 adg_assert_isapprox(primitive
->data
[2].point
.y
, 12);
216 adg_assert_isapprox(primitive
->data
[3].point
.x
, 13);
217 adg_assert_isapprox(primitive
->data
[3].point
.y
, 14);
219 adg_path_move_to_explicit(path
, 15, 16);
220 primitive
= adg_path_over_primitive(path
);
221 g_assert_nonnull(primitive
);
222 g_assert_cmpint(primitive
->data
->header
.type
, ==, CPML_CURVE
);
223 g_assert_cmpint(primitive
->data
->header
.length
, ==, 4);
224 adg_assert_isapprox(primitive
->org
->point
.x
, 7);
225 adg_assert_isapprox(primitive
->org
->point
.y
, 8);
226 adg_assert_isapprox(primitive
->data
[1].point
.x
, 9);
227 adg_assert_isapprox(primitive
->data
[1].point
.y
, 10);
228 adg_assert_isapprox(primitive
->data
[2].point
.x
, 11);
229 adg_assert_isapprox(primitive
->data
[2].point
.y
, 12);
230 adg_assert_isapprox(primitive
->data
[3].point
.x
, 13);
231 adg_assert_isapprox(primitive
->data
[3].point
.y
, 14);
233 adg_path_line_to_explicit(path
, 17, 18);
234 primitive
= adg_path_over_primitive(path
);
235 g_assert_nonnull(primitive
);
236 g_assert_cmpint(primitive
->data
->header
.type
, ==, CPML_CLOSE
);
237 g_assert_cmpint(primitive
->data
->header
.length
, ==, 1);
238 adg_assert_isapprox(primitive
->org
->point
.x
, 13);
239 adg_assert_isapprox(primitive
->org
->point
.y
, 14);
241 g_object_unref(path
);
245 _adg_method_append_primitive(void)
249 CpmlPrimitive primitive
;
250 const CpmlPrimitive
*last
;
252 path
= adg_path_new();
253 cpml_segment_from_cairo(&segment
, (cairo_path_t
*) adg_test_path());
254 cpml_primitive_from_segment(&primitive
, &segment
);
257 adg_path_append_primitive(NULL
, &primitive
);
258 adg_path_append_primitive(path
, NULL
);
260 adg_path_move_to_explicit(path
, 0, 1);
262 adg_path_append_primitive(path
, &primitive
);
263 last
= adg_path_last_primitive(path
);
264 g_assert_nonnull(last
);
265 g_assert_cmpint(last
->data
->header
.type
, ==, CPML_LINE
);
267 cpml_primitive_next(&primitive
);
268 adg_path_append_primitive(path
, &primitive
);
269 last
= adg_path_last_primitive(path
);
270 g_assert_nonnull(last
);
271 g_assert_cmpint(last
->data
->header
.type
, ==, CPML_ARC
);
273 cpml_primitive_next(&primitive
);
274 adg_path_append_primitive(path
, &primitive
);
275 last
= adg_path_last_primitive(path
);
276 g_assert_nonnull(last
);
277 g_assert_cmpint(last
->data
->header
.type
, ==, CPML_CURVE
);
279 cpml_primitive_next(&primitive
);
280 adg_path_append_primitive(path
, &primitive
);
281 last
= adg_path_last_primitive(path
);
282 g_assert_nonnull(last
);
283 g_assert_cmpint(last
->data
->header
.type
, ==, CPML_CLOSE
);
285 /* Now trying to reappending with mismatching start point */
286 adg_path_move_to_explicit(path
, -1, -2);
288 cpml_primitive_reset(&primitive
);
289 adg_path_append_primitive(path
, &primitive
);
290 last
= adg_path_last_primitive(path
);
291 g_assert_nonnull(last
);
292 g_assert_cmpint(last
->data
->header
.type
, ==, CPML_CLOSE
);
294 cpml_primitive_next(&primitive
);
295 adg_path_append_primitive(path
, &primitive
);
296 last
= adg_path_last_primitive(path
);
297 g_assert_nonnull(last
);
298 g_assert_cmpint(last
->data
->header
.type
, ==, CPML_CLOSE
);
300 cpml_primitive_next(&primitive
);
301 adg_path_append_primitive(path
, &primitive
);
302 last
= adg_path_last_primitive(path
);
303 g_assert_nonnull(last
);
304 g_assert_cmpint(last
->data
->header
.type
, ==, CPML_CLOSE
);
306 /* Invalid primitives must be discarded */
307 adg_path_move_to_explicit(path
, 0, 0);
308 adg_path_arc_to_explicit(path
, 1, 2, 0, 1);
309 cpml_primitive_reset(&primitive
);
310 primitive
.org
= NULL
;
311 adg_path_append_primitive(path
, &primitive
);
312 g_assert_cmpint(adg_path_last_primitive(path
)->data
->header
.type
, ==, CPML_ARC
);
314 cpml_primitive_reset(&primitive
);
315 primitive
.data
= NULL
;
316 adg_path_append_primitive(path
, &primitive
);
317 g_assert_cmpint(adg_path_last_primitive(path
)->data
->header
.type
, ==, CPML_ARC
);
319 cpml_primitive_reset(&primitive
);
320 adg_path_append_primitive(path
, &primitive
);
321 g_assert_cmpint(adg_path_last_primitive(path
)->data
->header
.type
, ==, CPML_LINE
);
323 g_object_unref(path
);
327 _adg_method_append_segment(void)
332 path
= adg_path_new();
335 adg_path_append_segment(NULL
, &segment
);
336 adg_path_append_segment(path
, NULL
);
339 cpml_segment_from_cairo(&segment
, (cairo_path_t
*) adg_test_path());
340 adg_path_append_segment(path
, &segment
);
341 g_assert_nonnull(adg_path_last_primitive(path
));
342 g_assert_nonnull(adg_path_over_primitive(path
));
343 g_assert_cmpint(adg_path_last_primitive(path
)->data
->header
.type
, ==, CPML_CLOSE
);
344 g_assert_cmpint(adg_path_over_primitive(path
)->data
->header
.type
, ==, CPML_CURVE
);
347 cpml_segment_next(&segment
);
348 adg_path_append_segment(path
, &segment
);
349 g_assert_nonnull(adg_path_last_primitive(path
));
350 g_assert_nonnull(adg_path_over_primitive(path
));
351 g_assert_cmpint(adg_path_over_primitive(path
)->data
->header
.type
, ==, CPML_LINE
);
352 g_assert_cmpint(adg_path_last_primitive(path
)->data
->header
.type
, ==, CPML_LINE
);
355 cpml_segment_next(&segment
);
356 adg_path_append_segment(path
, &segment
);
357 g_assert_nonnull(adg_path_last_primitive(path
));
358 g_assert_nonnull(adg_path_over_primitive(path
));
359 g_assert_cmpint(adg_path_over_primitive(path
)->data
->header
.type
, ==, CPML_CURVE
);
360 g_assert_cmpint(adg_path_last_primitive(path
)->data
->header
.type
, ==, CPML_CLOSE
);
363 cpml_segment_next(&segment
);
364 adg_path_append_segment(path
, &segment
);
365 g_assert_nonnull(adg_path_last_primitive(path
));
366 g_assert_nonnull(adg_path_over_primitive(path
));
367 g_assert_cmpint(adg_path_over_primitive(path
)->data
->header
.type
, ==, CPML_ARC
);
368 g_assert_cmpint(adg_path_last_primitive(path
)->data
->header
.type
, ==, CPML_ARC
);
371 cpml_segment_next(&segment
);
372 adg_path_append_segment(path
, &segment
);
373 g_assert_nonnull(adg_path_last_primitive(path
));
374 g_assert_nonnull(adg_path_over_primitive(path
));
375 g_assert_cmpint(adg_path_over_primitive(path
)->data
->header
.type
, ==, CPML_ARC
);
376 g_assert_cmpint(adg_path_last_primitive(path
)->data
->header
.type
, ==, CPML_CLOSE
);
378 g_object_unref(path
);
382 _adg_method_append_cairo_path(void)
385 const cairo_path_t
*cairo_path
;
386 cairo_path_data_t open_data
[] = {
387 { .header
= { CPML_MOVE
, 2 }},
388 { .point
= { 0, 1 }},
389 { .header
= { CPML_LINE
, 2 }},
392 cairo_path_t open_path
= {
393 CAIRO_STATUS_SUCCESS
,
395 G_N_ELEMENTS(open_data
)
399 path
= adg_path_new();
400 cairo_path
= adg_test_path();
403 adg_path_append_cairo_path(NULL
, cairo_path
);
404 adg_path_append_cairo_path(path
, NULL
);
406 /* Ensure the path is initially empty */
407 g_assert_null(adg_path_last_primitive(path
));
408 g_assert_false(adg_path_has_current_point(path
));
410 adg_path_append_cairo_path(path
, cairo_path
);
412 /* Check the path is no more empty */
413 g_assert_nonnull(adg_path_last_primitive(path
));
415 /* The provided test path ends with a CPML_CLOSE primitive so the current
416 * point should be still unset */
417 g_assert_false(adg_path_has_current_point(path
));
419 /* Append an open path to check if the current point is set */
420 adg_path_append_cairo_path(path
, &open_path
);
422 /* Check that the current point is properly set */
423 g_assert_true(adg_path_has_current_point(path
));
424 cp
= adg_path_get_current_point(path
);
425 g_assert_nonnull(cp
);
426 adg_assert_isapprox(cp
->x
, 2);
427 adg_assert_isapprox(cp
->y
, 3);
429 g_object_unref(path
);
433 _adg_method_append_trail(void)
437 const CpmlPair
*pair
;
439 path
= adg_path_new();
440 trail
= ADG_TRAIL(adg_path_new());
442 /* The trail must be non-empty and with a named pair */
443 adg_path_append_cairo_path(ADG_PATH(trail
), adg_test_path());
444 adg_model_set_named_pair_explicit(ADG_MODEL(trail
), "test", 1, 2);
447 adg_path_append_trail(NULL
, trail
);
448 adg_path_append_trail(path
, NULL
);
450 /* Ensure path is initially empty */
451 g_assert_null(adg_path_last_primitive(path
));
453 adg_path_append_trail(path
, trail
);
455 /* Check that path is no more empty */
456 g_assert_nonnull(adg_path_last_primitive(path
));
458 /* Check that "test" named pair has been transferred to path */
459 pair
= adg_model_get_named_pair(ADG_MODEL(path
), "test");
460 g_assert_nonnull(pair
);
461 adg_assert_isapprox(pair
->x
, 1);
462 adg_assert_isapprox(pair
->y
, 2);
464 g_object_unref(path
);
468 _adg_method_remove_primitive(void)
473 path
= adg_path_new();
476 adg_path_remove_primitive(NULL
);
477 adg_path_remove_primitive(path
);
479 adg_path_append_cairo_path(path
, adg_test_path());
481 /* Remove all primitives from test path */
482 for (n
= 1; adg_trail_put_segment(ADG_TRAIL(path
), 1, NULL
); ++n
) {
483 adg_path_remove_primitive(path
);
485 g_assert_cmpint(n
, ==, 12);
487 /* Ensure the current point is no more set */
488 g_assert_false(adg_path_has_current_point(path
));
490 g_object_unref(path
);
494 _adg_method_move_to(void)
496 AdgPath
*path
= adg_path_new();
497 CpmlPair pair
= { 1, 2 };
501 adg_path_move_to(NULL
, &pair
);
502 adg_path_move_to(path
, NULL
);
503 adg_path_move_to_explicit(NULL
, 3, 4);
505 adg_path_move_to(path
, &pair
);
506 cp
= adg_path_get_current_point(path
);
507 adg_assert_isapprox(cp
->x
, 1);
508 adg_assert_isapprox(cp
->y
, 2);
510 adg_path_move_to_explicit(path
, 3, 4);
511 cp
= adg_path_get_current_point(path
);
512 adg_assert_isapprox(cp
->x
, 3);
513 adg_assert_isapprox(cp
->y
, 4);
515 g_object_unref(path
);
519 _adg_method_line_to(void)
521 AdgPath
*path
= adg_path_new();
522 CpmlPair pair
= { 1, 2 };
526 adg_path_line_to(NULL
, &pair
);
527 adg_path_line_to(path
, NULL
);
528 adg_path_line_to_explicit(NULL
, 3, 4);
530 /* This should fail because there is no current point */
531 g_assert_null(adg_path_get_current_point(path
));
532 adg_path_line_to(path
, &pair
);
533 g_assert_null(adg_path_last_primitive(path
));
535 adg_path_move_to_explicit(path
, 0, 0);
536 adg_path_line_to(path
, &pair
);
537 g_assert_nonnull(adg_path_last_primitive(path
));
538 cp
= adg_path_get_current_point(path
);
539 g_assert_nonnull(cp
);
540 adg_assert_isapprox(cp
->x
, 1);
541 adg_assert_isapprox(cp
->y
, 2);
543 adg_path_line_to_explicit(path
, 3, 4);
544 cp
= adg_path_get_current_point(path
);
545 g_assert_nonnull(cp
);
546 adg_assert_isapprox(cp
->x
, 3);
547 adg_assert_isapprox(cp
->y
, 4);
549 g_object_unref(path
);
553 _adg_method_arc_to(void)
555 AdgPath
*path
= adg_path_new();
563 adg_path_arc_to(NULL
, &pair
[0], &pair
[1]);
564 adg_path_arc_to(path
, NULL
, &pair
[1]);
565 adg_path_arc_to(path
, &pair
[0], NULL
);
566 adg_path_arc_to_explicit(NULL
, 5, 6, 7, 8);
568 /* This should fail because there is no current point */
569 adg_path_arc_to(path
, &pair
[0], &pair
[1]);
570 g_assert_null(adg_path_last_primitive(path
));
572 adg_path_move_to_explicit(path
, 0, 0);
573 adg_path_arc_to(path
, &pair
[0], &pair
[1]);
574 g_assert_nonnull(adg_path_last_primitive(path
));
575 cp
= adg_path_get_current_point(path
);
576 adg_assert_isapprox(cp
->x
, 3);
577 adg_assert_isapprox(cp
->y
, 4);
579 adg_path_arc_to_explicit(path
, 5, 6, 7, 8);
580 cp
= adg_path_get_current_point(path
);
581 adg_assert_isapprox(cp
->x
, 7);
582 adg_assert_isapprox(cp
->y
, 8);
584 g_object_unref(path
);
588 _adg_method_curve_to(void)
590 AdgPath
*path
= adg_path_new();
599 adg_path_curve_to(NULL
, &pair
[0], &pair
[1], &pair
[2]);
600 adg_path_curve_to(path
, NULL
, &pair
[1], &pair
[2]);
601 adg_path_curve_to(path
, &pair
[0], NULL
, &pair
[2]);
602 adg_path_curve_to(path
, &pair
[0], &pair
[1], NULL
);
603 adg_path_curve_to_explicit(NULL
, 7, 8, 9, 10, 11, 12);
605 /* This should fail because there is no current point */
606 adg_path_curve_to(path
, &pair
[0], &pair
[1], &pair
[2]);
607 g_assert_null(adg_path_last_primitive(path
));
609 adg_path_move_to_explicit(path
, 0, 0);
610 adg_path_curve_to(path
, &pair
[0], &pair
[1], &pair
[2]);
611 g_assert_nonnull(adg_path_last_primitive(path
));
612 cp
= adg_path_get_current_point(path
);
613 adg_assert_isapprox(cp
->x
, 5);
614 adg_assert_isapprox(cp
->y
, 6);
616 adg_path_curve_to_explicit(path
, 7, 8, 9, 10, 11, 12);
617 cp
= adg_path_get_current_point(path
);
618 adg_assert_isapprox(cp
->x
, 11);
619 adg_assert_isapprox(cp
->y
, 12);
621 g_object_unref(path
);
625 _adg_method_arc(void)
627 AdgPath
*path
= adg_path_new();
628 CpmlPair pair
= { 3, 4 };
629 cairo_path_t
*cairo_path
;
631 CpmlPrimitive primitive
;
634 adg_path_arc(NULL
, &pair
, 1, 2, 3);
635 adg_path_arc(path
, NULL
, 1, 2, 3);
636 adg_path_arc_explicit(NULL
, 1, 2, 3, 4, 5);
638 /* This should *not* fail because this primitive
639 * automatically adds a leading CPML_MOVE */
640 adg_path_arc(path
, &pair
, 2, 0, G_PI_2
);
641 g_assert_nonnull(adg_path_last_primitive(path
));
643 /* Disconnected arcs should be automatically
644 * joined with CPML_LINEs */
645 adg_path_arc_explicit(path
, 3, 4, 2, G_PI
, -G_PI
);
646 g_assert_nonnull(adg_path_last_primitive(path
));
648 /* Check that the result is the expected one */
649 cairo_path
= adg_trail_cairo_path(ADG_TRAIL(path
));
650 g_assert_nonnull(cairo_path
);
651 g_assert_true(cpml_segment_from_cairo(&segment
, cairo_path
));
653 cpml_primitive_from_segment(&primitive
, &segment
);
654 g_assert_cmpint(primitive
.data
[0].header
.type
, ==, CPML_ARC
);
655 g_assert_cmpint(primitive
.data
[0].header
.length
, ==, 3);
656 adg_assert_isapprox((primitive
.org
)->point
.x
, 5);
657 adg_assert_isapprox((primitive
.org
)->point
.y
, 4);
658 adg_assert_isapprox(primitive
.data
[1].point
.x
, 4.414);
659 adg_assert_isapprox(primitive
.data
[1].point
.y
, 5.414);
660 adg_assert_isapprox(primitive
.data
[2].point
.x
, 3);
661 adg_assert_isapprox(primitive
.data
[2].point
.y
, 6);
663 g_assert_true(cpml_primitive_next(&primitive
));
664 g_assert_cmpint(primitive
.data
[0].header
.type
, ==, CPML_LINE
);
665 g_assert_cmpint(primitive
.data
[0].header
.length
, ==, 2);
666 adg_assert_isapprox(primitive
.data
[1].point
.x
, 1);
667 adg_assert_isapprox(primitive
.data
[1].point
.y
, 4);
669 g_assert_true(cpml_primitive_next(&primitive
));
670 g_assert_cmpint(primitive
.data
[0].header
.type
, ==, CPML_ARC
);
671 g_assert_cmpint(primitive
.data
[0].header
.length
, ==, 3);
672 adg_assert_isapprox(primitive
.data
[1].point
.x
, 5);
673 adg_assert_isapprox(primitive
.data
[1].point
.y
, 4);
674 adg_assert_isapprox(primitive
.data
[2].point
.x
, 1);
675 adg_assert_isapprox(primitive
.data
[2].point
.y
, 4);
677 g_assert_false(cpml_primitive_next(&primitive
));
679 g_object_unref(path
);
683 _adg_method_chamfer(void)
686 cairo_path_t
*cairo_path
;
688 CpmlPrimitive primitive
;
691 adg_path_chamfer(NULL
, 1, 2);
693 /* Perform an easy chamfer */
694 path
= adg_path_new();
695 adg_path_move_to_explicit(path
, 0, 0);
696 adg_path_line_to_explicit(path
, 0, 8);
697 adg_path_chamfer(path
, 2, 3);
698 adg_path_line_to_explicit(path
, 10, 8);
700 /* Check that the result is the expected one */
701 cairo_path
= adg_trail_cairo_path(ADG_TRAIL(path
));
702 g_assert_nonnull(cairo_path
);
703 g_assert_true(cpml_segment_from_cairo(&segment
, cairo_path
));
705 cpml_primitive_from_segment(&primitive
, &segment
);
706 g_assert_cmpint(primitive
.data
[0].header
.type
, ==, CPML_LINE
);
707 g_assert_cmpint(primitive
.data
[0].header
.length
, ==, 2);
708 adg_assert_isapprox((primitive
.org
)->point
.x
, 0);
709 adg_assert_isapprox((primitive
.org
)->point
.y
, 0);
710 adg_assert_isapprox(primitive
.data
[1].point
.x
, 0);
711 adg_assert_isapprox(primitive
.data
[1].point
.y
, 6);
713 g_assert_true(cpml_primitive_next(&primitive
));
714 g_assert_cmpint(primitive
.data
[0].header
.type
, ==, CPML_LINE
);
715 g_assert_cmpint(primitive
.data
[0].header
.length
, ==, 2);
716 adg_assert_isapprox((primitive
.org
)->point
.x
, 0);
717 adg_assert_isapprox((primitive
.org
)->point
.y
, 6);
718 adg_assert_isapprox(primitive
.data
[1].point
.x
, 3);
719 adg_assert_isapprox(primitive
.data
[1].point
.y
, 8);
721 g_assert_true(cpml_primitive_next(&primitive
));
722 g_assert_cmpint(primitive
.data
[0].header
.type
, ==, CPML_LINE
);
723 g_assert_cmpint(primitive
.data
[0].header
.length
, ==, 2);
724 adg_assert_isapprox((primitive
.org
)->point
.x
, 3);
725 adg_assert_isapprox((primitive
.org
)->point
.y
, 8);
726 adg_assert_isapprox(primitive
.data
[1].point
.x
, 10);
727 adg_assert_isapprox(primitive
.data
[1].point
.y
, 8);
729 g_assert_false(cpml_primitive_next(&primitive
));
731 /* TODO: perform more complex tests */
733 g_object_unref(path
);
737 _adg_method_fillet(void)
740 cairo_path_t
*cairo_path
;
742 CpmlPrimitive primitive
;
745 adg_path_fillet(NULL
, 1);
747 /* Perform an easy fillet */
748 path
= adg_path_new();
749 adg_path_move_to_explicit(path
, 0, 0);
750 adg_path_line_to_explicit(path
, 0, 8);
751 adg_path_fillet(path
, 3);
752 adg_path_line_to_explicit(path
, 10, 8);
754 /* Check that the result is the expected one */
755 cairo_path
= adg_trail_cairo_path(ADG_TRAIL(path
));
756 g_assert_nonnull(cairo_path
);
757 g_assert_true(cpml_segment_from_cairo(&segment
, cairo_path
));
759 cpml_primitive_from_segment(&primitive
, &segment
);
760 g_assert_cmpint(primitive
.data
[0].header
.type
, ==, CPML_LINE
);
761 g_assert_cmpint(primitive
.data
[0].header
.length
, ==, 2);
762 adg_assert_isapprox((primitive
.org
)->point
.x
, 0);
763 adg_assert_isapprox((primitive
.org
)->point
.y
, 0);
764 adg_assert_isapprox(primitive
.data
[1].point
.x
, 0);
765 adg_assert_isapprox(primitive
.data
[1].point
.y
, 5);
767 g_assert_true(cpml_primitive_next(&primitive
));
768 g_assert_cmpint(primitive
.data
[0].header
.type
, ==, CPML_ARC
);
769 g_assert_cmpint(primitive
.data
[0].header
.length
, ==, 3);
770 adg_assert_isapprox((primitive
.org
)->point
.x
, 0);
771 adg_assert_isapprox((primitive
.org
)->point
.y
, 5);
772 adg_assert_isapprox(primitive
.data
[1].point
.x
, 0.879);
773 adg_assert_isapprox(primitive
.data
[1].point
.y
, 7.121);
774 adg_assert_isapprox(primitive
.data
[2].point
.x
, 3);
775 adg_assert_isapprox(primitive
.data
[2].point
.y
, 8);
777 g_assert_true(cpml_primitive_next(&primitive
));
778 g_assert_cmpint(primitive
.data
[0].header
.type
, ==, CPML_LINE
);
779 g_assert_cmpint(primitive
.data
[0].header
.length
, ==, 2);
780 adg_assert_isapprox((primitive
.org
)->point
.x
, 3);
781 adg_assert_isapprox((primitive
.org
)->point
.y
, 8);
782 adg_assert_isapprox(primitive
.data
[1].point
.x
, 10);
783 adg_assert_isapprox(primitive
.data
[1].point
.y
, 8);
785 g_assert_false(cpml_primitive_next(&primitive
));
787 /* TODO: perform more complex tests */
789 g_object_unref(path
);
793 _adg_method_join(void)
796 cairo_path_t
*cairo_path
;
798 CpmlPrimitive primitive
;
800 path
= adg_path_new();
805 adg_path_move_to_explicit(path
, 0, 1);
806 adg_path_move_to_explicit(path
, 2, 3);
807 adg_path_line_to_explicit(path
, 4, 5);
808 adg_path_move_to_explicit(path
, 6, 7);
809 adg_path_line_to_explicit(path
, 8, 9);
811 /* Not specifying the vector means reflect on y=0 */
814 /* Check that the result is the expected one */
815 cairo_path
= adg_trail_cairo_path(ADG_TRAIL(path
));
816 g_assert_nonnull(cairo_path
);
817 g_assert_true(cpml_segment_from_cairo(&segment
, cairo_path
));
819 /* Check if the reverted segment matches */
820 cpml_primitive_from_segment(&primitive
, &segment
);
822 g_assert_cmpint(primitive
.data
[0].header
.type
, ==, CPML_LINE
);
823 g_assert_cmpint(primitive
.data
[0].header
.length
, ==, 2);
824 adg_assert_isapprox(primitive
.org
->point
.x
, 2);
825 adg_assert_isapprox(primitive
.org
->point
.y
, 3);
826 adg_assert_isapprox(primitive
.data
[1].point
.x
, 4);
827 adg_assert_isapprox(primitive
.data
[1].point
.y
, 5);
829 g_assert_true(cpml_primitive_next(&primitive
));
831 g_assert_cmpint(primitive
.data
[0].header
.type
, ==, CPML_LINE
);
832 g_assert_cmpint(primitive
.data
[0].header
.length
, ==, 2);
833 adg_assert_isapprox(primitive
.data
[1].point
.x
, 6);
834 adg_assert_isapprox(primitive
.data
[1].point
.y
, 7);
836 g_assert_true(cpml_primitive_next(&primitive
));
838 g_assert_cmpint(primitive
.data
[0].header
.type
, ==, CPML_LINE
);
839 g_assert_cmpint(primitive
.data
[0].header
.length
, ==, 2);
840 adg_assert_isapprox(primitive
.data
[1].point
.x
, 8);
841 adg_assert_isapprox(primitive
.data
[1].point
.y
, 9);
843 g_assert_false(cpml_primitive_next(&primitive
));
845 /* Check there are no more segments */
846 g_assert_false(cpml_segment_next(&segment
));
848 g_object_unref(path
);
852 _adg_method_reflect(void)
857 cairo_path_t
*cairo_path
;
859 CpmlPrimitive primitive
;
861 path
= adg_path_new();
864 adg_path_reflect(NULL
, &pair
);
865 adg_path_reflect_explicit(NULL
, 1, 2);
866 adg_path_reflect_explicit(path
, 0, 0);
868 adg_model_set_named_pair_explicit(ADG_MODEL(path
), "P1", 1, 2);
872 adg_model_set_named_pair(ADG_MODEL(path
), "P2", &pair
);
874 adg_path_move_to_explicit(path
, 0, 1);
875 adg_path_line_to_explicit(path
, 2, 3);
876 adg_path_arc_to_explicit(path
, 4, 5, 6, 7);
877 adg_path_curve_to_explicit(path
, 8, 9, 10, 11, 12, 13);
879 /* Not specifying the vector means reflect on y=0 */
880 adg_path_reflect(path
, NULL
);
882 /* Check that the result is the expected one */
883 cairo_path
= adg_trail_cairo_path(ADG_TRAIL(path
));
884 g_assert_nonnull(cairo_path
);
885 g_assert_true(cpml_segment_from_cairo(&segment
, cairo_path
));
887 /* Skip the original primitives */
888 cpml_primitive_from_segment(&primitive
, &segment
); /* CPML_LINE */
889 g_assert_true(cpml_primitive_next(&primitive
)); /* CPML_ARC */
890 g_assert_true(cpml_primitive_next(&primitive
)); /* CPML_CURVE */
892 /* There must not be an automatic join between segments */
893 g_assert_false(cpml_primitive_next(&primitive
));
895 /* Check if the reverted segment matches */
896 g_assert_true(cpml_segment_next(&segment
));
897 cpml_primitive_from_segment(&primitive
, &segment
);
899 g_assert_cmpint(primitive
.data
[0].header
.type
, ==, CPML_CURVE
);
900 adg_assert_isapprox(primitive
.org
->point
.x
, 12);
901 adg_assert_isapprox(primitive
.org
->point
.y
, -13);
902 g_assert_cmpint(primitive
.data
[0].header
.length
, ==, 4);
903 adg_assert_isapprox(primitive
.data
[1].point
.x
, 10);
904 adg_assert_isapprox(primitive
.data
[1].point
.y
, -11);
905 adg_assert_isapprox(primitive
.data
[2].point
.x
, 8);
906 adg_assert_isapprox(primitive
.data
[2].point
.y
, -9);
907 adg_assert_isapprox(primitive
.data
[3].point
.x
, 6);
908 adg_assert_isapprox(primitive
.data
[3].point
.y
, -7);
910 g_assert_true(cpml_primitive_next(&primitive
));
911 g_assert_cmpint(primitive
.data
[0].header
.type
, ==, CPML_ARC
);
912 g_assert_cmpint(primitive
.data
[0].header
.length
, ==, 3);
913 adg_assert_isapprox(primitive
.data
[1].point
.x
, 4);
914 adg_assert_isapprox(primitive
.data
[1].point
.y
, -5);
915 adg_assert_isapprox(primitive
.data
[2].point
.x
, 2);
916 adg_assert_isapprox(primitive
.data
[2].point
.y
, -3);
918 g_assert_true(cpml_primitive_next(&primitive
));
919 g_assert_cmpint(primitive
.data
[0].header
.type
, ==, CPML_LINE
);
920 g_assert_cmpint(primitive
.data
[0].header
.length
, ==, 2);
921 adg_assert_isapprox(primitive
.data
[1].point
.x
, 0);
922 adg_assert_isapprox(primitive
.data
[1].point
.y
, -1);
924 g_assert_false(cpml_primitive_next(&primitive
));
926 /* Check if the named pairs have been duplicated and mirrored */
927 p
= adg_model_get_named_pair(ADG_MODEL(path
), "P1");
928 adg_assert_isapprox(p
->x
, 1);
929 adg_assert_isapprox(p
->y
, 2);
931 p
= adg_model_get_named_pair(ADG_MODEL(path
), "-P1");
932 adg_assert_isapprox(p
->x
, 1);
933 adg_assert_isapprox(p
->y
, -2);
935 p
= adg_model_get_named_pair(ADG_MODEL(path
), "P2");
936 adg_assert_isapprox(p
->x
, -2);
937 adg_assert_isapprox(p
->y
, -3);
939 p
= adg_model_get_named_pair(ADG_MODEL(path
), "-P2");
940 adg_assert_isapprox(p
->x
, -2);
941 adg_assert_isapprox(p
->y
, 3);
943 g_object_unref(path
);
945 path
= adg_path_new();
949 adg_model_set_named_pair(ADG_MODEL(path
), "P1", &pair
);
951 adg_model_set_named_pair_explicit(ADG_MODEL(path
), "P2", -20, -30);
953 adg_path_move_to_explicit(path
, 0, 10);
954 adg_path_line_to_explicit(path
, 20, 30);
956 /* Reflect on the x=0 axis */
957 adg_path_reflect_explicit(path
, 0, 100);
959 /* Check that the result is the expected one */
960 cairo_path
= adg_trail_cairo_path(ADG_TRAIL(path
));
961 g_assert_nonnull(cairo_path
);
962 g_assert_true(cpml_segment_from_cairo(&segment
, cairo_path
));
964 /* Skip the original primitives */
965 cpml_primitive_from_segment(&primitive
, &segment
); /* CPML_LINE */
967 /* There must not be an automatic join between segments */
968 g_assert_false(cpml_primitive_next(&primitive
));
970 /* Check if the reverted segment matches */
971 g_assert_true(cpml_segment_next(&segment
));
972 cpml_primitive_from_segment(&primitive
, &segment
);
974 g_assert_cmpint(primitive
.data
[0].header
.type
, ==, CPML_LINE
);
975 adg_assert_isapprox(primitive
.org
->point
.x
, -20);
976 adg_assert_isapprox(primitive
.org
->point
.y
, 30);
977 g_assert_cmpint(primitive
.data
[0].header
.length
, ==, 2);
978 adg_assert_isapprox(primitive
.data
[1].point
.x
, 0);
979 adg_assert_isapprox(primitive
.data
[1].point
.y
, 10);
981 /* Check if the named pairs have been duplicated and mirrored */
982 p
= adg_model_get_named_pair(ADG_MODEL(path
), "P1");
983 adg_assert_isapprox(p
->x
, 10);
984 adg_assert_isapprox(p
->y
, 20);
986 p
= adg_model_get_named_pair(ADG_MODEL(path
), "-P1");
987 adg_assert_isapprox(p
->x
, -10);
988 adg_assert_isapprox(p
->y
, 20);
990 p
= adg_model_get_named_pair(ADG_MODEL(path
), "P2");
991 adg_assert_isapprox(p
->x
, -20);
992 adg_assert_isapprox(p
->y
, -30);
994 p
= adg_model_get_named_pair(ADG_MODEL(path
), "-P2");
995 adg_assert_isapprox(p
->x
, 20);
996 adg_assert_isapprox(p
->y
, -30);
998 g_object_unref(path
);
1003 main(int argc
, char *argv
[])
1005 adg_test_init(&argc
, &argv
);
1007 adg_test_add_object_checks("/adg/path/type/object", ADG_TYPE_PATH
);
1008 adg_test_add_model_checks("/adg/path/type/model", ADG_TYPE_PATH
);
1010 g_test_add_func("/adg/path/method/get-current-point", _adg_method_get_current_point
);
1011 g_test_add_func("/adg/path/method/has-current-point", _adg_method_has_current_point
);
1012 g_test_add_func("/adg/path/method/last-primitive", _adg_method_last_primitive
);
1013 g_test_add_func("/adg/path/method/over-primitive", _adg_method_over_primitive
);
1014 g_test_add_func("/adg/path/method/append-primitive", _adg_method_append_primitive
);
1015 g_test_add_func("/adg/path/method/append-segment", _adg_method_append_segment
);
1016 g_test_add_func("/adg/path/method/append-cairo-path", _adg_method_append_cairo_path
);
1017 g_test_add_func("/adg/path/method/append-trail", _adg_method_append_trail
);
1018 g_test_add_func("/adg/path/method/remove-primitive", _adg_method_remove_primitive
);
1019 g_test_add_func("/adg/path/method/move-to", _adg_method_move_to
);
1020 g_test_add_func("/adg/path/method/line-to", _adg_method_line_to
);
1021 g_test_add_func("/adg/path/method/arc-to", _adg_method_arc_to
);
1022 g_test_add_func("/adg/path/method/curve-to", _adg_method_curve_to
);
1023 g_test_add_func("/adg/path/method/arc", _adg_method_arc
);
1024 g_test_add_func("/adg/path/method/chamfer", _adg_method_chamfer
);
1025 g_test_add_func("/adg/path/method/fillet", _adg_method_fillet
);
1026 g_test_add_func("/adg/path/method/join", _adg_method_join
);
1027 g_test_add_func("/adg/path/method/reflect", _adg_method_reflect
);
1029 return g_test_run();