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
14namespace cc {
15namespace {
16
17bool 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
53TEST(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
74TEST(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
85TEST(SimpleEnclosedRegionTest, Clear) {
86  SimpleEnclosedRegion r(1, 2, 3, 4);
87  EXPECT_FALSE(r.IsEmpty());
88  r.Clear();
89  EXPECT_TRUE(r.IsEmpty());
90}
91
92TEST(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
105TEST(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
205TEST(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
289TEST(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
300TEST(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
309TEST(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
316TEST(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
414TEST(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