blob: 4d423db07bb514f0439c08c6e7fcc9fa5b438e03 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
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 */
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +00007
reed@android.com097a3512010-07-13 18:35:14 +00008#include "Test.h"
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +00009#include "TestClassDef.h"
reed@android.com097a3512010-07-13 18:35:14 +000010#include "SkRegion.h"
11#include "SkRandom.h"
12
mike@reedtribe.org5a7ae4f2012-11-07 01:57:32 +000013static void Union(SkRegion* rgn, const SkIRect& rect) {
14 rgn->op(rect, SkRegion::kUnion_Op);
15}
16
17#define TEST_NO_INTERSECT(rgn, rect) REPORTER_ASSERT(reporter, !rgn.intersects(rect))
18#define TEST_INTERSECT(rgn, rect) REPORTER_ASSERT(reporter, rgn.intersects(rect))
mike@reedtribe.org796a1752012-11-07 03:39:46 +000019#define TEST_NO_CONTAINS(rgn, rect) REPORTER_ASSERT(reporter, !rgn.contains(rect))
mike@reedtribe.org5a7ae4f2012-11-07 01:57:32 +000020
21// inspired by http://code.google.com/p/skia/issues/detail?id=958
22//
23static void test_fromchrome(skiatest::Reporter* reporter) {
24 SkRegion r;
25 Union(&r, SkIRect::MakeXYWH(0, 0, 1, 1));
26 TEST_NO_INTERSECT(r, SkIRect::MakeXYWH(0, 0, 0, 0));
27 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 0, 2, 2));
28 TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, 0, 2, 2));
29 TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, -1, 2, 2));
30 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, -1, 2, 2));
31 TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, -1, 3, 3));
skia.committer@gmail.com72b2e6f2012-11-08 02:03:56 +000032
mike@reedtribe.org5a7ae4f2012-11-07 01:57:32 +000033 Union(&r, SkIRect::MakeXYWH(0, 0, 3, 3));
34 Union(&r, SkIRect::MakeXYWH(10, 0, 3, 3));
35 Union(&r, SkIRect::MakeXYWH(0, 10, 13, 3));
36 TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, -1, 2, 2));
37 TEST_INTERSECT(r, SkIRect::MakeXYWH(2, -1, 2, 2));
38 TEST_INTERSECT(r, SkIRect::MakeXYWH(2, 2, 2, 2));
39 TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, 2, 2, 2));
skia.committer@gmail.com72b2e6f2012-11-08 02:03:56 +000040
mike@reedtribe.org5a7ae4f2012-11-07 01:57:32 +000041 TEST_INTERSECT(r, SkIRect::MakeXYWH(9, -1, 2, 2));
42 TEST_INTERSECT(r, SkIRect::MakeXYWH(12, -1, 2, 2));
43 TEST_INTERSECT(r, SkIRect::MakeXYWH(12, 2, 2, 2));
44 TEST_INTERSECT(r, SkIRect::MakeXYWH(9, 2, 2, 2));
skia.committer@gmail.com72b2e6f2012-11-08 02:03:56 +000045
mike@reedtribe.org5a7ae4f2012-11-07 01:57:32 +000046 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, -1, 13, 5));
47 TEST_INTERSECT(r, SkIRect::MakeXYWH(1, -1, 11, 5));
48 TEST_INTERSECT(r, SkIRect::MakeXYWH(2, -1, 9, 5));
49 TEST_INTERSECT(r, SkIRect::MakeXYWH(2, -1, 8, 5));
50 TEST_INTERSECT(r, SkIRect::MakeXYWH(3, -1, 8, 5));
skia.committer@gmail.com72b2e6f2012-11-08 02:03:56 +000051
mike@reedtribe.org5a7ae4f2012-11-07 01:57:32 +000052 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 1, 13, 1));
53 TEST_INTERSECT(r, SkIRect::MakeXYWH(1, 1, 11, 1));
54 TEST_INTERSECT(r, SkIRect::MakeXYWH(2, 1, 9, 1));
55 TEST_INTERSECT(r, SkIRect::MakeXYWH(2, 1, 8, 1));
56 TEST_INTERSECT(r, SkIRect::MakeXYWH(3, 1, 8, 1));
skia.committer@gmail.com72b2e6f2012-11-08 02:03:56 +000057
mike@reedtribe.org5a7ae4f2012-11-07 01:57:32 +000058 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 0, 13, 13));
59 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 1, 13, 11));
60 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 2, 13, 9));
61 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 2, 13, 8));
skia.committer@gmail.com72b2e6f2012-11-08 02:03:56 +000062
63
mike@reedtribe.org5a7ae4f2012-11-07 01:57:32 +000064 // These test SkRegion::contains(Rect) and SkRegion::contains(Region)
skia.committer@gmail.com72b2e6f2012-11-08 02:03:56 +000065
mike@reedtribe.org5a7ae4f2012-11-07 01:57:32 +000066 SkRegion container;
67 Union(&container, SkIRect::MakeXYWH(0, 0, 40, 20));
68 Union(&container, SkIRect::MakeXYWH(30, 20, 10, 20));
69 TEST_NO_CONTAINS(container, SkIRect::MakeXYWH(0, 0, 10, 39));
70 TEST_NO_CONTAINS(container, SkIRect::MakeXYWH(29, 0, 10, 39));
reed@google.combb094b92012-11-07 14:23:42 +000071
72 {
73 SkRegion rgn;
74 Union(&rgn, SkIRect::MakeXYWH(0, 0, 10, 10));
75 Union(&rgn, SkIRect::MakeLTRB(5, 10, 20, 20));
76 TEST_INTERSECT(rgn, SkIRect::MakeXYWH(15, 0, 5, 11));
77 }
mike@reedtribe.org5a7ae4f2012-11-07 01:57:32 +000078}
79
reed@google.com8a0d8ff2012-04-30 16:28:04 +000080static void test_empties(skiatest::Reporter* reporter) {
81 SkRegion valid(SkIRect::MakeWH(10, 10));
82 SkRegion empty, empty2;
83
84 REPORTER_ASSERT(reporter, empty.isEmpty());
85 REPORTER_ASSERT(reporter, !valid.isEmpty());
86
87 // test intersects
88 REPORTER_ASSERT(reporter, !empty.intersects(empty2));
89 REPORTER_ASSERT(reporter, !valid.intersects(empty));
90
91 // test contains
92 REPORTER_ASSERT(reporter, !empty.contains(empty2));
93 REPORTER_ASSERT(reporter, !valid.contains(empty));
94 REPORTER_ASSERT(reporter, !empty.contains(valid));
95}
96
mike@reedtribe.org67c31842012-04-28 20:09:19 +000097enum {
98 W = 256,
99 H = 256
100};
101
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000102static SkIRect randRect(SkRandom& rand) {
mike@reedtribe.org67c31842012-04-28 20:09:19 +0000103 int x = rand.nextU() % W;
104 int y = rand.nextU() % H;
105 int w = rand.nextU() % W;
106 int h = rand.nextU() % H;
107 return SkIRect::MakeXYWH(x, y, w >> 1, h >> 1);
108}
109
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000110static void randRgn(SkRandom& rand, SkRegion* rgn, int n) {
mike@reedtribe.org67c31842012-04-28 20:09:19 +0000111 rgn->setEmpty();
112 for (int i = 0; i < n; ++i) {
113 rgn->op(randRect(rand), SkRegion::kUnion_Op);
114 }
115}
116
117static bool slow_contains(const SkRegion& outer, const SkRegion& inner) {
118 SkRegion tmp;
119 tmp.op(outer, inner, SkRegion::kUnion_Op);
120 return outer == tmp;
121}
122
reed@google.com7ab71ba2012-05-02 16:09:21 +0000123static bool slow_contains(const SkRegion& outer, const SkIRect& r) {
124 SkRegion tmp;
125 tmp.op(outer, SkRegion(r), SkRegion::kUnion_Op);
126 return outer == tmp;
127}
128
mike@reedtribe.org67c31842012-04-28 20:09:19 +0000129static bool slow_intersects(const SkRegion& outer, const SkRegion& inner) {
130 SkRegion tmp;
131 return tmp.op(outer, inner, SkRegion::kIntersect_Op);
132}
133
reed@google.com7ab71ba2012-05-02 16:09:21 +0000134static void test_contains_iter(skiatest::Reporter* reporter, const SkRegion& rgn) {
135 SkRegion::Iterator iter(rgn);
136 while (!iter.done()) {
137 SkIRect r = iter.rect();
138 REPORTER_ASSERT(reporter, rgn.contains(r));
139 r.inset(-1, -1);
140 REPORTER_ASSERT(reporter, !rgn.contains(r));
141 iter.next();
142 }
143}
144
mike@reedtribe.org67c31842012-04-28 20:09:19 +0000145static void contains_proc(skiatest::Reporter* reporter,
146 const SkRegion& a, const SkRegion& b) {
reed@google.com7ab71ba2012-05-02 16:09:21 +0000147 // test rgn
mike@reedtribe.org67c31842012-04-28 20:09:19 +0000148 bool c0 = a.contains(b);
149 bool c1 = slow_contains(a, b);
150 REPORTER_ASSERT(reporter, c0 == c1);
reed@google.com7ab71ba2012-05-02 16:09:21 +0000151
152 // test rect
153 SkIRect r = a.getBounds();
154 r.inset(r.width()/4, r.height()/4);
155 c0 = a.contains(r);
156 c1 = slow_contains(a, r);
157 REPORTER_ASSERT(reporter, c0 == c1);
158
159 test_contains_iter(reporter, a);
160 test_contains_iter(reporter, b);
mike@reedtribe.org67c31842012-04-28 20:09:19 +0000161}
162
reed@google.com684119d2012-05-02 16:52:12 +0000163static void test_intersects_iter(skiatest::Reporter* reporter, const SkRegion& rgn) {
164 SkRegion::Iterator iter(rgn);
165 while (!iter.done()) {
166 SkIRect r = iter.rect();
167 REPORTER_ASSERT(reporter, rgn.intersects(r));
168 r.inset(-1, -1);
169 REPORTER_ASSERT(reporter, rgn.intersects(r));
170 iter.next();
171 }
172}
173
mike@reedtribe.org67c31842012-04-28 20:09:19 +0000174static void intersects_proc(skiatest::Reporter* reporter,
175 const SkRegion& a, const SkRegion& b) {
176 bool c0 = a.intersects(b);
177 bool c1 = slow_intersects(a, b);
178 REPORTER_ASSERT(reporter, c0 == c1);
reed@google.com684119d2012-05-02 16:52:12 +0000179
180 test_intersects_iter(reporter, a);
181 test_intersects_iter(reporter, b);
mike@reedtribe.org67c31842012-04-28 20:09:19 +0000182}
183
184static void test_proc(skiatest::Reporter* reporter,
185 void (*proc)(skiatest::Reporter*,
186 const SkRegion& a, const SkRegion&)) {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000187 SkRandom rand;
mike@reedtribe.org67c31842012-04-28 20:09:19 +0000188 for (int i = 0; i < 10000; ++i) {
189 SkRegion outer;
190 randRgn(rand, &outer, 8);
191 SkRegion inner;
192 randRgn(rand, &inner, 2);
193 proc(reporter, outer, inner);
194 }
195}
196
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000197static void rand_rect(SkIRect* rect, SkRandom& rand) {
reed@android.com097a3512010-07-13 18:35:14 +0000198 int bits = 6;
199 int shift = 32 - bits;
200 rect->set(rand.nextU() >> shift, rand.nextU() >> shift,
201 rand.nextU() >> shift, rand.nextU() >> shift);
202 rect->sort();
203}
204
205static bool test_rects(const SkIRect rect[], int count) {
206 SkRegion rgn0, rgn1;
207
208 for (int i = 0; i < count; i++) {
209 rgn0.op(rect[i], SkRegion::kUnion_Op);
210 }
211 rgn1.setRects(rect, count);
212
213 if (rgn0 != rgn1) {
214 SkDebugf("\n");
215 for (int i = 0; i < count; i++) {
216 SkDebugf(" { %d, %d, %d, %d },\n",
217 rect[i].fLeft, rect[i].fTop,
218 rect[i].fRight, rect[i].fBottom);
219 }
220 SkDebugf("\n");
221 return false;
222 }
223 return true;
224}
225
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +0000226DEF_TEST(Region, reporter) {
reed@android.com097a3512010-07-13 18:35:14 +0000227 const SkIRect r2[] = {
228 { 0, 0, 1, 1 },
229 { 2, 2, 3, 3 },
230 };
231 REPORTER_ASSERT(reporter, test_rects(r2, SK_ARRAY_COUNT(r2)));
rmistry@google.comd6176b02012-08-23 18:14:13 +0000232
reed@android.com097a3512010-07-13 18:35:14 +0000233 const SkIRect rects[] = {
234 { 0, 0, 1, 2 },
235 { 2, 1, 3, 3 },
236 { 4, 0, 5, 1 },
237 { 6, 0, 7, 4 },
238 };
239 REPORTER_ASSERT(reporter, test_rects(rects, SK_ARRAY_COUNT(rects)));
240
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000241 SkRandom rand;
reed@android.com097a3512010-07-13 18:35:14 +0000242 for (int i = 0; i < 1000; i++) {
243 SkRegion rgn0, rgn1;
244
245 const int N = 8;
246 SkIRect rect[N];
247 for (int j = 0; j < N; j++) {
248 rand_rect(&rect[j], rand);
249 }
250 REPORTER_ASSERT(reporter, test_rects(rect, N));
251 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000252
mike@reedtribe.org67c31842012-04-28 20:09:19 +0000253 test_proc(reporter, contains_proc);
254 test_proc(reporter, intersects_proc);
reed@google.com8a0d8ff2012-04-30 16:28:04 +0000255 test_empties(reporter);
mike@reedtribe.org5a7ae4f2012-11-07 01:57:32 +0000256 test_fromchrome(reporter);
reed@android.com097a3512010-07-13 18:35:14 +0000257}