2 * Copyright 2011 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
12 static void Union(SkRegion* rgn, const SkIRect& rect) {
13 rgn->op(rect, SkRegion::kUnion_Op);
16 #define TEST_NO_INTERSECT(rgn, rect) REPORTER_ASSERT(reporter, !rgn.intersects(rect))
17 #define TEST_INTERSECT(rgn, rect) REPORTER_ASSERT(reporter, rgn.intersects(rect))
18 #define TEST_NO_CONTAINS(rgn, rect) REPORTER_ASSERT(reporter, !rgn.contains(rect))
20 // inspired by http://code.google.com/p/skia/issues/detail?id=958
22 static void test_fromchrome(skiatest::Reporter* reporter) {
24 Union(&r, SkIRect::MakeXYWH(0, 0, 1, 1));
25 TEST_NO_INTERSECT(r, SkIRect::MakeXYWH(0, 0, 0, 0));
26 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 0, 2, 2));
27 TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, 0, 2, 2));
28 TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, -1, 2, 2));
29 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, -1, 2, 2));
30 TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, -1, 3, 3));
32 Union(&r, SkIRect::MakeXYWH(0, 0, 3, 3));
33 Union(&r, SkIRect::MakeXYWH(10, 0, 3, 3));
34 Union(&r, SkIRect::MakeXYWH(0, 10, 13, 3));
35 TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, -1, 2, 2));
36 TEST_INTERSECT(r, SkIRect::MakeXYWH(2, -1, 2, 2));
37 TEST_INTERSECT(r, SkIRect::MakeXYWH(2, 2, 2, 2));
38 TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, 2, 2, 2));
40 TEST_INTERSECT(r, SkIRect::MakeXYWH(9, -1, 2, 2));
41 TEST_INTERSECT(r, SkIRect::MakeXYWH(12, -1, 2, 2));
42 TEST_INTERSECT(r, SkIRect::MakeXYWH(12, 2, 2, 2));
43 TEST_INTERSECT(r, SkIRect::MakeXYWH(9, 2, 2, 2));
45 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, -1, 13, 5));
46 TEST_INTERSECT(r, SkIRect::MakeXYWH(1, -1, 11, 5));
47 TEST_INTERSECT(r, SkIRect::MakeXYWH(2, -1, 9, 5));
48 TEST_INTERSECT(r, SkIRect::MakeXYWH(2, -1, 8, 5));
49 TEST_INTERSECT(r, SkIRect::MakeXYWH(3, -1, 8, 5));
51 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 1, 13, 1));
52 TEST_INTERSECT(r, SkIRect::MakeXYWH(1, 1, 11, 1));
53 TEST_INTERSECT(r, SkIRect::MakeXYWH(2, 1, 9, 1));
54 TEST_INTERSECT(r, SkIRect::MakeXYWH(2, 1, 8, 1));
55 TEST_INTERSECT(r, SkIRect::MakeXYWH(3, 1, 8, 1));
57 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 0, 13, 13));
58 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 1, 13, 11));
59 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 2, 13, 9));
60 TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 2, 13, 8));
63 // These test SkRegion::contains(Rect) and SkRegion::contains(Region)
66 Union(&container, SkIRect::MakeXYWH(0, 0, 40, 20));
67 Union(&container, SkIRect::MakeXYWH(30, 20, 10, 20));
68 TEST_NO_CONTAINS(container, SkIRect::MakeXYWH(0, 0, 10, 39));
69 TEST_NO_CONTAINS(container, SkIRect::MakeXYWH(29, 0, 10, 39));
73 Union(&rgn, SkIRect::MakeXYWH(0, 0, 10, 10));
74 Union(&rgn, SkIRect::MakeLTRB(5, 10, 20, 20));
75 TEST_INTERSECT(rgn, SkIRect::MakeXYWH(15, 0, 5, 11));
79 static void test_empties(skiatest::Reporter* reporter) {
80 SkRegion valid(SkIRect::MakeWH(10, 10));
81 SkRegion empty, empty2;
83 REPORTER_ASSERT(reporter, empty.isEmpty());
84 REPORTER_ASSERT(reporter, !valid.isEmpty());
87 REPORTER_ASSERT(reporter, !empty.intersects(empty2));
88 REPORTER_ASSERT(reporter, !valid.intersects(empty));
91 REPORTER_ASSERT(reporter, !empty.contains(empty2));
92 REPORTER_ASSERT(reporter, !valid.contains(empty));
93 REPORTER_ASSERT(reporter, !empty.contains(valid));
101 static SkIRect randRect(SkRandom& rand) {
102 int x = rand.nextU() % W;
103 int y = rand.nextU() % H;
104 int w = rand.nextU() % W;
105 int h = rand.nextU() % H;
106 return SkIRect::MakeXYWH(x, y, w >> 1, h >> 1);
109 static void randRgn(SkRandom& rand, SkRegion* rgn, int n) {
111 for (int i = 0; i < n; ++i) {
112 rgn->op(randRect(rand), SkRegion::kUnion_Op);
116 static bool slow_contains(const SkRegion& outer, const SkRegion& inner) {
118 tmp.op(outer, inner, SkRegion::kUnion_Op);
122 static bool slow_contains(const SkRegion& outer, const SkIRect& r) {
124 tmp.op(outer, SkRegion(r), SkRegion::kUnion_Op);
128 static bool slow_intersects(const SkRegion& outer, const SkRegion& inner) {
130 return tmp.op(outer, inner, SkRegion::kIntersect_Op);
133 static void test_contains_iter(skiatest::Reporter* reporter, const SkRegion& rgn) {
134 SkRegion::Iterator iter(rgn);
135 while (!iter.done()) {
136 SkIRect r = iter.rect();
137 REPORTER_ASSERT(reporter, rgn.contains(r));
139 REPORTER_ASSERT(reporter, !rgn.contains(r));
144 static void contains_proc(skiatest::Reporter* reporter,
145 const SkRegion& a, const SkRegion& b) {
147 bool c0 = a.contains(b);
148 bool c1 = slow_contains(a, b);
149 REPORTER_ASSERT(reporter, c0 == c1);
152 SkIRect r = a.getBounds();
153 r.inset(r.width()/4, r.height()/4);
155 c1 = slow_contains(a, r);
156 REPORTER_ASSERT(reporter, c0 == c1);
158 test_contains_iter(reporter, a);
159 test_contains_iter(reporter, b);
162 static void test_intersects_iter(skiatest::Reporter* reporter, const SkRegion& rgn) {
163 SkRegion::Iterator iter(rgn);
164 while (!iter.done()) {
165 SkIRect r = iter.rect();
166 REPORTER_ASSERT(reporter, rgn.intersects(r));
168 REPORTER_ASSERT(reporter, rgn.intersects(r));
173 static void intersects_proc(skiatest::Reporter* reporter,
174 const SkRegion& a, const SkRegion& b) {
175 bool c0 = a.intersects(b);
176 bool c1 = slow_intersects(a, b);
177 REPORTER_ASSERT(reporter, c0 == c1);
179 test_intersects_iter(reporter, a);
180 test_intersects_iter(reporter, b);
183 static void test_proc(skiatest::Reporter* reporter,
184 void (*proc)(skiatest::Reporter*,
185 const SkRegion& a, const SkRegion&)) {
187 for (int i = 0; i < 10000; ++i) {
189 randRgn(rand, &outer, 8);
191 randRgn(rand, &inner, 2);
192 proc(reporter, outer, inner);
196 static void rand_rect(SkIRect* rect, SkRandom& rand) {
198 int shift = 32 - bits;
199 rect->set(rand.nextU() >> shift, rand.nextU() >> shift,
200 rand.nextU() >> shift, rand.nextU() >> shift);
204 static bool test_rects(const SkIRect rect[], int count) {
207 for (int i = 0; i < count; i++) {
208 rgn0.op(rect[i], SkRegion::kUnion_Op);
210 rgn1.setRects(rect, count);
214 for (int i = 0; i < count; i++) {
215 SkDebugf(" { %d, %d, %d, %d },\n",
216 rect[i].fLeft, rect[i].fTop,
217 rect[i].fRight, rect[i].fBottom);
225 DEF_TEST(Region, reporter) {
226 const SkIRect r2[] = {
230 REPORTER_ASSERT(reporter, test_rects(r2, SK_ARRAY_COUNT(r2)));
232 const SkIRect rects[] = {
238 REPORTER_ASSERT(reporter, test_rects(rects, SK_ARRAY_COUNT(rects)));
241 for (int i = 0; i < 1000; i++) {
246 for (int j = 0; j < N; j++) {
247 rand_rect(&rect[j], rand);
249 REPORTER_ASSERT(reporter, test_rects(rect, N));
252 test_proc(reporter, contains_proc);
253 test_proc(reporter, intersects_proc);
254 test_empties(reporter);
255 test_fromchrome(reporter);