blob: db43e333c054b88addde71b567baffa0d40c9ce1 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
reed@android.com097a3512010-07-13 18:35:14 +00008#include "Test.h"
9#include "SkRegion.h"
10#include "SkRandom.h"
11
reed@google.com8a0d8ff2012-04-30 16:28:04 +000012static void test_empties(skiatest::Reporter* reporter) {
13 SkRegion valid(SkIRect::MakeWH(10, 10));
14 SkRegion empty, empty2;
15
16 REPORTER_ASSERT(reporter, empty.isEmpty());
17 REPORTER_ASSERT(reporter, !valid.isEmpty());
18
19 // test intersects
20 REPORTER_ASSERT(reporter, !empty.intersects(empty2));
21 REPORTER_ASSERT(reporter, !valid.intersects(empty));
22
23 // test contains
24 REPORTER_ASSERT(reporter, !empty.contains(empty2));
25 REPORTER_ASSERT(reporter, !valid.contains(empty));
26 REPORTER_ASSERT(reporter, !empty.contains(valid));
27}
28
mike@reedtribe.org67c31842012-04-28 20:09:19 +000029enum {
30 W = 256,
31 H = 256
32};
33
34static SkIRect randRect(SkRandom& rand) {
35 int x = rand.nextU() % W;
36 int y = rand.nextU() % H;
37 int w = rand.nextU() % W;
38 int h = rand.nextU() % H;
39 return SkIRect::MakeXYWH(x, y, w >> 1, h >> 1);
40}
41
42static void randRgn(SkRandom& rand, SkRegion* rgn, int n) {
43 rgn->setEmpty();
44 for (int i = 0; i < n; ++i) {
45 rgn->op(randRect(rand), SkRegion::kUnion_Op);
46 }
47}
48
49static bool slow_contains(const SkRegion& outer, const SkRegion& inner) {
50 SkRegion tmp;
51 tmp.op(outer, inner, SkRegion::kUnion_Op);
52 return outer == tmp;
53}
54
reed@google.com7ab71ba2012-05-02 16:09:21 +000055static bool slow_contains(const SkRegion& outer, const SkIRect& r) {
56 SkRegion tmp;
57 tmp.op(outer, SkRegion(r), SkRegion::kUnion_Op);
58 return outer == tmp;
59}
60
mike@reedtribe.org67c31842012-04-28 20:09:19 +000061static bool slow_intersects(const SkRegion& outer, const SkRegion& inner) {
62 SkRegion tmp;
63 return tmp.op(outer, inner, SkRegion::kIntersect_Op);
64}
65
reed@google.com7ab71ba2012-05-02 16:09:21 +000066static void test_contains_iter(skiatest::Reporter* reporter, const SkRegion& rgn) {
67 SkRegion::Iterator iter(rgn);
68 while (!iter.done()) {
69 SkIRect r = iter.rect();
70 REPORTER_ASSERT(reporter, rgn.contains(r));
71 r.inset(-1, -1);
72 REPORTER_ASSERT(reporter, !rgn.contains(r));
73 iter.next();
74 }
75}
76
mike@reedtribe.org67c31842012-04-28 20:09:19 +000077static void contains_proc(skiatest::Reporter* reporter,
78 const SkRegion& a, const SkRegion& b) {
reed@google.com7ab71ba2012-05-02 16:09:21 +000079 // test rgn
mike@reedtribe.org67c31842012-04-28 20:09:19 +000080 bool c0 = a.contains(b);
81 bool c1 = slow_contains(a, b);
82 REPORTER_ASSERT(reporter, c0 == c1);
reed@google.com7ab71ba2012-05-02 16:09:21 +000083
84 // test rect
85 SkIRect r = a.getBounds();
86 r.inset(r.width()/4, r.height()/4);
87 c0 = a.contains(r);
88 c1 = slow_contains(a, r);
89 REPORTER_ASSERT(reporter, c0 == c1);
90
91 test_contains_iter(reporter, a);
92 test_contains_iter(reporter, b);
mike@reedtribe.org67c31842012-04-28 20:09:19 +000093}
94
reed@google.com684119d2012-05-02 16:52:12 +000095static void test_intersects_iter(skiatest::Reporter* reporter, const SkRegion& rgn) {
96 SkRegion::Iterator iter(rgn);
97 while (!iter.done()) {
98 SkIRect r = iter.rect();
99 REPORTER_ASSERT(reporter, rgn.intersects(r));
100 r.inset(-1, -1);
101 REPORTER_ASSERT(reporter, rgn.intersects(r));
102 iter.next();
103 }
104}
105
mike@reedtribe.org67c31842012-04-28 20:09:19 +0000106static void intersects_proc(skiatest::Reporter* reporter,
107 const SkRegion& a, const SkRegion& b) {
108 bool c0 = a.intersects(b);
109 bool c1 = slow_intersects(a, b);
110 REPORTER_ASSERT(reporter, c0 == c1);
reed@google.com684119d2012-05-02 16:52:12 +0000111
112 test_intersects_iter(reporter, a);
113 test_intersects_iter(reporter, b);
mike@reedtribe.org67c31842012-04-28 20:09:19 +0000114}
115
116static void test_proc(skiatest::Reporter* reporter,
117 void (*proc)(skiatest::Reporter*,
118 const SkRegion& a, const SkRegion&)) {
119 SkRandom rand;
120 for (int i = 0; i < 10000; ++i) {
121 SkRegion outer;
122 randRgn(rand, &outer, 8);
123 SkRegion inner;
124 randRgn(rand, &inner, 2);
125 proc(reporter, outer, inner);
126 }
127}
128
reed@android.com097a3512010-07-13 18:35:14 +0000129static void rand_rect(SkIRect* rect, SkRandom& rand) {
130 int bits = 6;
131 int shift = 32 - bits;
132 rect->set(rand.nextU() >> shift, rand.nextU() >> shift,
133 rand.nextU() >> shift, rand.nextU() >> shift);
134 rect->sort();
135}
136
137static bool test_rects(const SkIRect rect[], int count) {
138 SkRegion rgn0, rgn1;
139
140 for (int i = 0; i < count; i++) {
141 rgn0.op(rect[i], SkRegion::kUnion_Op);
142 }
143 rgn1.setRects(rect, count);
144
145 if (rgn0 != rgn1) {
146 SkDebugf("\n");
147 for (int i = 0; i < count; i++) {
148 SkDebugf(" { %d, %d, %d, %d },\n",
149 rect[i].fLeft, rect[i].fTop,
150 rect[i].fRight, rect[i].fBottom);
151 }
152 SkDebugf("\n");
153 return false;
154 }
155 return true;
156}
157
158static void TestRegion(skiatest::Reporter* reporter) {
159 const SkIRect r2[] = {
160 { 0, 0, 1, 1 },
161 { 2, 2, 3, 3 },
162 };
163 REPORTER_ASSERT(reporter, test_rects(r2, SK_ARRAY_COUNT(r2)));
164
165 const SkIRect rects[] = {
166 { 0, 0, 1, 2 },
167 { 2, 1, 3, 3 },
168 { 4, 0, 5, 1 },
169 { 6, 0, 7, 4 },
170 };
171 REPORTER_ASSERT(reporter, test_rects(rects, SK_ARRAY_COUNT(rects)));
172
173 SkRandom rand;
174 for (int i = 0; i < 1000; i++) {
175 SkRegion rgn0, rgn1;
176
177 const int N = 8;
178 SkIRect rect[N];
179 for (int j = 0; j < N; j++) {
180 rand_rect(&rect[j], rand);
181 }
182 REPORTER_ASSERT(reporter, test_rects(rect, N));
183 }
mike@reedtribe.org67c31842012-04-28 20:09:19 +0000184
185 test_proc(reporter, contains_proc);
186 test_proc(reporter, intersects_proc);
reed@google.com8a0d8ff2012-04-30 16:28:04 +0000187 test_empties(reporter);
reed@android.com097a3512010-07-13 18:35:14 +0000188}
189
190#include "TestClassDef.h"
191DEFINE_TESTCLASS("Region", RegionTestClass, TestRegion)