Flutter Engine
The Flutter Engine
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) {
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++) {
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 };
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 };
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.
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));
292}
293
294DEF_TEST(Region_writeToMemory, r) {
295 // Test an empty region.
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);
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);
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.
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;
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 };
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) {
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
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
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
Definition: FontMgrTest.cpp:39
int count
Definition: FontMgrTest.cpp:50
SkPoint pos
static void test_write(const SkRegion &region, skiatest::Reporter *r)
Definition: RegionTest.cpp:282
static void rand_rect(SkIRect *rect, SkRandom &rand)
Definition: RegionTest.cpp:218
DEF_TEST(Region, reporter)
Definition: RegionTest.cpp:247
static void intersects_proc(skiatest::Reporter *reporter, const SkRegion &a, const SkRegion &b)
Definition: RegionTest.cpp:195
@ H
Definition: RegionTest.cpp:120
@ W
Definition: RegionTest.cpp:119
static void test_intersects_iter(skiatest::Reporter *reporter, const SkRegion &rgn)
Definition: RegionTest.cpp:184
static void test_fromchrome(skiatest::Reporter *reporter)
Definition: RegionTest.cpp:37
static bool slow_intersects(const SkRegion &outer, const SkRegion &inner)
Definition: RegionTest.cpp:150
static void test_contains_iter(skiatest::Reporter *reporter, const SkRegion &rgn)
Definition: RegionTest.cpp:155
static bool test_rects(const SkIRect rect[], int count)
Definition: RegionTest.cpp:226
static void randRgn(SkRandom &rand, SkRegion *rgn, int n)
Definition: RegionTest.cpp:131
static void test_proc(skiatest::Reporter *reporter, void(*proc)(skiatest::Reporter *, const SkRegion &a, const SkRegion &))
Definition: RegionTest.cpp:205
#define TEST_NO_INTERSECT(rgn, rect)
Definition: RegionTest.cpp:31
static bool slow_contains(const SkRegion &outer, const SkRegion &inner)
Definition: RegionTest.cpp:138
static void test_empties(skiatest::Reporter *reporter)
Definition: RegionTest.cpp:94
static void Union(SkRegion *rgn, const SkIRect &rect)
Definition: RegionTest.cpp:27
#define TEST_NO_CONTAINS(rgn, rect)
Definition: RegionTest.cpp:33
#define TEST_INTERSECT(rgn, rect)
Definition: RegionTest.cpp:32
static SkIRect randRect(SkRandom &rand)
Definition: RegionTest.cpp:123
static void contains_proc(skiatest::Reporter *reporter, const SkRegion &a, const SkRegion &b)
Definition: RegionTest.cpp:166
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition: SkPath.cpp:3892
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
static void copy(void *dst, const uint8_t *src, int width, int bpp, int deltaSrc, int offset, const SkPMColor ctable[])
Definition: SkSwizzler.cpp:31
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
#define N
Definition: beziers.cpp:19
void * get()
Definition: SkAutoMalloc.h:64
Definition: SkPath.h:59
static SkPath RRect(const SkRRect &, SkPathDirection dir=SkPathDirection::kCW)
Definition: SkPath.cpp:3602
SkPath & moveTo(SkScalar x, SkScalar y)
Definition: SkPath.cpp:688
SkPath & close()
Definition: SkPath.cpp:823
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)
Definition: SkRegion.cpp:1369
const SkRegion * rgn() const
Definition: SkRegion.h:507
bool next(int *left, int *right)
Definition: SkRegion.cpp:1510
size_t readFromMemory(const void *buffer, size_t length)
Definition: SkRegion.cpp:1276
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
Definition: SkRegion.cpp:1149
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
ClipOpAndAA opAA SkRegion region
Definition: SkRecords.h:238
SkRRect rrect
Definition: SkRecords.h:232
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
Definition: copy.py:1
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
SkScalar w
SkScalar h
Definition: SkMD5.cpp:130
Definition: SkRect.h:32
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
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63