Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / skia / tests / RegionTest.cpp
1 /*
2  * Copyright 2011 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7
8 #include "include/core/SkPath.h"
9 #include "include/core/SkRRect.h"
10 #include "include/core/SkRegion.h"
11 #include "include/utils/SkRandom.h"
12 #include "src/core/SkAutoMalloc.h"
13 #include "tests/Test.h"
14
15 static void Union(SkRegion* rgn, const SkIRect& rect) {
16     rgn->op(rect, SkRegion::kUnion_Op);
17 }
18
19 #define TEST_NO_INTERSECT(rgn, rect)    REPORTER_ASSERT(reporter, !rgn.intersects(rect))
20 #define TEST_INTERSECT(rgn, rect)       REPORTER_ASSERT(reporter, rgn.intersects(rect))
21 #define TEST_NO_CONTAINS(rgn, rect)     REPORTER_ASSERT(reporter, !rgn.contains(rect))
22
23 // inspired by http://code.google.com/p/skia/issues/detail?id=958
24 //
25 static void test_fromchrome(skiatest::Reporter* reporter) {
26     SkRegion r;
27     Union(&r, SkIRect::MakeXYWH(0, 0, 1, 1));
28     TEST_NO_INTERSECT(r, SkIRect::MakeXYWH(0, 0, 0, 0));
29     TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 0, 2, 2));
30     TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, 0, 2, 2));
31     TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, -1, 2, 2));
32     TEST_INTERSECT(r, SkIRect::MakeXYWH(0, -1, 2, 2));
33     TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, -1, 3, 3));
34
35     Union(&r, SkIRect::MakeXYWH(0, 0, 3, 3));
36     Union(&r, SkIRect::MakeXYWH(10, 0, 3, 3));
37     Union(&r, SkIRect::MakeXYWH(0, 10, 13, 3));
38     TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, -1, 2, 2));
39     TEST_INTERSECT(r, SkIRect::MakeXYWH(2, -1, 2, 2));
40     TEST_INTERSECT(r, SkIRect::MakeXYWH(2, 2, 2, 2));
41     TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, 2, 2, 2));
42
43     TEST_INTERSECT(r, SkIRect::MakeXYWH(9, -1, 2, 2));
44     TEST_INTERSECT(r, SkIRect::MakeXYWH(12, -1, 2, 2));
45     TEST_INTERSECT(r, SkIRect::MakeXYWH(12, 2, 2, 2));
46     TEST_INTERSECT(r, SkIRect::MakeXYWH(9, 2, 2, 2));
47
48     TEST_INTERSECT(r, SkIRect::MakeXYWH(0, -1, 13, 5));
49     TEST_INTERSECT(r, SkIRect::MakeXYWH(1, -1, 11, 5));
50     TEST_INTERSECT(r, SkIRect::MakeXYWH(2, -1, 9, 5));
51     TEST_INTERSECT(r, SkIRect::MakeXYWH(2, -1, 8, 5));
52     TEST_INTERSECT(r, SkIRect::MakeXYWH(3, -1, 8, 5));
53
54     TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 1, 13, 1));
55     TEST_INTERSECT(r, SkIRect::MakeXYWH(1, 1, 11, 1));
56     TEST_INTERSECT(r, SkIRect::MakeXYWH(2, 1, 9, 1));
57     TEST_INTERSECT(r, SkIRect::MakeXYWH(2, 1, 8, 1));
58     TEST_INTERSECT(r, SkIRect::MakeXYWH(3, 1, 8, 1));
59
60     TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 0, 13, 13));
61     TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 1, 13, 11));
62     TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 2, 13, 9));
63     TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 2, 13, 8));
64
65
66     // These test SkRegion::contains(Rect) and SkRegion::contains(Region)
67
68     SkRegion container;
69     Union(&container, SkIRect::MakeXYWH(0, 0, 40, 20));
70     Union(&container, SkIRect::MakeXYWH(30, 20, 10, 20));
71     TEST_NO_CONTAINS(container, SkIRect::MakeXYWH(0, 0, 10, 39));
72     TEST_NO_CONTAINS(container, SkIRect::MakeXYWH(29, 0, 10, 39));
73
74     {
75         SkRegion rgn;
76         Union(&rgn, SkIRect::MakeXYWH(0, 0, 10, 10));
77         Union(&rgn, SkIRect::MakeLTRB(5, 10, 20, 20));
78         TEST_INTERSECT(rgn, SkIRect::MakeXYWH(15, 0, 5, 11));
79     }
80 }
81
82 static void test_empties(skiatest::Reporter* reporter) {
83     SkRegion valid(SkIRect::MakeWH(10, 10));
84     SkRegion empty, empty2;
85
86     REPORTER_ASSERT(reporter, empty.isEmpty());
87     REPORTER_ASSERT(reporter, !valid.isEmpty());
88
89     // test intersects
90     REPORTER_ASSERT(reporter, !empty.intersects(empty2));
91     REPORTER_ASSERT(reporter, !valid.intersects(empty));
92
93     // test contains
94     REPORTER_ASSERT(reporter, !empty.contains(empty2));
95     REPORTER_ASSERT(reporter, !valid.contains(empty));
96     REPORTER_ASSERT(reporter, !empty.contains(valid));
97
98     SkPath emptyPath;
99     emptyPath.moveTo(1, 5);
100     emptyPath.close();
101     SkRegion openClip;
102     openClip.setRect({-16000, -16000, 16000, 16000});
103     empty.setPath(emptyPath, openClip);  // should not assert
104 }
105
106 enum {
107     W = 256,
108     H = 256
109 };
110
111 static SkIRect randRect(SkRandom& rand) {
112     int x = rand.nextU() % W;
113     int y = rand.nextU() % H;
114     int w = rand.nextU() % W;
115     int h = rand.nextU() % H;
116     return SkIRect::MakeXYWH(x, y, w >> 1, h >> 1);
117 }
118
119 static void randRgn(SkRandom& rand, SkRegion* rgn, int n) {
120     rgn->setEmpty();
121     for (int i = 0; i < n; ++i) {
122         rgn->op(randRect(rand), SkRegion::kUnion_Op);
123     }
124 }
125
126 static bool slow_contains(const SkRegion& outer, const SkRegion& inner) {
127     SkRegion tmp;
128     tmp.op(outer, inner, SkRegion::kUnion_Op);
129     return outer == tmp;
130 }
131
132 static bool slow_contains(const SkRegion& outer, const SkIRect& r) {
133     SkRegion tmp;
134     tmp.op(outer, SkRegion(r), SkRegion::kUnion_Op);
135     return outer == tmp;
136 }
137
138 static bool slow_intersects(const SkRegion& outer, const SkRegion& inner) {
139     SkRegion tmp;
140     return tmp.op(outer, inner, SkRegion::kIntersect_Op);
141 }
142
143 static void test_contains_iter(skiatest::Reporter* reporter, const SkRegion& rgn) {
144     SkRegion::Iterator iter(rgn);
145     while (!iter.done()) {
146         SkIRect r = iter.rect();
147         REPORTER_ASSERT(reporter, rgn.contains(r));
148         r.inset(-1, -1);
149         REPORTER_ASSERT(reporter, !rgn.contains(r));
150         iter.next();
151     }
152 }
153
154 static void contains_proc(skiatest::Reporter* reporter,
155                           const SkRegion& a, const SkRegion& b) {
156     // test rgn
157     bool c0 = a.contains(b);
158     bool c1 = slow_contains(a, b);
159     REPORTER_ASSERT(reporter, c0 == c1);
160
161     // test rect
162     SkIRect r = a.getBounds();
163     r.inset(r.width()/4, r.height()/4);
164     c0 = a.contains(r);
165     c1 = slow_contains(a, r);
166     REPORTER_ASSERT(reporter, c0 == c1);
167
168     test_contains_iter(reporter, a);
169     test_contains_iter(reporter, b);
170 }
171
172 static void test_intersects_iter(skiatest::Reporter* reporter, const SkRegion& rgn) {
173     SkRegion::Iterator iter(rgn);
174     while (!iter.done()) {
175         SkIRect r = iter.rect();
176         REPORTER_ASSERT(reporter, rgn.intersects(r));
177         r.inset(-1, -1);
178         REPORTER_ASSERT(reporter, rgn.intersects(r));
179         iter.next();
180     }
181 }
182
183 static void intersects_proc(skiatest::Reporter* reporter,
184                           const SkRegion& a, const SkRegion& b) {
185     bool c0 = a.intersects(b);
186     bool c1 = slow_intersects(a, b);
187     REPORTER_ASSERT(reporter, c0 == c1);
188
189     test_intersects_iter(reporter, a);
190     test_intersects_iter(reporter, b);
191 }
192
193 static void test_proc(skiatest::Reporter* reporter,
194                       void (*proc)(skiatest::Reporter*,
195                                    const SkRegion& a, const SkRegion&)) {
196     SkRandom rand;
197     for (int i = 0; i < 10000; ++i) {
198         SkRegion outer;
199         randRgn(rand, &outer, 8);
200         SkRegion inner;
201         randRgn(rand, &inner, 2);
202         proc(reporter, outer, inner);
203     }
204 }
205
206 static void rand_rect(SkIRect* rect, SkRandom& rand) {
207     int bits = 6;
208     int shift = 32 - bits;
209     rect->setLTRB(rand.nextU() >> shift, rand.nextU() >> shift,
210                   rand.nextU() >> shift, rand.nextU() >> shift);
211     rect->sort();
212 }
213
214 static bool test_rects(const SkIRect rect[], int count) {
215     SkRegion rgn0, rgn1;
216
217     for (int i = 0; i < count; i++) {
218         rgn0.op(rect[i], SkRegion::kUnion_Op);
219     }
220     rgn1.setRects(rect, count);
221
222     if (rgn0 != rgn1) {
223         SkDebugf("\n");
224         for (int i = 0; i < count; i++) {
225             SkDebugf(" { %d, %d, %d, %d },\n",
226                      rect[i].fLeft, rect[i].fTop,
227                      rect[i].fRight, rect[i].fBottom);
228         }
229         SkDebugf("\n");
230         return false;
231     }
232     return true;
233 }
234
235 DEF_TEST(Region, reporter) {
236     const SkIRect r2[] = {
237         { 0, 0, 1, 1 },
238         { 2, 2, 3, 3 },
239     };
240     REPORTER_ASSERT(reporter, test_rects(r2, SK_ARRAY_COUNT(r2)));
241
242     const SkIRect rects[] = {
243         { 0, 0, 1, 2 },
244         { 2, 1, 3, 3 },
245         { 4, 0, 5, 1 },
246         { 6, 0, 7, 4 },
247     };
248     REPORTER_ASSERT(reporter, test_rects(rects, SK_ARRAY_COUNT(rects)));
249
250     SkRandom rand;
251     for (int i = 0; i < 1000; i++) {
252         SkRegion rgn0, rgn1;
253
254         const int N = 8;
255         SkIRect rect[N];
256         for (int j = 0; j < N; j++) {
257             rand_rect(&rect[j], rand);
258         }
259         REPORTER_ASSERT(reporter, test_rects(rect, N));
260     }
261
262     test_proc(reporter, contains_proc);
263     test_proc(reporter, intersects_proc);
264     test_empties(reporter);
265     test_fromchrome(reporter);
266 }
267
268 // Test that writeToMemory reports the same number of bytes whether there was a
269 // buffer to write to or not.
270 static void test_write(const SkRegion& region, skiatest::Reporter* r) {
271     const size_t bytesNeeded = region.writeToMemory(nullptr);
272     SkAutoMalloc storage(bytesNeeded);
273     const size_t bytesWritten = region.writeToMemory(storage.get());
274     REPORTER_ASSERT(r, bytesWritten == bytesNeeded);
275
276     // Also check that the bytes are meaningful.
277     SkRegion copy;
278     REPORTER_ASSERT(r, copy.readFromMemory(storage.get(), bytesNeeded));
279     REPORTER_ASSERT(r, region == copy);
280 }
281
282 DEF_TEST(Region_writeToMemory, r) {
283     // Test an empty region.
284     SkRegion region;
285     REPORTER_ASSERT(r, region.isEmpty());
286     test_write(region, r);
287
288     // Test a rectangular region
289     bool nonEmpty = region.setRect({0, 0, 50, 50});
290     REPORTER_ASSERT(r, nonEmpty);
291     REPORTER_ASSERT(r, region.isRect());
292     test_write(region, r);
293
294     // Test a complex region
295     nonEmpty = region.op({50, 50, 100, 100}, SkRegion::kUnion_Op);
296     REPORTER_ASSERT(r, nonEmpty);
297     REPORTER_ASSERT(r, region.isComplex());
298     test_write(region, r);
299
300     SkRegion complexRegion;
301     Union(&complexRegion, SkIRect::MakeXYWH(0, 0, 1, 1));
302     Union(&complexRegion, SkIRect::MakeXYWH(0, 0, 3, 3));
303     Union(&complexRegion, SkIRect::MakeXYWH(10, 0, 3, 3));
304     Union(&complexRegion, SkIRect::MakeXYWH(0, 10, 13, 3));
305     test_write(complexRegion, r);
306
307     Union(&complexRegion, SkIRect::MakeXYWH(10, 20, 3, 3));
308     Union(&complexRegion, SkIRect::MakeXYWH(0,  20, 3, 3));
309     test_write(complexRegion, r);
310 }
311
312 DEF_TEST(Region_readFromMemory_bad, r) {
313     // These assume what our binary format is: conceivably we could change it
314     // and might need to remove or change some of these tests.
315     SkRegion region;
316
317     {
318         // invalid boundary rectangle
319         int32_t data[5] = {0, 4, 4, 8, 2};
320         REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
321     }
322     // Region Layout, Serialized Format:
323     //    COUNT LEFT TOP RIGHT BOTTOM Y_SPAN_COUNT TOTAL_INTERVAL_COUNT
324     //    Top ( Bottom Span_Interval_Count ( Left Right )* Sentinel )+ Sentinel
325     {
326         // Example of valid data
327         int32_t data[] = {9, 0, 0, 10, 10, 1, 2, 0, 10, 2, 0, 4, 6, 10,
328                           2147483647, 2147483647};
329         REPORTER_ASSERT(r, 0 != region.readFromMemory(data, sizeof(data)));
330     }
331     {
332         // Example of valid data with 4 intervals
333         int32_t data[] = {19, 0, 0, 30, 30, 3, 4, 0, 10, 2, 0, 10, 20, 30,
334                           2147483647, 20, 0, 2147483647, 30, 2, 0, 10, 20, 30,
335                           2147483647, 2147483647};
336         REPORTER_ASSERT(r, 0 != region.readFromMemory(data, sizeof(data)));
337     }
338     {
339         // Short count
340         int32_t data[] = {8, 0, 0, 10, 10, 1, 2, 0, 10, 2, 0, 4, 6, 10,
341                           2147483647, 2147483647};
342         REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
343     }
344     {
345         // bounds don't match
346         int32_t data[] = {9, 0, 0, 10, 11, 1, 2, 0, 10, 2, 0, 4, 6, 10,
347                           2147483647, 2147483647};
348         REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
349     }
350     {
351         //  bad yspan count
352         int32_t data[] = {9, 0, 0, 10, 10, 2, 2, 0, 10, 2, 0, 4, 6, 10,
353                           2147483647, 2147483647};
354         REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
355     }
356     {
357         // bad int count
358         int32_t data[] = {9, 0, 0, 10, 10, 1, 3, 0, 10, 2, 0, 4, 6, 10,
359                           2147483647, 2147483647};
360         REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
361     }
362     {
363         // bad final sentinal
364         int32_t data[] = {9, 0, 0, 10, 10, 1, 2, 0, 10, 2, 0, 4, 6, 10,
365                           2147483647, -1};
366         REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
367     }
368     {
369         // bad row sentinal
370         int32_t data[] = {9, 0, 0, 10, 10, 1, 2, 0, 10, 2, 0, 4, 6, 10,
371                           -1, 2147483647};
372         REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
373     }
374     {
375         // starts with empty yspan
376         int32_t data[] = {12, 0, 0, 10, 10, 2, 2, -5, 0, 0, 2147483647, 10,
377                           2, 0, 4, 6, 10, 2147483647, 2147483647};
378         REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
379     }
380     {
381         // ends with empty yspan
382         int32_t data[] = {12, 0, 0, 10, 10, 2, 2, 0, 10, 2, 0, 4, 6, 10,
383                           2147483647, 15, 0, 2147483647, 2147483647};
384         REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
385     }
386     {
387         // y intervals out of order
388         int32_t data[] = {19, 0, -20, 30, 10, 3, 4, 0, 10, 2, 0, 10, 20, 30,
389                           2147483647, -20, 0, 2147483647, -10, 2, 0, 10, 20, 30,
390                           2147483647, 2147483647};
391         REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
392     }
393     {
394         // x intervals out of order
395         int32_t data[] = {9, 0, 0, 10, 10, 1, 2, 0, 10, 2, 6, 10, 0, 4,
396                           2147483647, 2147483647};
397         REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
398     }
399 }
400
401 DEF_TEST(region_toobig, reporter) {
402     const int big = 1 << 30;
403     const SkIRect neg = SkIRect::MakeXYWH(-big, -big, 10, 10);
404     const SkIRect pos = SkIRect::MakeXYWH( big,  big, 10, 10);
405
406     REPORTER_ASSERT(reporter, !neg.isEmpty());
407     REPORTER_ASSERT(reporter, !pos.isEmpty());
408
409     SkRegion negR(neg);
410     SkRegion posR(pos);
411
412     REPORTER_ASSERT(reporter, !negR.isEmpty());
413     REPORTER_ASSERT(reporter, !posR.isEmpty());
414
415     SkRegion rgn;
416     rgn.op(negR, posR, SkRegion::kUnion_Op);
417
418     // If we union those to rectangles, the resulting coordinates span more than int32_t, so
419     // we must mark the region as empty.
420     REPORTER_ASSERT(reporter, rgn.isEmpty());
421 }
422
423 DEF_TEST(region_inverse_union_skbug_7491, reporter) {
424     SkPath path;
425     path.setFillType(SkPathFillType::kInverseWinding);
426     path.moveTo(10, 20); path.lineTo(10, 30); path.lineTo(10.1f, 10); path.close();
427
428     SkRegion clip;
429     clip.op(SkIRect::MakeLTRB(10, 10, 15, 20), SkRegion::kUnion_Op);
430     clip.op(SkIRect::MakeLTRB(20, 10, 25, 20), SkRegion::kUnion_Op);
431
432     SkRegion rgn;
433     rgn.setPath(path, clip);
434
435     REPORTER_ASSERT(reporter, clip == rgn);
436 }
437
438 DEF_TEST(giant_path_region, reporter) {
439     const SkScalar big = 32767;
440     SkPath path;
441     path.moveTo(-big, 0);
442     path.quadTo(big, 0, big, big);
443     SkIRect ir = path.getBounds().round();
444     SkRegion rgn;
445     rgn.setPath(path, SkRegion(ir));
446 }
447
448 DEF_TEST(rrect_region_crbug_850350, reporter) {
449     SkMatrix m;
450     m.reset();
451     m[1] = 0.753662348f;
452     m[3] = 1.40079998E+20f;
453
454     const SkPoint corners[] = {
455         { 2.65876e-19f, 0.0194088f },
456         { 4896, 0.00114702f },
457         { 0, 0 },
458         { 0.00114702f, 0.00495333f },
459     };
460     SkRRect rrect;
461     rrect.setRectRadii({-8.72387e-31f, 1.29996e-38f, 4896, 1.125f}, corners);
462
463     SkPath path;
464     path.addRRect(rrect);
465     path.transform(m);
466
467     SkRegion rgn;
468     rgn.setPath(path, SkRegion{SkIRect{0, 0, 24, 24}});
469 }
470
471 DEF_TEST(region_bug_chromium_873051, reporter) {
472     SkRegion region;
473     REPORTER_ASSERT(reporter,  region.setRect({0, 0, 0x7FFFFFFE, 0x7FFFFFFE}));
474     REPORTER_ASSERT(reporter, !region.setRect({0, 0, 0x7FFFFFFE, 0x7FFFFFFF}));
475     REPORTER_ASSERT(reporter, !region.setRect({0, 0, 0x7FFFFFFF, 0x7FFFFFFE}));
476     REPORTER_ASSERT(reporter, !region.setRect({0, 0, 0x7FFFFFFF, 0x7FFFFFFF}));
477 }
478
479 DEF_TEST(region_empty_iter, reporter) {
480     SkRegion::Iterator emptyIter;
481     REPORTER_ASSERT(reporter, !emptyIter.rewind());
482     REPORTER_ASSERT(reporter, emptyIter.done());
483     auto eRect = emptyIter.rect();
484     REPORTER_ASSERT(reporter, eRect.isEmpty());
485     REPORTER_ASSERT(reporter, SkIRect::MakeEmpty() == eRect);
486     REPORTER_ASSERT(reporter, !emptyIter.rgn());
487
488     SkRegion region;
489     SkRegion::Iterator resetIter;
490     resetIter.reset(region);
491     REPORTER_ASSERT(reporter, resetIter.rewind());
492     REPORTER_ASSERT(reporter, resetIter.done());
493     auto rRect = resetIter.rect();
494     REPORTER_ASSERT(reporter, rRect.isEmpty());
495     REPORTER_ASSERT(reporter, SkIRect::MakeEmpty() == rRect);
496     REPORTER_ASSERT(reporter, resetIter.rgn());
497     REPORTER_ASSERT(reporter, resetIter.rgn()->isEmpty());
498
499     SkRegion::Iterator iter(region);
500     REPORTER_ASSERT(reporter, iter.done());
501     auto iRect = iter.rect();
502     REPORTER_ASSERT(reporter, iRect.isEmpty());
503     REPORTER_ASSERT(reporter, SkIRect::MakeEmpty() == iRect);
504     REPORTER_ASSERT(reporter, iter.rgn());
505     REPORTER_ASSERT(reporter, iter.rgn()->isEmpty());
506
507     SkRegion::Cliperator clipIter(region, {0, 0, 100, 100});
508     REPORTER_ASSERT(reporter, clipIter.done());
509     auto cRect = clipIter.rect();
510     REPORTER_ASSERT(reporter, cRect.isEmpty());
511     REPORTER_ASSERT(reporter, SkIRect::MakeEmpty() == cRect);
512
513     SkRegion::Spanerator spanIter(region, 0, 0, 100);
514     int left = 0, right = 0;
515     REPORTER_ASSERT(reporter, !spanIter.next(&left, &right));
516     REPORTER_ASSERT(reporter, !left);
517     REPORTER_ASSERT(reporter, !right);
518 }