RegionTest.cpp 17 KB

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