blob: 23ac9b7ae92e9eeab8cec67d10ea5ae9100d8d69 [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
95static void intersects_proc(skiatest::Reporter* reporter,
96 const SkRegion& a, const SkRegion& b) {
97 bool c0 = a.intersects(b);
98 bool c1 = slow_intersects(a, b);
99 REPORTER_ASSERT(reporter, c0 == c1);
100}
101
102static void test_proc(skiatest::Reporter* reporter,
103 void (*proc)(skiatest::Reporter*,
104 const SkRegion& a, const SkRegion&)) {
105 SkRandom rand;
106 for (int i = 0; i < 10000; ++i) {
107 SkRegion outer;
108 randRgn(rand, &outer, 8);
109 SkRegion inner;
110 randRgn(rand, &inner, 2);
111 proc(reporter, outer, inner);
112 }
113}
114
reed@android.com097a3512010-07-13 18:35:14 +0000115static void rand_rect(SkIRect* rect, SkRandom& rand) {
116 int bits = 6;
117 int shift = 32 - bits;
118 rect->set(rand.nextU() >> shift, rand.nextU() >> shift,
119 rand.nextU() >> shift, rand.nextU() >> shift);
120 rect->sort();
121}
122
123static bool test_rects(const SkIRect rect[], int count) {
124 SkRegion rgn0, rgn1;
125
126 for (int i = 0; i < count; i++) {
127 rgn0.op(rect[i], SkRegion::kUnion_Op);
128 }
129 rgn1.setRects(rect, count);
130
131 if (rgn0 != rgn1) {
132 SkDebugf("\n");
133 for (int i = 0; i < count; i++) {
134 SkDebugf(" { %d, %d, %d, %d },\n",
135 rect[i].fLeft, rect[i].fTop,
136 rect[i].fRight, rect[i].fBottom);
137 }
138 SkDebugf("\n");
139 return false;
140 }
141 return true;
142}
143
144static void TestRegion(skiatest::Reporter* reporter) {
145 const SkIRect r2[] = {
146 { 0, 0, 1, 1 },
147 { 2, 2, 3, 3 },
148 };
149 REPORTER_ASSERT(reporter, test_rects(r2, SK_ARRAY_COUNT(r2)));
150
151 const SkIRect rects[] = {
152 { 0, 0, 1, 2 },
153 { 2, 1, 3, 3 },
154 { 4, 0, 5, 1 },
155 { 6, 0, 7, 4 },
156 };
157 REPORTER_ASSERT(reporter, test_rects(rects, SK_ARRAY_COUNT(rects)));
158
159 SkRandom rand;
160 for (int i = 0; i < 1000; i++) {
161 SkRegion rgn0, rgn1;
162
163 const int N = 8;
164 SkIRect rect[N];
165 for (int j = 0; j < N; j++) {
166 rand_rect(&rect[j], rand);
167 }
168 REPORTER_ASSERT(reporter, test_rects(rect, N));
169 }
mike@reedtribe.org67c31842012-04-28 20:09:19 +0000170
171 test_proc(reporter, contains_proc);
172 test_proc(reporter, intersects_proc);
reed@google.com8a0d8ff2012-04-30 16:28:04 +0000173 test_empties(reporter);
reed@android.com097a3512010-07-13 18:35:14 +0000174}
175
176#include "TestClassDef.h"
177DEFINE_TESTCLASS("Region", RegionTestClass, TestRegion)