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.
26 _cpml_test_browsing(void)
29 g_assert_cmpint(cpml_segment_from_cairo(&segment
, (cairo_path_t
*) adg_test_path()), ==, 1);
32 g_assert_cmpint(segment
.data
[0].header
.type
, ==, CPML_MOVE
);
33 g_assert_cmpint(segment
.data
[2].header
.type
, ==, CPML_LINE
);
35 cpml_segment_reset(&segment
);
36 cpml_segment_reset(&segment
);
37 g_assert_cmpint(segment
.num_data
, ==, 12);
38 g_assert_cmpint(segment
.data
[0].header
.type
, ==, CPML_MOVE
);
39 g_assert_cmpint(segment
.data
[2].header
.type
, ==, CPML_LINE
);
40 g_assert_cmpint(segment
.data
[4].header
.type
, ==, CPML_ARC
);
41 g_assert_cmpint(segment
.data
[7].header
.type
, ==, CPML_CURVE
);
42 g_assert_cmpint(segment
.data
[11].header
.type
, ==, CPML_CLOSE
);
45 g_assert_cmpint(cpml_segment_next(&segment
), ==, 1);
46 g_assert_cmpint(segment
.num_data
, ==, 6);
47 g_assert_cmpint(segment
.data
[0].header
.type
, ==, CPML_MOVE
);
48 g_assert_cmpint(segment
.data
[2].header
.type
, ==, CPML_LINE
);
49 g_assert_cmpint(segment
.data
[4].header
.type
, ==, CPML_LINE
);
52 g_assert_cmpint(cpml_segment_next(&segment
), ==, 1);
53 g_assert_cmpint(segment
.num_data
, ==, 7);
54 g_assert_cmpint(segment
.data
[0].header
.type
, ==, CPML_MOVE
);
55 g_assert_cmpint(segment
.data
[2].header
.type
, ==, CPML_CURVE
);
56 g_assert_cmpint(segment
.data
[6].header
.type
, ==, CPML_CLOSE
);
59 g_assert_cmpint(cpml_segment_next(&segment
), ==, 1);
60 g_assert_cmpint(segment
.num_data
, ==, 8);
61 g_assert_cmpint(segment
.data
[0].header
.type
, ==, CPML_MOVE
);
62 g_assert_cmpint(segment
.data
[2].header
.type
, ==, CPML_ARC
);
63 g_assert_cmpint(segment
.data
[5].header
.type
, ==, CPML_ARC
);
66 g_assert_cmpint(cpml_segment_next(&segment
), ==, 1);
67 g_assert_cmpint(segment
.num_data
, ==, 3);
68 g_assert_cmpint(segment
.data
[0].header
.type
, ==, CPML_MOVE
);
69 g_assert_cmpint(segment
.data
[2].header
.type
, ==, CPML_CLOSE
);
71 g_assert_cmpint(cpml_segment_next(&segment
), ==, 0);
73 cpml_segment_reset(&segment
);
74 g_assert_cmpint(segment
.num_data
, ==, 12);
78 _cpml_test_sanity_from_cairo(gint i
)
80 cairo_path_t
*path
= (cairo_path_t
*) adg_test_path();
85 cpml_segment_from_cairo(NULL
, path
);
88 cpml_segment_from_cairo(&segment
, NULL
);
91 g_test_trap_assert_failed();
97 _cpml_test_sanity_get_length(gint i
)
101 cpml_segment_get_length(NULL
);
104 g_test_trap_assert_failed();
110 _cpml_test_sanity_put_intersections(gint i
)
112 CpmlSegment segment1
, segment2
;
115 /* Segment 1 and segment 2 intersects at least in (1,1) */
116 cpml_segment_from_cairo(&segment1
, (cairo_path_t
*) adg_test_path());
117 cpml_segment_copy(&segment2
, &segment1
);
118 cpml_segment_next(&segment2
);
122 cpml_segment_put_intersections(NULL
, &segment2
, 2, &pair
);
125 cpml_segment_put_intersections(&segment1
, NULL
, 2, &pair
);
128 cpml_segment_put_intersections(&segment1
, &segment2
, 2, NULL
);
131 g_test_trap_assert_failed();
137 _cpml_test_sanity_offset(gint i
)
141 cpml_segment_offset(NULL
, 1);
144 g_test_trap_assert_failed();
150 _cpml_test_sanity_transform(gint i
)
153 cairo_matrix_t matrix
;
155 cpml_segment_from_cairo(&segment
, (cairo_path_t
*) adg_test_path());
156 cairo_matrix_init_identity(&matrix
);
160 cpml_segment_transform(NULL
, &matrix
);
163 cpml_segment_transform(&segment
, NULL
);
166 g_test_trap_assert_failed();
172 _cpml_test_sanity_reverse(gint i
)
176 cpml_segment_reverse(NULL
);
179 g_test_trap_assert_failed();
185 _cpml_test_sanity_to_cairo(gint i
)
189 cpml_segment_from_cairo(&segment
, (cairo_path_t
*) adg_test_path());
193 cpml_segment_to_cairo(NULL
, adg_test_cairo_context());
196 cpml_segment_to_cairo(&segment
, NULL
);
198 g_test_trap_assert_failed();
204 _cpml_test_sanity_dump(gint i
)
208 cpml_segment_dump(NULL
);
211 g_test_trap_assert_failed();
217 _cpml_test_from_cairo(void)
220 cairo_path_data_t noop_data
[] = {
221 /* Useless heading primitives */
222 { .header
= { CPML_MOVE
, 2 }},
223 { .point
= { 0, 1 }},
224 { .header
= { CPML_MOVE
, 4 }},
225 { .point
= { 2, 3 }},
226 { .point
= { 4, 5 }},
227 { .point
= { 6, 7 }},
228 { .header
= { CPML_MOVE
, 2 }},
231 cairo_path_data_t invalid_primitive
[] = {
232 { .header
= { CPML_MOVE
, 2 }},
233 { .point
= { 0, 1 }},
234 { .header
= { CPML_ARC
, 2 }}, /* Should be CPML_ARC, 3 */
237 cairo_path_t noop_path
= {
238 CAIRO_STATUS_SUCCESS
,
240 G_N_ELEMENTS(noop_data
)
242 cairo_path_t empty_path
= {
243 CAIRO_STATUS_SUCCESS
,
244 adg_test_path()->data
,
247 cairo_path_t basic_path
= {
248 CAIRO_STATUS_SUCCESS
,
249 adg_test_path()->data
,
252 cairo_path_t invalid_path1
= {
253 CAIRO_STATUS_SUCCESS
,
254 adg_test_path()->data
,
257 cairo_path_t invalid_path2
= {
258 CAIRO_STATUS_SUCCESS
,
260 G_N_ELEMENTS(invalid_primitive
)
263 g_assert_cmpint(cpml_segment_from_cairo(&segment
, &noop_path
), ==, 0);
264 g_assert_cmpint(cpml_segment_from_cairo(&segment
, &empty_path
), ==, 0);
265 g_assert_cmpint(cpml_segment_from_cairo(&segment
, &basic_path
), ==, 1);
266 g_assert_cmpint(cpml_segment_from_cairo(&segment
, &invalid_path1
), ==, 0);
267 g_assert_cmpint(cpml_segment_from_cairo(&segment
, &invalid_path2
), ==, 0);
268 g_assert_cmpint(cpml_segment_from_cairo(&segment
, (cairo_path_t
*) adg_test_path()), ==, 1);
272 _cpml_test_get_length(void)
276 cpml_segment_from_cairo(&segment
, (cairo_path_t
*) adg_test_path());
278 /* First segment: not a round number so avoiding == */
279 g_assert_cmpfloat(cpml_segment_get_length(&segment
), >, 0);
281 cpml_segment_next(&segment
);
284 g_assert_cmpfloat(cpml_segment_get_length(&segment
), ==, 3);
285 g_assert_cmpfloat(cpml_segment_get_length(&segment
), ==, 3);
287 cpml_segment_next(&segment
);
290 /* TODO: Bézier curve length not yet implemented
291 * g_assert_cmpfloat(cpml_segment_get_length(&segment), >, 0); */
293 cpml_segment_next(&segment
);
296 adg_assert_isapprox(cpml_segment_get_length(&segment
), 13.114);
298 cpml_segment_next(&segment
);
301 g_assert_cmpfloat(cpml_segment_get_length(&segment
), ==, 0);
305 _cpml_test_put_intersections(void)
307 CpmlSegment segment1
, segment2
;
310 cpml_segment_from_cairo(&segment1
, (cairo_path_t
*) adg_test_path());
311 cpml_segment_copy(&segment2
, &segment1
);
313 cpml_segment_next(&segment2
);
315 /* The first segment intersects the second segment in (1, 1).
316 * TODO: avoid extrapolated intersections! Check
317 * cpml_primitive_put_intersections */
318 g_assert_cmpuint(cpml_segment_put_intersections(&segment1
, &segment2
, 10, pair
), ==, 3);
319 g_assert_cmpfloat(pair
[0].x
, ==, 1);
320 g_assert_cmpfloat(pair
[0].y
, ==, 1);
321 g_assert_cmpfloat(pair
[1].x
, ==, 2);
322 g_assert_cmpfloat(pair
[1].y
, ==, 0);
324 cpml_segment_next(&segment2
);
326 g_assert_cmpuint(cpml_segment_put_intersections(&segment1
, &segment2
, 10, pair
), ==, 1);
330 _cpml_test_offset(void)
332 CpmlSegment original
, *segment
;
334 /* Work on a copy to avoid modifying adg_test_path() data */
335 cpml_segment_from_cairo(&original
, (cairo_path_t
*) adg_test_path());
336 segment
= cpml_segment_deep_dup(&original
);
338 /* TODO: provide tests for arcs and curves */
339 cpml_segment_offset(segment
, 1);
342 cpml_segment_next(&original
);
343 segment
= cpml_segment_deep_dup(&original
);
344 cpml_segment_offset(segment
, 1);
346 g_assert_cmpint(segment
->data
[0].header
.type
, ==, CPML_MOVE
);
347 g_assert_cmpfloat(segment
->data
[1].point
.x
, ==, 0);
348 g_assert_cmpfloat(segment
->data
[1].point
.y
, ==, 1);
350 g_assert_cmpint(segment
->data
[2].header
.type
, ==, CPML_LINE
);
351 g_assert_cmpfloat(segment
->data
[3].point
.x
, ==, 0);
352 g_assert_cmpfloat(segment
->data
[3].point
.y
, ==, 1);
354 g_assert_cmpint(segment
->data
[4].header
.type
, ==, CPML_LINE
);
355 g_assert_cmpfloat(segment
->data
[5].point
.x
, ==, 0);
356 g_assert_cmpfloat(segment
->data
[5].point
.y
, ==, 2);
362 _cpml_test_transform(void)
364 CpmlSegment original
, *segment
;
365 cairo_matrix_t matrix
;
367 /* Work on a copy to avoid modifying adg_test_path() data */
368 cpml_segment_from_cairo(&original
, (cairo_path_t
*) adg_test_path());
369 segment
= cpml_segment_deep_dup(&original
);
371 cairo_matrix_init_translate(&matrix
, 1, 2);
372 cpml_segment_transform(segment
, &matrix
);
374 g_assert_cmpint(segment
->data
[0].header
.type
, ==, CPML_MOVE
);
375 g_assert_cmpfloat(segment
->data
[1].point
.x
, ==, 1);
376 g_assert_cmpfloat(segment
->data
[1].point
.y
, ==, 3);
378 g_assert_cmpint(segment
->data
[2].header
.type
, ==, CPML_LINE
);
379 g_assert_cmpfloat(segment
->data
[3].point
.x
, ==, 4);
380 g_assert_cmpfloat(segment
->data
[3].point
.y
, ==, 3);
382 g_assert_cmpint(segment
->data
[4].header
.type
, ==, CPML_ARC
);
383 g_assert_cmpfloat(segment
->data
[5].point
.x
, ==, 5);
384 g_assert_cmpfloat(segment
->data
[5].point
.y
, ==, 7);
385 g_assert_cmpfloat(segment
->data
[6].point
.x
, ==, 7);
386 g_assert_cmpfloat(segment
->data
[6].point
.y
, ==, 9);
388 g_assert_cmpint(segment
->data
[7].header
.type
, ==, CPML_CURVE
);
389 g_assert_cmpfloat(segment
->data
[8].point
.x
, ==, 9);
390 g_assert_cmpfloat(segment
->data
[8].point
.y
, ==, 11);
391 g_assert_cmpfloat(segment
->data
[9].point
.x
, ==, 11);
392 g_assert_cmpfloat(segment
->data
[9].point
.y
, ==, 13);
393 g_assert_cmpfloat(segment
->data
[10].point
.x
, ==, -1);
394 g_assert_cmpfloat(segment
->data
[10].point
.y
, ==, 4);
396 g_assert_cmpint(segment
->data
[11].header
.type
, ==, CPML_CLOSE
);
403 _cpml_test_reverse(void)
405 CpmlSegment original
, *segment
;
407 /* Work on a copy to avoid modifying adg_test_path() data */
408 cpml_segment_from_cairo(&original
, (cairo_path_t
*) adg_test_path());
409 segment
= cpml_segment_deep_dup(&original
);
412 cpml_segment_reverse(segment
);
414 g_assert_cmpint(segment
->num_data
, ==, 12);
416 g_assert_cmpint(segment
->data
[0].header
.type
, ==, CPML_MOVE
);
417 g_assert_cmpfloat(segment
->data
[1].point
.x
, ==, -2);
418 g_assert_cmpfloat(segment
->data
[1].point
.y
, ==, 2);
420 g_assert_cmpint(segment
->data
[2].header
.type
, ==, CPML_CURVE
);
421 g_assert_cmpfloat(segment
->data
[3].point
.x
, ==, 10);
422 g_assert_cmpfloat(segment
->data
[3].point
.y
, ==, 11);
423 g_assert_cmpfloat(segment
->data
[4].point
.x
, ==, 8);
424 g_assert_cmpfloat(segment
->data
[4].point
.y
, ==, 9);
425 g_assert_cmpfloat(segment
->data
[5].point
.x
, ==, 6);
426 g_assert_cmpfloat(segment
->data
[5].point
.y
, ==, 7);
428 g_assert_cmpint(segment
->data
[6].header
.type
, ==, CPML_ARC
);
429 g_assert_cmpfloat(segment
->data
[7].point
.x
, ==, 4);
430 g_assert_cmpfloat(segment
->data
[7].point
.y
, ==, 5);
431 g_assert_cmpfloat(segment
->data
[8].point
.x
, ==, 3);
432 g_assert_cmpfloat(segment
->data
[8].point
.y
, ==, 1);
434 g_assert_cmpint(segment
->data
[9].header
.type
, ==, CPML_LINE
);
435 g_assert_cmpfloat(segment
->data
[10].point
.x
, ==, 0);
436 g_assert_cmpfloat(segment
->data
[10].point
.y
, ==, 1);
438 g_assert_cmpint(segment
->data
[11].header
.type
, ==, CPML_CLOSE
);
444 _cpml_test_to_cairo(void)
448 int length
, last_length
;
450 cr
= adg_test_cairo_context();
451 cpml_segment_from_cairo(&segment
, (cairo_path_t
*) adg_test_path());
453 g_assert_cmpint(adg_test_cairo_num_data(cr
), ==, 0);
457 last_length
= length
;
458 cpml_segment_to_cairo(&segment
, cr
);
459 length
= adg_test_cairo_num_data(cr
);
460 g_assert_cmpint(length
, >, last_length
);
461 } while (cpml_segment_next(&segment
));
467 _cpml_test_dump(gint i
)
473 cpml_segment_from_cairo(&segment
, (cairo_path_t
*) adg_test_path());
474 cpml_segment_dump(&segment
);
477 g_test_trap_assert_passed();
478 g_test_trap_assert_stderr_unmatched("?");
479 g_test_trap_assert_stdout("*move*line*arc*curve*close*");
486 main(int argc
, char *argv
[])
488 adg_test_init(&argc
, &argv
);
490 g_test_add_func("/cpml/segment/behavior/browsing", _cpml_test_browsing
);
492 adg_test_add_traps("/cpml/segment/sanity/from-cairo", _cpml_test_sanity_from_cairo
, 2);
493 adg_test_add_traps("/cpml/segment/sanity/get-length", _cpml_test_sanity_get_length
, 1);
494 adg_test_add_traps("/cpml/segment/sanity/put-intersections", _cpml_test_sanity_put_intersections
, 3);
495 adg_test_add_traps("/cpml/segment/sanity/offset", _cpml_test_sanity_offset
, 1);
496 adg_test_add_traps("/cpml/segment/sanity/transform", _cpml_test_sanity_transform
, 2);
497 adg_test_add_traps("/cpml/segment/sanity/reverse", _cpml_test_sanity_reverse
, 1);
498 adg_test_add_traps("/cpml/segment/sanity/to-cairo", _cpml_test_sanity_to_cairo
, 2);
499 adg_test_add_traps("/cpml/segment/sanity/dump", _cpml_test_sanity_dump
, 1);
501 g_test_add_func("/cpml/segment/method/from-cairo", _cpml_test_from_cairo
);
502 g_test_add_func("/cpml/segment/method/get-length", _cpml_test_get_length
);
503 g_test_add_func("/cpml/segment/method/put-intersections", _cpml_test_put_intersections
);
504 g_test_add_func("/cpml/segment/method/offset", _cpml_test_offset
);
505 g_test_add_func("/cpml/segment/method/transform", _cpml_test_transform
);
506 g_test_add_func("/cpml/segment/method/reverse", _cpml_test_reverse
);
507 g_test_add_func("/cpml/segment/method/to-cairo", _cpml_test_to_cairo
);
508 adg_test_add_traps("/cpml/segment/method/dump", _cpml_test_dump
, 1);