Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
RegionTest.cpp
Go to the documentation of this file.
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
13#include "include/core/SkRect.h"
19#include "src/base/SkRandom.h"
20#include "src/core/SkScan.h"
21#include "tests/Test.h"
22
23#include <array>
24#include <cstddef>
25#include <cstdint>
26
27static void Union(SkRegion* rgn, const SkIRect& rect) {
28 rgn->op(rect, SkRegion::kUnion_Op);
29}
30
31#define TEST_NO_INTERSECT(rgn, rect) REPORTER_ASSERT(reporter, !rgn.intersects(rect))
32#define TEST_INTERSECT(rgn, rect) REPORTER_ASSERT(reporter, rgn.intersects(rect))
33#define TEST_NO_CONTAINS(rgn, rect) REPORTER_ASSERT(reporter, !rgn.contains(rect))
34
35// inspired by http://code.google.com/p/skia/issues/detail?id=958
36//
38 SkRegion r;
39 Union(&r, SkIRect::MakeXYWH(0, 0, 1, 1));
41 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 0, 2, 2));
42 TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, 0, 2, 2));
43 TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, -1, 2, 2));
44 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, -1, 2, 2));
45 TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, -1, 3, 3));
46
47 Union(&r, SkIRect::MakeXYWH(0, 0, 3, 3));
48 Union(&r, SkIRect::MakeXYWH(10, 0, 3, 3));
49 Union(&r, SkIRect::MakeXYWH(0, 10, 13, 3));
50 TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, -1, 2, 2));
51 TEST_INTERSECT(r, SkIRect::MakeXYWH(2, -1, 2, 2));
52 TEST_INTERSECT(r, SkIRect::MakeXYWH(2, 2, 2, 2));
53 TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, 2, 2, 2));
54
55 TEST_INTERSECT(r, SkIRect::MakeXYWH(9, -1, 2, 2));
56 TEST_INTERSECT(r, SkIRect::MakeXYWH(12, -1, 2, 2));
57 TEST_INTERSECT(r, SkIRect::MakeXYWH(12, 2, 2, 2));
58 TEST_INTERSECT(r, SkIRect::MakeXYWH(9, 2, 2, 2));
59
60 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, -1, 13, 5));
61 TEST_INTERSECT(r, SkIRect::MakeXYWH(1, -1, 11, 5));
62 TEST_INTERSECT(r, SkIRect::MakeXYWH(2, -1, 9, 5));
63 TEST_INTERSECT(r, SkIRect::MakeXYWH(2, -1, 8, 5));
64 TEST_INTERSECT(r, SkIRect::MakeXYWH(3, -1, 8, 5));
65
66 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 1, 13, 1));
67 TEST_INTERSECT(r, SkIRect::MakeXYWH(1, 1, 11, 1));
68 TEST_INTERSECT(r, SkIRect::MakeXYWH(2, 1, 9, 1));
69 TEST_INTERSECT(r, SkIRect::MakeXYWH(2, 1, 8, 1));
70 TEST_INTERSECT(r, SkIRect::MakeXYWH(3, 1, 8, 1));
71
72 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 0, 13, 13));
73 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 1, 13, 11));
74 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 2, 13, 9));
75 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 2, 13, 8));
76
77
78 // These test SkRegion::contains(Rect) and SkRegion::contains(Region)
79
80 SkRegion container;
81 Union(&container, SkIRect::MakeXYWH(0, 0, 40, 20));
82 Union(&container, SkIRect::MakeXYWH(30, 20, 10, 20));
83 TEST_NO_CONTAINS(container, SkIRect::MakeXYWH(0, 0, 10, 39));
84 TEST_NO_CONTAINS(container, SkIRect::MakeXYWH(29, 0, 10, 39));
85
86 {
87 SkRegion rgn;
88 Union(&rgn, SkIRect::MakeXYWH(0, 0, 10, 10));
89 Union(&rgn, SkIRect::MakeLTRB(5, 10, 20, 20));
90 TEST_INTERSECT(rgn, SkIRect::MakeXYWH(15, 0, 5, 11));
91 }
92}
93
95 SkRegion valid(SkIRect::MakeWH(10, 10));
96 SkRegion empty, empty2;
97
98 REPORTER_ASSERT(reporter, empty.isEmpty());
100
101 // test intersects
102 REPORTER_ASSERT(reporter, !empty.intersects(empty2));
104
105 // test contains
106 REPORTER_ASSERT(reporter, !empty.contains(empty2));
108 REPORTER_ASSERT(reporter, !empty.contains(valid));
109
110 SkPath emptyPath;
111 emptyPath.moveTo(1, 5);
112 emptyPath.close();
113 SkRegion openClip;
114 openClip.setRect({-16000, -16000, 16000, 16000});
115 empty.setPath(emptyPath, openClip); // should not assert
116}
117
118enum {
119 W = 256,
120 H = 256
122
123static SkIRect randRect(SkRandom& rand) {
124 int x = rand.nextU() % W;
125 int y = rand.nextU() % H;
126 int w = rand.nextU() % W;
127 int h = rand.nextU() % H;
128 return SkIRect::MakeXYWH(x, y, w >> 1, h >> 1);
129}
130
131static void randRgn(SkRandom& rand, SkRegion* rgn, int n) {
132 rgn->setEmpty();
133 for (int i = 0; i < n; ++i) {
134 rgn->op(randRect(rand), SkRegion::kUnion_Op);
135 }
136}
137
138static bool slow_contains(const SkRegion& outer, const SkRegion& inner) {
139 SkRegion tmp;
140 tmp.op(outer, inner, SkRegion::kUnion_Op);
141 return outer == tmp;
142}
143
144static bool slow_contains(const SkRegion& outer, const SkIRect& r) {
145 SkRegion tmp;
146 tmp.op(outer, SkRegion(r), SkRegion::kUnion_Op);
147 return outer == tmp;
148}
149
150static bool slow_intersects(const SkRegion& outer, const SkRegion& inner) {
151 SkRegion tmp;
152 return tmp.op(outer, inner, SkRegion::kIntersect_Op);
153}
154
156 SkRegion::Iterator iter(rgn);
157 while (!iter.done()) {
158 SkIRect r = iter.rect();
160 r.inset(-1, -1);
162 iter.next();
163 }
164}
165
167 const SkRegion& a, const SkRegion& b) {
168 // test rgn
169 bool c0 = a.contains(b);
170 bool c1 = slow_contains(a, b);
171 REPORTER_ASSERT(reporter, c0 == c1);
172
173 // test rect
174 SkIRect r = a.getBounds();
175 r.inset(r.width()/4, r.height()/4);
176 c0 = a.contains(r);
177 c1 = slow_contains(a, r);
178 REPORTER_ASSERT(reporter, c0 == c1);
179
182}
183
185 SkRegion::Iterator iter(rgn);
186 while (!iter.done()) {
187 SkIRect r = iter.rect();
189 r.inset(-1, -1);
191 iter.next();
192 }
193}
194
196 const SkRegion& a, const SkRegion& b) {
197 bool c0 = a.intersects(b);
198 bool c1 = slow_intersects(a, b);
199 REPORTER_ASSERT(reporter, c0 == c1);
200
203}
204
206 void (*proc)(skiatest::Reporter*,
207 const SkRegion& a, const SkRegion&)) {
208 SkRandom rand;
209 for (int i = 0; i < 10000; ++i) {
210 SkRegion outer;
211 randRgn(rand, &outer, 8);
212 SkRegion inner;
213 randRgn(rand, &inner, 2);
214 proc(reporter, outer, inner);
215 }
216}
217
218static void rand_rect(SkIRect* rect, SkRandom& rand) {
219 int bits = 6;
220 int shift = 32 - bits;
221 rect->setLTRB(rand.nextU() >> shift, rand.nextU() >> shift,
222 rand.nextU() >> shift, rand.nextU() >> shift);
223 rect->sort();
224}
225
226static bool test_rects(const SkIRect rect[], int count) {
227 SkRegion rgn0, rgn1;
228
229 for (int i = 0; i < count; i++) {
230 rgn0.op(rect[i], SkRegion::kUnion_Op);
231 }
232 rgn1.setRects(rect, count);
233
234 if (rgn0 != rgn1) {
235 SkDebugf("\n");
236 for (int i = 0; i < count; i++) {
237 SkDebugf(" { %d, %d, %d, %d },\n",
238 rect[i].fLeft, rect[i].fTop,
239 rect[i].fRight, rect[i].fBottom);
240 }
241 SkDebugf("\n");
242 return false;
243 }
244 return true;
245}
246
248 const SkIRect r2[] = {
249 { 0, 0, 1, 1 },
250 { 2, 2, 3, 3 },
251 };
252 REPORTER_ASSERT(reporter, test_rects(r2, std::size(r2)));
253
254 const SkIRect rects[] = {
255 { 0, 0, 1, 2 },
256 { 2, 1, 3, 3 },
257 { 4, 0, 5, 1 },
258 { 6, 0, 7, 4 },
259 };
260 REPORTER_ASSERT(reporter, test_rects(rects, std::size(rects)));
261
262 SkRandom rand;
263 for (int i = 0; i < 1000; i++) {
264 SkRegion rgn0, rgn1;
265
266 const int N = 8;
267 SkIRect rect[N];
268 for (int j = 0; j < N; j++) {
269 rand_rect(&rect[j], rand);
270 }
272 }
273
278}
279
280// Test that writeToMemory reports the same number of bytes whether there was a
281// buffer to write to or not.
282static void test_write(const SkRegion& region, skiatest::Reporter* r) {
283 const size_t bytesNeeded = region.writeToMemory(nullptr);
284 SkAutoMalloc storage(bytesNeeded);
285 const size_t bytesWritten = region.writeToMemory(storage.get());
286 REPORTER_ASSERT(r, bytesWritten == bytesNeeded);
287
288 // Also check that the bytes are meaningful.
290 REPORTER_ASSERT(r, copy.readFromMemory(storage.get(), bytesNeeded));
291 REPORTER_ASSERT(r, region == copy);
292}
293
294DEF_TEST(Region_writeToMemory, r) {
295 // Test an empty region.
296 SkRegion region;
297 REPORTER_ASSERT(r, region.isEmpty());
298 test_write(region, r);
299
300 // Test a rectangular region
301 bool nonEmpty = region.setRect({0, 0, 50, 50});
302 REPORTER_ASSERT(r, nonEmpty);
303 REPORTER_ASSERT(r, region.isRect());
304 test_write(region, r);
305
306 // Test a complex region
307 nonEmpty = region.op({50, 50, 100, 100}, SkRegion::kUnion_Op);
308 REPORTER_ASSERT(r, nonEmpty);
309 REPORTER_ASSERT(r, region.isComplex());
310 test_write(region, r);
311
312 SkRegion complexRegion;
313 Union(&complexRegion, SkIRect::MakeXYWH(0, 0, 1, 1));
314 Union(&complexRegion, SkIRect::MakeXYWH(0, 0, 3, 3));
315 Union(&complexRegion, SkIRect::MakeXYWH(10, 0, 3, 3));
316 Union(&complexRegion, SkIRect::MakeXYWH(0, 10, 13, 3));
317 test_write(complexRegion, r);
318
319 Union(&complexRegion, SkIRect::MakeXYWH(10, 20, 3, 3));
320 Union(&complexRegion, SkIRect::MakeXYWH(0, 20, 3, 3));
321 test_write(complexRegion, r);
322}
323
324DEF_TEST(Region_readFromMemory_bad, r) {
325 // These assume what our binary format is: conceivably we could change it
326 // and might need to remove or change some of these tests.
327 SkRegion region;
328
329 {
330 // invalid boundary rectangle
331 int32_t data[5] = {0, 4, 4, 8, 2};
332 REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
333 }
334 // Region Layout, Serialized Format:
335 // COUNT LEFT TOP RIGHT BOTTOM Y_SPAN_COUNT TOTAL_INTERVAL_COUNT
336 // Top ( Bottom Span_Interval_Count ( Left Right )* Sentinel )+ Sentinel
337 {
338 // Example of valid data
339 int32_t data[] = {9, 0, 0, 10, 10, 1, 2, 0, 10, 2, 0, 4, 6, 10,
340 2147483647, 2147483647};
341 REPORTER_ASSERT(r, 0 != region.readFromMemory(data, sizeof(data)));
342 }
343 {
344 // Example of valid data with 4 intervals
345 int32_t data[] = {19, 0, 0, 30, 30, 3, 4, 0, 10, 2, 0, 10, 20, 30,
346 2147483647, 20, 0, 2147483647, 30, 2, 0, 10, 20, 30,
347 2147483647, 2147483647};
348 REPORTER_ASSERT(r, 0 != region.readFromMemory(data, sizeof(data)));
349 }
350 {
351 // Short count
352 int32_t data[] = {8, 0, 0, 10, 10, 1, 2, 0, 10, 2, 0, 4, 6, 10,
353 2147483647, 2147483647};
354 REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
355 }
356 {
357 // bounds don't match
358 int32_t data[] = {9, 0, 0, 10, 11, 1, 2, 0, 10, 2, 0, 4, 6, 10,
359 2147483647, 2147483647};
360 REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
361 }
362 {
363 // bad yspan count
364 int32_t data[] = {9, 0, 0, 10, 10, 2, 2, 0, 10, 2, 0, 4, 6, 10,
365 2147483647, 2147483647};
366 REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
367 }
368 {
369 // bad int count
370 int32_t data[] = {9, 0, 0, 10, 10, 1, 3, 0, 10, 2, 0, 4, 6, 10,
371 2147483647, 2147483647};
372 REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
373 }
374 {
375 // bad final sentinal
376 int32_t data[] = {9, 0, 0, 10, 10, 1, 2, 0, 10, 2, 0, 4, 6, 10,
377 2147483647, -1};
378 REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
379 }
380 {
381 // bad row sentinal
382 int32_t data[] = {9, 0, 0, 10, 10, 1, 2, 0, 10, 2, 0, 4, 6, 10,
383 -1, 2147483647};
384 REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
385 }
386 {
387 // starts with empty yspan
388 int32_t data[] = {12, 0, 0, 10, 10, 2, 2, -5, 0, 0, 2147483647, 10,
389 2, 0, 4, 6, 10, 2147483647, 2147483647};
390 REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
391 }
392 {
393 // ends with empty yspan
394 int32_t data[] = {12, 0, 0, 10, 10, 2, 2, 0, 10, 2, 0, 4, 6, 10,
395 2147483647, 15, 0, 2147483647, 2147483647};
396 REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
397 }
398 {
399 // y intervals out of order
400 int32_t data[] = {19, 0, -20, 30, 10, 3, 4, 0, 10, 2, 0, 10, 20, 30,
401 2147483647, -20, 0, 2147483647, -10, 2, 0, 10, 20, 30,
402 2147483647, 2147483647};
403 REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
404 }
405 {
406 // x intervals out of order
407 int32_t data[] = {9, 0, 0, 10, 10, 1, 2, 0, 10, 2, 6, 10, 0, 4,
408 2147483647, 2147483647};
409 REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
410 }
411}
412
413DEF_TEST(region_toobig, reporter) {
414 const int big = 1 << 30;
415 const SkIRect neg = SkIRect::MakeXYWH(-big, -big, 10, 10);
416 const SkIRect pos = SkIRect::MakeXYWH( big, big, 10, 10);
417
419 REPORTER_ASSERT(reporter, !pos.isEmpty());
420
421 SkRegion negR(neg);
422 SkRegion posR(pos);
423
426
427 SkRegion rgn;
428 rgn.op(negR, posR, SkRegion::kUnion_Op);
429
430 // If we union those to rectangles, the resulting coordinates span more than int32_t, so
431 // we must mark the region as empty.
433}
434
435DEF_TEST(region_inverse_union_skbug_7491, reporter) {
436 SkPath path;
437 path.setFillType(SkPathFillType::kInverseWinding);
438 path.moveTo(10, 20); path.lineTo(10, 30); path.lineTo(10.1f, 10); path.close();
439
441 clip.op(SkIRect::MakeLTRB(10, 10, 15, 20), SkRegion::kUnion_Op);
442 clip.op(SkIRect::MakeLTRB(20, 10, 25, 20), SkRegion::kUnion_Op);
443
444 SkRegion rgn;
445 rgn.setPath(path, clip);
446
448}
449
450DEF_TEST(giant_path_region, reporter) {
451 const SkScalar big = 32767;
452 SkPath path;
453 path.moveTo(-big, 0);
454 path.quadTo(big, 0, big, big);
455 SkIRect ir = path.getBounds().round();
456 SkRegion rgn;
457 rgn.setPath(path, SkRegion(ir));
458}
459
460DEF_TEST(rrect_region_crbug_850350, reporter) {
461 SkMatrix m;
462 m.reset();
463 m[1] = 0.753662348f;
464 m[3] = 1.40079998E+20f;
465
466 const SkPoint corners[] = {
467 { 2.65876e-19f, 0.0194088f },
468 { 4896, 0.00114702f },
469 { 0, 0 },
470 { 0.00114702f, 0.00495333f },
471 };
472 SkRRect rrect;
473 rrect.setRectRadii({-8.72387e-31f, 1.29996e-38f, 4896, 1.125f}, corners);
474
475 SkPath path;
476 path.addRRect(rrect);
477 path.transform(m);
478
479 SkRegion rgn;
480 rgn.setPath(path, SkRegion{SkIRect{0, 0, 24, 24}});
481}
482
483DEF_TEST(region_bug_chromium_873051, reporter) {
484 SkRegion region;
485 REPORTER_ASSERT(reporter, region.setRect({0, 0, 0x7FFFFFFE, 0x7FFFFFFE}));
486 REPORTER_ASSERT(reporter, !region.setRect({0, 0, 0x7FFFFFFE, 0x7FFFFFFF}));
487 REPORTER_ASSERT(reporter, !region.setRect({0, 0, 0x7FFFFFFF, 0x7FFFFFFE}));
488 REPORTER_ASSERT(reporter, !region.setRect({0, 0, 0x7FFFFFFF, 0x7FFFFFFF}));
489}
490
491DEF_TEST(region_empty_iter, reporter) {
492 SkRegion::Iterator emptyIter;
493 REPORTER_ASSERT(reporter, !emptyIter.rewind());
494 REPORTER_ASSERT(reporter, emptyIter.done());
495 auto eRect = emptyIter.rect();
496 REPORTER_ASSERT(reporter, eRect.isEmpty());
498 REPORTER_ASSERT(reporter, !emptyIter.rgn());
499
500 SkRegion region;
501 SkRegion::Iterator resetIter;
502 resetIter.reset(region);
503 REPORTER_ASSERT(reporter, resetIter.rewind());
504 REPORTER_ASSERT(reporter, resetIter.done());
505 auto rRect = resetIter.rect();
506 REPORTER_ASSERT(reporter, rRect.isEmpty());
508 REPORTER_ASSERT(reporter, resetIter.rgn());
509 REPORTER_ASSERT(reporter, resetIter.rgn()->isEmpty());
510
511 SkRegion::Iterator iter(region);
513 auto iRect = iter.rect();
514 REPORTER_ASSERT(reporter, iRect.isEmpty());
518
519 SkRegion::Cliperator clipIter(region, {0, 0, 100, 100});
520 REPORTER_ASSERT(reporter, clipIter.done());
521 auto cRect = clipIter.rect();
522 REPORTER_ASSERT(reporter, cRect.isEmpty());
524
525 SkRegion::Spanerator spanIter(region, 0, 0, 100);
526 int left = 0, right = 0;
527 REPORTER_ASSERT(reporter, !spanIter.next(&left, &right));
530}
531
532DEF_TEST(region_very_large, reporter) {
533 SkIRect clipBounds = {-45000, -45000, 45000, 45000};
535
536 // Create a path that is larger than the scan conversion limits of SkScan, which is internally
537 // used to convert a path to a region.
538 SkPath largePath = SkPath::RRect(SkRRect::MakeRectXY(SkRect::Make(clipBounds), 200.f, 200.f));
539
540 SkRegion largeRegion;
541 REPORTER_ASSERT(reporter, largeRegion.setPath(largePath, SkRegion{clipBounds}));
542
543 // The path should have been converted successfully, so the corners of clipBounds should not be
544 // contained due to the path's rounded corners.
545 REPORTER_ASSERT(reporter, !largeRegion.contains(-44995, -44995));
546 REPORTER_ASSERT(reporter, !largeRegion.contains(-44995, 44995));
547 REPORTER_ASSERT(reporter, !largeRegion.contains( 44995, -44995));
548 REPORTER_ASSERT(reporter, !largeRegion.contains( 44995, 44995));
549
550 // But these points should be within the rounded corners.
551 REPORTER_ASSERT(reporter, largeRegion.contains(-44600, -44600));
552 REPORTER_ASSERT(reporter, largeRegion.contains(-44600, 44600));
553 REPORTER_ASSERT(reporter, largeRegion.contains( 44600, -44600));
554 REPORTER_ASSERT(reporter, largeRegion.contains( 44600, 44600));
555
556 // Make another path shaped like a D, so two corners will have its large radii and the other two
557 // will be rectangular and thus clipped by the original region.
558 static const SkVector kLargeRadii[4] = { {0.f, 0.f}, // TL
559 {2000.f, 2000.f}, // TR
560 {2000.f, 2000.f}, // BR
561 {0.f, 0.f}}; // BL
562 SkRRect largeRRect;
563 largeRRect.setRectRadii(SkRect::Make(clipBounds), kLargeRadii);
564 REPORTER_ASSERT(reporter, largeRegion.setPath(SkPath::RRect(largeRRect), SkRegion{largeRegion}));
565
566 REPORTER_ASSERT(reporter, !largeRegion.contains(-44995, -44995));
567 REPORTER_ASSERT(reporter, !largeRegion.contains(-44995, 44995));
568 REPORTER_ASSERT(reporter, !largeRegion.contains( 44995, -44995));
569 REPORTER_ASSERT(reporter, !largeRegion.contains( 44995, 44995));
570
571 REPORTER_ASSERT(reporter, largeRegion.contains(-44600, -44600));
572 REPORTER_ASSERT(reporter, largeRegion.contains(-44600, 44600));
573 // Right side has been clipped by an even larger corner radii
574 REPORTER_ASSERT(reporter, !largeRegion.contains( 44600, -44600));
575 REPORTER_ASSERT(reporter, !largeRegion.contains( 44600, 44600));
576
577 // Now test that the very large path with a small clip also works
578 largePath = SkPath::RRect(SkRRect::MakeRectXY({0.f, 0.f, 45000.f, 45000.f}, 200.f, 200.f));
579 SkRegion smallRegion;
580 REPORTER_ASSERT(reporter, smallRegion.setPath(largePath, SkRegion{{0, 0, 500, 500}}));
581
582 REPORTER_ASSERT(reporter, !smallRegion.contains(5, 5));
583 REPORTER_ASSERT(reporter, smallRegion.contains(0, 499));
584 REPORTER_ASSERT(reporter, smallRegion.contains(499, 0));
585 REPORTER_ASSERT(reporter, smallRegion.contains(499, 499));
586}
reporter
int count
SkPoint pos
static void test_write(const SkRegion &region, skiatest::Reporter *r)
static void rand_rect(SkIRect *rect, SkRandom &rand)
static void intersects_proc(skiatest::Reporter *reporter, const SkRegion &a, const SkRegion &b)
static void test_intersects_iter(skiatest::Reporter *reporter, const SkRegion &rgn)
static void test_fromchrome(skiatest::Reporter *reporter)
static bool slow_intersects(const SkRegion &outer, const SkRegion &inner)
static void test_contains_iter(skiatest::Reporter *reporter, const SkRegion &rgn)
static bool test_rects(const SkIRect rect[], int count)
static void randRgn(SkRandom &rand, SkRegion *rgn, int n)
static void test_proc(skiatest::Reporter *reporter, void(*proc)(skiatest::Reporter *, const SkRegion &a, const SkRegion &))
#define TEST_NO_INTERSECT(rgn, rect)
@ H
@ W
static bool slow_contains(const SkRegion &outer, const SkRegion &inner)
static void test_empties(skiatest::Reporter *reporter)
static void Union(SkRegion *rgn, const SkIRect &rect)
#define TEST_NO_CONTAINS(rgn, rect)
#define TEST_INTERSECT(rgn, rect)
static SkIRect randRect(SkRandom &rand)
static void contains_proc(skiatest::Reporter *reporter, const SkRegion &a, const SkRegion &b)
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition SkPath.cpp:3824
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
#define DEF_TEST(name, reporter)
Definition Test.h:312
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
#define N
Definition beziers.cpp:19
void * get()
static SkPath RRect(const SkRRect &, SkPathDirection dir=SkPathDirection::kCW)
Definition SkPath.cpp:3534
SkPath & moveTo(SkScalar x, SkScalar y)
Definition SkPath.cpp:678
SkPath & close()
Definition SkPath.cpp:813
static SkRRect MakeRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
Definition SkRRect.h:180
void setRectRadii(const SkRect &rect, const SkVector radii[4])
Definition SkRRect.cpp:189
uint32_t nextU()
Definition SkRandom.h:42
const SkIRect & rect() const
Definition SkRegion.h:501
bool done() const
Definition SkRegion.h:488
void reset(const SkRegion &region)
const SkRegion * rgn() const
Definition SkRegion.h:507
bool next(int *left, int *right)
size_t readFromMemory(const void *buffer, size_t length)
bool setEmpty()
Definition SkRegion.cpp:185
bool contains(int32_t x, int32_t y) const
Definition SkRegion.cpp:364
@ kUnion_Op
target unioned with operand
Definition SkRegion.h:369
@ kIntersect_Op
target intersected with operand
Definition SkRegion.h:368
bool setRects(const SkIRect rects[], int count)
Definition SkRegion.cpp:657
bool isComplex() const
Definition SkRegion.h:158
bool isRect() const
Definition SkRegion.h:152
bool op(const SkIRect &rect, Op op)
Definition SkRegion.h:384
bool setRect(const SkIRect &rect)
Definition SkRegion.cpp:192
bool isEmpty() const
Definition SkRegion.h:146
bool setPath(const SkPath &path, const SkRegion &clip)
size_t writeToMemory(void *buffer) const
bool intersects(const SkIRect &rect) const
Definition SkRegion.cpp:502
static bool PathRequiresTiling(const SkIRect &bounds)
float SkScalar
Definition extension.cpp:12
static bool b
struct MyStruct a[10]
EMSCRIPTEN_KEEPALIVE void empty()
double y
double x
Definition copy.py:1
SkScalar w
SkScalar h
Definition SkMD5.cpp:130
void inset(int32_t dx, int32_t dy)
Definition SkRect.h:411
static constexpr SkIRect MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b)
Definition SkRect.h:91
constexpr int32_t height() const
Definition SkRect.h:165
static constexpr SkIRect MakeEmpty()
Definition SkRect.h:45
constexpr int32_t width() const
Definition SkRect.h:158
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
Definition SkRect.h:56
bool isEmpty() const
Definition SkRect.h:202
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
Definition SkRect.h:104
static SkRect Make(const SkISize &size)
Definition SkRect.h:669