tests: cpml_primitive_put_vector_at
[adg.git] / src / cpml / tests / test-primitive.c
blob753f6d33e4b7da3f5b9b563e7ce473bf250e8fc3
1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007-2015 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 <cpml.h>
23 #include <string.h>
26 static void
27 _cpml_test_browsing(void)
29 CpmlSegment segment;
30 CpmlPrimitive primitive, primitive_copy;
32 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
34 cpml_primitive_from_segment(&primitive, &segment);
35 g_assert_cmpfloat((primitive.org)->point.x, ==, 0);
36 g_assert_cmpfloat((primitive.org)->point.y, ==, 1);
37 g_assert_cmpint((primitive.data)->header.type, ==, CPML_LINE);
38 g_assert_true(cpml_primitive_next(&primitive));
39 g_assert_cmpfloat((primitive.org)->point.x, ==, 3);
40 g_assert_cmpfloat((primitive.org)->point.y, ==, 1);
41 g_assert_cmpint((primitive.data)->header.type, ==, CPML_ARC);
42 g_assert_true(cpml_primitive_next(&primitive));
43 g_assert_cmpfloat((primitive.org)->point.x, ==, 6);
44 g_assert_cmpfloat((primitive.org)->point.y, ==, 7);
45 g_assert_cmpint((primitive.data)->header.type, ==, CPML_CURVE);
46 g_assert_true(cpml_primitive_next(&primitive));
47 g_assert_cmpfloat((primitive.org)->point.x, ==, -2);
48 g_assert_cmpfloat((primitive.org)->point.y, ==, 2);
49 g_assert_cmpint((primitive.data)->header.type, ==, CPML_CLOSE);
50 g_assert_false(cpml_primitive_next(&primitive));
52 cpml_primitive_reset(&primitive);
53 g_assert_true(cpml_primitive_next(&primitive));
54 cpml_primitive_reset(&primitive);
55 cpml_primitive_reset(&primitive);
56 g_assert_true(cpml_primitive_next(&primitive));
57 g_assert_true(cpml_primitive_next(&primitive));
58 g_assert_true(cpml_primitive_next(&primitive));
59 g_assert_false(cpml_primitive_next(&primitive));
61 cpml_primitive_copy(&primitive_copy, &primitive);
62 g_assert_false(cpml_primitive_next(&primitive_copy));
63 cpml_primitive_reset(&primitive);
64 g_assert_false(cpml_primitive_next(&primitive_copy));
65 cpml_primitive_reset(&primitive_copy);
66 g_assert_true(cpml_primitive_next(&primitive_copy));
69 static void
70 _cpml_test_sanity_from_segment(gint i)
72 CpmlPrimitive primitive;
73 CpmlSegment segment;
75 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
77 switch (i) {
78 case 1:
79 cpml_primitive_from_segment(NULL, &segment);
80 break;
81 case 2:
82 cpml_primitive_from_segment(&primitive, NULL);
83 break;
84 default:
85 g_test_trap_assert_failed();
86 break;
90 static void
91 _cpml_test_sanity_copy(gint i)
93 CpmlPrimitive primitive;
94 CpmlSegment segment;
96 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
97 cpml_primitive_from_segment(&primitive, &segment);
99 switch (i) {
100 case 1:
101 cpml_primitive_copy(NULL, &primitive);
102 break;
103 case 2:
104 cpml_primitive_copy(&primitive, NULL);
105 break;
106 default:
107 g_test_trap_assert_failed();
108 break;
112 static void
113 _cpml_test_sanity_get_n_points(gint i)
115 switch (i) {
116 case 1:
117 cpml_primitive_get_n_points(NULL);
118 break;
119 default:
120 g_test_trap_assert_failed();
121 break;
125 static void
126 _cpml_test_sanity_get_length(gint i)
128 switch (i) {
129 case 1:
130 cpml_primitive_get_length(NULL);
131 break;
132 default:
133 g_test_trap_assert_failed();
134 break;
138 static void
139 _cpml_test_sanity_put_extents(gint i)
141 CpmlSegment segment;
142 CpmlPrimitive primitive;
143 CpmlExtents extents;
145 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
146 cpml_primitive_from_segment(&primitive, &segment);
148 switch (i) {
149 case 1:
150 cpml_primitive_put_extents(NULL, &extents);
151 break;
152 case 2:
153 cpml_primitive_put_extents(&primitive, NULL);
154 break;
155 default:
156 g_test_trap_assert_failed();
157 break;
161 static void
162 _cpml_test_sanity_put_pair_at(gint i)
164 CpmlSegment segment;
165 CpmlPrimitive primitive;
166 CpmlPair pair;
168 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
169 cpml_primitive_from_segment(&primitive, &segment);
171 switch (i) {
172 case 1:
173 cpml_primitive_put_pair_at(NULL, 1, &pair);
174 break;
175 case 2:
176 cpml_primitive_put_pair_at(&primitive, 1, NULL);
177 break;
178 default:
179 g_test_trap_assert_failed();
180 break;
184 static void
185 _cpml_test_sanity_put_vector_at(gint i)
187 CpmlSegment segment;
188 CpmlPrimitive primitive;
189 CpmlVector vector;
191 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
192 cpml_primitive_from_segment(&primitive, &segment);
194 switch (i) {
195 case 1:
196 cpml_primitive_put_vector_at(NULL, 1, &vector);
197 break;
198 case 2:
199 cpml_primitive_put_vector_at(&primitive, 1, NULL);
200 break;
201 default:
202 g_test_trap_assert_failed();
203 break;
207 static void
208 _cpml_test_sanity_set_point(gint i)
210 CpmlSegment segment;
211 CpmlPrimitive primitive;
212 CpmlPair pair = { 1, 1 };
214 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
215 cpml_primitive_from_segment(&primitive, &segment);
217 switch (i) {
218 case 1:
219 cpml_primitive_set_point(NULL, 1, &pair);
220 break;
221 case 2:
222 cpml_primitive_set_point(&primitive, 1, NULL);
223 break;
224 default:
225 g_test_trap_assert_failed();
226 break;
230 static void
231 _cpml_test_sanity_put_point(gint i)
233 CpmlSegment segment;
234 CpmlPrimitive primitive;
235 CpmlPair pair;
237 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
238 cpml_primitive_from_segment(&primitive, &segment);
240 switch (i) {
241 case 1:
242 cpml_primitive_put_point(NULL, 0, &pair);
243 break;
244 case 2:
245 cpml_primitive_put_point(&primitive, 0, NULL);
246 break;
247 default:
248 g_test_trap_assert_failed();
249 break;
253 static void
254 _cpml_test_sanity_put_intersections(gint i)
256 CpmlSegment segment;
257 CpmlPrimitive primitive1, primitive2;
258 CpmlPair pair;
260 /* Set primitive1 to 1.1 and primitive 2 to 2.2,
261 * so there is an intersection point in (1, 1) */
262 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
263 cpml_primitive_from_segment(&primitive1, &segment);
265 cpml_segment_next(&segment);
266 cpml_primitive_from_segment(&primitive2, &segment);
267 cpml_primitive_next(&primitive2);
269 switch (i) {
270 case 1:
271 cpml_primitive_put_intersections(NULL, &primitive2, 2, &pair);
272 break;
273 case 2:
274 cpml_primitive_put_intersections(&primitive1, NULL, 2, &pair);
275 break;
276 case 3:
277 cpml_primitive_put_intersections(&primitive1, &primitive2, 2, NULL);
278 break;
279 default:
280 g_test_trap_assert_failed();
281 break;
285 static void
286 _cpml_test_sanity_put_intersections_with_segment(gint i)
288 CpmlPrimitive primitive;
289 CpmlSegment segment;
290 CpmlPair pair;
292 /* Set primitive 1.1 and segment to 2
293 * so there is an intersection point in (1,1) */
294 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
295 cpml_primitive_from_segment(&primitive, &segment);
297 cpml_segment_next(&segment);
299 switch (i) {
300 case 1:
301 cpml_primitive_put_intersections_with_segment(NULL, &segment, 2, &pair);
302 break;
303 case 2:
304 cpml_primitive_put_intersections_with_segment(&primitive, NULL, 2, &pair);
305 break;
306 case 3:
307 cpml_primitive_put_intersections_with_segment(&primitive, &segment, 2, NULL);
308 break;
309 default:
310 g_test_trap_assert_failed();
311 break;
315 static void
316 _cpml_test_sanity_join(gint i)
318 CpmlSegment segment;
319 CpmlPrimitive primitive;
321 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
322 cpml_primitive_from_segment(&primitive, &segment);
324 switch (i) {
325 case 1:
326 cpml_primitive_join(NULL, &primitive);
327 break;
328 case 2:
329 cpml_primitive_join(&primitive, NULL);
330 break;
331 default:
332 g_test_trap_assert_failed();
333 break;
337 static void
338 _cpml_test_sanity_dump(gint i)
340 switch (i) {
341 case 1:
342 cpml_segment_dump(NULL);
343 break;
344 default:
345 g_test_trap_assert_failed();
346 break;
350 static void
351 _cpml_test_sanity_to_cairo(gint i)
353 CpmlSegment segment;
354 CpmlPrimitive primitive;
356 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
357 cpml_primitive_from_segment(&primitive, &segment);
359 switch (i) {
360 case 1:
361 cpml_primitive_to_cairo(NULL, adg_test_cairo_context());
362 break;
363 case 2:
364 cpml_primitive_to_cairo(&primitive, NULL);
365 break;
366 default:
367 g_test_trap_assert_failed();
368 break;
372 static void
373 _cpml_test_from_segment(void)
375 CpmlSegment segment;
376 CpmlPrimitive primitive;
378 g_assert_true(cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path()));
380 cpml_primitive_from_segment(&primitive, &segment);
381 g_assert_nonnull(primitive.segment);
382 g_assert_nonnull(primitive.org);
383 g_assert_nonnull(primitive.data);
386 static void
387 _cpml_test_copy(void)
389 CpmlSegment segment;
390 CpmlPrimitive original;
391 CpmlPrimitive primitive = { NULL, NULL, NULL };
393 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
394 cpml_primitive_from_segment(&primitive, &segment);
396 g_assert_false(original.segment == primitive.segment);
397 g_assert_false(original.org == primitive.org);
398 g_assert_false(original.data == primitive.data);
400 cpml_primitive_copy(&primitive, &original);
402 g_assert_true(original.segment == primitive.segment);
403 g_assert_true(original.org == primitive.org);
404 g_assert_true(original.data == primitive.data);
407 static void
408 _cpml_test_type_get_n_points(void)
410 size_t n_points;
412 n_points = cpml_primitive_type_get_n_points(CPML_MOVE);
413 g_assert_cmpuint(n_points, ==, 0);
415 n_points = cpml_primitive_type_get_n_points(CPML_LINE);
416 g_assert_cmpuint(n_points, ==, 2);
418 n_points = cpml_primitive_type_get_n_points(CPML_ARC);
419 g_assert_cmpuint(n_points, ==, 3);
421 n_points = cpml_primitive_type_get_n_points(CPML_CURVE);
422 g_assert_cmpuint(n_points, ==, 4);
424 n_points = cpml_primitive_type_get_n_points(CPML_CLOSE);
425 g_assert_cmpuint(n_points, ==, 2);
428 static void
429 _cpml_test_get_n_points(void)
431 CpmlSegment segment;
432 CpmlPrimitive primitive;
433 size_t n_points;
435 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
437 /* Line */
438 cpml_primitive_from_segment(&primitive, &segment);
439 n_points = cpml_primitive_get_n_points(&primitive);
440 g_assert_cmpuint(n_points, ==, 2);
442 /* Arc */
443 cpml_primitive_next(&primitive);
444 n_points = cpml_primitive_get_n_points(&primitive);
445 g_assert_cmpuint(n_points, ==, 3);
447 /* Curve */
448 cpml_primitive_next(&primitive);
449 n_points = cpml_primitive_get_n_points(&primitive);
450 g_assert_cmpuint(n_points, ==, 4);
452 /* Close: although the end point is not needed, the CPML API
453 * returns 2 points to treat this primitive as a CPML_LINE */
454 cpml_primitive_next(&primitive);
455 n_points = cpml_primitive_get_n_points(&primitive);
456 g_assert_cmpuint(n_points, ==, 2);
459 static void
460 _cpml_test_get_length(void)
462 CpmlSegment segment;
463 CpmlPrimitive primitive;
465 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
466 cpml_segment_next(&segment);
467 cpml_primitive_from_segment(&primitive, &segment);
469 g_assert_cmpfloat(cpml_primitive_get_length(&primitive), ==, 1);
471 cpml_primitive_next(&primitive);
472 g_assert_cmpfloat(cpml_primitive_get_length(&primitive), ==, 2);
475 static void
476 _cpml_test_put_extents(void)
478 gsize data_size;
479 CpmlSegment segment;
480 CpmlPrimitive primitive;
481 CpmlExtents extents;
483 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
485 /* Line */
486 cpml_primitive_from_segment(&primitive, &segment);
487 cpml_primitive_put_extents(&primitive, &extents);
488 g_assert_true(extents.is_defined);
489 g_assert_cmpfloat(extents.org.x, ==, 0);
490 g_assert_cmpfloat(extents.org.y, ==, 1);
491 g_assert_cmpfloat(extents.size.x, ==, 3);
492 g_assert_cmpfloat(extents.size.y, ==, 0);
494 /* Arc: the extents are computed precisely... let's ensure
495 * at least all the 3 points are included */
496 cpml_primitive_next(&primitive);
497 cpml_primitive_put_extents(&primitive, &extents);
498 g_assert_true(extents.is_defined);
499 g_assert_cmpfloat(extents.org.x, <=, 3);
500 g_assert_cmpfloat(extents.org.y, <=, 1);
501 g_assert_cmpfloat(extents.size.x, >=, 3);
502 g_assert_cmpfloat(extents.size.y, >=, 6);
504 /* Curve: actually the extents are computed by using the
505 * convex hull (hence the exact coordinates of the points) */
506 cpml_primitive_next(&primitive);
507 cpml_primitive_put_extents(&primitive, &extents);
508 g_assert_true(extents.is_defined);
509 g_assert_cmpfloat(extents.org.x, ==, -2);
510 g_assert_cmpfloat(extents.org.y, ==, 2);
511 g_assert_cmpfloat(extents.size.x, ==, 12);
512 g_assert_cmpfloat(extents.size.y, ==, 9);
514 /* Close */
515 cpml_primitive_next(&primitive);
516 cpml_primitive_put_extents(&primitive, &extents);
517 g_assert_true(extents.is_defined);
518 g_assert_cmpfloat(extents.org.x, ==, -2);
519 g_assert_cmpfloat(extents.org.y, ==, 1);
520 g_assert_cmpfloat(extents.size.x, ==, 2);
521 g_assert_cmpfloat(extents.size.y, ==, 1);
524 static void
525 _cpml_test_put_pair_at(void)
527 gsize data_size;
528 CpmlSegment segment;
529 CpmlPrimitive primitive;
530 CpmlPair pair;
532 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
534 /* Line */
535 cpml_primitive_from_segment(&primitive, &segment);
536 cpml_primitive_put_pair_at(&primitive, 0, &pair);
537 g_assert_cmpfloat(pair.x, ==, 0);
538 g_assert_cmpfloat(pair.y, ==, 1);
539 cpml_primitive_put_pair_at(&primitive, 1, &pair);
540 g_assert_cmpfloat(pair.x, ==, 3);
541 g_assert_cmpfloat(pair.y, ==, 1);
542 cpml_primitive_put_pair_at(&primitive, 0.5, &pair);
543 g_assert_cmpfloat(pair.x, ==, 1.5);
544 g_assert_cmpfloat(pair.y, ==, 1);
546 /* Arc */
547 cpml_primitive_next(&primitive);
548 cpml_primitive_put_pair_at(&primitive, 0, &pair);
549 g_assert_cmpfloat(pair.x, ==, 3);
550 g_assert_cmpfloat(pair.y, ==, 1);
551 cpml_primitive_put_pair_at(&primitive, 1, &pair);
552 g_assert_cmpfloat(pair.x, ==, 6);
553 g_assert_cmpfloat(pair.y, ==, 7);
554 cpml_primitive_put_pair_at(&primitive, 0.5, &pair);
555 g_assert_cmpfloat(pair.x, >, 3);
556 g_assert_cmpfloat(pair.x, <, 6);
557 g_assert_cmpfloat(pair.y, >, 1);
558 g_assert_cmpfloat(pair.y, <, 7);
560 /* Close */
561 cpml_primitive_next(&primitive);
562 /* TODO: not yet implemented
563 * cpml_primitive_put_pair_at(&primitive, 0, &pair);
564 * g_assert_cmpfloat(pair.x, ==, 6);
565 * g_assert_cmpfloat(pair.y, ==, 7);
566 * cpml_primitive_put_pair_at(&primitive, 1, &pair);
567 * g_assert_cmpfloat(pair.x, ==, -2);
568 * g_assert_cmpfloat(pair.y, ==, 2);
569 * cpml_primitive_put_pair_at(&primitive, 0.5, &pair);
570 * g_assert_cmpfloat(pair.x, ==, 1);
571 * g_assert_cmpfloat(pair.y, ==, 1); */
573 /* Close */
574 cpml_primitive_next(&primitive);
575 cpml_primitive_put_pair_at(&primitive, 0, &pair);
576 g_assert_cmpfloat(pair.x, ==, -2);
577 g_assert_cmpfloat(pair.y, ==, 2);
578 cpml_primitive_put_pair_at(&primitive, 1, &pair);
579 g_assert_cmpfloat(pair.x, ==, 0);
580 g_assert_cmpfloat(pair.y, ==, 1);
581 cpml_primitive_put_pair_at(&primitive, 0.5, &pair);
582 g_assert_cmpfloat(pair.x, ==, -1);
583 g_assert_cmpfloat(pair.y, ==, 1.5);
586 static void
587 _cpml_test_put_vector_at(void)
589 gsize data_size;
590 CpmlSegment segment;
591 CpmlPrimitive primitive;
592 CpmlVector vector;
594 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
596 /* Line */
597 cpml_primitive_from_segment(&primitive, &segment);
598 cpml_primitive_put_vector_at(&primitive, 0, &vector);
599 g_assert_cmpfloat(vector.x, ==, 3);
600 g_assert_cmpfloat(vector.y, ==, 0);
601 cpml_primitive_put_vector_at(&primitive, 1, &vector);
602 g_assert_cmpfloat(vector.x, ==, 3);
603 g_assert_cmpfloat(vector.y, ==, 0);
604 cpml_primitive_put_vector_at(&primitive, 0.5, &vector);
605 g_assert_cmpfloat(vector.x, ==, 3);
606 g_assert_cmpfloat(vector.y, ==, 0);
608 /* Arc */
609 cpml_primitive_next(&primitive);
610 cpml_primitive_put_vector_at(&primitive, 0, &vector);
611 g_assert_cmpfloat(vector.x, >, -0.077);
612 g_assert_cmpfloat(vector.x, <, -0.076);
613 g_assert_cmpfloat(vector.y, >, 0.997);
614 g_assert_cmpfloat(vector.y, <, 0.998);
615 cpml_primitive_put_vector_at(&primitive, 1, &vector);
616 g_assert_cmpfloat(vector.x, >, 0.843);
617 g_assert_cmpfloat(vector.y, <, 0.844);
618 cpml_primitive_put_vector_at(&primitive, 0.5, &vector);
619 g_assert_cmpfloat(vector.x, >, 0.447);
620 g_assert_cmpfloat(vector.x, <, 0.448);
621 g_assert_cmpfloat(vector.y, >, 0.894);
622 g_assert_cmpfloat(vector.y, <, 0.895);
624 /* Close */
625 cpml_primitive_next(&primitive);
626 /* TODO: not yet implemented
627 * cpml_primitive_put_vector_at(&primitive, 0, &vector);
628 * g_assert_cmpfloat(vector.x, ==, 6);
629 * g_assert_cmpfloat(vector.y, ==, 7);
630 * cpml_primitive_put_vector_at(&primitive, 1, &vector);
631 * g_assert_cmpfloat(vector.x, ==, -2);
632 * g_assert_cmpfloat(vector.y, ==, 2);
633 * cpml_primitive_put_vector_at(&primitive, 0.5, &vector);
634 * g_assert_cmpfloat(vector.x, ==, 1);
635 * g_assert_cmpfloat(vector.y, ==, 1); */
637 /* Close */
638 cpml_primitive_next(&primitive);
639 cpml_primitive_put_vector_at(&primitive, 0, &vector);
640 g_assert_cmpfloat(vector.x, ==, 2);
641 g_assert_cmpfloat(vector.y, ==, -1);
642 cpml_primitive_put_vector_at(&primitive, 1, &vector);
643 g_assert_cmpfloat(vector.x, ==, 2);
644 g_assert_cmpfloat(vector.y, ==, -1);
645 cpml_primitive_put_vector_at(&primitive, 0.5, &vector);
646 g_assert_cmpfloat(vector.x, ==, 2);
647 g_assert_cmpfloat(vector.y, ==, -1);
650 static void
651 _cpml_test_set_point(void)
653 gsize data_size;
654 CpmlSegment original, *segment;
655 CpmlPrimitive primitive;
656 CpmlPair pair, pair2;
657 int equality;
659 /* Work on a copy to not modify the original path data */
660 cpml_segment_from_cairo(&original, (cairo_path_t *) adg_test_path());
661 data_size = original.num_data * sizeof(cairo_path_data_t);
662 segment = cpml_segment_deep_dup(&original);
664 /* Line */
665 cpml_primitive_from_segment(&primitive, segment);
667 equality = memcmp(original.data, segment->data, data_size);
668 g_assert_cmpint(equality, ==, 0);
669 cpml_primitive_put_point(&primitive, 0, &pair);
670 pair.x += 1;
671 cpml_primitive_set_point(&primitive, 0, &pair);
672 equality = memcmp(original.data, segment->data, data_size);
673 g_assert_cmpint(equality, !=, 0);
674 pair.x -= 1;
675 cpml_primitive_set_point(&primitive, 0, &pair);
676 equality = memcmp(original.data, segment->data, data_size);
677 g_assert_cmpint(equality, ==, 0);
678 cpml_primitive_put_point(&primitive, 1, &pair);
679 pair.y += 1;
680 cpml_primitive_set_point(&primitive, 1, &pair);
681 equality = memcmp(original.data, segment->data, data_size);
682 g_assert_cmpint(equality, !=, 0);
683 /* On a CPML_LINE primitives, -1 and 1 indices are equals */
684 cpml_primitive_put_point(&primitive, -1, &pair2);
685 g_assert_cmpfloat(pair.x, ==, pair2.x);
686 g_assert_cmpfloat(pair.y, ==, pair2.y);
687 memcpy(segment->data, original.data, data_size);
688 equality = memcmp(original.data, segment->data, data_size);
689 g_assert_cmpint(equality, ==, 0);
690 cpml_primitive_put_point(&primitive, 2, &pair);
691 pair.x += 1;
692 pair.y += 1;
693 /* This should be a NOP without segfaults */
694 cpml_primitive_set_point(&primitive, 2, &pair);
695 equality = memcmp(original.data, segment->data, data_size);
696 g_assert_cmpint(equality, ==, 0);
698 /* From now on, memcpy() is assumed to force equality (as already
699 * proved by the previous assertions) and pair2 is used as a
700 * different-from-everything pair, that is setting pair2 on any
701 * point will break the equality between segment->data and
702 * original.data
704 pair2.x = 12345;
705 pair2.y = 54321;
707 /* Arc */
708 cpml_primitive_next(&primitive);
710 cpml_primitive_set_point(&primitive, 0, &pair2);
711 equality = memcmp(original.data, segment->data, data_size);
712 g_assert_cmpint(equality, !=, 0);
713 memcpy(segment->data, original.data, data_size);
714 cpml_primitive_set_point(&primitive, 1, &pair2);
715 equality = memcmp(original.data, segment->data, data_size);
716 g_assert_cmpint(equality, !=, 0);
717 memcpy(segment->data, original.data, data_size);
718 cpml_primitive_set_point(&primitive, 2, &pair2);
719 equality = memcmp(original.data, segment->data, data_size);
720 g_assert_cmpint(equality, !=, 0);
721 memcpy(segment->data, original.data, data_size);
722 cpml_primitive_set_point(&primitive, 3, &pair2);
723 equality = memcmp(original.data, segment->data, data_size);
724 g_assert_cmpint(equality, ==, 0);
726 /* Curve */
727 cpml_primitive_next(&primitive);
729 cpml_primitive_set_point(&primitive, 0, &pair2);
730 equality = memcmp(original.data, segment->data, data_size);
731 g_assert_cmpint(equality, !=, 0);
732 memcpy(segment->data, original.data, data_size);
733 cpml_primitive_set_point(&primitive, 1, &pair2);
734 equality = memcmp(original.data, segment->data, data_size);
735 g_assert_cmpint(equality, !=, 0);
736 memcpy(segment->data, original.data, data_size);
737 cpml_primitive_set_point(&primitive, 2, &pair2);
738 equality = memcmp(original.data, segment->data, data_size);
739 g_assert_cmpint(equality, !=, 0);
740 memcpy(segment->data, original.data, data_size);
741 cpml_primitive_set_point(&primitive, 3, &pair2);
742 equality = memcmp(original.data, segment->data, data_size);
743 g_assert_cmpint(equality, !=, 0);
744 memcpy(segment->data, original.data, data_size);
745 cpml_primitive_set_point(&primitive, 4, &pair2);
746 equality = memcmp(original.data, segment->data, data_size);
747 g_assert_cmpint(equality, ==, 0);
749 /* Close */
750 cpml_primitive_next(&primitive);
752 cpml_primitive_set_point(&primitive, 0, &pair2);
753 equality = memcmp(original.data, segment->data, data_size);
754 g_assert_cmpint(equality, !=, 0);
755 memcpy(segment->data, original.data, data_size);
756 cpml_primitive_set_point(&primitive, 1, &pair2);
757 equality = memcmp(original.data, segment->data, data_size);
758 g_assert_cmpint(equality, !=, 0);
759 memcpy(segment->data, original.data, data_size);
760 cpml_primitive_set_point(&primitive, 2, &pair2);
761 equality = memcmp(original.data, segment->data, data_size);
762 g_assert_cmpint(equality, ==, 0);
764 g_free(segment);
767 static void
768 _cpml_test_put_point(void)
770 CpmlSegment segment;
771 CpmlPrimitive primitive;
772 CpmlPair pair;
774 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
776 /* Line */
777 cpml_primitive_from_segment(&primitive, &segment);
779 cpml_primitive_put_point(&primitive, 0, &pair);
780 g_assert_cmpfloat(pair.x, ==, 0);
781 g_assert_cmpfloat(pair.y, ==, 1);
782 cpml_primitive_put_point(&primitive, 1, &pair);
783 g_assert_cmpfloat(pair.x, ==, 3);
784 g_assert_cmpfloat(pair.y, ==, 1);
785 cpml_primitive_put_point(&primitive, 2, &pair);
786 g_assert_cmpfloat(pair.x, ==, 3);
787 g_assert_cmpfloat(pair.y, ==, 1);
788 /* The negative indices are checked only against CPML_LINE */
789 cpml_primitive_put_point(&primitive, -1, &pair);
790 g_assert_cmpfloat(pair.x, ==, 3);
791 g_assert_cmpfloat(pair.y, ==, 1);
792 cpml_primitive_put_point(&primitive, -2, &pair);
793 g_assert_cmpfloat(pair.x, ==, 0);
794 g_assert_cmpfloat(pair.y, ==, 1);
795 cpml_primitive_put_point(&primitive, -3, &pair);
796 g_assert_cmpfloat(pair.x, ==, 0);
797 g_assert_cmpfloat(pair.y, ==, 1);
799 /* Arc */
800 cpml_primitive_next(&primitive);
802 cpml_primitive_put_point(&primitive, 0, &pair);
803 g_assert_cmpfloat(pair.x, ==, 3);
804 g_assert_cmpfloat(pair.y, ==, 1);
805 cpml_primitive_put_point(&primitive, 1, &pair);
806 g_assert_cmpfloat(pair.x, ==, 4);
807 g_assert_cmpfloat(pair.y, ==, 5);
808 cpml_primitive_put_point(&primitive, 2, &pair);
809 g_assert_cmpfloat(pair.x, ==, 6);
810 g_assert_cmpfloat(pair.y, ==, 7);
811 cpml_primitive_put_point(&primitive, 3, &pair);
812 g_assert_cmpfloat(pair.x, ==, 6);
813 g_assert_cmpfloat(pair.y, ==, 7);
815 /* Curve */
816 cpml_primitive_next(&primitive);
818 cpml_primitive_put_point(&primitive, 0, &pair);
819 g_assert_cmpfloat(pair.x, ==, 6);
820 g_assert_cmpfloat(pair.y, ==, 7);
821 cpml_primitive_put_point(&primitive, 1, &pair);
822 g_assert_cmpfloat(pair.x, ==, 8);
823 g_assert_cmpfloat(pair.y, ==, 9);
824 cpml_primitive_put_point(&primitive, 2, &pair);
825 g_assert_cmpfloat(pair.x, ==, 10);
826 g_assert_cmpfloat(pair.y, ==, 11);
827 cpml_primitive_put_point(&primitive, 3, &pair);
828 g_assert_cmpfloat(pair.x, ==, -2);
829 g_assert_cmpfloat(pair.y, ==, 2);
830 cpml_primitive_put_point(&primitive, 4, &pair);
831 g_assert_cmpfloat(pair.x, ==, -2);
832 g_assert_cmpfloat(pair.y, ==, 2);
834 /* Close */
835 cpml_primitive_next(&primitive);
837 cpml_primitive_put_point(&primitive, 0, &pair);
838 g_assert_cmpfloat(pair.x, ==, -2);
839 g_assert_cmpfloat(pair.y, ==, 2);
840 cpml_primitive_put_point(&primitive, 1, &pair);
841 g_assert_cmpfloat(pair.x, ==, 0);
842 g_assert_cmpfloat(pair.y, ==, 1);
843 cpml_primitive_put_point(&primitive, 2, &pair);
844 g_assert_cmpfloat(pair.x, ==, 0);
845 g_assert_cmpfloat(pair.y, ==, 1);
848 static void
849 _cpml_test_put_intersections(void)
851 CpmlSegment segment;
852 CpmlPrimitive primitive1, primitive2;
853 CpmlPair pair[2];
855 /* Set primitive1 to 1.1 (first segment, first primitive) */
856 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
857 cpml_primitive_from_segment(&primitive1, &segment);
859 /* Set primitive2 to 2.1 (second segment, first primitive) */
860 cpml_segment_next(&segment);
861 cpml_primitive_from_segment(&primitive2, &segment);
863 /* primitive1 (1.1) does not intersect primitive2 (2.1) */
864 g_assert_cmpuint(cpml_primitive_put_intersections(&primitive1, &primitive2, 2, pair), ==, 0);
866 cpml_primitive_next(&primitive2);
868 /* primitive1 (1.1) intersects primitive2 (2.2) in (1, 1) */
869 g_assert_cmpuint(cpml_primitive_put_intersections(&primitive1, &primitive2, 2, pair), ==, 1);
870 g_assert_cmpfloat(pair[0].x, ==, 1);
871 g_assert_cmpfloat(pair[0].y, ==, 1);
872 g_assert_cmpint(cpml_primitive_is_inside(&primitive1, pair), ==, 1);
873 g_assert_cmpint(cpml_primitive_is_inside(&primitive2, pair), ==, 1);
875 /* Check the intersection is not returned when not requested */
876 g_assert_cmpuint(cpml_primitive_put_intersections(&primitive1, &primitive2, 0, pair), ==, 0);
878 cpml_primitive_next(&primitive1);
880 /* primitive1 (1.2) does not intersect primitive2 (2.2) */
881 g_assert_cmpuint(cpml_primitive_put_intersections(&primitive1, &primitive2, 2, pair), ==, 0);
883 cpml_primitive_next(&primitive1);
885 /* primitive1 (1.3) does not intersect primitive2 (2.2) */
886 g_assert_cmpuint(cpml_primitive_put_intersections(&primitive1, &primitive2, 2, pair), ==, 0);
888 cpml_primitive_next(&primitive1);
890 /* primitive1 (1.4) intersects primitive2 (2.2), but outside their boundaries */
891 g_assert_cmpuint(cpml_primitive_put_intersections(&primitive1, &primitive2, 2, pair), ==, 1);
892 g_assert_cmpfloat(pair[0].x, ==, 1);
893 g_assert_cmpfloat(pair[0].y, ==, -1);
894 g_assert_cmpint(cpml_primitive_is_inside(&primitive1, pair), ==, 0);
895 g_assert_cmpint(cpml_primitive_is_inside(&primitive2, pair), ==, 0);
898 static void
899 _cpml_test_put_intersections_with_segment(void)
901 CpmlSegment segment;
902 CpmlPrimitive primitive;
903 CpmlPair pair[4];
905 /* Set primitive to first segment, first primitive */
906 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
907 cpml_primitive_from_segment(&primitive, &segment);
909 /* Set segment to the second segment */
910 cpml_segment_next(&segment);
912 /* primitive (1.1) intersects segment (2) in (1, 1) */
913 g_assert_cmpuint(cpml_primitive_put_intersections_with_segment(&primitive, &segment, 4, pair), ==, 1);
914 g_assert_cmpfloat(pair[0].x, ==, 1);
915 g_assert_cmpfloat(pair[0].y, ==, 1);
917 cpml_primitive_next(&primitive);
919 /* primitive (1.1) does not intersect segment (2) */
920 g_assert_cmpuint(cpml_primitive_put_intersections_with_segment(&primitive, &segment, 4, pair), ==, 0);
922 /* Set primitive to second segment, first primitive */
923 cpml_primitive_from_segment(&primitive, &segment);
925 /* Set segment to the first segment */
926 cpml_segment_reset(&segment);
928 /* primitive (2.1) intersects segment (1) in extrapolation.
929 * TODO: change this behavior! They must not intersect. */
930 g_assert_cmpuint(cpml_primitive_put_intersections_with_segment(&primitive, &segment, 4, pair), ==, 1);
931 g_assert_cmpfloat(pair[0].x, ==, 2);
932 g_assert_cmpfloat(pair[0].y, ==, 0);
934 cpml_primitive_next(&primitive);
936 /* primitive (2.2) wrongly intersects segment (1) */
937 g_assert_cmpuint(cpml_primitive_put_intersections_with_segment(&primitive, &segment, 4, pair), ==, 1);
938 g_assert_cmpfloat(pair[0].x, ==, 2);
939 g_assert_cmpfloat(pair[0].y, ==, 0);
942 static void
943 _cpml_test_join(void)
945 cairo_path_data_t path_data[] = {
946 { .header = { CPML_MOVE, 2 }},
947 { .point = { 0, 0 }},
949 { .header = { CPML_LINE, 2 }},
950 { .point = { 2, 0 }},
952 { .header = { CPML_LINE, 2 }},
953 { .point = { 2, 2 }},
955 { .header = { CPML_LINE, 2 }},
956 { .point = { 1, 2 }},
958 { .header = { CPML_LINE, 2 }},
959 { .point = { 1, -2 }}
961 cairo_path_t path = {
962 CAIRO_STATUS_SUCCESS,
963 path_data,
964 G_N_ELEMENTS(path_data)
966 CpmlSegment segment;
967 CpmlPrimitive primitive1, primitive2;
969 cpml_segment_from_cairo(&segment, &path);
971 cpml_primitive_from_segment(&primitive1, &segment);
972 cpml_primitive_copy(&primitive2, &primitive1);
973 cpml_primitive_next(&primitive2);
975 /* primitive1 and primitive2 are already joint */
976 g_assert_cmpint(cpml_primitive_join(&primitive1, &primitive2), ==, 1);
977 g_assert_cmpfloat((primitive2.org)->point.x, ==, 2);
978 g_assert_cmpfloat((primitive2.org)->point.y, ==, 0);
980 cpml_primitive_next(&primitive2);
981 /* Now primitive1 and primitive2 are divergent,
982 * hence cannot be joined */
983 g_assert_cmpint(cpml_primitive_join(&primitive1, &primitive2), ==, 0);
985 cpml_primitive_next(&primitive2);
986 g_assert_cmpint(cpml_primitive_join(&primitive1, &primitive2), ==, 1);
987 g_assert_cmpfloat((primitive2.org)->point.x, ==, 1);
988 g_assert_cmpfloat((primitive2.org)->point.y, ==, 0);
991 static void
992 _cpml_test_to_cairo(void)
994 cairo_t *cr;
995 CpmlSegment segment;
996 CpmlPrimitive primitive;
997 int length, last_length;
999 cr = adg_test_cairo_context();
1000 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
1001 cpml_primitive_from_segment(&primitive, &segment);
1003 g_assert_cmpint(adg_test_cairo_num_data(cr), ==, 0);
1005 length = 0;
1006 do {
1007 last_length = length;
1008 cpml_primitive_to_cairo(&primitive, cr);
1009 length = adg_test_cairo_num_data(cr);
1010 g_assert_cmpint(length, >, last_length);
1011 } while (cpml_primitive_next(&primitive));
1013 cairo_destroy(cr);
1016 static void
1017 _cpml_test_dump(gint i)
1019 CpmlSegment segment;
1020 CpmlPrimitive primitive;
1022 switch (i) {
1023 case 1:
1024 cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
1025 cpml_primitive_from_segment(&primitive, &segment);
1026 cpml_primitive_dump(&primitive, 1);
1028 cpml_primitive_next(&primitive);
1029 cpml_primitive_dump(&primitive, 1);
1030 break;
1031 case 2:
1032 g_test_trap_assert_passed();
1033 g_test_trap_assert_stderr_unmatched("?");
1034 g_test_trap_assert_stdout("*NULL*");
1035 g_test_trap_assert_stdout("*move*");
1036 g_test_trap_assert_stdout("*line*");
1042 main(int argc, char *argv[])
1044 adg_test_init(&argc, &argv);
1046 g_test_add_func("/cpml/primitive/behavior/browsing", _cpml_test_browsing);
1048 adg_test_add_traps("/cpml/primitive/sanity/from-segment", _cpml_test_sanity_from_segment, 1);
1049 adg_test_add_traps("/cpml/primitive/sanity/copy", _cpml_test_sanity_copy, 2);
1050 adg_test_add_traps("/cpml/primitive/sanity/get-n-points", _cpml_test_sanity_get_n_points, 1);
1051 adg_test_add_traps("/cpml/primitive/sanity/get-length", _cpml_test_sanity_get_length, 1);
1052 adg_test_add_traps("/cpml/primitive/sanity/put-extents", _cpml_test_sanity_put_extents, 2);
1053 adg_test_add_traps("/cpml/primitive/sanity/put-pair-at", _cpml_test_sanity_put_pair_at, 2);
1054 adg_test_add_traps("/cpml/primitive/sanity/put-vector-at", _cpml_test_sanity_put_vector_at, 2);
1055 adg_test_add_traps("/cpml/primitive/sanity/set-point", _cpml_test_sanity_set_point, 2);
1056 adg_test_add_traps("/cpml/primitive/sanity/put-point", _cpml_test_sanity_put_point, 2);
1057 adg_test_add_traps("/cpml/primitive/sanity/put-intersections", _cpml_test_sanity_put_intersections, 3);
1058 adg_test_add_traps("/cpml/primitive/sanity/put-intersections-with-segment", _cpml_test_sanity_put_intersections_with_segment, 3);
1059 adg_test_add_traps("/cpml/primitive/sanity/join", _cpml_test_sanity_join, 2);
1060 adg_test_add_traps("/cpml/primitive/sanity/to-cairo", _cpml_test_sanity_to_cairo, 2);
1061 adg_test_add_traps("/cpml/primitive/sanity/dump", _cpml_test_sanity_dump, 1);
1063 g_test_add_func("/cpml/primitive/method/from-segment", _cpml_test_from_segment);
1064 g_test_add_func("/cpml/primitive/method/copy", _cpml_test_copy);
1065 g_test_add_func("/cpml/primitive/method/type-get-n-points", _cpml_test_type_get_n_points);
1066 g_test_add_func("/cpml/primitive/method/get-n-points", _cpml_test_get_n_points);
1067 g_test_add_func("/cpml/primitive/method/get-length", _cpml_test_get_length);
1068 g_test_add_func("/cpml/primitive/method/put-extents", _cpml_test_put_extents);
1069 g_test_add_func("/cpml/primitive/method/put-pair-at", _cpml_test_put_pair_at);
1070 g_test_add_func("/cpml/primitive/method/put-vector-at", _cpml_test_put_vector_at);
1071 g_test_add_func("/cpml/primitive/method/set-point", _cpml_test_set_point);
1072 g_test_add_func("/cpml/primitive/method/put-point", _cpml_test_put_point);
1073 g_test_add_func("/cpml/primitive/method/put-intersections", _cpml_test_put_intersections);
1074 g_test_add_func("/cpml/primitive/method/put-intersections-with-segment", _cpml_test_put_intersections_with_segment);
1075 g_test_add_func("/cpml/primitive/method/join", _cpml_test_join);
1076 g_test_add_func("/cpml/primitive/method/to-cairo", _cpml_test_to_cairo);
1077 adg_test_add_traps("/cpml/primitive/method/dump", _cpml_test_dump, 1);
1079 return g_test_run();