1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "cc/base/simple_enclosed_region.h"
6
7 #include <stddef.h>
8
9 #include <algorithm>
10 #include <vector>
11
12 #include "base/logging.h"
13 #include "cc/base/region.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace cc {
17 namespace {
18
ExpectRegionEq(const gfx::Rect & rect,const SimpleEnclosedRegion & region)19 bool ExpectRegionEq(const gfx::Rect& rect, const SimpleEnclosedRegion& region) {
20 std::vector<gfx::Rect> actual_rects;
21 std::vector<gfx::Rect> expected_rects;
22
23 if (!rect.IsEmpty())
24 expected_rects.push_back(rect);
25
26 for (size_t i = 0; i < region.GetRegionComplexity(); ++i)
27 actual_rects.push_back(region.GetRect(i));
28
29 if (rect.IsEmpty() != region.IsEmpty()) {
30 LOG(ERROR) << "Expected: " << rect.IsEmpty()
31 << " Actual: " << region.IsEmpty();
32 return false;
33 }
34
35 if (expected_rects.size() != actual_rects.size()) {
36 LOG(ERROR) << "Expected: " << expected_rects.size()
37 << " Actual: " << actual_rects.size();
38 return false;
39 }
40
41 std::sort(actual_rects.begin(), actual_rects.end());
42 std::sort(expected_rects.begin(), expected_rects.end());
43
44 for (size_t i = 0; i < expected_rects.size(); ++i) {
45 if (expected_rects[i] != actual_rects[i]) {
46 LOG(ERROR) << "Expected: " << expected_rects[i].ToString()
47 << " Actual: " << actual_rects[i].ToString();
48 return false;
49 }
50 }
51
52 return true;
53 }
54
TEST(SimpleEnclosedRegionTest,Create)55 TEST(SimpleEnclosedRegionTest, Create) {
56 SimpleEnclosedRegion r1;
57 EXPECT_TRUE(r1.IsEmpty());
58 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(), r1));
59
60 SimpleEnclosedRegion r2(gfx::Rect(2, 3, 4, 5));
61 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(2, 3, 4, 5), r2));
62
63 SimpleEnclosedRegion r3(2, 3, 4, 5);
64 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(2, 3, 4, 5), r3));
65
66 SimpleEnclosedRegion r4(4, 5);
67 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(4, 5), r4));
68
69 SimpleEnclosedRegion r5(Region(gfx::Rect(2, 3, 4, 5)));
70 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(2, 3, 4, 5), r5));
71
72 SimpleEnclosedRegion r6(r5);
73 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(2, 3, 4, 5), r6));
74 }
75
TEST(SimpleEnclosedRegionTest,Assign)76 TEST(SimpleEnclosedRegionTest, Assign) {
77 SimpleEnclosedRegion r;
78 EXPECT_TRUE(r.IsEmpty());
79
80 r = gfx::Rect(2, 3, 4, 5);
81 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(2, 3, 4, 5), r));
82
83 r = SimpleEnclosedRegion(3, 4, 5, 6);
84 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(3, 4, 5, 6), r));
85 }
86
TEST(SimpleEnclosedRegionTest,Clear)87 TEST(SimpleEnclosedRegionTest, Clear) {
88 SimpleEnclosedRegion r(1, 2, 3, 4);
89 EXPECT_FALSE(r.IsEmpty());
90 r.Clear();
91 EXPECT_TRUE(r.IsEmpty());
92 }
93
TEST(SimpleEnclosedRegionTest,GetRegionComplexity)94 TEST(SimpleEnclosedRegionTest, GetRegionComplexity) {
95 SimpleEnclosedRegion empty;
96 EXPECT_EQ(0u, empty.GetRegionComplexity());
97
98 SimpleEnclosedRegion stuff;
99 stuff.Union(gfx::Rect(1, 2, 3, 4));
100 EXPECT_EQ(1u, stuff.GetRegionComplexity());
101
102 // The SimpleEnclosedRegion only holds up to 1 rect.
103 stuff.Union(gfx::Rect(5, 6, 7, 8));
104 EXPECT_EQ(1u, stuff.GetRegionComplexity());
105 }
106
TEST(SimpleEnclosedRegionTest,Contains)107 TEST(SimpleEnclosedRegionTest, Contains) {
108 SimpleEnclosedRegion r(1, 2, 5, 6);
109
110 EXPECT_FALSE(r.Contains(gfx::Point(0, 2)));
111 EXPECT_FALSE(r.Contains(gfx::Point(1, 1)));
112 EXPECT_TRUE(r.Contains(gfx::Point(1, 2)));
113
114 EXPECT_FALSE(r.Contains(gfx::Point(6, 2)));
115 EXPECT_FALSE(r.Contains(gfx::Point(5, 1)));
116 EXPECT_TRUE(r.Contains(gfx::Point(5, 2)));
117
118 EXPECT_FALSE(r.Contains(gfx::Point(0, 7)));
119 EXPECT_FALSE(r.Contains(gfx::Point(1, 8)));
120 EXPECT_TRUE(r.Contains(gfx::Point(1, 7)));
121
122 EXPECT_FALSE(r.Contains(gfx::Point(6, 7)));
123 EXPECT_FALSE(r.Contains(gfx::Point(5, 8)));
124 EXPECT_TRUE(r.Contains(gfx::Point(5, 7)));
125
126 EXPECT_FALSE(r.Contains(gfx::Rect(0, 2, 1, 1)));
127 EXPECT_FALSE(r.Contains(gfx::Rect(1, 1, 1, 1)));
128 EXPECT_TRUE(r.Contains(gfx::Rect(1, 2, 1, 1)));
129 EXPECT_FALSE(r.Contains(gfx::Rect(0, 1, 2, 2)));
130
131 EXPECT_FALSE(r.Contains(gfx::Rect(6, 2, 1, 1)));
132 EXPECT_FALSE(r.Contains(gfx::Rect(5, 1, 1, 1)));
133 EXPECT_TRUE(r.Contains(gfx::Rect(5, 2, 1, 1)));
134 EXPECT_FALSE(r.Contains(gfx::Rect(5, 1, 2, 2)));
135
136 EXPECT_FALSE(r.Contains(gfx::Rect(0, 7, 1, 1)));
137 EXPECT_FALSE(r.Contains(gfx::Rect(1, 8, 1, 1)));
138 EXPECT_TRUE(r.Contains(gfx::Rect(1, 7, 1, 1)));
139 EXPECT_FALSE(r.Contains(gfx::Rect(0, 7, 2, 2)));
140
141 EXPECT_FALSE(r.Contains(gfx::Rect(6, 7, 1, 1)));
142 EXPECT_FALSE(r.Contains(gfx::Rect(5, 8, 1, 1)));
143 EXPECT_TRUE(r.Contains(gfx::Rect(5, 7, 1, 1)));
144 EXPECT_FALSE(r.Contains(gfx::Rect(5, 7, 2, 2)));
145
146 gfx::Rect q(1, 2, 5, 6);
147 EXPECT_TRUE(r.Contains(q)) << q.ToString();
148 q.Inset(-1, 0, 0, 0);
149 EXPECT_FALSE(r.Contains(q)) << q.ToString();
150 q.Inset(1, -1, 0, 0);
151 EXPECT_FALSE(r.Contains(q)) << q.ToString();
152 q.Inset(0, 1, -1, 0);
153 EXPECT_FALSE(r.Contains(q)) << q.ToString();
154 q.Inset(0, 0, 1, -1);
155 EXPECT_FALSE(r.Contains(q)) << q.ToString();
156
157 q.Inset(1, 0, 0, 1);
158 EXPECT_TRUE(r.Contains(q)) << q.ToString();
159 q.Inset(-1, 1, 0, 0);
160 EXPECT_TRUE(r.Contains(q)) << q.ToString();
161 q.Inset(0, -1, 1, 0);
162 EXPECT_TRUE(r.Contains(q)) << q.ToString();
163 q.Inset(0, 0, -1, 1);
164 EXPECT_TRUE(r.Contains(q)) << q.ToString();
165
166 EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(0, 2, 1, 1)));
167 EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(1, 1, 1, 1)));
168 EXPECT_TRUE(r.Contains(SimpleEnclosedRegion(1, 2, 1, 1)));
169 EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(0, 1, 2, 2)));
170
171 EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(6, 2, 1, 1)));
172 EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(5, 1, 1, 1)));
173 EXPECT_TRUE(r.Contains(SimpleEnclosedRegion(5, 2, 1, 1)));
174 EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(5, 1, 2, 2)));
175
176 EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(0, 7, 1, 1)));
177 EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(1, 8, 1, 1)));
178 EXPECT_TRUE(r.Contains(SimpleEnclosedRegion(1, 7, 1, 1)));
179 EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(0, 7, 2, 2)));
180
181 EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(6, 7, 1, 1)));
182 EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(5, 8, 1, 1)));
183 EXPECT_TRUE(r.Contains(SimpleEnclosedRegion(5, 7, 1, 1)));
184 EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(5, 7, 2, 2)));
185
186 q = gfx::Rect(1, 2, 5, 6);
187 EXPECT_TRUE(r.Contains(SimpleEnclosedRegion(q))) << q.ToString();
188 q.Inset(-1, 0, 0, 0);
189 EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(q))) << q.ToString();
190 q.Inset(1, -1, 0, 0);
191 EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(q))) << q.ToString();
192 q.Inset(0, 1, -1, 0);
193 EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(q))) << q.ToString();
194 q.Inset(0, 0, 1, -1);
195 EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(q))) << q.ToString();
196
197 q.Inset(1, 0, 0, 1);
198 EXPECT_TRUE(r.Contains(SimpleEnclosedRegion(q))) << q.ToString();
199 q.Inset(-1, 1, 0, 0);
200 EXPECT_TRUE(r.Contains(SimpleEnclosedRegion(q))) << q.ToString();
201 q.Inset(0, -1, 1, 0);
202 EXPECT_TRUE(r.Contains(SimpleEnclosedRegion(q))) << q.ToString();
203 q.Inset(0, 0, -1, 1);
204 EXPECT_TRUE(r.Contains(SimpleEnclosedRegion(q))) << q.ToString();
205 }
206
TEST(SimpleEnclosedRegionTest,Intersects)207 TEST(SimpleEnclosedRegionTest, Intersects) {
208 SimpleEnclosedRegion r(1, 2, 5, 6);
209
210 EXPECT_FALSE(r.Intersects(gfx::Rect(0, 2, 1, 1)));
211 EXPECT_FALSE(r.Intersects(gfx::Rect(1, 1, 1, 1)));
212 EXPECT_TRUE(r.Intersects(gfx::Rect(1, 2, 1, 1)));
213 EXPECT_TRUE(r.Intersects(gfx::Rect(0, 1, 2, 2)));
214
215 EXPECT_FALSE(r.Intersects(gfx::Rect(6, 2, 1, 1)));
216 EXPECT_FALSE(r.Intersects(gfx::Rect(5, 1, 1, 1)));
217 EXPECT_TRUE(r.Intersects(gfx::Rect(5, 2, 1, 1)));
218 EXPECT_TRUE(r.Intersects(gfx::Rect(5, 1, 2, 2)));
219
220 EXPECT_FALSE(r.Intersects(gfx::Rect(0, 7, 1, 1)));
221 EXPECT_FALSE(r.Intersects(gfx::Rect(1, 8, 1, 1)));
222 EXPECT_TRUE(r.Intersects(gfx::Rect(1, 7, 1, 1)));
223 EXPECT_TRUE(r.Intersects(gfx::Rect(0, 7, 2, 2)));
224
225 EXPECT_FALSE(r.Intersects(gfx::Rect(6, 7, 1, 1)));
226 EXPECT_FALSE(r.Intersects(gfx::Rect(5, 8, 1, 1)));
227 EXPECT_TRUE(r.Intersects(gfx::Rect(5, 7, 1, 1)));
228 EXPECT_TRUE(r.Intersects(gfx::Rect(5, 7, 2, 2)));
229
230 gfx::Rect q(1, 2, 5, 6);
231 EXPECT_TRUE(r.Intersects(q)) << q.ToString();
232 q.Inset(-1, 0, 0, 0);
233 EXPECT_TRUE(r.Intersects(q)) << q.ToString();
234 q.Inset(1, -1, 0, 0);
235 EXPECT_TRUE(r.Intersects(q)) << q.ToString();
236 q.Inset(0, 1, -1, 0);
237 EXPECT_TRUE(r.Intersects(q)) << q.ToString();
238 q.Inset(0, 0, 1, -1);
239 EXPECT_TRUE(r.Intersects(q)) << q.ToString();
240
241 q.Inset(1, 0, 0, 1);
242 EXPECT_TRUE(r.Intersects(q)) << q.ToString();
243 q.Inset(-1, 1, 0, 0);
244 EXPECT_TRUE(r.Intersects(q)) << q.ToString();
245 q.Inset(0, -1, 1, 0);
246 EXPECT_TRUE(r.Intersects(q)) << q.ToString();
247 q.Inset(0, 0, -1, 1);
248 EXPECT_TRUE(r.Intersects(q)) << q.ToString();
249
250 EXPECT_FALSE(r.Intersects(SimpleEnclosedRegion(0, 2, 1, 1)));
251 EXPECT_FALSE(r.Intersects(SimpleEnclosedRegion(1, 1, 1, 1)));
252 EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(1, 2, 1, 1)));
253 EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(0, 1, 2, 2)));
254
255 EXPECT_FALSE(r.Intersects(SimpleEnclosedRegion(6, 2, 1, 1)));
256 EXPECT_FALSE(r.Intersects(SimpleEnclosedRegion(5, 1, 1, 1)));
257 EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(5, 2, 1, 1)));
258 EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(5, 1, 2, 2)));
259
260 EXPECT_FALSE(r.Intersects(SimpleEnclosedRegion(0, 7, 1, 1)));
261 EXPECT_FALSE(r.Intersects(SimpleEnclosedRegion(1, 8, 1, 1)));
262 EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(1, 7, 1, 1)));
263 EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(0, 7, 2, 2)));
264
265 EXPECT_FALSE(r.Intersects(SimpleEnclosedRegion(6, 7, 1, 1)));
266 EXPECT_FALSE(r.Intersects(SimpleEnclosedRegion(5, 8, 1, 1)));
267 EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(5, 7, 1, 1)));
268 EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(5, 7, 2, 2)));
269
270 q = gfx::Rect(1, 2, 5, 6);
271 EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(q))) << q.ToString();
272 q.Inset(-1, 0, 0, 0);
273 EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(q))) << q.ToString();
274 q.Inset(1, -1, 0, 0);
275 EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(q))) << q.ToString();
276 q.Inset(0, 1, -1, 0);
277 EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(q))) << q.ToString();
278 q.Inset(0, 0, 1, -1);
279 EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(q))) << q.ToString();
280
281 q.Inset(1, 0, 0, 1);
282 EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(q))) << q.ToString();
283 q.Inset(-1, 1, 0, 0);
284 EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(q))) << q.ToString();
285 q.Inset(0, -1, 1, 0);
286 EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(q))) << q.ToString();
287 q.Inset(0, 0, -1, 1);
288 EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(q))) << q.ToString();
289 }
290
TEST(SimpleEnclosedRegionTest,Equals)291 TEST(SimpleEnclosedRegionTest, Equals) {
292 SimpleEnclosedRegion r(1, 2, 3, 4);
293 EXPECT_TRUE(r.Equals(SimpleEnclosedRegion(1, 2, 3, 4)));
294 EXPECT_FALSE(r.Equals(SimpleEnclosedRegion(2, 2, 3, 4)));
295 EXPECT_FALSE(r.Equals(SimpleEnclosedRegion(1, 3, 3, 4)));
296 EXPECT_FALSE(r.Equals(SimpleEnclosedRegion(1, 2, 4, 4)));
297 EXPECT_FALSE(r.Equals(SimpleEnclosedRegion(1, 2, 3, 5)));
298 EXPECT_FALSE(r.Equals(SimpleEnclosedRegion(2, 2, 2, 4)));
299 EXPECT_FALSE(r.Equals(SimpleEnclosedRegion(1, 3, 3, 3)));
300 }
301
TEST(SimpleEnclosedRegionTest,Bounds)302 TEST(SimpleEnclosedRegionTest, Bounds) {
303 SimpleEnclosedRegion r;
304 EXPECT_EQ(gfx::Rect(), r.bounds());
305 r = gfx::Rect(3, 4, 5, 6);
306 EXPECT_EQ(gfx::Rect(3, 4, 5, 6), r.bounds());
307 r.Union(gfx::Rect(1, 2, 12, 13));
308 EXPECT_EQ(gfx::Rect(1, 2, 12, 13), r.bounds());
309 }
310
TEST(SimpleEnclosedRegionTest,GetRect)311 TEST(SimpleEnclosedRegionTest, GetRect) {
312 SimpleEnclosedRegion r(3, 4, 5, 6);
313 EXPECT_EQ(gfx::Rect(3, 4, 5, 6), r.GetRect(0));
314 r.Union(gfx::Rect(1, 2, 12, 13));
315 EXPECT_EQ(gfx::Rect(1, 2, 12, 13), r.GetRect(0));
316 }
317
TEST(SimpleEnclosedRegionTest,Union)318 TEST(SimpleEnclosedRegionTest, Union) {
319 SimpleEnclosedRegion r;
320 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(), r));
321
322 // Empty Union anything = anything.
323 r.Union(gfx::Rect(4, 5, 6, 7));
324 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(4, 5, 6, 7), r));
325
326 // Anything Union empty = anything.
327 r.Union(gfx::Rect());
328 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(4, 5, 6, 7), r));
329
330 // Anything Union contained rect = Anything.
331 r.Union(gfx::Rect(5, 6, 4, 5));
332 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(4, 5, 6, 7), r));
333
334 // Anything Union containing rect = containing rect.
335 r.Union(gfx::Rect(2, 3, 8, 9));
336 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(2, 3, 8, 9), r));
337 r.Union(gfx::Rect(2, 3, 9, 10));
338 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(2, 3, 9, 10), r));
339
340 // Union with a second disjoint rect with area larger than half of the first
341 // one.
342 // +---+ +--+
343 // | | | |
344 // +---+ +--+
345 r.Union(gfx::Rect(20, 20, 6, 10));
346 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(20, 20, 6, 10), r));
347
348 // Union with a second disjoint rect with area smaller than half of the first
349 // one.
350 // +----+ +--+
351 // | | +--+
352 // +----+
353 r.Union(gfx::Rect(2, 3, 3, 3));
354 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(20, 20, 6, 10), r));
355
356 // Union with a second disjoint rect with area larger than the first one.
357 // +---+ +-------+
358 // | | | |
359 // +---+ +-------+
360 r.Union(gfx::Rect(2, 3, 15, 15));
361 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(2, 3, 15, 15), r));
362
363 // Union with rect which extends from the first one:
364 // +----------+
365 // | 1 | 2 |
366 // +-----+----+
367 r = gfx::Rect(10, 10, 10, 10);
368 r.Union(gfx::Rect(20, 10, 5, 10));
369 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 15, 10), r));
370
371 r = gfx::Rect(10, 10, 10, 10);
372 r.Union(gfx::Rect(10, 5, 10, 5));
373 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 5, 10, 15), r));
374
375 r = gfx::Rect(10, 10, 10, 10);
376 r.Union(gfx::Rect(5, 10, 5, 10));
377 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(5, 10, 15, 10), r));
378
379 r = gfx::Rect(10, 10, 10, 10);
380 r.Union(gfx::Rect(10, 20, 10, 5));
381 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 15), r));
382
383 // Union with rect which overlaps and extends from the first one:
384 // +----+--+---+
385 // | 1 | |2 |
386 // | | | |
387 // +----+--+---+
388 r = gfx::Rect(10, 10, 10, 10);
389 r.Union(gfx::Rect(10, 2, 10, 10));
390 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 2, 10, 18), r));
391
392 r = gfx::Rect(10, 10, 10, 10);
393 r.Union(gfx::Rect(2, 10, 10, 10));
394 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(2, 10, 18, 10), r));
395
396 r = gfx::Rect(10, 10, 10, 10);
397 r.Union(gfx::Rect(10, 18, 10, 10));
398 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 18), r));
399
400 r = gfx::Rect(10, 10, 10, 10);
401 r.Union(gfx::Rect(18, 10, 10, 10));
402 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 18, 10), r));
403
404 // Union with a second rect which overlaps with the first one and
405 // area(rect 1) + area(overlap) > area(rect 2)*2 and
406 // area(rect 1) < area(rect 2)*2.
407 // +---+
408 // +---|+ 2|
409 // | +---+
410 // | 1 |
411 // +----+ (same figure for next test case.)
412 r = gfx::Rect(10, 10, 10, 10);
413 r.Union(gfx::Rect(14, 12, 8, 7));
414 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 10), r));
415
416 r = gfx::Rect(10, 10, 10, 10);
417 r.Union(gfx::Rect(11, 9, 8, 7));
418 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 10), r));
419
420 r = gfx::Rect(10, 10, 10, 10);
421 r.Union(gfx::Rect(9, 12, 8, 7));
422 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 10), r));
423
424 r = gfx::Rect(10, 10, 10, 10);
425 r.Union(gfx::Rect(13, 11, 8, 7));
426 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 10), r));
427
428 // Union with a second rect which overlaps with the first one and
429 // area(rect 1) + area(overlap) < area(rect 2)*2 and
430 // area(rect 1) > area(rect 2).
431 r = gfx::Rect(10, 10, 5, 5);
432 r.Union(gfx::Rect(7, 7, 4, 4));
433 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(7, 7, 4, 4), r));
434
435 r = gfx::Rect(10, 10, 5, 5);
436 r.Union(gfx::Rect(14, 7, 4, 4));
437 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(14, 7, 4, 4), r));
438
439 r = gfx::Rect(10, 10, 5, 5);
440 r.Union(gfx::Rect(7, 14, 4, 4));
441 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(7, 14, 4, 4), r));
442
443 r = gfx::Rect(10, 10, 5, 5);
444 r.Union(gfx::Rect(14, 14, 4, 4));
445 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(14, 14, 4, 4), r));
446
447 // Union with a second rect which overlaps with the first one and the new
448 // unioned rect should combine both rect.
449 // +---+-+-----------+
450 // | 1| | 2 |
451 // | +-|-----------+
452 // +-----+
453 r = gfx::Rect(10, 10, 5, 5);
454 r.Union(gfx::Rect(5, 11, 7, 4));
455 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(5, 11, 10, 4), r));
456
457 r = gfx::Rect(10, 10, 5, 5);
458 r.Union(gfx::Rect(13, 10, 7, 4));
459 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 4), r));
460
461 r = gfx::Rect(10, 10, 5, 5);
462 r.Union(gfx::Rect(10, 12, 4, 7));
463 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 4, 9), r));
464
465 r = gfx::Rect(10, 10, 5, 5);
466 r.Union(gfx::Rect(11, 11, 4, 7));
467 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(11, 10, 4, 8), r));
468 }
469
TEST(SimpleEnclosedRegionTest,Subtract)470 TEST(SimpleEnclosedRegionTest, Subtract) {
471 SimpleEnclosedRegion r;
472 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(), r));
473
474 // Empty Subtract anything = empty.
475 r.Subtract(gfx::Rect(4, 5, 6, 7));
476 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(), r));
477
478 // Subtracting an enclosing rect = empty.
479 r = gfx::Rect(10, 10, 10, 10);
480 r.Subtract(gfx::Rect(10, 10, 10, 10));
481 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(), r));
482
483 r = gfx::Rect(10, 10, 10, 10);
484 r.Subtract(gfx::Rect(9, 9, 12, 12));
485 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(), r));
486
487 // Subtracting a rect that covers one side of the region will shrink that
488 // side.
489 r = gfx::Rect(10, 10, 10, 10);
490 r.Subtract(gfx::Rect(18, 10, 10, 10));
491 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 8, 10), r));
492
493 r = gfx::Rect(10, 10, 10, 10);
494 r.Subtract(gfx::Rect(18, 8, 10, 14));
495 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 8, 10), r));
496
497 r = gfx::Rect(10, 10, 10, 10);
498 r.Subtract(gfx::Rect(10, 18, 10, 10));
499 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 8), r));
500
501 r = gfx::Rect(10, 10, 10, 10);
502 r.Subtract(gfx::Rect(8, 18, 14, 10));
503 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 8), r));
504
505 r = gfx::Rect(10, 10, 10, 10);
506 r.Subtract(gfx::Rect(2, 10, 10, 10));
507 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(12, 10, 8, 10), r));
508
509 r = gfx::Rect(10, 10, 10, 10);
510 r.Subtract(gfx::Rect(2, 8, 10, 14));
511 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(12, 10, 8, 10), r));
512
513 r = gfx::Rect(10, 10, 10, 10);
514 r.Subtract(gfx::Rect(10, 2, 10, 10));
515 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 12, 10, 8), r));
516
517 r = gfx::Rect(10, 10, 10, 10);
518 r.Subtract(gfx::Rect(8, 2, 14, 10));
519 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 12, 10, 8), r));
520
521 // Subtracting a rect that does not cover a full side will still shrink that
522 // side.
523 r = gfx::Rect(10, 10, 10, 10);
524 r.Subtract(gfx::Rect(18, 12, 10, 8));
525 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 8, 10), r));
526
527 r = gfx::Rect(10, 10, 10, 10);
528 r.Subtract(gfx::Rect(18, 12, 10, 10));
529 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 8, 10), r));
530
531 r = gfx::Rect(10, 10, 10, 10);
532 r.Subtract(gfx::Rect(12, 18, 8, 10));
533 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 8), r));
534
535 r = gfx::Rect(10, 10, 10, 10);
536 r.Subtract(gfx::Rect(12, 18, 10, 10));
537 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 8), r));
538
539 r = gfx::Rect(10, 10, 10, 10);
540 r.Subtract(gfx::Rect(2, 12, 10, 8));
541 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(12, 10, 8, 10), r));
542
543 r = gfx::Rect(10, 10, 10, 10);
544 r.Subtract(gfx::Rect(2, 12, 10, 10));
545 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(12, 10, 8, 10), r));
546
547 r = gfx::Rect(10, 10, 10, 10);
548 r.Subtract(gfx::Rect(12, 2, 8, 10));
549 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 12, 10, 8), r));
550
551 r = gfx::Rect(10, 10, 10, 10);
552 r.Subtract(gfx::Rect(12, 2, 10, 10));
553 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 12, 10, 8), r));
554
555 // Subtracting a rect inside the region will make it choose the larger result.
556 r = gfx::Rect(10, 10, 10, 10);
557 r.Subtract(gfx::Rect(11, 11, 7, 8));
558 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(18, 10, 2, 10), r));
559
560 r = gfx::Rect(10, 10, 10, 10);
561 r.Subtract(gfx::Rect(11, 11, 8, 7));
562 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 18, 10, 2), r));
563
564 r = gfx::Rect(10, 10, 10, 10);
565 r.Subtract(gfx::Rect(12, 11, 7, 8));
566 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 2, 10), r));
567
568 r = gfx::Rect(10, 10, 10, 10);
569 r.Subtract(gfx::Rect(11, 12, 8, 7));
570 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 2), r));
571
572 // Subtracting a rect that cuts the region in two will choose the larger side.
573 // Here it's the top side.
574 r = gfx::Rect(10, 10, 10, 10);
575 r.Subtract(gfx::Rect(10, 14, 10, 3));
576 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 4), r));
577
578 r = gfx::Rect(10, 10, 10, 10);
579 r.Subtract(gfx::Rect(0, 14, 30, 3));
580 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 4), r));
581
582 r = gfx::Rect(10, 10, 10, 10);
583 r.Subtract(gfx::Rect(10, 14, 8, 3));
584 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 4), r));
585
586 r = gfx::Rect(10, 10, 10, 10);
587 r.Subtract(gfx::Rect(0, 14, 18, 3));
588 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 4), r));
589
590 r = gfx::Rect(10, 10, 10, 10);
591 r.Subtract(gfx::Rect(12, 14, 18, 3));
592 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 4), r));
593
594 // Here it's the bottom side.
595 r = gfx::Rect(10, 10, 10, 10);
596 r.Subtract(gfx::Rect(10, 13, 10, 3));
597 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 16, 10, 4), r));
598
599 r = gfx::Rect(10, 10, 10, 10);
600 r.Subtract(gfx::Rect(0, 13, 30, 3));
601 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 16, 10, 4), r));
602
603 r = gfx::Rect(10, 10, 10, 10);
604 r.Subtract(gfx::Rect(10, 13, 8, 3));
605 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 16, 10, 4), r));
606
607 r = gfx::Rect(10, 10, 10, 10);
608 r.Subtract(gfx::Rect(0, 13, 18, 3));
609 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 16, 10, 4), r));
610
611 r = gfx::Rect(10, 10, 10, 10);
612 r.Subtract(gfx::Rect(12, 13, 18, 3));
613 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 16, 10, 4), r));
614
615 // Here it's the left side.
616 r = gfx::Rect(10, 10, 10, 10);
617 r.Subtract(gfx::Rect(14, 10, 3, 10));
618 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 4, 10), r));
619
620 r = gfx::Rect(10, 10, 10, 10);
621 r.Subtract(gfx::Rect(14, 10, 3, 10));
622 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 4, 10), r));
623
624 r = gfx::Rect(10, 10, 10, 10);
625 r.Subtract(gfx::Rect(14, 10, 3, 10));
626 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 4, 10), r));
627
628 r = gfx::Rect(10, 10, 10, 10);
629 r.Subtract(gfx::Rect(14, 10, 3, 10));
630 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 4, 10), r));
631
632 r = gfx::Rect(10, 10, 10, 10);
633 r.Subtract(gfx::Rect(14, 10, 3, 10));
634 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 4, 10), r));
635
636 // Here it's the right side.
637 r = gfx::Rect(10, 10, 10, 10);
638 r.Subtract(gfx::Rect(13, 10, 3, 10));
639 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(16, 10, 4, 10), r));
640
641 r = gfx::Rect(10, 10, 10, 10);
642 r.Subtract(gfx::Rect(13, 10, 3, 10));
643 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(16, 10, 4, 10), r));
644
645 r = gfx::Rect(10, 10, 10, 10);
646 r.Subtract(gfx::Rect(13, 10, 3, 10));
647 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(16, 10, 4, 10), r));
648
649 r = gfx::Rect(10, 10, 10, 10);
650 r.Subtract(gfx::Rect(13, 10, 3, 10));
651 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(16, 10, 4, 10), r));
652
653 r = gfx::Rect(10, 10, 10, 10);
654 r.Subtract(gfx::Rect(13, 10, 3, 10));
655 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(16, 10, 4, 10), r));
656
657 // Subtracting a rect that leaves three possible choices will choose the
658 // larger.
659 r = gfx::Rect(10, 10, 10, 10);
660 r.Subtract(gfx::Rect(10, 14, 7, 3));
661 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 4), r));
662
663 r = gfx::Rect(10, 10, 10, 10);
664 r.Subtract(gfx::Rect(10, 14, 5, 3));
665 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(15, 10, 5, 10), r));
666
667 r = gfx::Rect(10, 10, 10, 10);
668 r.Subtract(gfx::Rect(13, 14, 7, 3));
669 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 4), r));
670
671 r = gfx::Rect(10, 10, 10, 10);
672 r.Subtract(gfx::Rect(15, 14, 5, 3));
673 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 5, 10), r));
674
675 r = gfx::Rect(10, 10, 10, 10);
676 r.Subtract(gfx::Rect(14, 10, 3, 7));
677 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 4, 10), r));
678
679 r = gfx::Rect(10, 10, 10, 10);
680 r.Subtract(gfx::Rect(14, 10, 3, 5));
681 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 15, 10, 5), r));
682
683 r = gfx::Rect(10, 10, 10, 10);
684 r.Subtract(gfx::Rect(14, 13, 3, 7));
685 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 4, 10), r));
686
687 r = gfx::Rect(10, 10, 10, 10);
688 r.Subtract(gfx::Rect(14, 15, 3, 5));
689 EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 5), r));
690 }
691
692 } // namespace
693 } // namespace cc
694