doc: update copyright line for 2021
[adg.git] / src / adg / tests / test-path.c
blobb93529aa8255d2a81e7e8438ea2cc8b3d48d403d
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.
21 #include <adg-test.h>
22 #include <adg.h>
25 static void
26 _adg_method_get_current_point(void)
28 AdgPath *path;
29 const CpmlPair *cp;
31 /* Check sanity */
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);
39 g_assert_nonnull(cp);
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);
45 g_assert_nonnull(cp);
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);
51 g_assert_nonnull(cp);
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);
57 g_assert_nonnull(cp);
58 adg_assert_isapprox(cp->x, 13);
59 adg_assert_isapprox(cp->y, 14);
61 adg_path_close(path);
62 g_assert_null(adg_path_get_current_point(path));
64 g_object_unref(path);
67 static void
68 _adg_method_has_current_point(void)
70 AdgPath *path;
72 /* Check sanity */
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));
80 adg_path_close(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));
86 g_object_unref(path);
89 static void
90 _adg_method_last_primitive(void)
92 AdgPath *path;
93 const CpmlPrimitive *primitive;
95 /* Check sanity */
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);
165 static void
166 _adg_method_over_primitive(void)
168 AdgPath *path;
169 const CpmlPrimitive *primitive;
171 /* Check sanity */
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);
244 static void
245 _adg_method_append_primitive(void)
247 AdgPath *path;
248 CpmlSegment segment;
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);
256 /* Check sanity */
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);
326 static void
327 _adg_method_append_segment(void)
329 AdgPath *path;
330 CpmlSegment segment;
332 path = adg_path_new();
334 /* Check sanity */
335 adg_path_append_segment(NULL, &segment);
336 adg_path_append_segment(path, NULL);
338 /* First segment */
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);
346 /* Second segment */
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);
354 /* Third segment */
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);
362 /* Forth segment */
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);
370 /* Fifth segment */
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);
381 static void
382 _adg_method_append_cairo_path(void)
384 AdgPath *path;
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 }},
390 { .point = { 2, 3 }}
392 cairo_path_t open_path = {
393 CAIRO_STATUS_SUCCESS,
394 open_data,
395 G_N_ELEMENTS(open_data)
397 const CpmlPair *cp;
399 path = adg_path_new();
400 cairo_path = adg_test_path();
402 /* Check sanity */
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);
432 static void
433 _adg_method_append_trail(void)
435 AdgPath *path;
436 AdgTrail *trail;
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);
446 /* Check sanity */
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);
467 static void
468 _adg_method_remove_primitive(void)
470 AdgPath *path;
471 int n;
473 path = adg_path_new();
475 /* Check sanity */
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);
493 static void
494 _adg_method_move_to(void)
496 AdgPath *path = adg_path_new();
497 CpmlPair pair = { 1, 2 };
498 const CpmlPair *cp;
500 /* Check sanity */
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);
518 static void
519 _adg_method_line_to(void)
521 AdgPath *path = adg_path_new();
522 CpmlPair pair = { 1, 2 };
523 const CpmlPair *cp;
525 /* Check sanity */
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);
552 static void
553 _adg_method_arc_to(void)
555 AdgPath *path = adg_path_new();
556 CpmlPair pair[] = {
557 { 1, 2 },
558 { 3, 4 }
560 const CpmlPair *cp;
562 /* Check sanity */
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);
587 static void
588 _adg_method_curve_to(void)
590 AdgPath *path = adg_path_new();
591 CpmlPair pair[] = {
592 { 1, 2 },
593 { 3, 4 },
594 { 5, 6 },
596 const CpmlPair *cp;
598 /* Check sanity */
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);
624 static void
625 _adg_method_arc(void)
627 AdgPath *path = adg_path_new();
628 CpmlPair pair = { 3, 4 };
629 cairo_path_t *cairo_path;
630 CpmlSegment segment;
631 CpmlPrimitive primitive;
633 /* Check sanity */
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);
682 static void
683 _adg_method_chamfer(void)
685 AdgPath *path;
686 cairo_path_t *cairo_path;
687 CpmlSegment segment;
688 CpmlPrimitive primitive;
690 /* Sanity checks */
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);
736 static void
737 _adg_method_fillet(void)
739 AdgPath *path;
740 cairo_path_t *cairo_path;
741 CpmlSegment segment;
742 CpmlPrimitive primitive;
744 /* Sanity checks */
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);
792 static void
793 _adg_method_join(void)
795 AdgPath *path;
796 cairo_path_t *cairo_path;
797 CpmlSegment segment;
798 CpmlPrimitive primitive;
800 path = adg_path_new();
802 /* Check sanity */
803 adg_path_join(NULL);
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 */
812 adg_path_join(path);
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);
851 static void
852 _adg_method_reflect(void)
854 AdgPath *path;
855 CpmlPair pair;
856 const CpmlPair *p;
857 cairo_path_t *cairo_path;
858 CpmlSegment segment;
859 CpmlPrimitive primitive;
861 path = adg_path_new();
863 /* Check sanity */
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);
870 pair.x = -2;
871 pair.y = -3;
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();
947 pair.x = 10;
948 pair.y = 20;
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();