gfx/tests/gtest/TestRegion.cpp

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:b6f22996aa97
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #include "gtest/gtest.h"
7 #include "nsRegion.h"
8
9 class TestLargestRegion {
10 public:
11 static void TestSingleRect(nsRect r) {
12 nsRegion region(r);
13 EXPECT_TRUE(region.GetLargestRectangle().IsEqualInterior(r));
14 }
15 // Construct a rectangle, remove part of it, then check the remainder
16 static void TestNonRectangular() {
17 nsRegion r(nsRect(0, 0, 30, 30));
18
19 const int nTests = 19;
20 struct {
21 nsRect rect;
22 int64_t expectedArea;
23 } tests[nTests] = {
24 // Remove a 20x10 chunk from the square
25 { nsRect(0, 0, 20, 10), 600 },
26 { nsRect(10, 0, 20, 10), 600 },
27 { nsRect(10, 20, 20, 10), 600 },
28 { nsRect(0, 20, 20, 10), 600 },
29 // Remove a 10x20 chunk from the square
30 { nsRect(0, 0, 10, 20), 600 },
31 { nsRect(20, 0, 10, 20), 600 },
32 { nsRect(20, 10, 10, 20), 600 },
33 { nsRect(0, 10, 10, 20), 600 },
34 // Remove the center 10x10
35 { nsRect(10, 10, 10, 10), 300 },
36 // Remove the middle column
37 { nsRect(10, 0, 10, 30), 300 },
38 // Remove the middle row
39 { nsRect(0, 10, 30, 10), 300 },
40 // Remove the corners 10x10
41 { nsRect(0, 0, 10, 10), 600 },
42 { nsRect(20, 20, 10, 10), 600 },
43 { nsRect(20, 0, 10, 10), 600 },
44 { nsRect(0, 20, 10, 10), 600 },
45 // Remove the corners 20x20
46 { nsRect(0, 0, 20, 20), 300 },
47 { nsRect(10, 10, 20, 20), 300 },
48 { nsRect(10, 0, 20, 20), 300 },
49 { nsRect(0, 10, 20, 20), 300 }
50 };
51
52 for (int32_t i = 0; i < nTests; i++) {
53 nsRegion r2;
54 r2.Sub(r, tests[i].rect);
55
56 EXPECT_TRUE(r2.IsComplex()) << "nsRegion code got unexpectedly smarter!";
57
58 nsRect largest = r2.GetLargestRectangle();
59 EXPECT_TRUE(largest.width * largest.height == tests[i].expectedArea) <<
60 "Did not successfully find largest rectangle in non-rectangular region on iteration " << i;
61 }
62
63 }
64 static void TwoRectTest() {
65 nsRegion r(nsRect(0, 0, 100, 100));
66 const int nTests = 4;
67 struct {
68 nsRect rect1, rect2;
69 int64_t expectedArea;
70 } tests[nTests] = {
71 { nsRect(0, 0, 75, 40), nsRect(0, 60, 75, 40), 2500 },
72 { nsRect(25, 0, 75, 40), nsRect(25, 60, 75, 40), 2500 },
73 { nsRect(25, 0, 75, 40), nsRect(0, 60, 75, 40), 2000 },
74 { nsRect(0, 0, 75, 40), nsRect(25, 60, 75, 40), 2000 },
75 };
76 for (int32_t i = 0; i < nTests; i++) {
77 nsRegion r2;
78
79 r2.Sub(r, tests[i].rect1);
80 r2.Sub(r2, tests[i].rect2);
81
82 EXPECT_TRUE(r2.IsComplex()) << "nsRegion code got unexpectedly smarter!";
83
84 nsRect largest = r2.GetLargestRectangle();
85 EXPECT_TRUE(largest.width * largest.height == tests[i].expectedArea) <<
86 "Did not successfully find largest rectangle in two-rect-subtract region on iteration " << i;
87 }
88 }
89 static void TestContainsSpecifiedRect() {
90 nsRegion r(nsRect(0, 0, 100, 100));
91 r.Or(r, nsRect(0, 300, 50, 50));
92 EXPECT_TRUE(r.GetLargestRectangle(nsRect(0, 300, 10, 10)).IsEqualInterior(nsRect(0, 300, 50, 50))) <<
93 "Chose wrong rectangle";
94 }
95 static void TestContainsSpecifiedOverflowingRect() {
96 nsRegion r(nsRect(0, 0, 100, 100));
97 r.Or(r, nsRect(0, 300, 50, 50));
98 EXPECT_TRUE(r.GetLargestRectangle(nsRect(0, 290, 10, 20)).IsEqualInterior(nsRect(0, 300, 50, 50))) <<
99 "Chose wrong rectangle";
100 }
101 };
102
103 TEST(Gfx, RegionSingleRect) {
104 TestLargestRegion::TestSingleRect(nsRect(0, 52, 720, 480));
105 TestLargestRegion::TestSingleRect(nsRect(-20, 40, 50, 20));
106 TestLargestRegion::TestSingleRect(nsRect(-20, 40, 10, 8));
107 TestLargestRegion::TestSingleRect(nsRect(-20, -40, 10, 8));
108 TestLargestRegion::TestSingleRect(nsRect(-10, -10, 20, 20));
109 }
110
111 TEST(Gfx, RegionNonRectangular) {
112 TestLargestRegion::TestNonRectangular();
113 }
114
115 TEST(Gfx, RegionTwoRectTest) {
116 TestLargestRegion::TwoRectTest();
117 }
118
119 TEST(Gfx, RegionContainsSpecifiedRect) {
120 TestLargestRegion::TestContainsSpecifiedRect();
121 }
122
123 TEST(Gfx, RegionTestContainsSpecifiedOverflowingRect) {
124 TestLargestRegion::TestContainsSpecifiedOverflowingRect();
125 }
126
127 TEST(Gfx, RegionScaleToInside) {
128 { // no rectangles
129 nsRegion r;
130
131 nsIntRegion scaled = r.ScaleToInsidePixels(1, 1, 60);
132 nsIntRegion result;
133
134 EXPECT_TRUE(result.IsEqual(scaled)) <<
135 "scaled result incorrect";
136 }
137
138 { // one rectangle
139 nsRegion r(nsRect(0,44760,19096,264));
140
141 nsIntRegion scaled = r.ScaleToInsidePixels(1, 1, 60);
142 nsIntRegion result(nsIntRect(0,746,318,4));
143
144 EXPECT_TRUE(result.IsEqual(scaled)) <<
145 "scaled result incorrect";
146 }
147
148
149 { // the first rectangle gets adjusted
150 nsRegion r(nsRect(0,44760,19096,264));
151 r.Or(r, nsRect(0,45024,19360,1056));
152
153 nsIntRegion scaled = r.ScaleToInsidePixels(1, 1, 60);
154 nsIntRegion result(nsIntRect(0,746,318,5));
155 result.Or(result, nsIntRect(0,751,322,17));
156
157 EXPECT_TRUE(result.IsEqual(scaled)) <<
158 "scaled result incorrect";
159 }
160
161 { // the second rectangle gets adjusted
162 nsRegion r(nsRect(0,44760,19360,264));
163 r.Or(r, nsRect(0,45024,19096,1056));
164
165 nsIntRegion scaled = r.ScaleToInsidePixels(1, 1, 60);
166 nsIntRegion result(nsIntRect(0,746,322,4));
167 result.Or(result, nsIntRect(0,750,318,18));
168
169 EXPECT_TRUE(result.IsEqual(scaled)) <<
170 "scaled result incorrect";
171 }
172
173 }
174
175 TEST(Gfx, RegionSimplify) {
176 { // ensure simplify works on a single rect
177 nsRegion r(nsRect(0,100,200,100));
178
179 r.SimplifyOutwardByArea(100*100);
180
181 nsRegion result(nsRect(0,100,200,100));
182
183 EXPECT_TRUE(r.IsEqual(result)) <<
184 "regions not the same";
185 }
186
187 { // the rectangles will be merged
188 nsRegion r(nsRect(0,100,200,100));
189 r.Or(r, nsRect(0,200,300,200));
190
191 r.SimplifyOutwardByArea(100*100);
192
193 nsRegion result(nsRect(0,100,300,300));
194
195 EXPECT_TRUE(r.IsEqual(result)) <<
196 "regions not merged";
197 }
198
199 { // two rectangle on the first span
200 // one on the second
201 nsRegion r(nsRect(0,100,200,100));
202 r.Or(r, nsRect(0,200,300,200));
203 r.Or(r, nsRect(250,100,50,100));
204
205 EXPECT_TRUE(r.GetNumRects() == 3) <<
206 "wrong number of rects";
207
208 r.SimplifyOutwardByArea(100*100);
209
210 nsRegion result(nsRect(0,100,300,300));
211
212 EXPECT_TRUE(r.IsEqual(result)) <<
213 "regions not merged";
214 }
215
216 { // the rectangles will be merged
217 nsRegion r(nsRect(0,100,200,100));
218 r.Or(r, nsRect(0,200,300,200));
219 r.Or(r, nsRect(250,100,50,100));
220 r.Sub(r, nsRect(200,200,40,200));
221
222 EXPECT_TRUE(r.GetNumRects() == 4) <<
223 "wrong number of rects";
224
225 r.SimplifyOutwardByArea(100*100);
226
227 nsRegion result(nsRect(0,100,300,300));
228 result.Sub(result, nsRect(200,100,40,300));
229
230 EXPECT_TRUE(r.IsEqual(result)) <<
231 "regions not merged";
232 }
233
234 { // three spans of rectangles
235 nsRegion r(nsRect(0,100,200,100));
236 r.Or(r, nsRect(0,200,300,200));
237 r.Or(r, nsRect(250,100,50,50));
238 r.Sub(r, nsRect(200,200,40,200));
239
240 r.SimplifyOutwardByArea(100*100);
241
242 nsRegion result(nsRect(0,100,300,300));
243 result.Sub(result, nsRect(200,100,40,300));
244
245 EXPECT_TRUE(r.IsEqual(result)) <<
246 "regions not merged";
247 }
248
249 { // three spans of rectangles and an unmerged rectangle
250 nsRegion r(nsRect(0,100,200,100));
251 r.Or(r, nsRect(0,200,300,200));
252 r.Or(r, nsRect(250,100,50,50));
253 r.Sub(r, nsRect(200,200,40,200));
254 r.Or(r, nsRect(250,900,150,50));
255
256 r.SimplifyOutwardByArea(100*100);
257
258 nsRegion result(nsRect(0,100,300,300));
259 result.Sub(result, nsRect(200,100,40,300));
260 result.Or(result, nsRect(250,900,150,50));
261
262 EXPECT_TRUE(r.IsEqual(result)) <<
263 "regions not merged";
264 }
265
266 { // unmerged regions
267 nsRegion r(nsRect(0,100,200,100));
268 r.Or(r, nsRect(0,200,300,200));
269
270 r.SimplifyOutwardByArea(100);
271
272 nsRegion result(nsRect(0,100,200,100));
273 result.Or(result, nsRect(0,200,300,200));
274
275 EXPECT_TRUE(r.IsEqual(result)) <<
276 "regions not merged";
277 }
278
279 { // empty region
280 // just make sure this doesn't crash.
281 nsRegion r;
282 r.SimplifyOutwardByArea(100);
283 }
284
285 }

mercurial