| // Copyright 2014 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #include "cc/base/simple_enclosed_region.h" | 
 |  | 
 | #include <stddef.h> | 
 |  | 
 | #include <algorithm> | 
 | #include <vector> | 
 |  | 
 | #include "base/logging.h" | 
 | #include "cc/base/region.h" | 
 | #include "testing/gtest/include/gtest/gtest.h" | 
 |  | 
 | namespace cc { | 
 | namespace { | 
 |  | 
 | bool ExpectRegionEq(const gfx::Rect& rect, const SimpleEnclosedRegion& region) { | 
 |   std::vector<gfx::Rect> actual_rects; | 
 |   std::vector<gfx::Rect> expected_rects; | 
 |  | 
 |   if (!rect.IsEmpty()) | 
 |     expected_rects.push_back(rect); | 
 |  | 
 |   for (size_t i = 0; i < region.GetRegionComplexity(); ++i) | 
 |     actual_rects.push_back(region.GetRect(i)); | 
 |  | 
 |   if (rect.IsEmpty() != region.IsEmpty()) { | 
 |     LOG(ERROR) << "Expected: " << rect.IsEmpty() | 
 |                << " Actual: " << region.IsEmpty(); | 
 |     return false; | 
 |   } | 
 |  | 
 |   if (expected_rects.size() != actual_rects.size()) { | 
 |     LOG(ERROR) << "Expected: " << expected_rects.size() | 
 |                << " Actual: " << actual_rects.size(); | 
 |     return false; | 
 |   } | 
 |  | 
 |   std::sort(actual_rects.begin(), actual_rects.end()); | 
 |   std::sort(expected_rects.begin(), expected_rects.end()); | 
 |  | 
 |   for (size_t i = 0; i < expected_rects.size(); ++i) { | 
 |     if (expected_rects[i] != actual_rects[i]) { | 
 |       LOG(ERROR) << "Expected: " << expected_rects[i].ToString() | 
 |                  << " Actual: " << actual_rects[i].ToString(); | 
 |       return false; | 
 |     } | 
 |   } | 
 |  | 
 |   return true; | 
 | } | 
 |  | 
 | TEST(SimpleEnclosedRegionTest, Create) { | 
 |   SimpleEnclosedRegion r1; | 
 |   EXPECT_TRUE(r1.IsEmpty()); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(), r1)); | 
 |  | 
 |   SimpleEnclosedRegion r2(gfx::Rect(2, 3, 4, 5)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(2, 3, 4, 5), r2)); | 
 |  | 
 |   SimpleEnclosedRegion r3(2, 3, 4, 5); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(2, 3, 4, 5), r3)); | 
 |  | 
 |   SimpleEnclosedRegion r4(4, 5); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(4, 5), r4)); | 
 |  | 
 |   SimpleEnclosedRegion r5(Region(gfx::Rect(2, 3, 4, 5))); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(2, 3, 4, 5), r5)); | 
 |  | 
 |   SimpleEnclosedRegion r6(r5); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(2, 3, 4, 5), r6)); | 
 | } | 
 |  | 
 | TEST(SimpleEnclosedRegionTest, Assign) { | 
 |   SimpleEnclosedRegion r; | 
 |   EXPECT_TRUE(r.IsEmpty()); | 
 |  | 
 |   r = gfx::Rect(2, 3, 4, 5); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(2, 3, 4, 5), r)); | 
 |  | 
 |   r = SimpleEnclosedRegion(3, 4, 5, 6); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(3, 4, 5, 6), r)); | 
 | } | 
 |  | 
 | TEST(SimpleEnclosedRegionTest, Clear) { | 
 |   SimpleEnclosedRegion r(1, 2, 3, 4); | 
 |   EXPECT_FALSE(r.IsEmpty()); | 
 |   r.Clear(); | 
 |   EXPECT_TRUE(r.IsEmpty()); | 
 | } | 
 |  | 
 | TEST(SimpleEnclosedRegionTest, GetRegionComplexity) { | 
 |   SimpleEnclosedRegion empty; | 
 |   EXPECT_EQ(0u, empty.GetRegionComplexity()); | 
 |  | 
 |   SimpleEnclosedRegion stuff; | 
 |   stuff.Union(gfx::Rect(1, 2, 3, 4)); | 
 |   EXPECT_EQ(1u, stuff.GetRegionComplexity()); | 
 |  | 
 |   // The SimpleEnclosedRegion only holds up to 1 rect. | 
 |   stuff.Union(gfx::Rect(5, 6, 7, 8)); | 
 |   EXPECT_EQ(1u, stuff.GetRegionComplexity()); | 
 | } | 
 |  | 
 | TEST(SimpleEnclosedRegionTest, Contains) { | 
 |   SimpleEnclosedRegion r(1, 2, 5, 6); | 
 |  | 
 |   EXPECT_FALSE(r.Contains(gfx::Point(0, 2))); | 
 |   EXPECT_FALSE(r.Contains(gfx::Point(1, 1))); | 
 |   EXPECT_TRUE(r.Contains(gfx::Point(1, 2))); | 
 |  | 
 |   EXPECT_FALSE(r.Contains(gfx::Point(6, 2))); | 
 |   EXPECT_FALSE(r.Contains(gfx::Point(5, 1))); | 
 |   EXPECT_TRUE(r.Contains(gfx::Point(5, 2))); | 
 |  | 
 |   EXPECT_FALSE(r.Contains(gfx::Point(0, 7))); | 
 |   EXPECT_FALSE(r.Contains(gfx::Point(1, 8))); | 
 |   EXPECT_TRUE(r.Contains(gfx::Point(1, 7))); | 
 |  | 
 |   EXPECT_FALSE(r.Contains(gfx::Point(6, 7))); | 
 |   EXPECT_FALSE(r.Contains(gfx::Point(5, 8))); | 
 |   EXPECT_TRUE(r.Contains(gfx::Point(5, 7))); | 
 |  | 
 |   EXPECT_FALSE(r.Contains(gfx::Rect(0, 2, 1, 1))); | 
 |   EXPECT_FALSE(r.Contains(gfx::Rect(1, 1, 1, 1))); | 
 |   EXPECT_TRUE(r.Contains(gfx::Rect(1, 2, 1, 1))); | 
 |   EXPECT_FALSE(r.Contains(gfx::Rect(0, 1, 2, 2))); | 
 |  | 
 |   EXPECT_FALSE(r.Contains(gfx::Rect(6, 2, 1, 1))); | 
 |   EXPECT_FALSE(r.Contains(gfx::Rect(5, 1, 1, 1))); | 
 |   EXPECT_TRUE(r.Contains(gfx::Rect(5, 2, 1, 1))); | 
 |   EXPECT_FALSE(r.Contains(gfx::Rect(5, 1, 2, 2))); | 
 |  | 
 |   EXPECT_FALSE(r.Contains(gfx::Rect(0, 7, 1, 1))); | 
 |   EXPECT_FALSE(r.Contains(gfx::Rect(1, 8, 1, 1))); | 
 |   EXPECT_TRUE(r.Contains(gfx::Rect(1, 7, 1, 1))); | 
 |   EXPECT_FALSE(r.Contains(gfx::Rect(0, 7, 2, 2))); | 
 |  | 
 |   EXPECT_FALSE(r.Contains(gfx::Rect(6, 7, 1, 1))); | 
 |   EXPECT_FALSE(r.Contains(gfx::Rect(5, 8, 1, 1))); | 
 |   EXPECT_TRUE(r.Contains(gfx::Rect(5, 7, 1, 1))); | 
 |   EXPECT_FALSE(r.Contains(gfx::Rect(5, 7, 2, 2))); | 
 |  | 
 |   gfx::Rect q(1, 2, 5, 6); | 
 |   EXPECT_TRUE(r.Contains(q)) << q.ToString(); | 
 |   q.Inset(-1, 0, 0, 0); | 
 |   EXPECT_FALSE(r.Contains(q)) << q.ToString(); | 
 |   q.Inset(1, -1, 0, 0); | 
 |   EXPECT_FALSE(r.Contains(q)) << q.ToString(); | 
 |   q.Inset(0, 1, -1, 0); | 
 |   EXPECT_FALSE(r.Contains(q)) << q.ToString(); | 
 |   q.Inset(0, 0, 1, -1); | 
 |   EXPECT_FALSE(r.Contains(q)) << q.ToString(); | 
 |  | 
 |   q.Inset(1, 0, 0, 1); | 
 |   EXPECT_TRUE(r.Contains(q)) << q.ToString(); | 
 |   q.Inset(-1, 1, 0, 0); | 
 |   EXPECT_TRUE(r.Contains(q)) << q.ToString(); | 
 |   q.Inset(0, -1, 1, 0); | 
 |   EXPECT_TRUE(r.Contains(q)) << q.ToString(); | 
 |   q.Inset(0, 0, -1, 1); | 
 |   EXPECT_TRUE(r.Contains(q)) << q.ToString(); | 
 |  | 
 |   EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(0, 2, 1, 1))); | 
 |   EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(1, 1, 1, 1))); | 
 |   EXPECT_TRUE(r.Contains(SimpleEnclosedRegion(1, 2, 1, 1))); | 
 |   EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(0, 1, 2, 2))); | 
 |  | 
 |   EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(6, 2, 1, 1))); | 
 |   EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(5, 1, 1, 1))); | 
 |   EXPECT_TRUE(r.Contains(SimpleEnclosedRegion(5, 2, 1, 1))); | 
 |   EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(5, 1, 2, 2))); | 
 |  | 
 |   EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(0, 7, 1, 1))); | 
 |   EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(1, 8, 1, 1))); | 
 |   EXPECT_TRUE(r.Contains(SimpleEnclosedRegion(1, 7, 1, 1))); | 
 |   EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(0, 7, 2, 2))); | 
 |  | 
 |   EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(6, 7, 1, 1))); | 
 |   EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(5, 8, 1, 1))); | 
 |   EXPECT_TRUE(r.Contains(SimpleEnclosedRegion(5, 7, 1, 1))); | 
 |   EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(5, 7, 2, 2))); | 
 |  | 
 |   q = gfx::Rect(1, 2, 5, 6); | 
 |   EXPECT_TRUE(r.Contains(SimpleEnclosedRegion(q))) << q.ToString(); | 
 |   q.Inset(-1, 0, 0, 0); | 
 |   EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(q))) << q.ToString(); | 
 |   q.Inset(1, -1, 0, 0); | 
 |   EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(q))) << q.ToString(); | 
 |   q.Inset(0, 1, -1, 0); | 
 |   EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(q))) << q.ToString(); | 
 |   q.Inset(0, 0, 1, -1); | 
 |   EXPECT_FALSE(r.Contains(SimpleEnclosedRegion(q))) << q.ToString(); | 
 |  | 
 |   q.Inset(1, 0, 0, 1); | 
 |   EXPECT_TRUE(r.Contains(SimpleEnclosedRegion(q))) << q.ToString(); | 
 |   q.Inset(-1, 1, 0, 0); | 
 |   EXPECT_TRUE(r.Contains(SimpleEnclosedRegion(q))) << q.ToString(); | 
 |   q.Inset(0, -1, 1, 0); | 
 |   EXPECT_TRUE(r.Contains(SimpleEnclosedRegion(q))) << q.ToString(); | 
 |   q.Inset(0, 0, -1, 1); | 
 |   EXPECT_TRUE(r.Contains(SimpleEnclosedRegion(q))) << q.ToString(); | 
 | } | 
 |  | 
 | TEST(SimpleEnclosedRegionTest, Intersects) { | 
 |   SimpleEnclosedRegion r(1, 2, 5, 6); | 
 |  | 
 |   EXPECT_FALSE(r.Intersects(gfx::Rect(0, 2, 1, 1))); | 
 |   EXPECT_FALSE(r.Intersects(gfx::Rect(1, 1, 1, 1))); | 
 |   EXPECT_TRUE(r.Intersects(gfx::Rect(1, 2, 1, 1))); | 
 |   EXPECT_TRUE(r.Intersects(gfx::Rect(0, 1, 2, 2))); | 
 |  | 
 |   EXPECT_FALSE(r.Intersects(gfx::Rect(6, 2, 1, 1))); | 
 |   EXPECT_FALSE(r.Intersects(gfx::Rect(5, 1, 1, 1))); | 
 |   EXPECT_TRUE(r.Intersects(gfx::Rect(5, 2, 1, 1))); | 
 |   EXPECT_TRUE(r.Intersects(gfx::Rect(5, 1, 2, 2))); | 
 |  | 
 |   EXPECT_FALSE(r.Intersects(gfx::Rect(0, 7, 1, 1))); | 
 |   EXPECT_FALSE(r.Intersects(gfx::Rect(1, 8, 1, 1))); | 
 |   EXPECT_TRUE(r.Intersects(gfx::Rect(1, 7, 1, 1))); | 
 |   EXPECT_TRUE(r.Intersects(gfx::Rect(0, 7, 2, 2))); | 
 |  | 
 |   EXPECT_FALSE(r.Intersects(gfx::Rect(6, 7, 1, 1))); | 
 |   EXPECT_FALSE(r.Intersects(gfx::Rect(5, 8, 1, 1))); | 
 |   EXPECT_TRUE(r.Intersects(gfx::Rect(5, 7, 1, 1))); | 
 |   EXPECT_TRUE(r.Intersects(gfx::Rect(5, 7, 2, 2))); | 
 |  | 
 |   gfx::Rect q(1, 2, 5, 6); | 
 |   EXPECT_TRUE(r.Intersects(q)) << q.ToString(); | 
 |   q.Inset(-1, 0, 0, 0); | 
 |   EXPECT_TRUE(r.Intersects(q)) << q.ToString(); | 
 |   q.Inset(1, -1, 0, 0); | 
 |   EXPECT_TRUE(r.Intersects(q)) << q.ToString(); | 
 |   q.Inset(0, 1, -1, 0); | 
 |   EXPECT_TRUE(r.Intersects(q)) << q.ToString(); | 
 |   q.Inset(0, 0, 1, -1); | 
 |   EXPECT_TRUE(r.Intersects(q)) << q.ToString(); | 
 |  | 
 |   q.Inset(1, 0, 0, 1); | 
 |   EXPECT_TRUE(r.Intersects(q)) << q.ToString(); | 
 |   q.Inset(-1, 1, 0, 0); | 
 |   EXPECT_TRUE(r.Intersects(q)) << q.ToString(); | 
 |   q.Inset(0, -1, 1, 0); | 
 |   EXPECT_TRUE(r.Intersects(q)) << q.ToString(); | 
 |   q.Inset(0, 0, -1, 1); | 
 |   EXPECT_TRUE(r.Intersects(q)) << q.ToString(); | 
 |  | 
 |   EXPECT_FALSE(r.Intersects(SimpleEnclosedRegion(0, 2, 1, 1))); | 
 |   EXPECT_FALSE(r.Intersects(SimpleEnclosedRegion(1, 1, 1, 1))); | 
 |   EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(1, 2, 1, 1))); | 
 |   EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(0, 1, 2, 2))); | 
 |  | 
 |   EXPECT_FALSE(r.Intersects(SimpleEnclosedRegion(6, 2, 1, 1))); | 
 |   EXPECT_FALSE(r.Intersects(SimpleEnclosedRegion(5, 1, 1, 1))); | 
 |   EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(5, 2, 1, 1))); | 
 |   EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(5, 1, 2, 2))); | 
 |  | 
 |   EXPECT_FALSE(r.Intersects(SimpleEnclosedRegion(0, 7, 1, 1))); | 
 |   EXPECT_FALSE(r.Intersects(SimpleEnclosedRegion(1, 8, 1, 1))); | 
 |   EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(1, 7, 1, 1))); | 
 |   EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(0, 7, 2, 2))); | 
 |  | 
 |   EXPECT_FALSE(r.Intersects(SimpleEnclosedRegion(6, 7, 1, 1))); | 
 |   EXPECT_FALSE(r.Intersects(SimpleEnclosedRegion(5, 8, 1, 1))); | 
 |   EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(5, 7, 1, 1))); | 
 |   EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(5, 7, 2, 2))); | 
 |  | 
 |   q = gfx::Rect(1, 2, 5, 6); | 
 |   EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(q))) << q.ToString(); | 
 |   q.Inset(-1, 0, 0, 0); | 
 |   EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(q))) << q.ToString(); | 
 |   q.Inset(1, -1, 0, 0); | 
 |   EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(q))) << q.ToString(); | 
 |   q.Inset(0, 1, -1, 0); | 
 |   EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(q))) << q.ToString(); | 
 |   q.Inset(0, 0, 1, -1); | 
 |   EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(q))) << q.ToString(); | 
 |  | 
 |   q.Inset(1, 0, 0, 1); | 
 |   EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(q))) << q.ToString(); | 
 |   q.Inset(-1, 1, 0, 0); | 
 |   EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(q))) << q.ToString(); | 
 |   q.Inset(0, -1, 1, 0); | 
 |   EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(q))) << q.ToString(); | 
 |   q.Inset(0, 0, -1, 1); | 
 |   EXPECT_TRUE(r.Intersects(SimpleEnclosedRegion(q))) << q.ToString(); | 
 | } | 
 |  | 
 | TEST(SimpleEnclosedRegionTest, Equals) { | 
 |   SimpleEnclosedRegion r(1, 2, 3, 4); | 
 |   EXPECT_TRUE(r.Equals(SimpleEnclosedRegion(1, 2, 3, 4))); | 
 |   EXPECT_FALSE(r.Equals(SimpleEnclosedRegion(2, 2, 3, 4))); | 
 |   EXPECT_FALSE(r.Equals(SimpleEnclosedRegion(1, 3, 3, 4))); | 
 |   EXPECT_FALSE(r.Equals(SimpleEnclosedRegion(1, 2, 4, 4))); | 
 |   EXPECT_FALSE(r.Equals(SimpleEnclosedRegion(1, 2, 3, 5))); | 
 |   EXPECT_FALSE(r.Equals(SimpleEnclosedRegion(2, 2, 2, 4))); | 
 |   EXPECT_FALSE(r.Equals(SimpleEnclosedRegion(1, 3, 3, 3))); | 
 | } | 
 |  | 
 | TEST(SimpleEnclosedRegionTest, Bounds) { | 
 |   SimpleEnclosedRegion r; | 
 |   EXPECT_EQ(gfx::Rect(), r.bounds()); | 
 |   r = gfx::Rect(3, 4, 5, 6); | 
 |   EXPECT_EQ(gfx::Rect(3, 4, 5, 6), r.bounds()); | 
 |   r.Union(gfx::Rect(1, 2, 12, 13)); | 
 |   EXPECT_EQ(gfx::Rect(1, 2, 12, 13), r.bounds()); | 
 | } | 
 |  | 
 | TEST(SimpleEnclosedRegionTest, GetRect) { | 
 |   SimpleEnclosedRegion r(3, 4, 5, 6); | 
 |   EXPECT_EQ(gfx::Rect(3, 4, 5, 6), r.GetRect(0)); | 
 |   r.Union(gfx::Rect(1, 2, 12, 13)); | 
 |   EXPECT_EQ(gfx::Rect(1, 2, 12, 13), r.GetRect(0)); | 
 | } | 
 |  | 
 | TEST(SimpleEnclosedRegionTest, Union) { | 
 |   SimpleEnclosedRegion r; | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(), r)); | 
 |  | 
 |   // Empty Union anything = anything. | 
 |   r.Union(gfx::Rect(4, 5, 6, 7)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(4, 5, 6, 7), r)); | 
 |  | 
 |   // Anything Union empty = anything. | 
 |   r.Union(gfx::Rect()); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(4, 5, 6, 7), r)); | 
 |  | 
 |   // Anything Union contained rect = Anything. | 
 |   r.Union(gfx::Rect(5, 6, 4, 5)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(4, 5, 6, 7), r)); | 
 |  | 
 |   // Anything Union containing rect = containing rect. | 
 |   r.Union(gfx::Rect(2, 3, 8, 9)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(2, 3, 8, 9), r)); | 
 |   r.Union(gfx::Rect(2, 3, 9, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(2, 3, 9, 10), r)); | 
 |  | 
 |   // Union with a smaller disjoint rect is ignored. | 
 |   r.Union(gfx::Rect(20, 21, 9, 9)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(2, 3, 9, 10), r)); | 
 |  | 
 |   // Union with a smaller overlapping rect is ignored. | 
 |   r.Union(gfx::Rect(3, 4, 9, 9)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(2, 3, 9, 10), r)); | 
 |  | 
 |   // Union with an equal sized rect can be either one. | 
 |   r.Union(gfx::Rect(4, 4, 9, 10)); | 
 |   EXPECT_EQ(1u, r.GetRegionComplexity()); | 
 |   EXPECT_TRUE(r.bounds() == gfx::Rect(2, 3, 9, 10) || | 
 |               r.bounds() == gfx::Rect(4, 4, 9, 10)); | 
 |  | 
 |   // Union with a larger disjoint rect is taken. | 
 |   r.Union(gfx::Rect(20, 21, 12, 13)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(20, 21, 12, 13), r)); | 
 |  | 
 |   // Union with a larger overlapping rect is taken. | 
 |   r.Union(gfx::Rect(19, 19, 12, 14)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(19, 19, 12, 14), r)); | 
 |  | 
 |   // True also when the rect covers one edge of the existing region. | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Union(gfx::Rect(12, 7, 9, 16)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(12, 7, 9, 16), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Union(gfx::Rect(9, 7, 9, 16)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(9, 7, 9, 16), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Union(gfx::Rect(7, 12, 16, 9)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(7, 12, 16, 9), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Union(gfx::Rect(7, 9, 16, 9)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(7, 9, 16, 9), r)); | 
 |  | 
 |   // But if the existing region can be expanded to make a larger rect, then it | 
 |   // will. Union area is 9*12 = 108. By merging, we make a rect with an area of | 
 |   // 10*11 = 110. The resulting rect is expanded as far as possible while | 
 |   // remaining enclosed in the Union. | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Union(gfx::Rect(12, 9, 9, 12)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 11, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Union(gfx::Rect(9, 9, 9, 12)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(9, 10, 11, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Union(gfx::Rect(9, 12, 12, 9)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 11), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Union(gfx::Rect(9, 9, 12, 9)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 9, 10, 11), r)); | 
 |  | 
 |   r = gfx::Rect(12, 9, 9, 12); | 
 |   r.Union(gfx::Rect(10, 10, 10, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 11, 10), r)); | 
 |  | 
 |   r = gfx::Rect(9, 9, 9, 12); | 
 |   r.Union(gfx::Rect(10, 10, 10, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(9, 10, 11, 10), r)); | 
 |  | 
 |   r = gfx::Rect(9, 12, 12, 9); | 
 |   r.Union(gfx::Rect(10, 10, 10, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 11), r)); | 
 |  | 
 |   r = gfx::Rect(9, 9, 12, 9); | 
 |   r.Union(gfx::Rect(10, 10, 10, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 9, 10, 11), r)); | 
 | } | 
 |  | 
 | TEST(SimpleEnclosedRegionTest, Subtract) { | 
 |   SimpleEnclosedRegion r; | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(), r)); | 
 |  | 
 |   // Empty Subtract anything = empty. | 
 |   r.Subtract(gfx::Rect(4, 5, 6, 7)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(), r)); | 
 |  | 
 |   // Subtracting an enclosing rect = empty. | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(10, 10, 10, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(9, 9, 12, 12)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(), r)); | 
 |  | 
 |   // Subtracting a rect that covers one side of the region will shrink that | 
 |   // side. | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(18, 10, 10, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 8, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(18, 8, 10, 14)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 8, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(10, 18, 10, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 8), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(8, 18, 14, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 8), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(2, 10, 10, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(12, 10, 8, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(2, 8, 10, 14)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(12, 10, 8, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(10, 2, 10, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 12, 10, 8), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(8, 2, 14, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 12, 10, 8), r)); | 
 |  | 
 |   // Subtracting a rect that does not cover a full side will still shrink that | 
 |   // side. | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(18, 12, 10, 8)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 8, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(18, 12, 10, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 8, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(12, 18, 8, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 8), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(12, 18, 10, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 8), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(2, 12, 10, 8)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(12, 10, 8, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(2, 12, 10, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(12, 10, 8, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(12, 2, 8, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 12, 10, 8), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(12, 2, 10, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 12, 10, 8), r)); | 
 |  | 
 |   // Subtracting a rect inside the region will make it choose the larger result. | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(11, 11, 7, 8)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(18, 10, 2, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(11, 11, 8, 7)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 18, 10, 2), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(12, 11, 7, 8)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 2, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(11, 12, 8, 7)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 2), r)); | 
 |  | 
 |   // Subtracting a rect that cuts the region in two will choose the larger side. | 
 |   // Here it's the top side. | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(10, 14, 10, 3)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 4), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(0, 14, 30, 3)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 4), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(10, 14, 8, 3)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 4), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(0, 14, 18, 3)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 4), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(12, 14, 18, 3)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 4), r)); | 
 |  | 
 |   // Here it's the bottom side. | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(10, 13, 10, 3)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 16, 10, 4), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(0, 13, 30, 3)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 16, 10, 4), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(10, 13, 8, 3)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 16, 10, 4), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(0, 13, 18, 3)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 16, 10, 4), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(12, 13, 18, 3)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 16, 10, 4), r)); | 
 |  | 
 |   // Here it's the left side. | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(14, 10, 3, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 4, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(14, 10, 3, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 4, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(14, 10, 3, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 4, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(14, 10, 3, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 4, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(14, 10, 3, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 4, 10), r)); | 
 |  | 
 |   // Here it's the right side. | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(13, 10, 3, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(16, 10, 4, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(13, 10, 3, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(16, 10, 4, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(13, 10, 3, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(16, 10, 4, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(13, 10, 3, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(16, 10, 4, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(13, 10, 3, 10)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(16, 10, 4, 10), r)); | 
 |  | 
 |   // Subtracting a rect that leaves three possible choices will choose the | 
 |   // larger. | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(10, 14, 7, 3)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 4), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(10, 14, 5, 3)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(15, 10, 5, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(13, 14, 7, 3)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 4), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(15, 14, 5, 3)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 5, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(14, 10, 3, 7)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 4, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(14, 10, 3, 5)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 15, 10, 5), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(14, 13, 3, 7)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 4, 10), r)); | 
 |  | 
 |   r = gfx::Rect(10, 10, 10, 10); | 
 |   r.Subtract(gfx::Rect(14, 15, 3, 5)); | 
 |   EXPECT_TRUE(ExpectRegionEq(gfx::Rect(10, 10, 10, 5), r)); | 
 | } | 
 |  | 
 | }  // namespace | 
 | }  // namespace cc |