1 /*
2 * Copyright (c) 2018-2019 Hanspeter Portner (dev@open-music-kontrollers.ch)
3 *
4 * This is free software: you can redistribute it and/or modify
5 * it under the terms of the Artistic License 2.0 as published by
6 * The Perl Foundation.
7 *
8 * This source is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * Artistic License 2.0 for more details.
12 *
13 * You should have received a copy of the Artistic License 2.0
14 * along the source as a COPYING file. If not, obtain it from
15 * http://www.perlfoundation.org/artistic_license_2_0.
16 */
17
18 #include <inttypes.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <assert.h>
22
23 #include <d2tk/core.h>
24 #include <d2tk/hash.h>
25 #include "mock.h"
26
27 static void
_test_hash()28 _test_hash()
29 {
30 const uint32_t bar = 12;
31 const char *foo = "barbarbarbar";
32
33 const uint64_t hash1 = d2tk_hash(&bar, sizeof(bar));
34 const uint64_t hash2 = d2tk_hash(foo, strlen(foo));
35
36 assert(hash1 != hash2);
37 }
38
39 static void
_test_hash_foreach()40 _test_hash_foreach()
41 {
42 const uint32_t bar = 12;
43 const char *foo = "foofoofoofoo";
44
45 const d2tk_hash_dict_t dict [] = {
46 { foo, strlen(foo) },
47 { &bar, sizeof(bar) },
48 { NULL, 0 }
49 };
50
51 const uint64_t hash1 = d2tk_hash_dict(dict);
52
53 const uint64_t hash2 = d2tk_hash_foreach(foo, strlen(foo),
54 &bar, sizeof(bar),
55 NULL);
56
57 assert(hash1 == hash2);
58 }
59
60 static void
_test_rect_shrink()61 _test_rect_shrink()
62 {
63 d2tk_rect_t dst;
64
65 // initialization
66 const d2tk_rect_t src = D2TK_RECT(1, 2, 3, 4);
67 assert(src.x == 1);
68 assert(src.y == 2);
69 assert(src.w == 3);
70 assert(src.h == 4);
71
72 // shrink on x-axis
73 memset(&dst, 0x0, sizeof(dst));
74 d2tk_rect_shrink_x(&dst, &src, 1);
75 assert(dst.x == 1 + 1);
76 assert(dst.y == 2);
77 assert(dst.w == 3 - 2*1);
78 assert(dst.h == 4);
79
80 // shrink on y-axis
81 memset(&dst, 0x0, sizeof(dst));
82 d2tk_rect_shrink_y(&dst, &src, 1);
83 assert(dst.x == 1);
84 assert(dst.y == 2 + 1);
85 assert(dst.w == 3);
86 assert(dst.h == 4 - 2*1);
87
88 // shrink on x/y-axes
89 memset(&dst, 0x0, sizeof(dst));
90 d2tk_rect_shrink(&dst, &src, 1);
91 assert(dst.x == 1 + 1);
92 assert(dst.y == 2 + 1);
93 assert(dst.w == 3 - 2*1);
94 assert(dst.h == 4 - 2*1);
95 }
96
97 static void
_test_point()98 _test_point()
99 {
100 // initialization
101 const d2tk_point_t src = D2TK_POINT(11, 22);
102 assert(src.x == 11);
103 assert(src.y == 22);
104 }
105
106 static void
_test_dimensions()107 _test_dimensions()
108 {
109 d2tk_coord_t w;
110 d2tk_coord_t h;
111
112 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, NULL);
113 assert(core);
114
115 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
116
117 w = 0;
118 h = 0;
119 d2tk_core_get_dimensions(core, &w, &h);
120 assert(w == DIM_W);
121 assert(h == DIM_H);
122
123 w = 0;
124 h = 0;
125 d2tk_core_get_dimensions(core, NULL, NULL);
126 assert(w == 0);
127 assert(h == 0);
128
129 d2tk_core_free(core);
130 }
131
132 #define BG_COLOR 0x222222ff
133
134 static void
_test_bg_color()135 _test_bg_color()
136 {
137 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, NULL);
138 assert(core);
139
140 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
141
142 d2tk_core_set_bg_color(core, BG_COLOR);
143 assert(BG_COLOR == d2tk_core_get_bg_color(core));
144
145 d2tk_core_free(core);
146 }
147
148 #undef BG_COLOR
149
150 #define MOVE_TO_X 10
151 #define MOVE_TO_Y 20
152
153 static void
_check_move_to(const d2tk_com_t * com,const d2tk_clip_t * clip)154 _check_move_to(const d2tk_com_t *com, const d2tk_clip_t *clip)
155 {
156 assert(clip->x0 == CLIP_X);
157 assert(clip->y0 == CLIP_Y);
158 assert(clip->x1 == CLIP_X + CLIP_W);
159 assert(clip->y1 == CLIP_Y + CLIP_H);
160 assert(clip->w == CLIP_W);
161 assert(clip->h == CLIP_H);
162
163 assert(com->size == sizeof(d2tk_body_move_to_t));
164 assert(com->instr == D2TK_INSTR_MOVE_TO);
165 assert(com->body->move_to.x == MOVE_TO_X - CLIP_X);
166 assert(com->body->move_to.y == MOVE_TO_Y - CLIP_Y);
167 }
168
169 static void
_test_move_to()170 _test_move_to()
171 {
172 d2tk_mock_ctx_t ctx = {
173 .check = _check_move_to
174 };
175
176 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
177 assert(core);
178
179 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
180
181 d2tk_core_pre(core, NULL);
182 const ssize_t ref = d2tk_core_bbox_push(core, true,
183 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
184 assert(ref >= 0);
185
186 d2tk_core_move_to(core, MOVE_TO_X, MOVE_TO_Y);
187
188 d2tk_core_bbox_pop(core, ref);
189 d2tk_core_post(core);
190
191 // trigger garbage collector
192 for(unsigned i = 0; i < 0x400; i++)
193 {
194 d2tk_core_pre(core, NULL);
195 d2tk_core_post(core);
196 }
197
198 d2tk_core_free(core);
199 }
200
201 #undef MOVE_TO_X
202 #undef MOVE_TO_Y
203
204 #define LINE_TO_X 10
205 #define LINE_TO_Y 20
206
207 static void
_check_line_to(const d2tk_com_t * com,const d2tk_clip_t * clip)208 _check_line_to(const d2tk_com_t *com, const d2tk_clip_t *clip)
209 {
210 assert(clip->x0 == CLIP_X);
211 assert(clip->y0 == CLIP_Y);
212 assert(clip->x1 == CLIP_X + CLIP_W);
213 assert(clip->y1 == CLIP_Y + CLIP_H);
214 assert(clip->w == CLIP_W);
215 assert(clip->h == CLIP_H);
216
217 assert(com->size == sizeof(d2tk_body_line_to_t));
218 assert(com->instr == D2TK_INSTR_LINE_TO);
219 assert(com->body->line_to.x == LINE_TO_X - CLIP_X);
220 assert(com->body->line_to.y == LINE_TO_Y - CLIP_Y);
221 }
222
223 static void
_test_line_to()224 _test_line_to()
225 {
226 d2tk_mock_ctx_t ctx = {
227 .check = _check_line_to
228 };
229
230 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
231 assert(core);
232
233 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
234
235 d2tk_core_pre(core, NULL);
236 const ssize_t ref = d2tk_core_bbox_push(core, true,
237 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
238 assert(ref >= 0);
239
240 d2tk_core_line_to(core, LINE_TO_X, LINE_TO_Y);
241
242 d2tk_core_bbox_pop(core, ref);
243 d2tk_core_post(core);
244 d2tk_core_free(core);
245 }
246
247 #undef LINE_TO_X
248 #undef LINE_TO_Y
249
250 #define RECT_X 10
251 #define RECT_Y 20
252 #define RECT_W 30
253 #define RECT_H 40
254
255 static void
_check_rect(const d2tk_com_t * com,const d2tk_clip_t * clip)256 _check_rect(const d2tk_com_t *com, const d2tk_clip_t *clip)
257 {
258 assert(clip->x0 == CLIP_X);
259 assert(clip->y0 == CLIP_Y);
260 assert(clip->x1 == CLIP_X + CLIP_W);
261 assert(clip->y1 == CLIP_Y + CLIP_H);
262 assert(clip->w == CLIP_W);
263 assert(clip->h == CLIP_H);
264
265 assert(com->size == sizeof(d2tk_body_rect_t));
266 assert(com->instr == D2TK_INSTR_RECT);
267 assert(com->body->rect.x == RECT_X - CLIP_X);
268 assert(com->body->rect.y == RECT_Y - CLIP_Y);
269 assert(com->body->rect.w == RECT_W);
270 assert(com->body->rect.h == RECT_H);
271 }
272
273 static void
_test_rect()274 _test_rect()
275 {
276 d2tk_mock_ctx_t ctx = {
277 .check = _check_rect
278 };
279
280 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
281 assert(core);
282
283 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
284
285 d2tk_core_pre(core, NULL);
286 const ssize_t ref = d2tk_core_bbox_push(core, true,
287 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
288 assert(ref >= 0);
289
290 d2tk_core_rect(core, &D2TK_RECT(RECT_X, RECT_Y, RECT_W, RECT_H));
291
292 d2tk_core_bbox_pop(core, ref);
293 d2tk_core_post(core);
294 d2tk_core_free(core);
295 }
296
297 #undef RECT_X
298 #undef RECT_Y
299 #undef RECT_W
300 #undef RECT_H
301
302 #define ROUNDED_RECT_X 10
303 #define ROUNDED_RECT_Y 20
304 #define ROUNDED_RECT_W 30
305 #define ROUNDED_RECT_H 40
306 #define ROUNDED_RECT_R 5
307
308 static void
_check_rounded_rect(const d2tk_com_t * com,const d2tk_clip_t * clip)309 _check_rounded_rect(const d2tk_com_t *com, const d2tk_clip_t *clip)
310 {
311 assert(clip->x0 == CLIP_X);
312 assert(clip->y0 == CLIP_Y);
313 assert(clip->x1 == CLIP_X + CLIP_W);
314 assert(clip->y1 == CLIP_Y + CLIP_H);
315 assert(clip->w == CLIP_W);
316 assert(clip->h == CLIP_H);
317
318 assert(com->size == sizeof(d2tk_body_rounded_rect_t));
319 assert(com->instr == D2TK_INSTR_ROUNDED_RECT);
320 assert(com->body->rounded_rect.x == ROUNDED_RECT_X - CLIP_X);
321 assert(com->body->rounded_rect.y == ROUNDED_RECT_Y - CLIP_Y);
322 assert(com->body->rounded_rect.w == ROUNDED_RECT_W);
323 assert(com->body->rounded_rect.h == ROUNDED_RECT_H);
324 assert(com->body->rounded_rect.r == ROUNDED_RECT_R);
325 }
326
327 static void
_test_rounded_rect()328 _test_rounded_rect()
329 {
330 d2tk_mock_ctx_t ctx = {
331 .check = _check_rounded_rect
332 };
333
334 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
335 assert(core);
336
337 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
338
339 d2tk_core_pre(core, NULL);
340 const ssize_t ref = d2tk_core_bbox_push(core, true,
341 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
342 assert(ref >= 0);
343
344 d2tk_core_rounded_rect(core,
345 &D2TK_RECT(ROUNDED_RECT_X, ROUNDED_RECT_Y, ROUNDED_RECT_W, ROUNDED_RECT_H),
346 ROUNDED_RECT_R);
347
348 d2tk_core_bbox_pop(core, ref);
349 d2tk_core_post(core);
350 d2tk_core_free(core);
351 }
352
353 #undef ROUNDED_RECT_X
354 #undef ROUNDED_RECT_Y
355 #undef ROUNDED_RECT_W
356 #undef ROUNDED_RECT_H
357 #undef ROUNDED_RECT_R
358
359 #define ARC_X 10
360 #define ARC_Y 20
361 #define ARC_R 5
362 #define ARC_A 30
363 #define ARC_B 60
364 #define ARC_CW true
365
366 static void
_check_arc(const d2tk_com_t * com,const d2tk_clip_t * clip)367 _check_arc(const d2tk_com_t *com, const d2tk_clip_t *clip)
368 {
369 assert(clip->x0 == CLIP_X);
370 assert(clip->y0 == CLIP_Y);
371 assert(clip->x1 == CLIP_X + CLIP_W);
372 assert(clip->y1 == CLIP_Y + CLIP_H);
373 assert(clip->w == CLIP_W);
374 assert(clip->h == CLIP_H);
375
376 assert(com->size == sizeof(d2tk_body_arc_t));
377 assert(com->instr == D2TK_INSTR_ARC);
378 assert(com->body->arc.x == ARC_X - CLIP_X);
379 assert(com->body->arc.y == ARC_Y - CLIP_Y);
380 assert(com->body->arc.r == ARC_R);
381 assert(com->body->arc.a == ARC_A);
382 assert(com->body->arc.b == ARC_B);
383 assert(com->body->arc.cw == ARC_CW);
384 }
385
386 static void
_test_arc()387 _test_arc()
388 {
389 d2tk_mock_ctx_t ctx = {
390 .check = _check_arc
391 };
392
393 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
394 assert(core);
395
396 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
397
398 d2tk_core_pre(core, NULL);
399 const ssize_t ref = d2tk_core_bbox_push(core, true,
400 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
401 assert(ref >= 0);
402
403 d2tk_core_arc(core, ARC_X, ARC_Y, ARC_R, ARC_A, ARC_B, ARC_CW);
404
405 d2tk_core_bbox_pop(core, ref);
406 d2tk_core_post(core);
407 d2tk_core_free(core);
408 }
409
410 #undef ARC_X
411 #undef ARC_Y
412 #undef ARC_R
413 #undef ARC_A
414 #undef ARC_B
415 #undef ARC_CW
416
417 #define CURVE_TO_X1 10
418 #define CURVE_TO_Y1 10
419 #define CURVE_TO_X2 20
420 #define CURVE_TO_Y2 20
421 #define CURVE_TO_X3 30
422 #define CURVE_TO_Y3 30
423
424 static void
_check_curve_to(const d2tk_com_t * com,const d2tk_clip_t * clip)425 _check_curve_to(const d2tk_com_t *com, const d2tk_clip_t *clip)
426 {
427 assert(clip->x0 == CLIP_X);
428 assert(clip->y0 == CLIP_Y);
429 assert(clip->x1 == CLIP_X + CLIP_W);
430 assert(clip->y1 == CLIP_Y + CLIP_H);
431 assert(clip->w == CLIP_W);
432 assert(clip->h == CLIP_H);
433
434 assert(com->size == sizeof(d2tk_body_curve_to_t));
435 assert(com->instr == D2TK_INSTR_CURVE_TO);
436 assert(com->body->curve_to.x1 == CURVE_TO_X1 - CLIP_X);
437 assert(com->body->curve_to.y1 == CURVE_TO_Y1 - CLIP_Y);
438 assert(com->body->curve_to.x2 == CURVE_TO_X2 - CLIP_X);
439 assert(com->body->curve_to.y2 == CURVE_TO_Y2 - CLIP_Y);
440 assert(com->body->curve_to.x3 == CURVE_TO_X3 - CLIP_X);
441 assert(com->body->curve_to.y3 == CURVE_TO_Y3 - CLIP_Y);
442 }
443
444 static void
_test_curve_to()445 _test_curve_to()
446 {
447 d2tk_mock_ctx_t ctx = {
448 .check = _check_curve_to
449 };
450
451 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
452 assert(core);
453
454 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
455
456 d2tk_core_pre(core, NULL);
457 const ssize_t ref = d2tk_core_bbox_push(core, true,
458 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
459 assert(ref >= 0);
460
461 d2tk_core_curve_to(core, CURVE_TO_X1, CURVE_TO_Y1, CURVE_TO_X2, CURVE_TO_Y2,
462 CURVE_TO_X3, CURVE_TO_Y3);
463
464 d2tk_core_bbox_pop(core, ref);
465 d2tk_core_post(core);
466 d2tk_core_free(core);
467 }
468
469 #undef CURVE_TO_X1
470 #undef CURVE_TO_Y1
471 #undef CURVE_TO_X2
472 #undef CURVE_TO_Y2
473 #undef CURVE_TO_X3
474 #undef CURVE_TO_Y3
475
476 #define COLOR_RGBA 0xff00ff00
477
478 static void
_check_color(const d2tk_com_t * com,const d2tk_clip_t * clip)479 _check_color(const d2tk_com_t *com, const d2tk_clip_t *clip)
480 {
481 assert(clip->x0 == CLIP_X);
482 assert(clip->y0 == CLIP_Y);
483 assert(clip->x1 == CLIP_X + CLIP_W);
484 assert(clip->y1 == CLIP_Y + CLIP_H);
485 assert(clip->w == CLIP_W);
486 assert(clip->h == CLIP_H);
487
488 assert(com->size == sizeof(d2tk_body_color_t));
489 assert(com->instr == D2TK_INSTR_COLOR);
490 assert(com->body->color.rgba == COLOR_RGBA);
491 }
492
493 static void
_test_color()494 _test_color()
495 {
496 d2tk_mock_ctx_t ctx = {
497 .check = _check_color
498 };
499
500 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
501 assert(core);
502
503 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
504
505 d2tk_core_pre(core, NULL);
506 const ssize_t ref = d2tk_core_bbox_push(core, true,
507 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
508 assert(ref >= 0);
509
510 d2tk_core_color(core, COLOR_RGBA);
511
512 d2tk_core_bbox_pop(core, ref);
513 d2tk_core_post(core);
514 d2tk_core_free(core);
515 }
516
517 #undef COLOR_RGBA
518
519 #define LINEAR_GRADIENT_X_0 10
520 #define LINEAR_GRADIENT_Y_0 20
521 #define LINEAR_GRADIENT_X_1 30
522 #define LINEAR_GRADIENT_Y_1 40
523 #define LINEAR_GRADIENT_RGBA_0 0xff00ff00
524 #define LINEAR_GRADIENT_RGBA_1 0xffff00ff
525
526 static void
_check_linear_gradient(const d2tk_com_t * com,const d2tk_clip_t * clip)527 _check_linear_gradient(const d2tk_com_t *com, const d2tk_clip_t *clip)
528 {
529 assert(clip->x0 == CLIP_X);
530 assert(clip->y0 == CLIP_Y);
531 assert(clip->x1 == CLIP_X + CLIP_W);
532 assert(clip->y1 == CLIP_Y + CLIP_H);
533 assert(clip->w == CLIP_W);
534 assert(clip->h == CLIP_H);
535
536 assert(com->size == sizeof(d2tk_body_linear_gradient_t));
537 assert(com->instr == D2TK_INSTR_LINEAR_GRADIENT);
538 assert(com->body->linear_gradient.p[0].x == LINEAR_GRADIENT_X_0 - CLIP_X);
539 assert(com->body->linear_gradient.p[0].y == LINEAR_GRADIENT_Y_0 - CLIP_Y);
540 assert(com->body->linear_gradient.p[1].x == LINEAR_GRADIENT_X_1 - CLIP_X);
541 assert(com->body->linear_gradient.p[1].y == LINEAR_GRADIENT_Y_1 - CLIP_Y);
542 assert(com->body->linear_gradient.rgba[0] == LINEAR_GRADIENT_RGBA_0);
543 assert(com->body->linear_gradient.rgba[1] == LINEAR_GRADIENT_RGBA_1);
544 }
545
546 static void
_test_linear_gradient()547 _test_linear_gradient()
548 {
549 d2tk_mock_ctx_t ctx = {
550 .check = _check_linear_gradient
551 };
552
553 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
554 assert(core);
555
556 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
557
558 d2tk_core_pre(core, NULL);
559 const ssize_t ref = d2tk_core_bbox_push(core, true,
560 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
561 assert(ref >= 0);
562
563 const d2tk_point_t p [2] = {
564 D2TK_POINT(LINEAR_GRADIENT_X_0, LINEAR_GRADIENT_Y_0),
565 D2TK_POINT(LINEAR_GRADIENT_X_1, LINEAR_GRADIENT_Y_1)
566 };
567 const uint32_t rgba [2] = {
568 LINEAR_GRADIENT_RGBA_0,
569 LINEAR_GRADIENT_RGBA_1
570 };
571 d2tk_core_linear_gradient(core, p, rgba);
572
573 d2tk_core_bbox_pop(core, ref);
574 d2tk_core_post(core);
575 d2tk_core_free(core);
576 }
577
578 #undef LINEAR_GRADIENT_X_0
579 #undef LINEAR_GRADIENT_Y_0
580 #undef LINEAR_GRADIENT_X_1
581 #undef LINEAR_GRADIENT_Y_1
582 #undef LINEAR_GRADIENT_RGBA_0
583 #undef LINEAR_GRADIENT_RGBA_1
584
585 static void
_check_stroke(const d2tk_com_t * com,const d2tk_clip_t * clip)586 _check_stroke(const d2tk_com_t *com, const d2tk_clip_t *clip)
587 {
588 assert(clip->x0 == CLIP_X);
589 assert(clip->y0 == CLIP_Y);
590 assert(clip->x1 == CLIP_X + CLIP_W);
591 assert(clip->y1 == CLIP_Y + CLIP_H);
592 assert(clip->w == CLIP_W);
593 assert(clip->h == CLIP_H);
594
595 assert(com->size == 0);
596 assert(com->instr == D2TK_INSTR_STROKE);
597 }
598
599 static void
_test_stroke()600 _test_stroke()
601 {
602 d2tk_mock_ctx_t ctx = {
603 .check = _check_stroke
604 };
605
606 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
607 assert(core);
608
609 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
610
611 d2tk_core_pre(core, NULL);
612 const ssize_t ref = d2tk_core_bbox_push(core, true,
613 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
614 assert(ref >= 0);
615
616 d2tk_core_stroke(core);
617
618 d2tk_core_bbox_pop(core, ref);
619 d2tk_core_post(core);
620 d2tk_core_free(core);
621 }
622
623 static void
_check_fill(const d2tk_com_t * com,const d2tk_clip_t * clip)624 _check_fill(const d2tk_com_t *com, const d2tk_clip_t *clip)
625 {
626 assert(clip->x0 == CLIP_X);
627 assert(clip->y0 == CLIP_Y);
628 assert(clip->x1 == CLIP_X + CLIP_W);
629 assert(clip->y1 == CLIP_Y + CLIP_H);
630 assert(clip->w == CLIP_W);
631 assert(clip->h == CLIP_H);
632
633 assert(com->size == 0);
634 assert(com->instr == D2TK_INSTR_FILL);
635 }
636
637 static void
_test_fill()638 _test_fill()
639 {
640 d2tk_mock_ctx_t ctx = {
641 .check = _check_fill
642 };
643
644 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
645 assert(core);
646
647 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
648
649 d2tk_core_pre(core, NULL);
650 const ssize_t ref = d2tk_core_bbox_push(core, true,
651 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
652 assert(ref >= 0);
653
654 d2tk_core_fill(core);
655
656 d2tk_core_bbox_pop(core, ref);
657 d2tk_core_post(core);
658 d2tk_core_free(core);
659 }
660
661 static void
_check_save(const d2tk_com_t * com,const d2tk_clip_t * clip)662 _check_save(const d2tk_com_t *com, const d2tk_clip_t *clip)
663 {
664 assert(clip->x0 == CLIP_X);
665 assert(clip->y0 == CLIP_Y);
666 assert(clip->x1 == CLIP_X + CLIP_W);
667 assert(clip->y1 == CLIP_Y + CLIP_H);
668 assert(clip->w == CLIP_W);
669 assert(clip->h == CLIP_H);
670
671 assert(com->size == 0);
672 assert(com->instr == D2TK_INSTR_SAVE);
673 }
674
675 static void
_test_save()676 _test_save()
677 {
678 d2tk_mock_ctx_t ctx = {
679 .check = _check_save
680 };
681
682 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
683 assert(core);
684
685 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
686
687 d2tk_core_pre(core, NULL);
688 const ssize_t ref = d2tk_core_bbox_push(core, true,
689 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
690 assert(ref >= 0);
691
692 d2tk_core_save(core);
693
694 d2tk_core_bbox_pop(core, ref);
695 d2tk_core_post(core);
696 d2tk_core_free(core);
697 }
698
699 static void
_check_restore(const d2tk_com_t * com,const d2tk_clip_t * clip)700 _check_restore(const d2tk_com_t *com, const d2tk_clip_t *clip)
701 {
702 assert(clip->x0 == CLIP_X);
703 assert(clip->y0 == CLIP_Y);
704 assert(clip->x1 == CLIP_X + CLIP_W);
705 assert(clip->y1 == CLIP_Y + CLIP_H);
706 assert(clip->w == CLIP_W);
707 assert(clip->h == CLIP_H);
708
709 assert(com->size == 0);
710 assert(com->instr == D2TK_INSTR_RESTORE);
711 }
712
713 static void
_test_restore()714 _test_restore()
715 {
716 d2tk_mock_ctx_t ctx = {
717 .check = _check_restore
718 };
719
720 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
721 assert(core);
722
723 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
724
725 d2tk_core_pre(core, NULL);
726 const ssize_t ref = d2tk_core_bbox_push(core, true,
727 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
728 assert(ref >= 0);
729
730 d2tk_core_restore(core);
731
732 d2tk_core_bbox_pop(core, ref);
733 d2tk_core_post(core);
734 d2tk_core_free(core);
735 }
736
737 #define ROTATE_DEG 45
738
739 static void
_check_rotate(const d2tk_com_t * com,const d2tk_clip_t * clip)740 _check_rotate(const d2tk_com_t *com, const d2tk_clip_t *clip)
741 {
742 assert(clip->x0 == CLIP_X);
743 assert(clip->y0 == CLIP_Y);
744 assert(clip->x1 == CLIP_X + CLIP_W);
745 assert(clip->y1 == CLIP_Y + CLIP_H);
746 assert(clip->w == CLIP_W);
747 assert(clip->h == CLIP_H);
748
749 assert(com->size == sizeof(d2tk_body_rotate_t));
750 assert(com->instr == D2TK_INSTR_ROTATE);
751 assert(com->body->rotate.deg == ROTATE_DEG);
752 }
753
754 static void
_test_rotate()755 _test_rotate()
756 {
757 d2tk_mock_ctx_t ctx = {
758 .check = _check_rotate
759 };
760
761 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
762 assert(core);
763
764 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
765
766 d2tk_core_pre(core, NULL);
767 const ssize_t ref = d2tk_core_bbox_push(core, true,
768 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
769 assert(ref >= 0);
770
771 d2tk_core_rotate(core, ROTATE_DEG);
772
773 d2tk_core_bbox_pop(core, ref);
774 d2tk_core_post(core);
775 d2tk_core_free(core);
776 }
777
778 #undef ROTATE_DEG
779
780 static void
_check_begin_path(const d2tk_com_t * com,const d2tk_clip_t * clip)781 _check_begin_path(const d2tk_com_t *com, const d2tk_clip_t *clip)
782 {
783 assert(clip->x0 == CLIP_X);
784 assert(clip->y0 == CLIP_Y);
785 assert(clip->x1 == CLIP_X + CLIP_W);
786 assert(clip->y1 == CLIP_Y + CLIP_H);
787 assert(clip->w == CLIP_W);
788 assert(clip->h == CLIP_H);
789
790 assert(com->size == 0);
791 assert(com->instr == D2TK_INSTR_BEGIN_PATH);
792 }
793
794 static void
_test_begin_path()795 _test_begin_path()
796 {
797 d2tk_mock_ctx_t ctx = {
798 .check = _check_begin_path
799 };
800
801 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
802 assert(core);
803
804 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
805
806 d2tk_core_pre(core, NULL);
807 const ssize_t ref = d2tk_core_bbox_push(core, true,
808 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
809 assert(ref >= 0);
810
811 d2tk_core_begin_path(core);
812
813 d2tk_core_bbox_pop(core, ref);
814 d2tk_core_post(core);
815 d2tk_core_free(core);
816 }
817
818 static void
_check_close_path(const d2tk_com_t * com,const d2tk_clip_t * clip)819 _check_close_path(const d2tk_com_t *com, const d2tk_clip_t *clip)
820 {
821 assert(clip->x0 == CLIP_X);
822 assert(clip->y0 == CLIP_Y);
823 assert(clip->x1 == CLIP_X + CLIP_W);
824 assert(clip->y1 == CLIP_Y + CLIP_H);
825 assert(clip->w == CLIP_W);
826 assert(clip->h == CLIP_H);
827
828 assert(com->size == 0);
829 assert(com->instr == D2TK_INSTR_CLOSE_PATH);
830 }
831
832 static void
_test_close_path()833 _test_close_path()
834 {
835 d2tk_mock_ctx_t ctx = {
836 .check = _check_close_path
837 };
838
839 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
840 assert(core);
841
842 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
843
844 d2tk_core_pre(core, NULL);
845 const ssize_t ref = d2tk_core_bbox_push(core, true,
846 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
847 assert(ref >= 0);
848
849 d2tk_core_close_path(core);
850
851 d2tk_core_bbox_pop(core, ref);
852 d2tk_core_post(core);
853 d2tk_core_free(core);
854 }
855
856 #define SCISSOR_X 10
857 #define SCISSOR_Y 20
858 #define SCISSOR_W 30
859 #define SCISSOR_H 40
860
861 static void
_check_scissor(const d2tk_com_t * com,const d2tk_clip_t * clip)862 _check_scissor(const d2tk_com_t *com, const d2tk_clip_t *clip)
863 {
864 assert(clip->x0 == CLIP_X);
865 assert(clip->y0 == CLIP_Y);
866 assert(clip->x1 == CLIP_X + CLIP_W);
867 assert(clip->y1 == CLIP_Y + CLIP_H);
868 assert(clip->w == CLIP_W);
869 assert(clip->h == CLIP_H);
870
871 assert(com->size == sizeof(d2tk_body_scissor_t));
872 assert(com->instr == D2TK_INSTR_SCISSOR);
873 assert(com->body->scissor.x == SCISSOR_X - CLIP_X);
874 assert(com->body->scissor.y == SCISSOR_Y - CLIP_Y);
875 assert(com->body->scissor.w == SCISSOR_W);
876 assert(com->body->scissor.h == SCISSOR_H);
877 }
878
879 static void
_test_scissor()880 _test_scissor()
881 {
882 d2tk_mock_ctx_t ctx = {
883 .check = _check_scissor
884 };
885
886 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
887 assert(core);
888
889 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
890
891 d2tk_core_pre(core, NULL);
892 const ssize_t ref = d2tk_core_bbox_push(core, true,
893 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
894 assert(ref >= 0);
895
896 d2tk_core_scissor(core, &D2TK_RECT(SCISSOR_X, SCISSOR_Y, SCISSOR_W, SCISSOR_H));
897
898 d2tk_core_bbox_pop(core, ref);
899 d2tk_core_post(core);
900 d2tk_core_free(core);
901 }
902
903 #undef SCISSOR_X
904 #undef SCISSOR_Y
905 #undef SCISSOR_W
906 #undef SCISSOR_H
907
908 static void
_check_reset_scissor(const d2tk_com_t * com,const d2tk_clip_t * clip)909 _check_reset_scissor(const d2tk_com_t *com, const d2tk_clip_t *clip)
910 {
911 assert(clip->x0 == CLIP_X);
912 assert(clip->y0 == CLIP_Y);
913 assert(clip->x1 == CLIP_X + CLIP_W);
914 assert(clip->y1 == CLIP_Y + CLIP_H);
915 assert(clip->w == CLIP_W);
916 assert(clip->h == CLIP_H);
917
918 assert(com->size == 0);
919 assert(com->instr == D2TK_INSTR_RESET_SCISSOR);
920 }
921
922 static void
_test_reset_scissor()923 _test_reset_scissor()
924 {
925 d2tk_mock_ctx_t ctx = {
926 .check = _check_reset_scissor
927 };
928
929 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
930 assert(core);
931
932 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
933
934 d2tk_core_pre(core, NULL);
935 const ssize_t ref = d2tk_core_bbox_push(core, true,
936 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
937 assert(ref >= 0);
938
939 d2tk_core_reset_scissor(core);
940
941 d2tk_core_bbox_pop(core, ref);
942 d2tk_core_post(core);
943 d2tk_core_free(core);
944 }
945
946 #define FONT_SIZE 11
947
948 static void
_check_font_size(const d2tk_com_t * com,const d2tk_clip_t * clip)949 _check_font_size(const d2tk_com_t *com, const d2tk_clip_t *clip)
950 {
951 assert(clip->x0 == CLIP_X);
952 assert(clip->y0 == CLIP_Y);
953 assert(clip->x1 == CLIP_X + CLIP_W);
954 assert(clip->y1 == CLIP_Y + CLIP_H);
955 assert(clip->w == CLIP_W);
956 assert(clip->h == CLIP_H);
957
958 assert(com->size == sizeof(d2tk_body_font_size_t));
959 assert(com->instr == D2TK_INSTR_FONT_SIZE);
960 assert(com->body->font_size.size == FONT_SIZE);
961 }
962
963 static void
_test_font_size()964 _test_font_size()
965 {
966 d2tk_mock_ctx_t ctx = {
967 .check = _check_font_size
968 };
969
970 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
971 assert(core);
972
973 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
974
975 d2tk_core_pre(core, NULL);
976 const ssize_t ref = d2tk_core_bbox_push(core, true,
977 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
978 assert(ref >= 0);
979
980 d2tk_core_font_size(core, FONT_SIZE);
981
982 d2tk_core_bbox_pop(core, ref);
983 d2tk_core_post(core);
984 d2tk_core_free(core);
985 }
986
987 #undef FONT_SIZE
988
989 #define FONT_FACE "Monospace"
990
991 static void
_check_font_face(const d2tk_com_t * com,const d2tk_clip_t * clip)992 _check_font_face(const d2tk_com_t *com, const d2tk_clip_t *clip)
993 {
994 assert(clip->x0 == CLIP_X);
995 assert(clip->y0 == CLIP_Y);
996 assert(clip->x1 == CLIP_X + CLIP_W);
997 assert(clip->y1 == CLIP_Y + CLIP_H);
998 assert(clip->w == CLIP_W);
999 assert(clip->h == CLIP_H);
1000
1001 assert(com->size == sizeof(d2tk_body_font_face_t) + strlen(FONT_FACE));
1002 assert(com->instr == D2TK_INSTR_FONT_FACE);
1003 assert(strcmp(com->body->font_face.face, FONT_FACE) == 0);
1004 }
1005
1006 static void
_test_font_face()1007 _test_font_face()
1008 {
1009 d2tk_mock_ctx_t ctx = {
1010 .check = _check_font_face
1011 };
1012
1013 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
1014 assert(core);
1015
1016 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
1017
1018 d2tk_core_pre(core, NULL);
1019 const ssize_t ref = d2tk_core_bbox_push(core, true,
1020 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
1021 assert(ref >= 0);
1022
1023 d2tk_core_font_face(core, strlen(FONT_FACE), FONT_FACE);
1024
1025 d2tk_core_bbox_pop(core, ref);
1026 d2tk_core_post(core);
1027 d2tk_core_free(core);
1028 }
1029
1030 #undef FONT_FACE
1031
1032 #define TEXT_X 10
1033 #define TEXT_Y 20
1034 #define TEXT_W 30
1035 #define TEXT_H 40
1036 #define TEXT_TEXT "Text" "времени" "äöäÄÖÄ"
1037 #define TEXT_ALIGN D2TK_ALIGN_LEFT
1038
1039 static void
_check_text(const d2tk_com_t * com,const d2tk_clip_t * clip)1040 _check_text(const d2tk_com_t *com, const d2tk_clip_t *clip)
1041 {
1042 assert(clip->x0 == CLIP_X);
1043 assert(clip->y0 == CLIP_Y);
1044 assert(clip->x1 == CLIP_X + CLIP_W);
1045 assert(clip->y1 == CLIP_Y + CLIP_H);
1046 assert(clip->w == CLIP_W);
1047 assert(clip->h == CLIP_H);
1048
1049 assert(com->size == sizeof(d2tk_body_text_t) + strlen(TEXT_TEXT));
1050 assert(com->instr == D2TK_INSTR_TEXT);
1051 assert(com->body->text.x == TEXT_X - CLIP_X);
1052 assert(com->body->text.y == TEXT_Y - CLIP_Y);
1053 assert(com->body->text.w == TEXT_W);
1054 assert(com->body->text.h == TEXT_H);
1055 assert(strcmp(com->body->text.text, TEXT_TEXT) == 0);
1056 assert(com->body->text.align == TEXT_ALIGN);
1057 }
1058
1059 static void
_test_text()1060 _test_text()
1061 {
1062 d2tk_mock_ctx_t ctx = {
1063 .check = _check_text
1064 };
1065
1066 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
1067 assert(core);
1068
1069 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
1070
1071 d2tk_core_pre(core, NULL);
1072 const ssize_t ref = d2tk_core_bbox_push(core, true,
1073 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
1074 assert(ref >= 0);
1075
1076 d2tk_core_text(core, &D2TK_RECT(TEXT_X, TEXT_Y, TEXT_W, TEXT_H),
1077 strlen(TEXT_TEXT), TEXT_TEXT, TEXT_ALIGN);
1078
1079 d2tk_core_bbox_pop(core, ref);
1080 d2tk_core_post(core);
1081 d2tk_core_free(core);
1082 }
1083
1084 #undef TEXT_X
1085 #undef TEXT_Y
1086 #undef TEXT_W
1087 #undef TEXT_H
1088 #undef TEXT_TEXT
1089 #undef TEXT_ALIGN
1090
1091 #define IMAGE_X 10
1092 #define IMAGE_Y 20
1093 #define IMAGE_W 30
1094 #define IMAGE_H 40
1095 #define IMAGE_PATH "./libre-sugar-skull.png"
1096 #define IMAGE_ALIGN D2TK_ALIGN_LEFT
1097
1098 static void
_check_image(const d2tk_com_t * com,const d2tk_clip_t * clip)1099 _check_image(const d2tk_com_t *com, const d2tk_clip_t *clip)
1100 {
1101 assert(clip->x0 == CLIP_X);
1102 assert(clip->y0 == CLIP_Y);
1103 assert(clip->x1 == CLIP_X + CLIP_W);
1104 assert(clip->y1 == CLIP_Y + CLIP_H);
1105 assert(clip->w == CLIP_W);
1106 assert(clip->h == CLIP_H);
1107
1108 assert(com->size == sizeof(d2tk_body_image_t) + strlen(IMAGE_PATH));
1109 assert(com->instr == D2TK_INSTR_IMAGE);
1110 assert(com->body->image.x == IMAGE_X - CLIP_X);
1111 assert(com->body->image.y == IMAGE_Y - CLIP_Y);
1112 assert(com->body->image.w == IMAGE_W);
1113 assert(com->body->image.h == IMAGE_H);
1114 assert(strcmp(com->body->image.path , IMAGE_PATH) == 0);
1115 assert(com->body->image.align == IMAGE_ALIGN);
1116 }
1117
1118 static void
_test_image()1119 _test_image()
1120 {
1121 d2tk_mock_ctx_t ctx = {
1122 .check = _check_image
1123 };
1124
1125 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
1126 assert(core);
1127
1128 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
1129
1130 d2tk_core_pre(core, NULL);
1131 const ssize_t ref = d2tk_core_bbox_push(core, true,
1132 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
1133 assert(ref >= 0);
1134
1135 d2tk_core_image(core, &D2TK_RECT(IMAGE_X, IMAGE_Y, IMAGE_W, IMAGE_H),
1136 strlen(IMAGE_PATH), IMAGE_PATH, IMAGE_ALIGN);
1137
1138 d2tk_core_bbox_pop(core, ref);
1139 d2tk_core_post(core);
1140 d2tk_core_free(core);
1141 }
1142
1143 #undef IMAGE_X
1144 #undef IMAGE_Y
1145 #undef IMAGE_W
1146 #undef IMAGE_H
1147 #undef IMAGE_PATH
1148 #undef IMAGE_ALIGN
1149
1150 #define BITMAP_X 10
1151 #define BITMAP_Y 20
1152 #define BITMAP_W 30
1153 #define BITMAP_H 40
1154 #define BITMAP_WIDTH 24
1155 #define BITMAP_HEIGHT 24
1156 #define BITMAP_STRIDE 32*sizeof(uint32_t)
1157 #define BITMAP_ALIGN D2TK_ALIGN_LEFT
1158
1159 static void
_check_bitmap(const d2tk_com_t * com,const d2tk_clip_t * clip)1160 _check_bitmap(const d2tk_com_t *com, const d2tk_clip_t *clip)
1161 {
1162 assert(clip->x0 == CLIP_X);
1163 assert(clip->y0 == CLIP_Y);
1164 assert(clip->x1 == CLIP_X + CLIP_W);
1165 assert(clip->y1 == CLIP_Y + CLIP_H);
1166 assert(clip->w == CLIP_W);
1167 assert(clip->h == CLIP_H);
1168
1169 assert(com->size == sizeof(d2tk_body_bitmap_t));
1170 assert(com->instr == D2TK_INSTR_BITMAP);
1171 assert(com->body->bitmap.x == BITMAP_X - CLIP_X);
1172 assert(com->body->bitmap.y == BITMAP_Y - CLIP_Y);
1173 assert(com->body->bitmap.w == BITMAP_W);
1174 assert(com->body->bitmap.h == BITMAP_H);
1175 assert(com->body->bitmap.align == BITMAP_ALIGN);
1176 assert(com->body->bitmap.surf.w == BITMAP_WIDTH);
1177 assert(com->body->bitmap.surf.h == BITMAP_HEIGHT);
1178 assert(com->body->bitmap.surf.stride == BITMAP_STRIDE);
1179 for(unsigned y = 0, o = 0;
1180 y < com->body->bitmap.surf.h;
1181 y++, o += com->body->bitmap.surf.stride/sizeof(uint32_t))
1182 {
1183 for(unsigned x = 0; x < com->body->bitmap.surf.w; x++)
1184 {
1185 const unsigned idx = o + x;
1186
1187 assert(com->body->bitmap.surf.argb[idx] == 999 - idx);
1188 }
1189 }
1190 }
1191
1192 static void
_test_bitmap()1193 _test_bitmap()
1194 {
1195 d2tk_mock_ctx_t ctx = {
1196 .check = _check_bitmap
1197 };
1198
1199 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
1200 assert(core);
1201
1202 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
1203
1204 d2tk_core_pre(core, NULL);
1205 const ssize_t ref = d2tk_core_bbox_push(core, true,
1206 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
1207 assert(ref >= 0);
1208
1209 uint32_t surf [BITMAP_STRIDE/sizeof(uint32_t)*BITMAP_HEIGHT];
1210 for(unsigned y = 0, o = 0;
1211 y < BITMAP_HEIGHT;
1212 y++, o += BITMAP_STRIDE/sizeof(uint32_t))
1213 {
1214 for(unsigned x = 0; x < BITMAP_WIDTH; x++)
1215 {
1216 const unsigned idx = o + x;
1217
1218 surf[idx] = 999 - idx;
1219 }
1220 }
1221
1222 const uint64_t rev = 0;
1223
1224 d2tk_core_bitmap(core, &D2TK_RECT(BITMAP_X, BITMAP_Y, BITMAP_W, BITMAP_H),
1225 BITMAP_WIDTH, BITMAP_HEIGHT, BITMAP_STRIDE, surf, rev, BITMAP_ALIGN);
1226
1227 d2tk_core_bbox_pop(core, ref);
1228 d2tk_core_post(core);
1229 d2tk_core_free(core);
1230 }
1231
1232 #undef BITMAP_X
1233 #undef BITMAP_Y
1234 #undef BITMAP_W
1235 #undef BITMAP_H
1236 #undef BITMAP_WIDTH
1237 #undef BITMAP_HEIGHT
1238 #undef BITMAP_STRIDE
1239 #undef BITMAP_ALIGN
1240
1241 #define CUSTOM_X 10
1242 #define CUSTOM_Y 20
1243 #define CUSTOM_W 30
1244 #define CUSTOM_H 40
1245 static const uint32_t _data = 12;
1246 #define CUSTOM_DATA (&_data)
1247
1248 static void
_custom(void * ctx,const d2tk_rect_t * rect,const void * data)1249 _custom(void *ctx, const d2tk_rect_t *rect, const void *data)
1250 {
1251 assert(ctx == NULL);
1252 assert(rect != NULL);
1253 assert(rect->x == CUSTOM_X);
1254 assert(rect->y == CUSTOM_Y);
1255 assert(rect->w == CUSTOM_W);
1256 assert(rect->h == CUSTOM_H);
1257 assert(data == CUSTOM_DATA);
1258 }
1259
1260 static void
_check_custom(const d2tk_com_t * com,const d2tk_clip_t * clip)1261 _check_custom(const d2tk_com_t *com, const d2tk_clip_t *clip)
1262 {
1263 assert(clip->x0 == CLIP_X);
1264 assert(clip->y0 == CLIP_Y);
1265 assert(clip->x1 == CLIP_X + CLIP_W);
1266 assert(clip->y1 == CLIP_Y + CLIP_H);
1267 assert(clip->w == CLIP_W);
1268 assert(clip->h == CLIP_H);
1269
1270 const uint64_t dhash = d2tk_hash(CUSTOM_DATA, sizeof(uint32_t));
1271
1272 assert(com->size == sizeof(d2tk_body_custom_t));
1273 assert(com->instr == D2TK_INSTR_CUSTOM);
1274 assert(com->body->custom.x == CUSTOM_X - CLIP_X);
1275 assert(com->body->custom.y == CUSTOM_Y - CLIP_Y);
1276 assert(com->body->custom.w == CUSTOM_W);
1277 assert(com->body->custom.h == CUSTOM_H);
1278 assert(com->body->custom.dhash == dhash);
1279 assert(com->body->custom.data == CUSTOM_DATA);
1280 assert(com->body->custom.custom == _custom);
1281 }
1282
1283 static void
_test_custom()1284 _test_custom()
1285 {
1286 d2tk_mock_ctx_t ctx = {
1287 .check = _check_custom
1288 };
1289
1290 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
1291 assert(core);
1292
1293 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
1294
1295 d2tk_core_pre(core, NULL);
1296 const ssize_t ref = d2tk_core_bbox_push(core, true,
1297 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
1298 assert(ref >= 0);
1299
1300 const uint64_t dhash = d2tk_hash(CUSTOM_DATA, sizeof(uint32_t));
1301
1302 d2tk_core_custom(core, &D2TK_RECT(CUSTOM_X, CUSTOM_Y, CUSTOM_W, CUSTOM_H),
1303 dhash, CUSTOM_DATA, _custom);
1304
1305 d2tk_core_bbox_pop(core, ref);
1306 d2tk_core_post(core);
1307 d2tk_core_free(core);
1308 }
1309
1310 #undef CUSTOM_X
1311 #undef CUSTOM_Y
1312 #undef CUSTOM_W
1313 #undef CUSTOM_H
1314 #undef CUSTOM_SIZE
1315 #undef CUSTOM_DATA
1316
1317 #define STROKE_WIDTH 2
1318
1319 static void
_check_stroke_width(const d2tk_com_t * com,const d2tk_clip_t * clip)1320 _check_stroke_width(const d2tk_com_t *com, const d2tk_clip_t *clip)
1321 {
1322 assert(clip->x0 == CLIP_X);
1323 assert(clip->y0 == CLIP_Y);
1324 assert(clip->x1 == CLIP_X + CLIP_W);
1325 assert(clip->y1 == CLIP_Y + CLIP_H);
1326 assert(clip->w == CLIP_W);
1327 assert(clip->h == CLIP_H);
1328
1329 assert(com->size == sizeof(d2tk_body_stroke_width_t));
1330 assert(com->instr == D2TK_INSTR_STROKE_WIDTH);
1331 assert(com->body->stroke_width.width == STROKE_WIDTH);
1332 }
1333
1334 static void
_test_stroke_width()1335 _test_stroke_width()
1336 {
1337 d2tk_mock_ctx_t ctx = {
1338 .check = _check_stroke_width
1339 };
1340
1341 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver, &ctx);
1342 assert(core);
1343
1344 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
1345
1346 d2tk_core_pre(core, NULL);
1347 const ssize_t ref = d2tk_core_bbox_push(core, true,
1348 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
1349 assert(ref >= 0);
1350
1351 d2tk_core_stroke_width(core, STROKE_WIDTH);
1352
1353 d2tk_core_bbox_pop(core, ref);
1354 d2tk_core_post(core);
1355 d2tk_core_free(core);
1356 }
1357
1358 #undef STROKE_WIDTH
1359
1360 static void
_check_triple(const d2tk_com_t * com,const d2tk_clip_t * clip)1361 _check_triple(const d2tk_com_t *com, const d2tk_clip_t *clip)
1362 {
1363 assert(clip->x0 == CLIP_X);
1364 assert(clip->y0 == CLIP_Y);
1365 assert(clip->x1 == CLIP_X + CLIP_W);
1366 assert(clip->y1 == CLIP_Y + CLIP_H);
1367 assert(clip->w == CLIP_W);
1368 assert(clip->h == CLIP_H);
1369
1370 (void)com; //FIXME
1371 }
1372
1373 static void
_test_triple()1374 _test_triple()
1375 {
1376 d2tk_mock_ctx_t ctx = {
1377 .check = _check_triple
1378 };
1379
1380 d2tk_core_t *core = d2tk_core_new(&d2tk_mock_driver_triple, &ctx);
1381 assert(core);
1382
1383 d2tk_core_set_dimensions(core, DIM_W, DIM_H);
1384
1385 for(unsigned i = 0; i < 3; i++)
1386 {
1387 d2tk_core_pre(core, NULL);
1388
1389 if(i != 0)
1390 {
1391 const ssize_t ref = d2tk_core_bbox_push(core, true,
1392 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
1393 assert(ref >= 0);
1394
1395 d2tk_core_rect(core, &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
1396
1397 d2tk_core_bbox_pop(core, ref);
1398 }
1399
1400 if(i != 1)
1401 {
1402 const ssize_t ref = d2tk_core_bbox_push(core, true,
1403 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
1404 assert(ref >= 0);
1405
1406 d2tk_core_rect(core, &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W/2, CLIP_H));
1407
1408 d2tk_core_bbox_pop(core, ref);
1409 }
1410
1411 if(i != 2)
1412 {
1413 const ssize_t ref = d2tk_core_bbox_push(core, true,
1414 &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H));
1415 assert(ref >= 0);
1416
1417 d2tk_core_rect(core, &D2TK_RECT(CLIP_X, CLIP_Y, CLIP_W, CLIP_H/2));
1418
1419 d2tk_core_bbox_pop(core, ref);
1420 }
1421
1422 d2tk_core_post(core);
1423 }
1424
1425 d2tk_core_free(core);
1426 }
1427
1428 int
main(int argc,char ** argv)1429 main(int argc __attribute__((unused)), char **argv __attribute__((unused)))
1430 {
1431 _test_hash();
1432 _test_hash_foreach();
1433 _test_rect_shrink();
1434 _test_point();
1435 _test_dimensions();
1436 _test_bg_color();
1437
1438 _test_move_to();
1439 _test_line_to();
1440 _test_rect();
1441 _test_rounded_rect();
1442 _test_arc();
1443 _test_curve_to();
1444 _test_color();
1445 _test_linear_gradient();
1446 _test_stroke();
1447 _test_fill();
1448 _test_save();
1449 _test_restore();
1450 _test_rotate();
1451 _test_begin_path();
1452 _test_close_path();
1453 _test_scissor();
1454 _test_reset_scissor();
1455 _test_font_size();
1456 _test_font_face();
1457 _test_text();
1458 _test_image();
1459 _test_bitmap();
1460 _test_custom();
1461 _test_stroke_width();
1462
1463 _test_triple();
1464
1465 return EXIT_SUCCESS;
1466 }
1467