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