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