FreeRDP
Loading...
Searching...
No Matches
TestFreeRDPRegion.c
1
20#include <winpr/crt.h>
21#include <winpr/print.h>
22
23#include <freerdp/codec/region.h>
24
25static BOOL compareRectangles(const RECTANGLE_16* src1, const RECTANGLE_16* src2, int nb)
26{
27 for (int i = 0; i < nb; i++, src1++, src2++)
28 {
29 if (memcmp(src1, src2, sizeof(RECTANGLE_16)) != 0)
30 {
31 (void)fprintf(stderr,
32 "expecting rect %d (%" PRIu16 ",%" PRIu16 "-%" PRIu16 ",%" PRIu16
33 ") and have (%" PRIu16 ",%" PRIu16 "-%" PRIu16 ",%" PRIu16 ")\n",
34 i, src2->left, src2->top, src2->right, src2->bottom, src1->left,
35 src1->top, src1->right, src1->bottom);
36 return FALSE;
37 }
38 }
39
40 return TRUE;
41}
42
43static int test_basic(void)
44{
45 REGION16 region = { 0 };
46 int retCode = -1;
47 const RECTANGLE_16* rects = NULL;
48 UINT32 nbRects = 0;
49 /* R1 + R2 ==> disjointed rects */
50 RECTANGLE_16 r1 = { 0, 101, 200, 201 };
51 RECTANGLE_16 r2 = { 150, 301, 250, 401 };
52 RECTANGLE_16 r1_r2[] = { { 0, 101, 200, 201 }, { 150, 301, 250, 401 } };
53 /* r1 */
54 region16_init(&region);
55
56 if (!region16_union_rect(&region, &region, &r1))
57 goto out;
58
59 rects = region16_rects(&region, &nbRects);
60
61 if (!rects || nbRects != 1 || memcmp(rects, &r1, sizeof(RECTANGLE_16)) != 0)
62 goto out;
63
64 /* r1 + r2 */
65 if (!region16_union_rect(&region, &region, &r2))
66 goto out;
67
68 rects = region16_rects(&region, &nbRects);
69
70 if (!rects || nbRects != 2 ||
71 !compareRectangles(rects, r1_r2, WINPR_ASSERTING_INT_CAST(int, nbRects)))
72 goto out;
73
74 /* clear region */
75 region16_clear(&region);
76 region16_rects(&region, &nbRects);
77
78 if (nbRects)
79 goto out;
80
81 retCode = 0;
82out:
83 region16_uninit(&region);
84 return retCode;
85}
86
87static int test_r1_r3(void)
88{
89 REGION16 region;
90 int retCode = -1;
91 const RECTANGLE_16* rects = NULL;
92 UINT32 nbRects = 0;
93 RECTANGLE_16 r1 = { 0, 101, 200, 201 };
94 RECTANGLE_16 r3 = { 150, 151, 250, 251 };
95 RECTANGLE_16 r1_r3[] = { { 0, 101, 200, 151 }, { 0, 151, 250, 201 }, { 150, 201, 250, 251 } };
96 region16_init(&region);
97 /*
98 * +===============================================================
99 * |
100 * |+-----+ +-----+
101 * || r1 | | |
102 * || +-+------+ +-----+--------+
103 * || | r3 | | |
104 * |+---+ | ====> +-----+--------+
105 * | | | | |
106 * | +--------+ +--------+
107 */
108
109 /* R1 + R3 */
110 if (!region16_union_rect(&region, &region, &r1))
111 goto out;
112
113 if (!region16_union_rect(&region, &region, &r3))
114 goto out;
115
116 rects = region16_rects(&region, &nbRects);
117
118 if (!rects || nbRects != 3 ||
119 !compareRectangles(rects, r1_r3, WINPR_ASSERTING_INT_CAST(int, nbRects)))
120 goto out;
121
122 /* R3 + R1 */
123 region16_clear(&region);
124
125 if (!region16_union_rect(&region, &region, &r3))
126 goto out;
127
128 if (!region16_union_rect(&region, &region, &r1))
129 goto out;
130
131 rects = region16_rects(&region, &nbRects);
132
133 if (!rects || nbRects != 3 ||
134 !compareRectangles(rects, r1_r3, WINPR_ASSERTING_INT_CAST(int, nbRects)))
135 goto out;
136
137 retCode = 0;
138out:
139 region16_uninit(&region);
140 return retCode;
141}
142
143static int test_r9_r10(void)
144{
145 REGION16 region;
146 int retCode = -1;
147 const RECTANGLE_16* rects = NULL;
148 UINT32 nbRects = 0;
149 /*
150 * +===============================================================
151 * |
152 * | +---+ +---+
153 * |+--|r10|-+ +--+---+-+
154 * ||r9| | | | |
155 * || | | | | |
156 * || | | | =====> | |
157 * || | | | | |
158 * || | | | | |
159 * |+--| |-+ +--+---+-+
160 * | +---+ +---+
161 */
162 RECTANGLE_16 r9 = { 0, 100, 400, 200 };
163 RECTANGLE_16 r10 = { 200, 0, 300, 300 };
164 RECTANGLE_16 r9_r10[] = {
165 { 200, 0, 300, 100 },
166 { 0, 100, 400, 200 },
167 { 200, 200, 300, 300 },
168 };
169 region16_init(&region);
170
171 if (!region16_union_rect(&region, &region, &r9))
172 goto out;
173
174 if (!region16_union_rect(&region, &region, &r10))
175 goto out;
176
177 rects = region16_rects(&region, &nbRects);
178
179 if (!rects || nbRects != 3 ||
180 !compareRectangles(rects, r9_r10, WINPR_ASSERTING_INT_CAST(int, nbRects)))
181 goto out;
182
183 retCode = 0;
184out:
185 region16_uninit(&region);
186 return retCode;
187}
188
189static int test_r1_r5(void)
190{
191 REGION16 region;
192 int retCode = -1;
193 const RECTANGLE_16* rects = NULL;
194 UINT32 nbRects = 0;
195 RECTANGLE_16 r1 = { 0, 101, 200, 201 };
196 RECTANGLE_16 r5 = { 150, 121, 300, 131 };
197 RECTANGLE_16 r1_r5[] = { { 0, 101, 200, 121 }, { 0, 121, 300, 131 }, { 0, 131, 200, 201 } };
198 region16_init(&region);
199
200 /*
201 * +===============================================================
202 * |
203 * |+--------+ +--------+
204 * || r1 | | |
205 * || +--+----+ +--------+----+
206 * || | r5 | =====> | |
207 * || +-------+ +--------+----+
208 * || | | |
209 * |+--------+ +--------+
210 * |
211 *
212 */
213 if (!region16_union_rect(&region, &region, &r1))
214 goto out;
215
216 if (!region16_union_rect(&region, &region, &r5))
217 goto out;
218
219 rects = region16_rects(&region, &nbRects);
220
221 if (!rects || nbRects != 3 ||
222 !compareRectangles(rects, r1_r5, WINPR_ASSERTING_INT_CAST(int, nbRects)))
223 goto out;
224
225 retCode = 0;
226out:
227 region16_uninit(&region);
228 return retCode;
229}
230
231static int test_r1_r6(void)
232{
233 REGION16 region = { 0 };
234 int retCode = -1;
235 const RECTANGLE_16* rects = NULL;
236 UINT32 nbRects = 0;
237 RECTANGLE_16 r1 = { 0, 101, 200, 201 };
238 RECTANGLE_16 r6 = { 150, 121, 170, 131 };
239 region16_init(&region);
240 /*
241 * +===============================================================
242 * |
243 * |+--------+ +--------+
244 * || r1 | | |
245 * || +--+ | | |
246 * || |r6| | =====> | |
247 * || +--+ | | |
248 * || | | |
249 * |+--------+ +--------+
250 * |
251 */
252 region16_clear(&region);
253
254 if (!region16_union_rect(&region, &region, &r1))
255 goto out;
256
257 if (!region16_union_rect(&region, &region, &r6))
258 goto out;
259
260 rects = region16_rects(&region, &nbRects);
261
262 if (!rects || nbRects != 1 ||
263 !compareRectangles(rects, &r1, WINPR_ASSERTING_INT_CAST(int, nbRects)))
264 goto out;
265
266 retCode = 0;
267out:
268 region16_uninit(&region);
269 return retCode;
270}
271
272static int test_r1_r2_r4(void)
273{
274 REGION16 region;
275 int retCode = -1;
276 const RECTANGLE_16* rects = NULL;
277 UINT32 nbRects = 0;
278 RECTANGLE_16 r1 = { 0, 101, 200, 201 };
279 RECTANGLE_16 r2 = { 150, 301, 250, 401 };
280 RECTANGLE_16 r4 = { 150, 251, 250, 301 };
281 RECTANGLE_16 r1_r2_r4[] = { { 0, 101, 200, 201 }, { 150, 251, 250, 401 } };
282 /*
283 * +===============================================================
284 * |
285 * |+-----+ +-----+
286 * || r1 | | |
287 * || | | |
288 * || | | |
289 * |+-----+ ====> +-----+
290 * |
291 * | +--------+ +--------+
292 * | | r4 | | |
293 * | +--------+ | |
294 * | | r2 | | |
295 * | | | | |
296 * | +--------+ +--------+
297 *
298 */
299 region16_init(&region);
300
301 if (!region16_union_rect(&region, &region, &r1))
302 goto out;
303
304 if (!region16_union_rect(&region, &region, &r2))
305 goto out;
306
307 if (!region16_union_rect(&region, &region, &r4))
308 goto out;
309
310 rects = region16_rects(&region, &nbRects);
311
312 if (!rects || nbRects != 2 ||
313 !compareRectangles(rects, r1_r2_r4, WINPR_ASSERTING_INT_CAST(int, nbRects)))
314 goto out;
315
316 retCode = 0;
317out:
318 region16_uninit(&region);
319 return retCode;
320}
321
322static int test_r1_r7_r8(void)
323{
324 REGION16 region;
325 int retCode = -1;
326 const RECTANGLE_16* rects = NULL;
327 UINT32 nbRects = 0;
328 RECTANGLE_16 r1 = { 0, 101, 200, 201 };
329 RECTANGLE_16 r7 = { 300, 101, 500, 201 };
330 RECTANGLE_16 r8 = { 150, 121, 400, 131 };
331 RECTANGLE_16 r1_r7_r8[] = {
332 { 0, 101, 200, 121 }, { 300, 101, 500, 121 }, { 0, 121, 500, 131 },
333 { 0, 131, 200, 201 }, { 300, 131, 500, 201 },
334 };
335 /*
336 * +===============================================================
337 * |
338 * |+--------+ +--------+ +--------+ +--------+
339 * || r1 | | r7 | | | | |
340 * || +------------+ | +--------+---+--------+
341 * || | r8 | | =====> | |
342 * || +------------+ | +--------+---+--------+
343 * || | | | | | | |
344 * |+--------+ +--------+ +--------+ +--------+
345 * |
346 */
347 region16_init(&region);
348
349 if (!region16_union_rect(&region, &region, &r1))
350 goto out;
351
352 if (!region16_union_rect(&region, &region, &r7))
353 goto out;
354
355 if (!region16_union_rect(&region, &region, &r8))
356 goto out;
357
358 rects = region16_rects(&region, &nbRects);
359
360 if (!rects || nbRects != 5 ||
361 !compareRectangles(rects, r1_r7_r8, WINPR_ASSERTING_INT_CAST(int, nbRects)))
362 goto out;
363
364 region16_clear(&region);
365
366 if (!region16_union_rect(&region, &region, &r1))
367 goto out;
368
369 if (!region16_union_rect(&region, &region, &r8))
370 goto out;
371
372 if (!region16_union_rect(&region, &region, &r7))
373 goto out;
374
375 rects = region16_rects(&region, &nbRects);
376
377 if (!rects || nbRects != 5 ||
378 !compareRectangles(rects, r1_r7_r8, WINPR_ASSERTING_INT_CAST(int, nbRects)))
379 goto out;
380
381 region16_clear(&region);
382
383 if (!region16_union_rect(&region, &region, &r8))
384 goto out;
385
386 if (!region16_union_rect(&region, &region, &r7))
387 goto out;
388
389 if (!region16_union_rect(&region, &region, &r1))
390 goto out;
391
392 rects = region16_rects(&region, &nbRects);
393
394 if (!rects || nbRects != 5 ||
395 !compareRectangles(rects, r1_r7_r8, WINPR_ASSERTING_INT_CAST(int, nbRects)))
396 goto out;
397
398 retCode = 0;
399out:
400 region16_uninit(&region);
401 return retCode;
402}
403
404static int test_r1_r2_r3_r4(void)
405{
406 REGION16 region;
407 int retCode = -1;
408 const RECTANGLE_16* rects = NULL;
409 UINT32 nbRects = 0;
410 RECTANGLE_16 r1 = { 0, 101, 200, 201 };
411 RECTANGLE_16 r2 = { 150, 301, 250, 401 };
412 RECTANGLE_16 r3 = { 150, 151, 250, 251 };
413 RECTANGLE_16 r4 = { 150, 251, 250, 301 };
414 RECTANGLE_16 r1_r2_r3[] = {
415 { 0, 101, 200, 151 }, { 0, 151, 250, 201 }, { 150, 201, 250, 251 }, { 150, 301, 250, 401 }
416 };
417 RECTANGLE_16 r1_r2_r3_r4[] = { { 0, 101, 200, 151 },
418 { 0, 151, 250, 201 },
419 { 150, 201, 250, 401 } };
420 region16_init(&region);
421
422 /*
423 * +===============================================================
424 * |
425 * |+-----+ +-----+
426 * || r1 | | |
427 * || +-+------+ +-----+--------+
428 * || | r3 | | |
429 * |+---+ | ====> +-----+--------+
430 * | | | | |
431 * | +--------+ +--------+
432 * | +--------+ +--------+
433 * | | r2 | | |
434 * | | | | |
435 * | +--------+ +--------+
436 */
437 if (!region16_union_rect(&region, &region, &r1))
438 goto out;
439
440 if (!region16_union_rect(&region, &region, &r2))
441 goto out;
442
443 if (!region16_union_rect(&region, &region, &r3))
444 goto out;
445
446 rects = region16_rects(&region, &nbRects);
447
448 if (!rects || nbRects != 4 || !compareRectangles(rects, r1_r2_r3, 4))
449 goto out;
450
451 /*
452 * +===============================================================
453 * |
454 * |+-----+ +-----+
455 * || | | |
456 * |+-----+--------+ +-----+--------+
457 * || | ==> | |
458 * |+-----+--------+ +-----+--------+
459 * | | | | |
460 * | +--------+ | |
461 * | | + r4 | | |
462 * | +--------+ | |
463 * | | | | |
464 * | | | | |
465 * | +--------+ +--------+
466 */
467 if (!region16_union_rect(&region, &region, &r4))
468 goto out;
469
470 rects = region16_rects(&region, &nbRects);
471
472 if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r2_r3_r4, 3))
473 goto out;
474
475 retCode = 0;
476out:
477 region16_uninit(&region);
478 return retCode;
479}
480
481static int test_from_weston(void)
482{
483 /*
484 * 0: 0,0 -> 640,32 (w=640 h=32)
485 * 1: 236,169 -> 268,201 (w=32 h=32)
486 * 2: 246,258 -> 278,290 (w=32 h=32)
487 */
488 REGION16 region;
489 int retCode = -1;
490 const RECTANGLE_16* rects = NULL;
491 UINT32 nbRects = 0;
492 RECTANGLE_16 r1 = { 0, 0, 640, 32 };
493 RECTANGLE_16 r2 = { 236, 169, 268, 201 };
494 RECTANGLE_16 r3 = { 246, 258, 278, 290 };
495 RECTANGLE_16 r1_r2_r3[] = { { 0, 0, 640, 32 }, { 236, 169, 268, 201 }, { 246, 258, 278, 290 } };
496 region16_init(&region);
497
498 /*
499 * +===============================================================
500 * |+-------------------------------------------------------------+
501 * || r1 |
502 * |+-------------------------------------------------------------+
503 * |
504 * | +---------------+
505 * | | r2 |
506 * | +---------------+
507 * |
508 * | +---------------+
509 * | | r3 |
510 * | +---------------+
511 * |
512 */
513 if (!region16_union_rect(&region, &region, &r1))
514 goto out;
515
516 if (!region16_union_rect(&region, &region, &r2))
517 goto out;
518
519 if (!region16_union_rect(&region, &region, &r3))
520 goto out;
521
522 rects = region16_rects(&region, &nbRects);
523
524 if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r2_r3, 3))
525 goto out;
526
527 retCode = 0;
528out:
529 region16_uninit(&region);
530 return retCode;
531}
532
533static int test_r1_inter_r3(void)
534{
535 REGION16 region;
536 REGION16 intersection;
537 int retCode = -1;
538 const RECTANGLE_16* rects = NULL;
539 UINT32 nbRects = 0;
540 RECTANGLE_16 r1 = { 0, 101, 200, 201 };
541 RECTANGLE_16 r3 = { 150, 151, 250, 251 };
542 RECTANGLE_16 r1_inter_r3[] = {
543 { 150, 151, 200, 201 },
544 };
545 region16_init(&region);
546 region16_init(&intersection);
547
548 /*
549 * +===============================================================
550 * |
551 * |+-----+
552 * || r1 |
553 * || +-+------+ +-+
554 * || | r3 | r1&r3 | |
555 * |+---+ | ====> +-+
556 * | | |
557 * | +--------+
558 */
559 if (!region16_union_rect(&region, &region, &r1))
560 goto out;
561
562 if (!region16_intersects_rect(&region, &r3))
563 goto out;
564
565 if (!region16_intersect_rect(&intersection, &region, &r3))
566 goto out;
567
568 rects = region16_rects(&intersection, &nbRects);
569
570 if (!rects || nbRects != 1 ||
571 !compareRectangles(rects, r1_inter_r3, WINPR_ASSERTING_INT_CAST(int, nbRects)))
572 goto out;
573
574 retCode = 0;
575out:
576 region16_uninit(&region);
577 region16_uninit(&intersection);
578 return retCode;
579}
580
581static int test_r1_r3_inter_r11(void)
582{
583 REGION16 region;
584 REGION16 intersection;
585 int retCode = -1;
586 const RECTANGLE_16* rects = NULL;
587 UINT32 nbRects = 0;
588 RECTANGLE_16 r1 = { 0, 101, 200, 201 };
589 RECTANGLE_16 r3 = { 150, 151, 250, 251 };
590 RECTANGLE_16 r11 = { 170, 151, 600, 301 };
591 RECTANGLE_16 r1_r3_inter_r11[] = {
592 { 170, 151, 250, 251 },
593 };
594 region16_init(&region);
595 region16_init(&intersection);
596
597 /*
598 * +===============================================================
599 * |
600 * |+-----+
601 * || |
602 * || +------+
603 * || r1+r3 | (r1+r3) & r11
604 * || +----------------+ +--------+
605 * |+---+ | | | ====> | |
606 * | | | | | | |
607 * | | | | | | |
608 * | +-|------+ | +--------+
609 * | | r11 |
610 * | +----------------+
611 *
612 *
613 * R1+R3 is made of 3 bands, R11 overlap the second and the third band. The
614 * intersection is made of two band that must be reassembled to give only
615 * one
616 */
617 if (!region16_union_rect(&region, &region, &r1))
618 goto out;
619
620 if (!region16_union_rect(&region, &region, &r3))
621 goto out;
622
623 if (!region16_intersects_rect(&region, &r11))
624 goto out;
625
626 if (!region16_intersect_rect(&intersection, &region, &r11))
627 goto out;
628
629 rects = region16_rects(&intersection, &nbRects);
630
631 if (!rects || nbRects != 1 ||
632 !compareRectangles(rects, r1_r3_inter_r11, WINPR_ASSERTING_INT_CAST(int, nbRects)))
633 goto out;
634
635 retCode = 0;
636out:
637 region16_uninit(&intersection);
638 region16_uninit(&region);
639 return retCode;
640}
641
642static int test_norbert_case(void)
643{
644 REGION16 region;
645 REGION16 intersection;
646 int retCode = -1;
647 const RECTANGLE_16* rects = NULL;
648 UINT32 nbRects = 0;
649 RECTANGLE_16 inRectangles[5] = { { 1680, 0, 1920, 242 },
650 { 294, 242, 971, 776 },
651 { 1680, 242, 1920, 776 },
652 { 1680, 776, 1920, 1036 },
653 { 2, 1040, 53, 1078 } };
654 RECTANGLE_16 screenRect = { 0, 0, 1920, 1080 };
655 RECTANGLE_16 expected_inter_extents = { 2, 0, 1920, 1078 };
656 region16_init(&region);
657 region16_init(&intersection);
658
659 /*
660 * Consider following as a screen with resolution 1920*1080
661 * | | | | | | |
662 * | |2 |53 |294 |971 |1680 |
663 * | | | | | | |
664 * 0 +=+======================================+======+
665 * | | | |
666 * | | R[0]|
667 * 242 | +-----------+ +------+
668 * | | | | | |
669 * | | | | |
670 * | | R[1]| | R[2]|
671 * 776 | | +-----------+ +------+
672 * | | |
673 * | | R[3]|
674 * 1036 | | +------+
675 * 1040 | +----+
676 * | |R[4]| Union of R[0-4]|
677 * 1078 | +----+ - - - - - - - -+
678 * 1080 |
679 *
680 *
681 * The result is union of R[0] - R[4].
682 * After intersected with the full screen rect, the
683 * result should keep the same.
684 */
685 for (int i = 0; i < 5; i++)
686 {
687 if (!region16_union_rect(&region, &region, &inRectangles[i]))
688 goto out;
689 }
690
691 if (!compareRectangles(region16_extents(&region), &expected_inter_extents, 1))
692 goto out;
693
694 if (!region16_intersect_rect(&intersection, &region, &screenRect))
695 goto out;
696
697 rects = region16_rects(&intersection, &nbRects);
698
699 if (!rects || nbRects != 5 ||
700 !compareRectangles(rects, inRectangles, WINPR_ASSERTING_INT_CAST(int, nbRects)))
701 goto out;
702
703 if (!compareRectangles(region16_extents(&intersection), &expected_inter_extents, 1))
704 goto out;
705
706 retCode = 0;
707out:
708 region16_uninit(&intersection);
709 region16_uninit(&region);
710 return retCode;
711}
712
713static int test_norbert2_case(void)
714{
715 REGION16 region;
716 int retCode = -1;
717 const RECTANGLE_16* rects = NULL;
718 UINT32 nbRects = 0;
719 RECTANGLE_16 rect1 = { 464, 696, 476, 709 };
720 RECTANGLE_16 rect2 = { 0, 0, 1024, 32 };
721 region16_init(&region);
722
723 if (!region16_union_rect(&region, &region, &rect1))
724 {
725 (void)fprintf(stderr, "%s: Error 1 - region16_union_rect failed\n", __func__);
726 goto out;
727 }
728
729 if (!(rects = region16_rects(&region, &nbRects)))
730 {
731 (void)fprintf(stderr, "%s: Error 2 - region16_rects failed\n", __func__);
732 goto out;
733 }
734
735 if (nbRects != 1)
736 {
737 (void)fprintf(stderr, "%s: Error 3 - expected nbRects == 1 but got %" PRIu32 "\n", __func__,
738 nbRects);
739 goto out;
740 }
741
742 if (!compareRectangles(&rects[0], &rect1, 1))
743 {
744 (void)fprintf(stderr, "%s: Error 4 - compare failed\n", __func__);
745 goto out;
746 }
747
748 if (!region16_union_rect(&region, &region, &rect2))
749 {
750 (void)fprintf(stderr, "%s: Error 5 - region16_union_rect failed\n", __func__);
751 goto out;
752 }
753
754 if (!(rects = region16_rects(&region, &nbRects)))
755 {
756 (void)fprintf(stderr, "%s: Error 6 - region16_rects failed\n", __func__);
757 goto out;
758 }
759
760 if (nbRects != 2)
761 {
762 (void)fprintf(stderr, "%s: Error 7 - expected nbRects == 2 but got %" PRIu32 "\n", __func__,
763 nbRects);
764 goto out;
765 }
766
767 if (!compareRectangles(&rects[0], &rect2, 1))
768 {
769 (void)fprintf(stderr, "%s: Error 8 - compare failed\n", __func__);
770 goto out;
771 }
772
773 if (!compareRectangles(&rects[1], &rect1, 1))
774 {
775 (void)fprintf(stderr, "%s: Error 9 - compare failed\n", __func__);
776 goto out;
777 }
778
779 retCode = 0;
780out:
781 region16_uninit(&region);
782 return retCode;
783}
784
785static int test_empty_rectangle(void)
786{
787 REGION16 region;
788 REGION16 intersection;
789 int retCode = -1;
790 RECTANGLE_16 emptyRectangles[3] = { { 0, 0, 0, 0 }, { 10, 10, 10, 11 }, { 10, 10, 11, 10 } };
791 RECTANGLE_16 firstRect = { 0, 0, 100, 100 };
792 RECTANGLE_16 anotherRect = { 100, 100, 200, 200 };
793 RECTANGLE_16 expected_inter_extents = { 0, 0, 0, 0 };
794 region16_init(&region);
795 region16_init(&intersection);
796
797 /* Check for empty rectangles */
798 for (int i = 0; i < 3; i++)
799 {
800 if (!rectangle_is_empty(&emptyRectangles[i]))
801 goto out;
802 }
803
804 /* Check for non-empty rectangles */
805 if (rectangle_is_empty(&firstRect))
806 goto out;
807
808 /* Intersect 2 non-intersect rectangle, result should be empty */
809 if (!region16_union_rect(&region, &region, &firstRect))
810 goto out;
811
812 if (!region16_intersect_rect(&region, &region, &anotherRect))
813 goto out;
814
815 if (!compareRectangles(region16_extents(&region), &expected_inter_extents, 1))
816 goto out;
817
818 if (!region16_is_empty(&region))
819 goto out;
820
821 if (!rectangle_is_empty(region16_extents(&intersection)))
822 goto out;
823
824 retCode = 0;
825out:
826 region16_uninit(&intersection);
827 region16_uninit(&region);
828 return retCode;
829}
830
831typedef int (*TestFunction)(void);
832struct UnitaryTest
833{
834 const char* name;
835 TestFunction func;
836};
837
838static struct UnitaryTest tests[] = { { "Basic trivial tests", test_basic },
839 { "R1+R3 and R3+R1", test_r1_r3 },
840 { "R1+R5", test_r1_r5 },
841 { "R1+R6", test_r1_r6 },
842 { "R9+R10", test_r9_r10 },
843 { "R1+R2+R4", test_r1_r2_r4 },
844 { "R1+R7+R8 in many orders", test_r1_r7_r8 },
845 { "R1+R2+R3+R4", test_r1_r2_r3_r4 },
846 { "data from weston", test_from_weston },
847 { "R1 & R3", test_r1_inter_r3 },
848 { "(R1+R3)&R11 (band merge)", test_r1_r3_inter_r11 },
849 { "norbert's case", test_norbert_case },
850 { "norbert's case 2", test_norbert2_case },
851 { "empty rectangle case", test_empty_rectangle },
852
853 { NULL, NULL } };
854
855int TestFreeRDPRegion(int argc, char* argv[])
856{
857 int testNb = 0;
858 int retCode = -1;
859 WINPR_UNUSED(argc);
860 WINPR_UNUSED(argv);
861
862 for (int i = 0; tests[i].func; i++)
863 {
864 testNb++;
865 (void)fprintf(stderr, "%d: %s\n", testNb, tests[i].name);
866 retCode = tests[i].func();
867
868 if (retCode < 0)
869 break;
870 }
871
872 if (retCode < 0)
873 (void)fprintf(stderr, "failed for test %d\n", testNb);
874
875 return retCode;
876}