1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include <limits>
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
8*635a8641SAndroid Build Coastguard Worker
9*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
10*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
11*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
12*635a8641SAndroid Build Coastguard Worker #include "ui/gfx/geometry/rect.h"
13*635a8641SAndroid Build Coastguard Worker #include "ui/gfx/geometry/rect_conversions.h"
14*635a8641SAndroid Build Coastguard Worker #include "ui/gfx/test/gfx_util.h"
15*635a8641SAndroid Build Coastguard Worker
16*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
17*635a8641SAndroid Build Coastguard Worker #include <windows.h>
18*635a8641SAndroid Build Coastguard Worker #endif
19*635a8641SAndroid Build Coastguard Worker
20*635a8641SAndroid Build Coastguard Worker namespace gfx {
21*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,Contains)22*635a8641SAndroid Build Coastguard Worker TEST(RectTest, Contains) {
23*635a8641SAndroid Build Coastguard Worker static const struct ContainsCase {
24*635a8641SAndroid Build Coastguard Worker int rect_x;
25*635a8641SAndroid Build Coastguard Worker int rect_y;
26*635a8641SAndroid Build Coastguard Worker int rect_width;
27*635a8641SAndroid Build Coastguard Worker int rect_height;
28*635a8641SAndroid Build Coastguard Worker int point_x;
29*635a8641SAndroid Build Coastguard Worker int point_y;
30*635a8641SAndroid Build Coastguard Worker bool contained;
31*635a8641SAndroid Build Coastguard Worker } contains_cases[] = {
32*635a8641SAndroid Build Coastguard Worker {0, 0, 10, 10, 0, 0, true},
33*635a8641SAndroid Build Coastguard Worker {0, 0, 10, 10, 5, 5, true},
34*635a8641SAndroid Build Coastguard Worker {0, 0, 10, 10, 9, 9, true},
35*635a8641SAndroid Build Coastguard Worker {0, 0, 10, 10, 5, 10, false},
36*635a8641SAndroid Build Coastguard Worker {0, 0, 10, 10, 10, 5, false},
37*635a8641SAndroid Build Coastguard Worker {0, 0, 10, 10, -1, -1, false},
38*635a8641SAndroid Build Coastguard Worker {0, 0, 10, 10, 50, 50, false},
39*635a8641SAndroid Build Coastguard Worker #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
40*635a8641SAndroid Build Coastguard Worker {0, 0, -10, -10, 0, 0, false},
41*635a8641SAndroid Build Coastguard Worker #endif
42*635a8641SAndroid Build Coastguard Worker };
43*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < arraysize(contains_cases); ++i) {
44*635a8641SAndroid Build Coastguard Worker const ContainsCase& value = contains_cases[i];
45*635a8641SAndroid Build Coastguard Worker Rect rect(value.rect_x, value.rect_y, value.rect_width, value.rect_height);
46*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(value.contained, rect.Contains(value.point_x, value.point_y));
47*635a8641SAndroid Build Coastguard Worker }
48*635a8641SAndroid Build Coastguard Worker }
49*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,Intersects)50*635a8641SAndroid Build Coastguard Worker TEST(RectTest, Intersects) {
51*635a8641SAndroid Build Coastguard Worker static const struct {
52*635a8641SAndroid Build Coastguard Worker int x1; // rect 1
53*635a8641SAndroid Build Coastguard Worker int y1;
54*635a8641SAndroid Build Coastguard Worker int w1;
55*635a8641SAndroid Build Coastguard Worker int h1;
56*635a8641SAndroid Build Coastguard Worker int x2; // rect 2
57*635a8641SAndroid Build Coastguard Worker int y2;
58*635a8641SAndroid Build Coastguard Worker int w2;
59*635a8641SAndroid Build Coastguard Worker int h2;
60*635a8641SAndroid Build Coastguard Worker bool intersects;
61*635a8641SAndroid Build Coastguard Worker } tests[] = {
62*635a8641SAndroid Build Coastguard Worker { 0, 0, 0, 0, 0, 0, 0, 0, false },
63*635a8641SAndroid Build Coastguard Worker { 0, 0, 0, 0, -10, -10, 20, 20, false },
64*635a8641SAndroid Build Coastguard Worker { -10, 0, 0, 20, 0, -10, 20, 0, false },
65*635a8641SAndroid Build Coastguard Worker { 0, 0, 10, 10, 0, 0, 10, 10, true },
66*635a8641SAndroid Build Coastguard Worker { 0, 0, 10, 10, 10, 10, 10, 10, false },
67*635a8641SAndroid Build Coastguard Worker { 10, 10, 10, 10, 0, 0, 10, 10, false },
68*635a8641SAndroid Build Coastguard Worker { 10, 10, 10, 10, 5, 5, 10, 10, true },
69*635a8641SAndroid Build Coastguard Worker { 10, 10, 10, 10, 15, 15, 10, 10, true },
70*635a8641SAndroid Build Coastguard Worker { 10, 10, 10, 10, 20, 15, 10, 10, false },
71*635a8641SAndroid Build Coastguard Worker { 10, 10, 10, 10, 21, 15, 10, 10, false }
72*635a8641SAndroid Build Coastguard Worker };
73*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < arraysize(tests); ++i) {
74*635a8641SAndroid Build Coastguard Worker Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
75*635a8641SAndroid Build Coastguard Worker Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
76*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(tests[i].intersects, r1.Intersects(r2));
77*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(tests[i].intersects, r2.Intersects(r1));
78*635a8641SAndroid Build Coastguard Worker }
79*635a8641SAndroid Build Coastguard Worker }
80*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,Intersect)81*635a8641SAndroid Build Coastguard Worker TEST(RectTest, Intersect) {
82*635a8641SAndroid Build Coastguard Worker static const struct {
83*635a8641SAndroid Build Coastguard Worker int x1; // rect 1
84*635a8641SAndroid Build Coastguard Worker int y1;
85*635a8641SAndroid Build Coastguard Worker int w1;
86*635a8641SAndroid Build Coastguard Worker int h1;
87*635a8641SAndroid Build Coastguard Worker int x2; // rect 2
88*635a8641SAndroid Build Coastguard Worker int y2;
89*635a8641SAndroid Build Coastguard Worker int w2;
90*635a8641SAndroid Build Coastguard Worker int h2;
91*635a8641SAndroid Build Coastguard Worker int x3; // rect 3: the union of rects 1 and 2
92*635a8641SAndroid Build Coastguard Worker int y3;
93*635a8641SAndroid Build Coastguard Worker int w3;
94*635a8641SAndroid Build Coastguard Worker int h3;
95*635a8641SAndroid Build Coastguard Worker } tests[] = {
96*635a8641SAndroid Build Coastguard Worker { 0, 0, 0, 0, // zeros
97*635a8641SAndroid Build Coastguard Worker 0, 0, 0, 0,
98*635a8641SAndroid Build Coastguard Worker 0, 0, 0, 0 },
99*635a8641SAndroid Build Coastguard Worker { 0, 0, 4, 4, // equal
100*635a8641SAndroid Build Coastguard Worker 0, 0, 4, 4,
101*635a8641SAndroid Build Coastguard Worker 0, 0, 4, 4 },
102*635a8641SAndroid Build Coastguard Worker { 0, 0, 4, 4, // neighboring
103*635a8641SAndroid Build Coastguard Worker 4, 4, 4, 4,
104*635a8641SAndroid Build Coastguard Worker 0, 0, 0, 0 },
105*635a8641SAndroid Build Coastguard Worker { 0, 0, 4, 4, // overlapping corners
106*635a8641SAndroid Build Coastguard Worker 2, 2, 4, 4,
107*635a8641SAndroid Build Coastguard Worker 2, 2, 2, 2 },
108*635a8641SAndroid Build Coastguard Worker { 0, 0, 4, 4, // T junction
109*635a8641SAndroid Build Coastguard Worker 3, 1, 4, 2,
110*635a8641SAndroid Build Coastguard Worker 3, 1, 1, 2 },
111*635a8641SAndroid Build Coastguard Worker { 3, 0, 2, 2, // gap
112*635a8641SAndroid Build Coastguard Worker 0, 0, 2, 2,
113*635a8641SAndroid Build Coastguard Worker 0, 0, 0, 0 }
114*635a8641SAndroid Build Coastguard Worker };
115*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < arraysize(tests); ++i) {
116*635a8641SAndroid Build Coastguard Worker Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
117*635a8641SAndroid Build Coastguard Worker Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
118*635a8641SAndroid Build Coastguard Worker Rect r3(tests[i].x3, tests[i].y3, tests[i].w3, tests[i].h3);
119*635a8641SAndroid Build Coastguard Worker Rect ir = IntersectRects(r1, r2);
120*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(r3.x(), ir.x());
121*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(r3.y(), ir.y());
122*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(r3.width(), ir.width());
123*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(r3.height(), ir.height());
124*635a8641SAndroid Build Coastguard Worker }
125*635a8641SAndroid Build Coastguard Worker }
126*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,Union)127*635a8641SAndroid Build Coastguard Worker TEST(RectTest, Union) {
128*635a8641SAndroid Build Coastguard Worker static const struct Test {
129*635a8641SAndroid Build Coastguard Worker int x1; // rect 1
130*635a8641SAndroid Build Coastguard Worker int y1;
131*635a8641SAndroid Build Coastguard Worker int w1;
132*635a8641SAndroid Build Coastguard Worker int h1;
133*635a8641SAndroid Build Coastguard Worker int x2; // rect 2
134*635a8641SAndroid Build Coastguard Worker int y2;
135*635a8641SAndroid Build Coastguard Worker int w2;
136*635a8641SAndroid Build Coastguard Worker int h2;
137*635a8641SAndroid Build Coastguard Worker int x3; // rect 3: the union of rects 1 and 2
138*635a8641SAndroid Build Coastguard Worker int y3;
139*635a8641SAndroid Build Coastguard Worker int w3;
140*635a8641SAndroid Build Coastguard Worker int h3;
141*635a8641SAndroid Build Coastguard Worker } tests[] = {
142*635a8641SAndroid Build Coastguard Worker { 0, 0, 0, 0,
143*635a8641SAndroid Build Coastguard Worker 0, 0, 0, 0,
144*635a8641SAndroid Build Coastguard Worker 0, 0, 0, 0 },
145*635a8641SAndroid Build Coastguard Worker { 0, 0, 4, 4,
146*635a8641SAndroid Build Coastguard Worker 0, 0, 4, 4,
147*635a8641SAndroid Build Coastguard Worker 0, 0, 4, 4 },
148*635a8641SAndroid Build Coastguard Worker { 0, 0, 4, 4,
149*635a8641SAndroid Build Coastguard Worker 4, 4, 4, 4,
150*635a8641SAndroid Build Coastguard Worker 0, 0, 8, 8 },
151*635a8641SAndroid Build Coastguard Worker { 0, 0, 4, 4,
152*635a8641SAndroid Build Coastguard Worker 0, 5, 4, 4,
153*635a8641SAndroid Build Coastguard Worker 0, 0, 4, 9 },
154*635a8641SAndroid Build Coastguard Worker { 0, 0, 2, 2,
155*635a8641SAndroid Build Coastguard Worker 3, 3, 2, 2,
156*635a8641SAndroid Build Coastguard Worker 0, 0, 5, 5 },
157*635a8641SAndroid Build Coastguard Worker { 3, 3, 2, 2, // reverse r1 and r2 from previous test
158*635a8641SAndroid Build Coastguard Worker 0, 0, 2, 2,
159*635a8641SAndroid Build Coastguard Worker 0, 0, 5, 5 },
160*635a8641SAndroid Build Coastguard Worker { 0, 0, 0, 0, // union with empty rect
161*635a8641SAndroid Build Coastguard Worker 2, 2, 2, 2,
162*635a8641SAndroid Build Coastguard Worker 2, 2, 2, 2 }
163*635a8641SAndroid Build Coastguard Worker };
164*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < arraysize(tests); ++i) {
165*635a8641SAndroid Build Coastguard Worker Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
166*635a8641SAndroid Build Coastguard Worker Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
167*635a8641SAndroid Build Coastguard Worker Rect r3(tests[i].x3, tests[i].y3, tests[i].w3, tests[i].h3);
168*635a8641SAndroid Build Coastguard Worker Rect u = UnionRects(r1, r2);
169*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(r3.x(), u.x());
170*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(r3.y(), u.y());
171*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(r3.width(), u.width());
172*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(r3.height(), u.height());
173*635a8641SAndroid Build Coastguard Worker }
174*635a8641SAndroid Build Coastguard Worker }
175*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,Equals)176*635a8641SAndroid Build Coastguard Worker TEST(RectTest, Equals) {
177*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(Rect(0, 0, 0, 0) == Rect(0, 0, 0, 0));
178*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(Rect(1, 2, 3, 4) == Rect(1, 2, 3, 4));
179*635a8641SAndroid Build Coastguard Worker ASSERT_FALSE(Rect(0, 0, 0, 0) == Rect(0, 0, 0, 1));
180*635a8641SAndroid Build Coastguard Worker ASSERT_FALSE(Rect(0, 0, 0, 0) == Rect(0, 0, 1, 0));
181*635a8641SAndroid Build Coastguard Worker ASSERT_FALSE(Rect(0, 0, 0, 0) == Rect(0, 1, 0, 0));
182*635a8641SAndroid Build Coastguard Worker ASSERT_FALSE(Rect(0, 0, 0, 0) == Rect(1, 0, 0, 0));
183*635a8641SAndroid Build Coastguard Worker }
184*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,AdjustToFit)185*635a8641SAndroid Build Coastguard Worker TEST(RectTest, AdjustToFit) {
186*635a8641SAndroid Build Coastguard Worker static const struct Test {
187*635a8641SAndroid Build Coastguard Worker int x1; // source
188*635a8641SAndroid Build Coastguard Worker int y1;
189*635a8641SAndroid Build Coastguard Worker int w1;
190*635a8641SAndroid Build Coastguard Worker int h1;
191*635a8641SAndroid Build Coastguard Worker int x2; // target
192*635a8641SAndroid Build Coastguard Worker int y2;
193*635a8641SAndroid Build Coastguard Worker int w2;
194*635a8641SAndroid Build Coastguard Worker int h2;
195*635a8641SAndroid Build Coastguard Worker int x3; // rect 3: results of invoking AdjustToFit
196*635a8641SAndroid Build Coastguard Worker int y3;
197*635a8641SAndroid Build Coastguard Worker int w3;
198*635a8641SAndroid Build Coastguard Worker int h3;
199*635a8641SAndroid Build Coastguard Worker } tests[] = {
200*635a8641SAndroid Build Coastguard Worker { 0, 0, 2, 2,
201*635a8641SAndroid Build Coastguard Worker 0, 0, 2, 2,
202*635a8641SAndroid Build Coastguard Worker 0, 0, 2, 2 },
203*635a8641SAndroid Build Coastguard Worker { 2, 2, 3, 3,
204*635a8641SAndroid Build Coastguard Worker 0, 0, 4, 4,
205*635a8641SAndroid Build Coastguard Worker 1, 1, 3, 3 },
206*635a8641SAndroid Build Coastguard Worker { -1, -1, 5, 5,
207*635a8641SAndroid Build Coastguard Worker 0, 0, 4, 4,
208*635a8641SAndroid Build Coastguard Worker 0, 0, 4, 4 },
209*635a8641SAndroid Build Coastguard Worker { 2, 2, 4, 4,
210*635a8641SAndroid Build Coastguard Worker 0, 0, 3, 3,
211*635a8641SAndroid Build Coastguard Worker 0, 0, 3, 3 },
212*635a8641SAndroid Build Coastguard Worker { 2, 2, 1, 1,
213*635a8641SAndroid Build Coastguard Worker 0, 0, 3, 3,
214*635a8641SAndroid Build Coastguard Worker 2, 2, 1, 1 }
215*635a8641SAndroid Build Coastguard Worker };
216*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < arraysize(tests); ++i) {
217*635a8641SAndroid Build Coastguard Worker Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
218*635a8641SAndroid Build Coastguard Worker Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
219*635a8641SAndroid Build Coastguard Worker Rect r3(tests[i].x3, tests[i].y3, tests[i].w3, tests[i].h3);
220*635a8641SAndroid Build Coastguard Worker Rect u = r1;
221*635a8641SAndroid Build Coastguard Worker u.AdjustToFit(r2);
222*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(r3.x(), u.x());
223*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(r3.y(), u.y());
224*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(r3.width(), u.width());
225*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(r3.height(), u.height());
226*635a8641SAndroid Build Coastguard Worker }
227*635a8641SAndroid Build Coastguard Worker }
228*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,Subtract)229*635a8641SAndroid Build Coastguard Worker TEST(RectTest, Subtract) {
230*635a8641SAndroid Build Coastguard Worker Rect result;
231*635a8641SAndroid Build Coastguard Worker
232*635a8641SAndroid Build Coastguard Worker // Matching
233*635a8641SAndroid Build Coastguard Worker result = Rect(10, 10, 20, 20);
234*635a8641SAndroid Build Coastguard Worker result.Subtract(Rect(10, 10, 20, 20));
235*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Rect(0, 0, 0, 0), result);
236*635a8641SAndroid Build Coastguard Worker
237*635a8641SAndroid Build Coastguard Worker // Contains
238*635a8641SAndroid Build Coastguard Worker result = Rect(10, 10, 20, 20);
239*635a8641SAndroid Build Coastguard Worker result.Subtract(Rect(5, 5, 30, 30));
240*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Rect(0, 0, 0, 0), result);
241*635a8641SAndroid Build Coastguard Worker
242*635a8641SAndroid Build Coastguard Worker // No intersection
243*635a8641SAndroid Build Coastguard Worker result = Rect(10, 10, 20, 20);
244*635a8641SAndroid Build Coastguard Worker result.Subtract(Rect(30, 30, 30, 30));
245*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Rect(10, 10, 20, 20), result);
246*635a8641SAndroid Build Coastguard Worker
247*635a8641SAndroid Build Coastguard Worker // Not a complete intersection in either direction
248*635a8641SAndroid Build Coastguard Worker result = Rect(10, 10, 20, 20);
249*635a8641SAndroid Build Coastguard Worker result.Subtract(Rect(15, 15, 20, 20));
250*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Rect(10, 10, 20, 20), result);
251*635a8641SAndroid Build Coastguard Worker
252*635a8641SAndroid Build Coastguard Worker // Complete intersection in the x-direction, top edge is fully covered.
253*635a8641SAndroid Build Coastguard Worker result = Rect(10, 10, 20, 20);
254*635a8641SAndroid Build Coastguard Worker result.Subtract(Rect(10, 15, 20, 20));
255*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Rect(10, 10, 20, 5), result);
256*635a8641SAndroid Build Coastguard Worker
257*635a8641SAndroid Build Coastguard Worker // Complete intersection in the x-direction, top edge is fully covered.
258*635a8641SAndroid Build Coastguard Worker result = Rect(10, 10, 20, 20);
259*635a8641SAndroid Build Coastguard Worker result.Subtract(Rect(5, 15, 30, 20));
260*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Rect(10, 10, 20, 5), result);
261*635a8641SAndroid Build Coastguard Worker
262*635a8641SAndroid Build Coastguard Worker // Complete intersection in the x-direction, bottom edge is fully covered.
263*635a8641SAndroid Build Coastguard Worker result = Rect(10, 10, 20, 20);
264*635a8641SAndroid Build Coastguard Worker result.Subtract(Rect(5, 5, 30, 20));
265*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Rect(10, 25, 20, 5), result);
266*635a8641SAndroid Build Coastguard Worker
267*635a8641SAndroid Build Coastguard Worker // Complete intersection in the x-direction, none of the edges is fully
268*635a8641SAndroid Build Coastguard Worker // covered.
269*635a8641SAndroid Build Coastguard Worker result = Rect(10, 10, 20, 20);
270*635a8641SAndroid Build Coastguard Worker result.Subtract(Rect(5, 15, 30, 1));
271*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Rect(10, 10, 20, 20), result);
272*635a8641SAndroid Build Coastguard Worker
273*635a8641SAndroid Build Coastguard Worker // Complete intersection in the y-direction, left edge is fully covered.
274*635a8641SAndroid Build Coastguard Worker result = Rect(10, 10, 20, 20);
275*635a8641SAndroid Build Coastguard Worker result.Subtract(Rect(10, 10, 10, 30));
276*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Rect(20, 10, 10, 20), result);
277*635a8641SAndroid Build Coastguard Worker
278*635a8641SAndroid Build Coastguard Worker // Complete intersection in the y-direction, left edge is fully covered.
279*635a8641SAndroid Build Coastguard Worker result = Rect(10, 10, 20, 20);
280*635a8641SAndroid Build Coastguard Worker result.Subtract(Rect(5, 5, 20, 30));
281*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Rect(25, 10, 5, 20), result);
282*635a8641SAndroid Build Coastguard Worker
283*635a8641SAndroid Build Coastguard Worker // Complete intersection in the y-direction, right edge is fully covered.
284*635a8641SAndroid Build Coastguard Worker result = Rect(10, 10, 20, 20);
285*635a8641SAndroid Build Coastguard Worker result.Subtract(Rect(20, 5, 20, 30));
286*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Rect(10, 10, 10, 20), result);
287*635a8641SAndroid Build Coastguard Worker
288*635a8641SAndroid Build Coastguard Worker // Complete intersection in the y-direction, none of the edges is fully
289*635a8641SAndroid Build Coastguard Worker // covered.
290*635a8641SAndroid Build Coastguard Worker result = Rect(10, 10, 20, 20);
291*635a8641SAndroid Build Coastguard Worker result.Subtract(Rect(15, 5, 1, 30));
292*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Rect(10, 10, 20, 20), result);
293*635a8641SAndroid Build Coastguard Worker }
294*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,IsEmpty)295*635a8641SAndroid Build Coastguard Worker TEST(RectTest, IsEmpty) {
296*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(Rect(0, 0, 0, 0).IsEmpty());
297*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(Rect(0, 0, 0, 0).size().IsEmpty());
298*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(Rect(0, 0, 10, 0).IsEmpty());
299*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(Rect(0, 0, 10, 0).size().IsEmpty());
300*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(Rect(0, 0, 0, 10).IsEmpty());
301*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(Rect(0, 0, 0, 10).size().IsEmpty());
302*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(Rect(0, 0, 10, 10).IsEmpty());
303*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(Rect(0, 0, 10, 10).size().IsEmpty());
304*635a8641SAndroid Build Coastguard Worker }
305*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,SplitVertically)306*635a8641SAndroid Build Coastguard Worker TEST(RectTest, SplitVertically) {
307*635a8641SAndroid Build Coastguard Worker Rect left_half, right_half;
308*635a8641SAndroid Build Coastguard Worker
309*635a8641SAndroid Build Coastguard Worker // Splitting when origin is (0, 0).
310*635a8641SAndroid Build Coastguard Worker Rect(0, 0, 20, 20).SplitVertically(&left_half, &right_half);
311*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(left_half == Rect(0, 0, 10, 20));
312*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(right_half == Rect(10, 0, 10, 20));
313*635a8641SAndroid Build Coastguard Worker
314*635a8641SAndroid Build Coastguard Worker // Splitting when origin is arbitrary.
315*635a8641SAndroid Build Coastguard Worker Rect(10, 10, 20, 10).SplitVertically(&left_half, &right_half);
316*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(left_half == Rect(10, 10, 10, 10));
317*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(right_half == Rect(20, 10, 10, 10));
318*635a8641SAndroid Build Coastguard Worker
319*635a8641SAndroid Build Coastguard Worker // Splitting a rectangle of zero width.
320*635a8641SAndroid Build Coastguard Worker Rect(10, 10, 0, 10).SplitVertically(&left_half, &right_half);
321*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(left_half == Rect(10, 10, 0, 10));
322*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(right_half == Rect(10, 10, 0, 10));
323*635a8641SAndroid Build Coastguard Worker
324*635a8641SAndroid Build Coastguard Worker // Splitting a rectangle of odd width.
325*635a8641SAndroid Build Coastguard Worker Rect(10, 10, 5, 10).SplitVertically(&left_half, &right_half);
326*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(left_half == Rect(10, 10, 2, 10));
327*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(right_half == Rect(12, 10, 3, 10));
328*635a8641SAndroid Build Coastguard Worker }
329*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,CenterPoint)330*635a8641SAndroid Build Coastguard Worker TEST(RectTest, CenterPoint) {
331*635a8641SAndroid Build Coastguard Worker Point center;
332*635a8641SAndroid Build Coastguard Worker
333*635a8641SAndroid Build Coastguard Worker // When origin is (0, 0).
334*635a8641SAndroid Build Coastguard Worker center = Rect(0, 0, 20, 20).CenterPoint();
335*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(center == Point(10, 10));
336*635a8641SAndroid Build Coastguard Worker
337*635a8641SAndroid Build Coastguard Worker // When origin is even.
338*635a8641SAndroid Build Coastguard Worker center = Rect(10, 10, 20, 20).CenterPoint();
339*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(center == Point(20, 20));
340*635a8641SAndroid Build Coastguard Worker
341*635a8641SAndroid Build Coastguard Worker // When origin is odd.
342*635a8641SAndroid Build Coastguard Worker center = Rect(11, 11, 20, 20).CenterPoint();
343*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(center == Point(21, 21));
344*635a8641SAndroid Build Coastguard Worker
345*635a8641SAndroid Build Coastguard Worker // When 0 width or height.
346*635a8641SAndroid Build Coastguard Worker center = Rect(10, 10, 0, 20).CenterPoint();
347*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(center == Point(10, 20));
348*635a8641SAndroid Build Coastguard Worker center = Rect(10, 10, 20, 0).CenterPoint();
349*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(center == Point(20, 10));
350*635a8641SAndroid Build Coastguard Worker
351*635a8641SAndroid Build Coastguard Worker // When an odd size.
352*635a8641SAndroid Build Coastguard Worker center = Rect(10, 10, 21, 21).CenterPoint();
353*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(center == Point(20, 20));
354*635a8641SAndroid Build Coastguard Worker
355*635a8641SAndroid Build Coastguard Worker // When an odd size and position.
356*635a8641SAndroid Build Coastguard Worker center = Rect(11, 11, 21, 21).CenterPoint();
357*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(center == Point(21, 21));
358*635a8641SAndroid Build Coastguard Worker }
359*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,CenterPointF)360*635a8641SAndroid Build Coastguard Worker TEST(RectTest, CenterPointF) {
361*635a8641SAndroid Build Coastguard Worker PointF center;
362*635a8641SAndroid Build Coastguard Worker
363*635a8641SAndroid Build Coastguard Worker // When origin is (0, 0).
364*635a8641SAndroid Build Coastguard Worker center = RectF(0, 0, 20, 20).CenterPoint();
365*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(center == PointF(10, 10));
366*635a8641SAndroid Build Coastguard Worker
367*635a8641SAndroid Build Coastguard Worker // When origin is even.
368*635a8641SAndroid Build Coastguard Worker center = RectF(10, 10, 20, 20).CenterPoint();
369*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(center == PointF(20, 20));
370*635a8641SAndroid Build Coastguard Worker
371*635a8641SAndroid Build Coastguard Worker // When origin is odd.
372*635a8641SAndroid Build Coastguard Worker center = RectF(11, 11, 20, 20).CenterPoint();
373*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(center == PointF(21, 21));
374*635a8641SAndroid Build Coastguard Worker
375*635a8641SAndroid Build Coastguard Worker // When 0 width or height.
376*635a8641SAndroid Build Coastguard Worker center = RectF(10, 10, 0, 20).CenterPoint();
377*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(center == PointF(10, 20));
378*635a8641SAndroid Build Coastguard Worker center = RectF(10, 10, 20, 0).CenterPoint();
379*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(center == PointF(20, 10));
380*635a8641SAndroid Build Coastguard Worker
381*635a8641SAndroid Build Coastguard Worker // When an odd size.
382*635a8641SAndroid Build Coastguard Worker center = RectF(10, 10, 21, 21).CenterPoint();
383*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(center == PointF(20.5f, 20.5f));
384*635a8641SAndroid Build Coastguard Worker
385*635a8641SAndroid Build Coastguard Worker // When an odd size and position.
386*635a8641SAndroid Build Coastguard Worker center = RectF(11, 11, 21, 21).CenterPoint();
387*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(center == PointF(21.5f, 21.5f));
388*635a8641SAndroid Build Coastguard Worker }
389*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,SharesEdgeWith)390*635a8641SAndroid Build Coastguard Worker TEST(RectTest, SharesEdgeWith) {
391*635a8641SAndroid Build Coastguard Worker Rect r(2, 3, 4, 5);
392*635a8641SAndroid Build Coastguard Worker
393*635a8641SAndroid Build Coastguard Worker // Must be non-overlapping
394*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(r.SharesEdgeWith(r));
395*635a8641SAndroid Build Coastguard Worker
396*635a8641SAndroid Build Coastguard Worker Rect just_above(2, 1, 4, 2);
397*635a8641SAndroid Build Coastguard Worker Rect just_below(2, 8, 4, 2);
398*635a8641SAndroid Build Coastguard Worker Rect just_left(0, 3, 2, 5);
399*635a8641SAndroid Build Coastguard Worker Rect just_right(6, 3, 2, 5);
400*635a8641SAndroid Build Coastguard Worker
401*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(r.SharesEdgeWith(just_above));
402*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(r.SharesEdgeWith(just_below));
403*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(r.SharesEdgeWith(just_left));
404*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(r.SharesEdgeWith(just_right));
405*635a8641SAndroid Build Coastguard Worker
406*635a8641SAndroid Build Coastguard Worker // Wrong placement
407*635a8641SAndroid Build Coastguard Worker Rect same_height_no_edge(0, 0, 1, 5);
408*635a8641SAndroid Build Coastguard Worker Rect same_width_no_edge(0, 0, 4, 1);
409*635a8641SAndroid Build Coastguard Worker
410*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(r.SharesEdgeWith(same_height_no_edge));
411*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(r.SharesEdgeWith(same_width_no_edge));
412*635a8641SAndroid Build Coastguard Worker
413*635a8641SAndroid Build Coastguard Worker Rect just_above_no_edge(2, 1, 5, 2); // too wide
414*635a8641SAndroid Build Coastguard Worker Rect just_below_no_edge(2, 8, 3, 2); // too narrow
415*635a8641SAndroid Build Coastguard Worker Rect just_left_no_edge(0, 3, 2, 6); // too tall
416*635a8641SAndroid Build Coastguard Worker Rect just_right_no_edge(6, 3, 2, 4); // too short
417*635a8641SAndroid Build Coastguard Worker
418*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(r.SharesEdgeWith(just_above_no_edge));
419*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(r.SharesEdgeWith(just_below_no_edge));
420*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(r.SharesEdgeWith(just_left_no_edge));
421*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(r.SharesEdgeWith(just_right_no_edge));
422*635a8641SAndroid Build Coastguard Worker }
423*635a8641SAndroid Build Coastguard Worker
424*635a8641SAndroid Build Coastguard Worker // Similar to EXPECT_FLOAT_EQ, but lets NaN equal NaN
425*635a8641SAndroid Build Coastguard Worker #define EXPECT_FLOAT_AND_NAN_EQ(a, b) \
426*635a8641SAndroid Build Coastguard Worker { if (a == a || b == b) { EXPECT_FLOAT_EQ(a, b); } }
427*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,ScaleRect)428*635a8641SAndroid Build Coastguard Worker TEST(RectTest, ScaleRect) {
429*635a8641SAndroid Build Coastguard Worker static const struct Test {
430*635a8641SAndroid Build Coastguard Worker int x1; // source
431*635a8641SAndroid Build Coastguard Worker int y1;
432*635a8641SAndroid Build Coastguard Worker int w1;
433*635a8641SAndroid Build Coastguard Worker int h1;
434*635a8641SAndroid Build Coastguard Worker float scale;
435*635a8641SAndroid Build Coastguard Worker float x2; // target
436*635a8641SAndroid Build Coastguard Worker float y2;
437*635a8641SAndroid Build Coastguard Worker float w2;
438*635a8641SAndroid Build Coastguard Worker float h2;
439*635a8641SAndroid Build Coastguard Worker } tests[] = {
440*635a8641SAndroid Build Coastguard Worker { 3, 3, 3, 3,
441*635a8641SAndroid Build Coastguard Worker 1.5f,
442*635a8641SAndroid Build Coastguard Worker 4.5f, 4.5f, 4.5f, 4.5f },
443*635a8641SAndroid Build Coastguard Worker { 3, 3, 3, 3,
444*635a8641SAndroid Build Coastguard Worker 0.0f,
445*635a8641SAndroid Build Coastguard Worker 0.0f, 0.0f, 0.0f, 0.0f },
446*635a8641SAndroid Build Coastguard Worker { 3, 3, 3, 3,
447*635a8641SAndroid Build Coastguard Worker std::numeric_limits<float>::quiet_NaN(),
448*635a8641SAndroid Build Coastguard Worker std::numeric_limits<float>::quiet_NaN(),
449*635a8641SAndroid Build Coastguard Worker std::numeric_limits<float>::quiet_NaN(),
450*635a8641SAndroid Build Coastguard Worker std::numeric_limits<float>::quiet_NaN(),
451*635a8641SAndroid Build Coastguard Worker std::numeric_limits<float>::quiet_NaN() },
452*635a8641SAndroid Build Coastguard Worker { 3, 3, 3, 3,
453*635a8641SAndroid Build Coastguard Worker std::numeric_limits<float>::max(),
454*635a8641SAndroid Build Coastguard Worker std::numeric_limits<float>::max(),
455*635a8641SAndroid Build Coastguard Worker std::numeric_limits<float>::max(),
456*635a8641SAndroid Build Coastguard Worker std::numeric_limits<float>::max(),
457*635a8641SAndroid Build Coastguard Worker std::numeric_limits<float>::max() }
458*635a8641SAndroid Build Coastguard Worker };
459*635a8641SAndroid Build Coastguard Worker
460*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < arraysize(tests); ++i) {
461*635a8641SAndroid Build Coastguard Worker RectF r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
462*635a8641SAndroid Build Coastguard Worker RectF r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
463*635a8641SAndroid Build Coastguard Worker
464*635a8641SAndroid Build Coastguard Worker RectF scaled = ScaleRect(r1, tests[i].scale);
465*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_AND_NAN_EQ(r2.x(), scaled.x());
466*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_AND_NAN_EQ(r2.y(), scaled.y());
467*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_AND_NAN_EQ(r2.width(), scaled.width());
468*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_AND_NAN_EQ(r2.height(), scaled.height());
469*635a8641SAndroid Build Coastguard Worker }
470*635a8641SAndroid Build Coastguard Worker }
471*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,ToEnclosedRect)472*635a8641SAndroid Build Coastguard Worker TEST(RectTest, ToEnclosedRect) {
473*635a8641SAndroid Build Coastguard Worker static const int max_int = std::numeric_limits<int>::max();
474*635a8641SAndroid Build Coastguard Worker static const int min_int = std::numeric_limits<int>::min();
475*635a8641SAndroid Build Coastguard Worker static const float max_float = std::numeric_limits<float>::max();
476*635a8641SAndroid Build Coastguard Worker static const float max_int_f = static_cast<float>(max_int);
477*635a8641SAndroid Build Coastguard Worker static const float min_int_f = static_cast<float>(min_int);
478*635a8641SAndroid Build Coastguard Worker
479*635a8641SAndroid Build Coastguard Worker static const struct Test {
480*635a8641SAndroid Build Coastguard Worker struct {
481*635a8641SAndroid Build Coastguard Worker float x;
482*635a8641SAndroid Build Coastguard Worker float y;
483*635a8641SAndroid Build Coastguard Worker float width;
484*635a8641SAndroid Build Coastguard Worker float height;
485*635a8641SAndroid Build Coastguard Worker } in;
486*635a8641SAndroid Build Coastguard Worker struct {
487*635a8641SAndroid Build Coastguard Worker int x;
488*635a8641SAndroid Build Coastguard Worker int y;
489*635a8641SAndroid Build Coastguard Worker int width;
490*635a8641SAndroid Build Coastguard Worker int height;
491*635a8641SAndroid Build Coastguard Worker } expected;
492*635a8641SAndroid Build Coastguard Worker } tests[] = {
493*635a8641SAndroid Build Coastguard Worker {{0.0f, 0.0f, 0.0f, 0.0f}, {0, 0, 0, 0}},
494*635a8641SAndroid Build Coastguard Worker {{-1.5f, -1.5f, 3.0f, 3.0f}, {-1, -1, 2, 2}},
495*635a8641SAndroid Build Coastguard Worker {{-1.5f, -1.5f, 3.5f, 3.5f}, {-1, -1, 3, 3}},
496*635a8641SAndroid Build Coastguard Worker {{max_float, max_float, 2.0f, 2.0f}, {max_int, max_int, 0, 0}},
497*635a8641SAndroid Build Coastguard Worker {{0.0f, 0.0f, max_float, max_float}, {0, 0, max_int, max_int}},
498*635a8641SAndroid Build Coastguard Worker {{20000.5f, 20000.5f, 0.5f, 0.5f}, {20001, 20001, 0, 0}},
499*635a8641SAndroid Build Coastguard Worker {{max_int_f, max_int_f, max_int_f, max_int_f}, {max_int, max_int, 0, 0}}};
500*635a8641SAndroid Build Coastguard Worker
501*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < arraysize(tests); ++i) {
502*635a8641SAndroid Build Coastguard Worker RectF source(tests[i].in.x, tests[i].in.y, tests[i].in.width,
503*635a8641SAndroid Build Coastguard Worker tests[i].in.height);
504*635a8641SAndroid Build Coastguard Worker Rect enclosed = ToEnclosedRect(source);
505*635a8641SAndroid Build Coastguard Worker
506*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(tests[i].expected.x, enclosed.x());
507*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(tests[i].expected.y, enclosed.y());
508*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(tests[i].expected.width, enclosed.width());
509*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(tests[i].expected.height, enclosed.height());
510*635a8641SAndroid Build Coastguard Worker }
511*635a8641SAndroid Build Coastguard Worker
512*635a8641SAndroid Build Coastguard Worker {
513*635a8641SAndroid Build Coastguard Worker RectF source(min_int_f, min_int_f, max_int_f * 3.f, max_int_f * 3.f);
514*635a8641SAndroid Build Coastguard Worker Rect enclosed = ToEnclosedRect(source);
515*635a8641SAndroid Build Coastguard Worker
516*635a8641SAndroid Build Coastguard Worker // That rect can't be represented, but it should be big.
517*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(max_int, enclosed.width());
518*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(max_int, enclosed.height());
519*635a8641SAndroid Build Coastguard Worker // It should include some axis near the global origin.
520*635a8641SAndroid Build Coastguard Worker EXPECT_GT(1, enclosed.x());
521*635a8641SAndroid Build Coastguard Worker EXPECT_GT(1, enclosed.y());
522*635a8641SAndroid Build Coastguard Worker // And it should not cause computation issues for itself.
523*635a8641SAndroid Build Coastguard Worker EXPECT_LT(0, enclosed.right());
524*635a8641SAndroid Build Coastguard Worker EXPECT_LT(0, enclosed.bottom());
525*635a8641SAndroid Build Coastguard Worker }
526*635a8641SAndroid Build Coastguard Worker }
527*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,ToEnclosingRect)528*635a8641SAndroid Build Coastguard Worker TEST(RectTest, ToEnclosingRect) {
529*635a8641SAndroid Build Coastguard Worker static const int max_int = std::numeric_limits<int>::max();
530*635a8641SAndroid Build Coastguard Worker static const int min_int = std::numeric_limits<int>::min();
531*635a8641SAndroid Build Coastguard Worker static const float max_float = std::numeric_limits<float>::max();
532*635a8641SAndroid Build Coastguard Worker static const float epsilon_float = std::numeric_limits<float>::epsilon();
533*635a8641SAndroid Build Coastguard Worker static const float max_int_f = static_cast<float>(max_int);
534*635a8641SAndroid Build Coastguard Worker static const float min_int_f = static_cast<float>(min_int);
535*635a8641SAndroid Build Coastguard Worker static const struct Test {
536*635a8641SAndroid Build Coastguard Worker struct {
537*635a8641SAndroid Build Coastguard Worker float x;
538*635a8641SAndroid Build Coastguard Worker float y;
539*635a8641SAndroid Build Coastguard Worker float width;
540*635a8641SAndroid Build Coastguard Worker float height;
541*635a8641SAndroid Build Coastguard Worker } in;
542*635a8641SAndroid Build Coastguard Worker struct {
543*635a8641SAndroid Build Coastguard Worker int x;
544*635a8641SAndroid Build Coastguard Worker int y;
545*635a8641SAndroid Build Coastguard Worker int width;
546*635a8641SAndroid Build Coastguard Worker int height;
547*635a8641SAndroid Build Coastguard Worker } expected;
548*635a8641SAndroid Build Coastguard Worker } tests[] = {
549*635a8641SAndroid Build Coastguard Worker {{0.0f, 0.0f, 0.0f, 0.0f}, {0, 0, 0, 0}},
550*635a8641SAndroid Build Coastguard Worker {{5.5f, 5.5f, 0.0f, 0.0f}, {5, 5, 0, 0}},
551*635a8641SAndroid Build Coastguard Worker {{3.5f, 2.5f, epsilon_float, -0.0f}, {3, 2, 0, 0}},
552*635a8641SAndroid Build Coastguard Worker {{3.5f, 2.5f, 0.f, 0.001f}, {3, 2, 0, 1}},
553*635a8641SAndroid Build Coastguard Worker {{-1.5f, -1.5f, 3.0f, 3.0f}, {-2, -2, 4, 4}},
554*635a8641SAndroid Build Coastguard Worker {{-1.5f, -1.5f, 3.5f, 3.5f}, {-2, -2, 4, 4}},
555*635a8641SAndroid Build Coastguard Worker {{max_float, max_float, 2.0f, 2.0f}, {max_int, max_int, 0, 0}},
556*635a8641SAndroid Build Coastguard Worker {{0.0f, 0.0f, max_float, max_float}, {0, 0, max_int, max_int}},
557*635a8641SAndroid Build Coastguard Worker {{20000.5f, 20000.5f, 0.5f, 0.5f}, {20000, 20000, 1, 1}},
558*635a8641SAndroid Build Coastguard Worker {{max_int_f, max_int_f, max_int_f, max_int_f}, {max_int, max_int, 0, 0}},
559*635a8641SAndroid Build Coastguard Worker {{-0.5f, -0.5f, 22777712.f, 1.f}, {-1, -1, 22777713, 2}}};
560*635a8641SAndroid Build Coastguard Worker
561*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < arraysize(tests); ++i) {
562*635a8641SAndroid Build Coastguard Worker RectF source(tests[i].in.x, tests[i].in.y, tests[i].in.width,
563*635a8641SAndroid Build Coastguard Worker tests[i].in.height);
564*635a8641SAndroid Build Coastguard Worker
565*635a8641SAndroid Build Coastguard Worker Rect enclosing = ToEnclosingRect(source);
566*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(tests[i].expected.x, enclosing.x());
567*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(tests[i].expected.y, enclosing.y());
568*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(tests[i].expected.width, enclosing.width());
569*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(tests[i].expected.height, enclosing.height());
570*635a8641SAndroid Build Coastguard Worker }
571*635a8641SAndroid Build Coastguard Worker
572*635a8641SAndroid Build Coastguard Worker {
573*635a8641SAndroid Build Coastguard Worker RectF source(min_int_f, min_int_f, max_int_f * 3.f, max_int_f * 3.f);
574*635a8641SAndroid Build Coastguard Worker Rect enclosing = ToEnclosingRect(source);
575*635a8641SAndroid Build Coastguard Worker
576*635a8641SAndroid Build Coastguard Worker // That rect can't be represented, but it should be big.
577*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(max_int, enclosing.width());
578*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(max_int, enclosing.height());
579*635a8641SAndroid Build Coastguard Worker // It should include some axis near the global origin.
580*635a8641SAndroid Build Coastguard Worker EXPECT_GT(1, enclosing.x());
581*635a8641SAndroid Build Coastguard Worker EXPECT_GT(1, enclosing.y());
582*635a8641SAndroid Build Coastguard Worker // And it should cause computation issues for itself.
583*635a8641SAndroid Build Coastguard Worker EXPECT_LT(0, enclosing.right());
584*635a8641SAndroid Build Coastguard Worker EXPECT_LT(0, enclosing.bottom());
585*635a8641SAndroid Build Coastguard Worker }
586*635a8641SAndroid Build Coastguard Worker }
587*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,ToNearestRect)588*635a8641SAndroid Build Coastguard Worker TEST(RectTest, ToNearestRect) {
589*635a8641SAndroid Build Coastguard Worker Rect rect;
590*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(rect, ToNearestRect(RectF(rect)));
591*635a8641SAndroid Build Coastguard Worker
592*635a8641SAndroid Build Coastguard Worker rect = Rect(-1, -1, 3, 3);
593*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(rect, ToNearestRect(RectF(rect)));
594*635a8641SAndroid Build Coastguard Worker
595*635a8641SAndroid Build Coastguard Worker RectF rectf(-1.00001f, -0.999999f, 3.0000001f, 2.999999f);
596*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(rect, ToNearestRect(rectf));
597*635a8641SAndroid Build Coastguard Worker }
598*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,ToFlooredRect)599*635a8641SAndroid Build Coastguard Worker TEST(RectTest, ToFlooredRect) {
600*635a8641SAndroid Build Coastguard Worker static const struct Test {
601*635a8641SAndroid Build Coastguard Worker float x1; // source
602*635a8641SAndroid Build Coastguard Worker float y1;
603*635a8641SAndroid Build Coastguard Worker float w1;
604*635a8641SAndroid Build Coastguard Worker float h1;
605*635a8641SAndroid Build Coastguard Worker int x2; // target
606*635a8641SAndroid Build Coastguard Worker int y2;
607*635a8641SAndroid Build Coastguard Worker int w2;
608*635a8641SAndroid Build Coastguard Worker int h2;
609*635a8641SAndroid Build Coastguard Worker } tests [] = {
610*635a8641SAndroid Build Coastguard Worker { 0.0f, 0.0f, 0.0f, 0.0f,
611*635a8641SAndroid Build Coastguard Worker 0, 0, 0, 0 },
612*635a8641SAndroid Build Coastguard Worker { -1.5f, -1.5f, 3.0f, 3.0f,
613*635a8641SAndroid Build Coastguard Worker -2, -2, 3, 3 },
614*635a8641SAndroid Build Coastguard Worker { -1.5f, -1.5f, 3.5f, 3.5f,
615*635a8641SAndroid Build Coastguard Worker -2, -2, 3, 3 },
616*635a8641SAndroid Build Coastguard Worker { 20000.5f, 20000.5f, 0.5f, 0.5f,
617*635a8641SAndroid Build Coastguard Worker 20000, 20000, 0, 0 },
618*635a8641SAndroid Build Coastguard Worker };
619*635a8641SAndroid Build Coastguard Worker
620*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < arraysize(tests); ++i) {
621*635a8641SAndroid Build Coastguard Worker RectF r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
622*635a8641SAndroid Build Coastguard Worker Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
623*635a8641SAndroid Build Coastguard Worker
624*635a8641SAndroid Build Coastguard Worker Rect floored = ToFlooredRectDeprecated(r1);
625*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(r2.x(), floored.x());
626*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(r2.y(), floored.y());
627*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(r2.width(), floored.width());
628*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(r2.height(), floored.height());
629*635a8641SAndroid Build Coastguard Worker }
630*635a8641SAndroid Build Coastguard Worker }
631*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,ScaleToEnclosedRect)632*635a8641SAndroid Build Coastguard Worker TEST(RectTest, ScaleToEnclosedRect) {
633*635a8641SAndroid Build Coastguard Worker static const struct Test {
634*635a8641SAndroid Build Coastguard Worker Rect input_rect;
635*635a8641SAndroid Build Coastguard Worker float input_scale;
636*635a8641SAndroid Build Coastguard Worker Rect expected_rect;
637*635a8641SAndroid Build Coastguard Worker } tests[] = {
638*635a8641SAndroid Build Coastguard Worker {
639*635a8641SAndroid Build Coastguard Worker Rect(),
640*635a8641SAndroid Build Coastguard Worker 5.f,
641*635a8641SAndroid Build Coastguard Worker Rect(),
642*635a8641SAndroid Build Coastguard Worker }, {
643*635a8641SAndroid Build Coastguard Worker Rect(1, 1, 1, 1),
644*635a8641SAndroid Build Coastguard Worker 5.f,
645*635a8641SAndroid Build Coastguard Worker Rect(5, 5, 5, 5),
646*635a8641SAndroid Build Coastguard Worker }, {
647*635a8641SAndroid Build Coastguard Worker Rect(-1, -1, 0, 0),
648*635a8641SAndroid Build Coastguard Worker 5.f,
649*635a8641SAndroid Build Coastguard Worker Rect(-5, -5, 0, 0),
650*635a8641SAndroid Build Coastguard Worker }, {
651*635a8641SAndroid Build Coastguard Worker Rect(1, -1, 0, 1),
652*635a8641SAndroid Build Coastguard Worker 5.f,
653*635a8641SAndroid Build Coastguard Worker Rect(5, -5, 0, 5),
654*635a8641SAndroid Build Coastguard Worker }, {
655*635a8641SAndroid Build Coastguard Worker Rect(-1, 1, 1, 0),
656*635a8641SAndroid Build Coastguard Worker 5.f,
657*635a8641SAndroid Build Coastguard Worker Rect(-5, 5, 5, 0),
658*635a8641SAndroid Build Coastguard Worker }, {
659*635a8641SAndroid Build Coastguard Worker Rect(1, 2, 3, 4),
660*635a8641SAndroid Build Coastguard Worker 1.5f,
661*635a8641SAndroid Build Coastguard Worker Rect(2, 3, 4, 6),
662*635a8641SAndroid Build Coastguard Worker }, {
663*635a8641SAndroid Build Coastguard Worker Rect(-1, -2, 0, 0),
664*635a8641SAndroid Build Coastguard Worker 1.5f,
665*635a8641SAndroid Build Coastguard Worker Rect(-1, -3, 0, 0),
666*635a8641SAndroid Build Coastguard Worker }
667*635a8641SAndroid Build Coastguard Worker };
668*635a8641SAndroid Build Coastguard Worker
669*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < arraysize(tests); ++i) {
670*635a8641SAndroid Build Coastguard Worker Rect result = ScaleToEnclosedRect(tests[i].input_rect,
671*635a8641SAndroid Build Coastguard Worker tests[i].input_scale);
672*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(tests[i].expected_rect, result);
673*635a8641SAndroid Build Coastguard Worker }
674*635a8641SAndroid Build Coastguard Worker }
675*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,ScaleToEnclosingRect)676*635a8641SAndroid Build Coastguard Worker TEST(RectTest, ScaleToEnclosingRect) {
677*635a8641SAndroid Build Coastguard Worker static const struct Test {
678*635a8641SAndroid Build Coastguard Worker Rect input_rect;
679*635a8641SAndroid Build Coastguard Worker float input_scale;
680*635a8641SAndroid Build Coastguard Worker Rect expected_rect;
681*635a8641SAndroid Build Coastguard Worker } tests[] = {
682*635a8641SAndroid Build Coastguard Worker {
683*635a8641SAndroid Build Coastguard Worker Rect(),
684*635a8641SAndroid Build Coastguard Worker 5.f,
685*635a8641SAndroid Build Coastguard Worker Rect(),
686*635a8641SAndroid Build Coastguard Worker }, {
687*635a8641SAndroid Build Coastguard Worker Rect(1, 1, 1, 1),
688*635a8641SAndroid Build Coastguard Worker 5.f,
689*635a8641SAndroid Build Coastguard Worker Rect(5, 5, 5, 5),
690*635a8641SAndroid Build Coastguard Worker }, {
691*635a8641SAndroid Build Coastguard Worker Rect(-1, -1, 0, 0),
692*635a8641SAndroid Build Coastguard Worker 5.f,
693*635a8641SAndroid Build Coastguard Worker Rect(-5, -5, 0, 0),
694*635a8641SAndroid Build Coastguard Worker }, {
695*635a8641SAndroid Build Coastguard Worker Rect(1, -1, 0, 1),
696*635a8641SAndroid Build Coastguard Worker 5.f,
697*635a8641SAndroid Build Coastguard Worker Rect(5, -5, 0, 5),
698*635a8641SAndroid Build Coastguard Worker }, {
699*635a8641SAndroid Build Coastguard Worker Rect(-1, 1, 1, 0),
700*635a8641SAndroid Build Coastguard Worker 5.f,
701*635a8641SAndroid Build Coastguard Worker Rect(-5, 5, 5, 0),
702*635a8641SAndroid Build Coastguard Worker }, {
703*635a8641SAndroid Build Coastguard Worker Rect(1, 2, 3, 4),
704*635a8641SAndroid Build Coastguard Worker 1.5f,
705*635a8641SAndroid Build Coastguard Worker Rect(1, 3, 5, 6),
706*635a8641SAndroid Build Coastguard Worker }, {
707*635a8641SAndroid Build Coastguard Worker Rect(-1, -2, 0, 0),
708*635a8641SAndroid Build Coastguard Worker 1.5f,
709*635a8641SAndroid Build Coastguard Worker Rect(-2, -3, 0, 0),
710*635a8641SAndroid Build Coastguard Worker }
711*635a8641SAndroid Build Coastguard Worker };
712*635a8641SAndroid Build Coastguard Worker
713*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < arraysize(tests); ++i) {
714*635a8641SAndroid Build Coastguard Worker Rect result =
715*635a8641SAndroid Build Coastguard Worker ScaleToEnclosingRect(tests[i].input_rect, tests[i].input_scale);
716*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(tests[i].expected_rect, result);
717*635a8641SAndroid Build Coastguard Worker Rect result_safe =
718*635a8641SAndroid Build Coastguard Worker ScaleToEnclosingRectSafe(tests[i].input_rect, tests[i].input_scale);
719*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(tests[i].expected_rect, result_safe);
720*635a8641SAndroid Build Coastguard Worker }
721*635a8641SAndroid Build Coastguard Worker }
722*635a8641SAndroid Build Coastguard Worker
723*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
TEST(RectTest,ConstructAndAssign)724*635a8641SAndroid Build Coastguard Worker TEST(RectTest, ConstructAndAssign) {
725*635a8641SAndroid Build Coastguard Worker const RECT rect_1 = { 0, 0, 10, 10 };
726*635a8641SAndroid Build Coastguard Worker const RECT rect_2 = { 0, 0, -10, -10 };
727*635a8641SAndroid Build Coastguard Worker Rect test1(rect_1);
728*635a8641SAndroid Build Coastguard Worker Rect test2(rect_2);
729*635a8641SAndroid Build Coastguard Worker }
730*635a8641SAndroid Build Coastguard Worker #endif
731*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,ToRectF)732*635a8641SAndroid Build Coastguard Worker TEST(RectTest, ToRectF) {
733*635a8641SAndroid Build Coastguard Worker // Check that explicit conversion from integer to float compiles.
734*635a8641SAndroid Build Coastguard Worker Rect a(10, 20, 30, 40);
735*635a8641SAndroid Build Coastguard Worker RectF b(10, 20, 30, 40);
736*635a8641SAndroid Build Coastguard Worker
737*635a8641SAndroid Build Coastguard Worker RectF c = RectF(a);
738*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(b, c);
739*635a8641SAndroid Build Coastguard Worker }
740*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,BoundingRect)741*635a8641SAndroid Build Coastguard Worker TEST(RectTest, BoundingRect) {
742*635a8641SAndroid Build Coastguard Worker struct {
743*635a8641SAndroid Build Coastguard Worker Point a;
744*635a8641SAndroid Build Coastguard Worker Point b;
745*635a8641SAndroid Build Coastguard Worker Rect expected;
746*635a8641SAndroid Build Coastguard Worker } int_tests[] = {
747*635a8641SAndroid Build Coastguard Worker // If point B dominates A, then A should be the origin.
748*635a8641SAndroid Build Coastguard Worker { Point(4, 6), Point(4, 6), Rect(4, 6, 0, 0) },
749*635a8641SAndroid Build Coastguard Worker { Point(4, 6), Point(8, 6), Rect(4, 6, 4, 0) },
750*635a8641SAndroid Build Coastguard Worker { Point(4, 6), Point(4, 9), Rect(4, 6, 0, 3) },
751*635a8641SAndroid Build Coastguard Worker { Point(4, 6), Point(8, 9), Rect(4, 6, 4, 3) },
752*635a8641SAndroid Build Coastguard Worker // If point A dominates B, then B should be the origin.
753*635a8641SAndroid Build Coastguard Worker { Point(4, 6), Point(4, 6), Rect(4, 6, 0, 0) },
754*635a8641SAndroid Build Coastguard Worker { Point(8, 6), Point(4, 6), Rect(4, 6, 4, 0) },
755*635a8641SAndroid Build Coastguard Worker { Point(4, 9), Point(4, 6), Rect(4, 6, 0, 3) },
756*635a8641SAndroid Build Coastguard Worker { Point(8, 9), Point(4, 6), Rect(4, 6, 4, 3) },
757*635a8641SAndroid Build Coastguard Worker // If neither point dominates, then the origin is a combination of the two.
758*635a8641SAndroid Build Coastguard Worker { Point(4, 6), Point(6, 4), Rect(4, 4, 2, 2) },
759*635a8641SAndroid Build Coastguard Worker { Point(-4, -6), Point(-6, -4), Rect(-6, -6, 2, 2) },
760*635a8641SAndroid Build Coastguard Worker { Point(-4, 6), Point(6, -4), Rect(-4, -4, 10, 10) },
761*635a8641SAndroid Build Coastguard Worker };
762*635a8641SAndroid Build Coastguard Worker
763*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < arraysize(int_tests); ++i) {
764*635a8641SAndroid Build Coastguard Worker Rect actual = BoundingRect(int_tests[i].a, int_tests[i].b);
765*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(int_tests[i].expected, actual);
766*635a8641SAndroid Build Coastguard Worker }
767*635a8641SAndroid Build Coastguard Worker
768*635a8641SAndroid Build Coastguard Worker struct {
769*635a8641SAndroid Build Coastguard Worker PointF a;
770*635a8641SAndroid Build Coastguard Worker PointF b;
771*635a8641SAndroid Build Coastguard Worker RectF expected;
772*635a8641SAndroid Build Coastguard Worker } float_tests[] = {
773*635a8641SAndroid Build Coastguard Worker // If point B dominates A, then A should be the origin.
774*635a8641SAndroid Build Coastguard Worker { PointF(4.2f, 6.8f), PointF(4.2f, 6.8f),
775*635a8641SAndroid Build Coastguard Worker RectF(4.2f, 6.8f, 0, 0) },
776*635a8641SAndroid Build Coastguard Worker { PointF(4.2f, 6.8f), PointF(8.5f, 6.8f),
777*635a8641SAndroid Build Coastguard Worker RectF(4.2f, 6.8f, 4.3f, 0) },
778*635a8641SAndroid Build Coastguard Worker { PointF(4.2f, 6.8f), PointF(4.2f, 9.3f),
779*635a8641SAndroid Build Coastguard Worker RectF(4.2f, 6.8f, 0, 2.5f) },
780*635a8641SAndroid Build Coastguard Worker { PointF(4.2f, 6.8f), PointF(8.5f, 9.3f),
781*635a8641SAndroid Build Coastguard Worker RectF(4.2f, 6.8f, 4.3f, 2.5f) },
782*635a8641SAndroid Build Coastguard Worker // If point A dominates B, then B should be the origin.
783*635a8641SAndroid Build Coastguard Worker { PointF(4.2f, 6.8f), PointF(4.2f, 6.8f),
784*635a8641SAndroid Build Coastguard Worker RectF(4.2f, 6.8f, 0, 0) },
785*635a8641SAndroid Build Coastguard Worker { PointF(8.5f, 6.8f), PointF(4.2f, 6.8f),
786*635a8641SAndroid Build Coastguard Worker RectF(4.2f, 6.8f, 4.3f, 0) },
787*635a8641SAndroid Build Coastguard Worker { PointF(4.2f, 9.3f), PointF(4.2f, 6.8f),
788*635a8641SAndroid Build Coastguard Worker RectF(4.2f, 6.8f, 0, 2.5f) },
789*635a8641SAndroid Build Coastguard Worker { PointF(8.5f, 9.3f), PointF(4.2f, 6.8f),
790*635a8641SAndroid Build Coastguard Worker RectF(4.2f, 6.8f, 4.3f, 2.5f) },
791*635a8641SAndroid Build Coastguard Worker // If neither point dominates, then the origin is a combination of the two.
792*635a8641SAndroid Build Coastguard Worker { PointF(4.2f, 6.8f), PointF(6.8f, 4.2f),
793*635a8641SAndroid Build Coastguard Worker RectF(4.2f, 4.2f, 2.6f, 2.6f) },
794*635a8641SAndroid Build Coastguard Worker { PointF(-4.2f, -6.8f), PointF(-6.8f, -4.2f),
795*635a8641SAndroid Build Coastguard Worker RectF(-6.8f, -6.8f, 2.6f, 2.6f) },
796*635a8641SAndroid Build Coastguard Worker { PointF(-4.2f, 6.8f), PointF(6.8f, -4.2f),
797*635a8641SAndroid Build Coastguard Worker RectF(-4.2f, -4.2f, 11.0f, 11.0f) }
798*635a8641SAndroid Build Coastguard Worker };
799*635a8641SAndroid Build Coastguard Worker
800*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < arraysize(float_tests); ++i) {
801*635a8641SAndroid Build Coastguard Worker RectF actual = BoundingRect(float_tests[i].a, float_tests[i].b);
802*635a8641SAndroid Build Coastguard Worker EXPECT_RECTF_EQ(float_tests[i].expected, actual);
803*635a8641SAndroid Build Coastguard Worker }
804*635a8641SAndroid Build Coastguard Worker }
805*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,IsExpressibleAsRect)806*635a8641SAndroid Build Coastguard Worker TEST(RectTest, IsExpressibleAsRect) {
807*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(RectF().IsExpressibleAsRect());
808*635a8641SAndroid Build Coastguard Worker
809*635a8641SAndroid Build Coastguard Worker float min = std::numeric_limits<int>::min();
810*635a8641SAndroid Build Coastguard Worker float max = std::numeric_limits<int>::max();
811*635a8641SAndroid Build Coastguard Worker float infinity = std::numeric_limits<float>::infinity();
812*635a8641SAndroid Build Coastguard Worker
813*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(RectF(
814*635a8641SAndroid Build Coastguard Worker min + 200, min + 200, max - 200, max - 200).IsExpressibleAsRect());
815*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(RectF(
816*635a8641SAndroid Build Coastguard Worker min - 200, min + 200, max + 200, max + 200).IsExpressibleAsRect());
817*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(RectF(
818*635a8641SAndroid Build Coastguard Worker min + 200 , min - 200, max + 200, max + 200).IsExpressibleAsRect());
819*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(RectF(
820*635a8641SAndroid Build Coastguard Worker min + 200, min + 200, max + 200, max - 200).IsExpressibleAsRect());
821*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(RectF(
822*635a8641SAndroid Build Coastguard Worker min + 200, min + 200, max - 200, max + 200).IsExpressibleAsRect());
823*635a8641SAndroid Build Coastguard Worker
824*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(RectF(0, 0, max - 200, max - 200).IsExpressibleAsRect());
825*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(RectF(200, 0, max + 200, max - 200).IsExpressibleAsRect());
826*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(RectF(0, 200, max - 200, max + 200).IsExpressibleAsRect());
827*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(RectF(0, 0, max + 200, max - 200).IsExpressibleAsRect());
828*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(RectF(0, 0, max - 200, max + 200).IsExpressibleAsRect());
829*635a8641SAndroid Build Coastguard Worker
830*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(RectF(infinity, 0, 1, 1).IsExpressibleAsRect());
831*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(RectF(0, infinity, 1, 1).IsExpressibleAsRect());
832*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(RectF(0, 0, infinity, 1).IsExpressibleAsRect());
833*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(RectF(0, 0, 1, infinity).IsExpressibleAsRect());
834*635a8641SAndroid Build Coastguard Worker }
835*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,Offset)836*635a8641SAndroid Build Coastguard Worker TEST(RectTest, Offset) {
837*635a8641SAndroid Build Coastguard Worker Rect i(1, 2, 3, 4);
838*635a8641SAndroid Build Coastguard Worker
839*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Rect(2, 1, 3, 4), (i + Vector2d(1, -1)));
840*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Rect(2, 1, 3, 4), (Vector2d(1, -1) + i));
841*635a8641SAndroid Build Coastguard Worker i += Vector2d(1, -1);
842*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Rect(2, 1, 3, 4), i);
843*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Rect(1, 2, 3, 4), (i - Vector2d(1, -1)));
844*635a8641SAndroid Build Coastguard Worker i -= Vector2d(1, -1);
845*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Rect(1, 2, 3, 4), i);
846*635a8641SAndroid Build Coastguard Worker
847*635a8641SAndroid Build Coastguard Worker RectF f(1.1f, 2.2f, 3.3f, 4.4f);
848*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(RectF(2.2f, 1.1f, 3.3f, 4.4f), (f + Vector2dF(1.1f, -1.1f)));
849*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(RectF(2.2f, 1.1f, 3.3f, 4.4f), (Vector2dF(1.1f, -1.1f) + f));
850*635a8641SAndroid Build Coastguard Worker f += Vector2dF(1.1f, -1.1f);
851*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(RectF(2.2f, 1.1f, 3.3f, 4.4f), f);
852*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(RectF(1.1f, 2.2f, 3.3f, 4.4f), (f - Vector2dF(1.1f, -1.1f)));
853*635a8641SAndroid Build Coastguard Worker f -= Vector2dF(1.1f, -1.1f);
854*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(RectF(1.1f, 2.2f, 3.3f, 4.4f), f);
855*635a8641SAndroid Build Coastguard Worker }
856*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,Corners)857*635a8641SAndroid Build Coastguard Worker TEST(RectTest, Corners) {
858*635a8641SAndroid Build Coastguard Worker Rect i(1, 2, 3, 4);
859*635a8641SAndroid Build Coastguard Worker RectF f(1.1f, 2.1f, 3.1f, 4.1f);
860*635a8641SAndroid Build Coastguard Worker
861*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Point(1, 2), i.origin());
862*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Point(4, 2), i.top_right());
863*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Point(1, 6), i.bottom_left());
864*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Point(4, 6), i.bottom_right());
865*635a8641SAndroid Build Coastguard Worker
866*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(PointF(1.1f, 2.1f), f.origin());
867*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(PointF(4.2f, 2.1f), f.top_right());
868*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(PointF(1.1f, 6.2f), f.bottom_left());
869*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(PointF(4.2f, 6.2f), f.bottom_right());
870*635a8641SAndroid Build Coastguard Worker }
871*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,ManhattanDistanceToPoint)872*635a8641SAndroid Build Coastguard Worker TEST(RectTest, ManhattanDistanceToPoint) {
873*635a8641SAndroid Build Coastguard Worker Rect i(1, 2, 3, 4);
874*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, i.ManhattanDistanceToPoint(Point(1, 2)));
875*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, i.ManhattanDistanceToPoint(Point(4, 6)));
876*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, i.ManhattanDistanceToPoint(Point(2, 4)));
877*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(3, i.ManhattanDistanceToPoint(Point(0, 0)));
878*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(2, i.ManhattanDistanceToPoint(Point(2, 0)));
879*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(3, i.ManhattanDistanceToPoint(Point(5, 0)));
880*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1, i.ManhattanDistanceToPoint(Point(5, 4)));
881*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(3, i.ManhattanDistanceToPoint(Point(5, 8)));
882*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(2, i.ManhattanDistanceToPoint(Point(3, 8)));
883*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(2, i.ManhattanDistanceToPoint(Point(0, 7)));
884*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1, i.ManhattanDistanceToPoint(Point(0, 3)));
885*635a8641SAndroid Build Coastguard Worker
886*635a8641SAndroid Build Coastguard Worker RectF f(1.1f, 2.1f, 3.1f, 4.1f);
887*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(0.f, f.ManhattanDistanceToPoint(PointF(1.1f, 2.1f)));
888*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(0.f, f.ManhattanDistanceToPoint(PointF(4.2f, 6.f)));
889*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(0.f, f.ManhattanDistanceToPoint(PointF(2.f, 4.f)));
890*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(3.2f, f.ManhattanDistanceToPoint(PointF(0.f, 0.f)));
891*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(2.1f, f.ManhattanDistanceToPoint(PointF(2.f, 0.f)));
892*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(2.9f, f.ManhattanDistanceToPoint(PointF(5.f, 0.f)));
893*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(.8f, f.ManhattanDistanceToPoint(PointF(5.f, 4.f)));
894*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(2.6f, f.ManhattanDistanceToPoint(PointF(5.f, 8.f)));
895*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(1.8f, f.ManhattanDistanceToPoint(PointF(3.f, 8.f)));
896*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(1.9f, f.ManhattanDistanceToPoint(PointF(0.f, 7.f)));
897*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(1.1f, f.ManhattanDistanceToPoint(PointF(0.f, 3.f)));
898*635a8641SAndroid Build Coastguard Worker }
899*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,ManhattanInternalDistance)900*635a8641SAndroid Build Coastguard Worker TEST(RectTest, ManhattanInternalDistance) {
901*635a8641SAndroid Build Coastguard Worker Rect i(0, 0, 400, 400);
902*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, i.ManhattanInternalDistance(gfx::Rect(-1, 0, 2, 1)));
903*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1, i.ManhattanInternalDistance(gfx::Rect(400, 0, 1, 400)));
904*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(2, i.ManhattanInternalDistance(gfx::Rect(-100, -100, 100, 100)));
905*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(2, i.ManhattanInternalDistance(gfx::Rect(-101, 100, 100, 100)));
906*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(4, i.ManhattanInternalDistance(gfx::Rect(-101, -101, 100, 100)));
907*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(435, i.ManhattanInternalDistance(gfx::Rect(630, 603, 100, 100)));
908*635a8641SAndroid Build Coastguard Worker
909*635a8641SAndroid Build Coastguard Worker RectF f(0.0f, 0.0f, 400.0f, 400.0f);
910*635a8641SAndroid Build Coastguard Worker static const float kEpsilon = std::numeric_limits<float>::epsilon();
911*635a8641SAndroid Build Coastguard Worker
912*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(
913*635a8641SAndroid Build Coastguard Worker 0.0f, f.ManhattanInternalDistance(gfx::RectF(-1.0f, 0.0f, 2.0f, 1.0f)));
914*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(
915*635a8641SAndroid Build Coastguard Worker kEpsilon,
916*635a8641SAndroid Build Coastguard Worker f.ManhattanInternalDistance(gfx::RectF(400.0f, 0.0f, 1.0f, 400.0f)));
917*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(2.0f * kEpsilon,
918*635a8641SAndroid Build Coastguard Worker f.ManhattanInternalDistance(
919*635a8641SAndroid Build Coastguard Worker gfx::RectF(-100.0f, -100.0f, 100.0f, 100.0f)));
920*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(
921*635a8641SAndroid Build Coastguard Worker 1.0f + kEpsilon,
922*635a8641SAndroid Build Coastguard Worker f.ManhattanInternalDistance(gfx::RectF(-101.0f, 100.0f, 100.0f, 100.0f)));
923*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(2.0f + 2.0f * kEpsilon,
924*635a8641SAndroid Build Coastguard Worker f.ManhattanInternalDistance(
925*635a8641SAndroid Build Coastguard Worker gfx::RectF(-101.0f, -101.0f, 100.0f, 100.0f)));
926*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(
927*635a8641SAndroid Build Coastguard Worker 433.0f + 2.0f * kEpsilon,
928*635a8641SAndroid Build Coastguard Worker f.ManhattanInternalDistance(gfx::RectF(630.0f, 603.0f, 100.0f, 100.0f)));
929*635a8641SAndroid Build Coastguard Worker
930*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(
931*635a8641SAndroid Build Coastguard Worker 0.0f, f.ManhattanInternalDistance(gfx::RectF(-1.0f, 0.0f, 1.1f, 1.0f)));
932*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(
933*635a8641SAndroid Build Coastguard Worker 0.1f + kEpsilon,
934*635a8641SAndroid Build Coastguard Worker f.ManhattanInternalDistance(gfx::RectF(-1.5f, 0.0f, 1.4f, 1.0f)));
935*635a8641SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(
936*635a8641SAndroid Build Coastguard Worker kEpsilon,
937*635a8641SAndroid Build Coastguard Worker f.ManhattanInternalDistance(gfx::RectF(-1.5f, 0.0f, 1.5f, 1.0f)));
938*635a8641SAndroid Build Coastguard Worker }
939*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,IntegerOverflow)940*635a8641SAndroid Build Coastguard Worker TEST(RectTest, IntegerOverflow) {
941*635a8641SAndroid Build Coastguard Worker int limit = std::numeric_limits<int>::max();
942*635a8641SAndroid Build Coastguard Worker int min_limit = std::numeric_limits<int>::min();
943*635a8641SAndroid Build Coastguard Worker int expected = 10;
944*635a8641SAndroid Build Coastguard Worker int large_number = limit - expected;
945*635a8641SAndroid Build Coastguard Worker
946*635a8641SAndroid Build Coastguard Worker Rect height_overflow(0, large_number, 100, 100);
947*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(large_number, height_overflow.y());
948*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected, height_overflow.height());
949*635a8641SAndroid Build Coastguard Worker
950*635a8641SAndroid Build Coastguard Worker Rect width_overflow(large_number, 0, 100, 100);
951*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(large_number, width_overflow.x());
952*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected, width_overflow.width());
953*635a8641SAndroid Build Coastguard Worker
954*635a8641SAndroid Build Coastguard Worker Rect size_height_overflow(Point(0, large_number), Size(100, 100));
955*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(large_number, size_height_overflow.y());
956*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected, size_height_overflow.height());
957*635a8641SAndroid Build Coastguard Worker
958*635a8641SAndroid Build Coastguard Worker Rect size_width_overflow(Point(large_number, 0), Size(100, 100));
959*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(large_number, size_width_overflow.x());
960*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected, size_width_overflow.width());
961*635a8641SAndroid Build Coastguard Worker
962*635a8641SAndroid Build Coastguard Worker Rect set_height_overflow(0, large_number, 100, 5);
963*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(5, set_height_overflow.height());
964*635a8641SAndroid Build Coastguard Worker set_height_overflow.set_height(100);
965*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected, set_height_overflow.height());
966*635a8641SAndroid Build Coastguard Worker
967*635a8641SAndroid Build Coastguard Worker Rect set_y_overflow(100, 100, 100, 100);
968*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(100, set_y_overflow.height());
969*635a8641SAndroid Build Coastguard Worker set_y_overflow.set_y(large_number);
970*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected, set_y_overflow.height());
971*635a8641SAndroid Build Coastguard Worker
972*635a8641SAndroid Build Coastguard Worker Rect set_width_overflow(large_number, 0, 5, 100);
973*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(5, set_width_overflow.width());
974*635a8641SAndroid Build Coastguard Worker set_width_overflow.set_width(100);
975*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected, set_width_overflow.width());
976*635a8641SAndroid Build Coastguard Worker
977*635a8641SAndroid Build Coastguard Worker Rect set_x_overflow(100, 100, 100, 100);
978*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(100, set_x_overflow.width());
979*635a8641SAndroid Build Coastguard Worker set_x_overflow.set_x(large_number);
980*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected, set_x_overflow.width());
981*635a8641SAndroid Build Coastguard Worker
982*635a8641SAndroid Build Coastguard Worker Point large_offset(large_number, large_number);
983*635a8641SAndroid Build Coastguard Worker Size size(100, 100);
984*635a8641SAndroid Build Coastguard Worker Size expected_size(10, 10);
985*635a8641SAndroid Build Coastguard Worker
986*635a8641SAndroid Build Coastguard Worker Rect set_origin_overflow(100, 100, 100, 100);
987*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(size, set_origin_overflow.size());
988*635a8641SAndroid Build Coastguard Worker set_origin_overflow.set_origin(large_offset);
989*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(large_offset, set_origin_overflow.origin());
990*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected_size, set_origin_overflow.size());
991*635a8641SAndroid Build Coastguard Worker
992*635a8641SAndroid Build Coastguard Worker Rect set_size_overflow(large_number, large_number, 5, 5);
993*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(Size(5, 5), set_size_overflow.size());
994*635a8641SAndroid Build Coastguard Worker set_size_overflow.set_size(size);
995*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(large_offset, set_size_overflow.origin());
996*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected_size, set_size_overflow.size());
997*635a8641SAndroid Build Coastguard Worker
998*635a8641SAndroid Build Coastguard Worker Rect set_rect_overflow;
999*635a8641SAndroid Build Coastguard Worker set_rect_overflow.SetRect(large_number, large_number, 100, 100);
1000*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(large_offset, set_rect_overflow.origin());
1001*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected_size, set_rect_overflow.size());
1002*635a8641SAndroid Build Coastguard Worker
1003*635a8641SAndroid Build Coastguard Worker // Insetting an empty rect, but the total inset (left + right) could overflow.
1004*635a8641SAndroid Build Coastguard Worker Rect inset_overflow;
1005*635a8641SAndroid Build Coastguard Worker inset_overflow.Inset(large_number, large_number, 100, 100);
1006*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(large_offset, inset_overflow.origin());
1007*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(gfx::Size(), inset_overflow.size());
1008*635a8641SAndroid Build Coastguard Worker
1009*635a8641SAndroid Build Coastguard Worker // Insetting where the total inset (width - left - right) could overflow.
1010*635a8641SAndroid Build Coastguard Worker // Also, this insetting by the min limit in all directions cannot
1011*635a8641SAndroid Build Coastguard Worker // represent width() without overflow, so that will also clamp.
1012*635a8641SAndroid Build Coastguard Worker Rect inset_overflow2;
1013*635a8641SAndroid Build Coastguard Worker inset_overflow2.Inset(min_limit, min_limit, min_limit, min_limit);
1014*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(inset_overflow2, gfx::Rect(min_limit, min_limit, limit, limit));
1015*635a8641SAndroid Build Coastguard Worker
1016*635a8641SAndroid Build Coastguard Worker // Insetting where the width shouldn't change, but if the insets operations
1017*635a8641SAndroid Build Coastguard Worker // clamped in the wrong order, e.g. ((width - left) - right) vs (width - (left
1018*635a8641SAndroid Build Coastguard Worker // + right)) then this will not work properly. This is the proper order,
1019*635a8641SAndroid Build Coastguard Worker // as if left + right overflows, the width cannot be decreased by more than
1020*635a8641SAndroid Build Coastguard Worker // max int anyway. Additionally, if left + right underflows, it cannot be
1021*635a8641SAndroid Build Coastguard Worker // increased by more then max int.
1022*635a8641SAndroid Build Coastguard Worker Rect inset_overflow3(0, 0, limit, limit);
1023*635a8641SAndroid Build Coastguard Worker inset_overflow3.Inset(-100, -100, 100, 100);
1024*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(inset_overflow3, gfx::Rect(-100, -100, limit, limit));
1025*635a8641SAndroid Build Coastguard Worker
1026*635a8641SAndroid Build Coastguard Worker Rect inset_overflow4(-1000, -1000, limit, limit);
1027*635a8641SAndroid Build Coastguard Worker inset_overflow4.Inset(100, 100, -100, -100);
1028*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(inset_overflow4, gfx::Rect(-900, -900, limit, limit));
1029*635a8641SAndroid Build Coastguard Worker
1030*635a8641SAndroid Build Coastguard Worker Rect offset_overflow(0, 0, 100, 100);
1031*635a8641SAndroid Build Coastguard Worker offset_overflow.Offset(large_number, large_number);
1032*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(large_offset, offset_overflow.origin());
1033*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected_size, offset_overflow.size());
1034*635a8641SAndroid Build Coastguard Worker
1035*635a8641SAndroid Build Coastguard Worker Rect operator_overflow(0, 0, 100, 100);
1036*635a8641SAndroid Build Coastguard Worker operator_overflow += Vector2d(large_number, large_number);
1037*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(large_offset, operator_overflow.origin());
1038*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected_size, operator_overflow.size());
1039*635a8641SAndroid Build Coastguard Worker
1040*635a8641SAndroid Build Coastguard Worker Rect origin_maxint(limit, limit, limit, limit);
1041*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(origin_maxint, Rect(gfx::Point(limit, limit), gfx::Size()));
1042*635a8641SAndroid Build Coastguard Worker
1043*635a8641SAndroid Build Coastguard Worker // Expect a rect at the origin and a rect whose right/bottom is maxint
1044*635a8641SAndroid Build Coastguard Worker // create a rect that extends from 0..maxint in both extents.
1045*635a8641SAndroid Build Coastguard Worker {
1046*635a8641SAndroid Build Coastguard Worker Rect origin_small(0, 0, 100, 100);
1047*635a8641SAndroid Build Coastguard Worker Rect big_clamped(50, 50, limit, limit);
1048*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(big_clamped.right(), limit);
1049*635a8641SAndroid Build Coastguard Worker
1050*635a8641SAndroid Build Coastguard Worker Rect unioned = UnionRects(origin_small, big_clamped);
1051*635a8641SAndroid Build Coastguard Worker Rect rect_limit(0, 0, limit, limit);
1052*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(unioned, rect_limit);
1053*635a8641SAndroid Build Coastguard Worker }
1054*635a8641SAndroid Build Coastguard Worker
1055*635a8641SAndroid Build Coastguard Worker // Expect a rect that would overflow width (but not right) to be clamped
1056*635a8641SAndroid Build Coastguard Worker // and to have maxint extents after unioning.
1057*635a8641SAndroid Build Coastguard Worker {
1058*635a8641SAndroid Build Coastguard Worker Rect small(-500, -400, 100, 100);
1059*635a8641SAndroid Build Coastguard Worker Rect big(-400, -500, limit, limit);
1060*635a8641SAndroid Build Coastguard Worker // Technically, this should be limit + 100 width, but will clamp to maxint.
1061*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(UnionRects(small, big), Rect(-500, -500, limit, limit));
1062*635a8641SAndroid Build Coastguard Worker }
1063*635a8641SAndroid Build Coastguard Worker
1064*635a8641SAndroid Build Coastguard Worker // Expect a rect that would overflow right *and* width to be clamped.
1065*635a8641SAndroid Build Coastguard Worker {
1066*635a8641SAndroid Build Coastguard Worker Rect clamped(500, 500, limit, limit);
1067*635a8641SAndroid Build Coastguard Worker Rect positive_origin(100, 100, 500, 500);
1068*635a8641SAndroid Build Coastguard Worker
1069*635a8641SAndroid Build Coastguard Worker // Ideally, this should be (100, 100, limit + 400, limit + 400).
1070*635a8641SAndroid Build Coastguard Worker // However, width overflows and would be clamped to limit, but right
1071*635a8641SAndroid Build Coastguard Worker // overflows too and so will be clamped to limit - 100.
1072*635a8641SAndroid Build Coastguard Worker Rect expected(100, 100, limit - 100, limit - 100);
1073*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(UnionRects(clamped, positive_origin), expected);
1074*635a8641SAndroid Build Coastguard Worker }
1075*635a8641SAndroid Build Coastguard Worker
1076*635a8641SAndroid Build Coastguard Worker // Unioning a left=minint rect with a right=maxint rect.
1077*635a8641SAndroid Build Coastguard Worker // We can't represent both ends of the spectrum in the same rect.
1078*635a8641SAndroid Build Coastguard Worker // Make sure we keep the most useful area.
1079*635a8641SAndroid Build Coastguard Worker {
1080*635a8641SAndroid Build Coastguard Worker int part_limit = min_limit / 3;
1081*635a8641SAndroid Build Coastguard Worker Rect left_minint(min_limit, min_limit, 1, 1);
1082*635a8641SAndroid Build Coastguard Worker Rect right_maxint(limit - 1, limit - 1, limit, limit);
1083*635a8641SAndroid Build Coastguard Worker Rect expected(part_limit, part_limit, 2 * part_limit, 2 * part_limit);
1084*635a8641SAndroid Build Coastguard Worker Rect result = UnionRects(left_minint, right_maxint);
1085*635a8641SAndroid Build Coastguard Worker
1086*635a8641SAndroid Build Coastguard Worker // The result should be maximally big.
1087*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(limit, result.height());
1088*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(limit, result.width());
1089*635a8641SAndroid Build Coastguard Worker
1090*635a8641SAndroid Build Coastguard Worker // The result should include the area near the origin.
1091*635a8641SAndroid Build Coastguard Worker EXPECT_GT(-part_limit, result.x());
1092*635a8641SAndroid Build Coastguard Worker EXPECT_LT(part_limit, result.right());
1093*635a8641SAndroid Build Coastguard Worker EXPECT_GT(-part_limit, result.y());
1094*635a8641SAndroid Build Coastguard Worker EXPECT_LT(part_limit, result.bottom());
1095*635a8641SAndroid Build Coastguard Worker
1096*635a8641SAndroid Build Coastguard Worker // More succinctly, but harder to read in the results.
1097*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(UnionRects(left_minint, right_maxint).Contains(expected));
1098*635a8641SAndroid Build Coastguard Worker }
1099*635a8641SAndroid Build Coastguard Worker }
1100*635a8641SAndroid Build Coastguard Worker
TEST(RectTest,ScaleToEnclosingRectSafe)1101*635a8641SAndroid Build Coastguard Worker TEST(RectTest, ScaleToEnclosingRectSafe) {
1102*635a8641SAndroid Build Coastguard Worker const int max_int = std::numeric_limits<int>::max();
1103*635a8641SAndroid Build Coastguard Worker const int min_int = std::numeric_limits<int>::min();
1104*635a8641SAndroid Build Coastguard Worker
1105*635a8641SAndroid Build Coastguard Worker Rect xy_underflow(-100000, -123456, 10, 20);
1106*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(ScaleToEnclosingRectSafe(xy_underflow, 100000, 100000),
1107*635a8641SAndroid Build Coastguard Worker Rect(min_int, min_int, 1000000, 2000000));
1108*635a8641SAndroid Build Coastguard Worker
1109*635a8641SAndroid Build Coastguard Worker // A location overflow means that width/right and bottom/top also
1110*635a8641SAndroid Build Coastguard Worker // overflow so need to be clamped.
1111*635a8641SAndroid Build Coastguard Worker Rect xy_overflow(100000, 123456, 10, 20);
1112*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(ScaleToEnclosingRectSafe(xy_overflow, 100000, 100000),
1113*635a8641SAndroid Build Coastguard Worker Rect(max_int, max_int, 0, 0));
1114*635a8641SAndroid Build Coastguard Worker
1115*635a8641SAndroid Build Coastguard Worker // In practice all rects are clamped to 0 width / 0 height so
1116*635a8641SAndroid Build Coastguard Worker // negative sizes don't matter, but try this for the sake of testing.
1117*635a8641SAndroid Build Coastguard Worker Rect size_underflow(-1, -2, 100000, 100000);
1118*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(ScaleToEnclosingRectSafe(size_underflow, -100000, -100000),
1119*635a8641SAndroid Build Coastguard Worker Rect(100000, 200000, 0, 0));
1120*635a8641SAndroid Build Coastguard Worker
1121*635a8641SAndroid Build Coastguard Worker Rect size_overflow(-1, -2, 123456, 234567);
1122*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(ScaleToEnclosingRectSafe(size_overflow, 100000, 100000),
1123*635a8641SAndroid Build Coastguard Worker Rect(-100000, -200000, max_int, max_int));
1124*635a8641SAndroid Build Coastguard Worker // Verify width/right gets clamped properly too if x/y positive.
1125*635a8641SAndroid Build Coastguard Worker Rect size_overflow2(1, 2, 123456, 234567);
1126*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(ScaleToEnclosingRectSafe(size_overflow2, 100000, 100000),
1127*635a8641SAndroid Build Coastguard Worker Rect(100000, 200000, max_int - 100000, max_int - 200000));
1128*635a8641SAndroid Build Coastguard Worker
1129*635a8641SAndroid Build Coastguard Worker Rect max_rect(max_int, max_int, max_int, max_int);
1130*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(ScaleToEnclosingRectSafe(max_rect, max_int, max_int),
1131*635a8641SAndroid Build Coastguard Worker Rect(max_int, max_int, 0, 0));
1132*635a8641SAndroid Build Coastguard Worker
1133*635a8641SAndroid Build Coastguard Worker Rect min_rect(min_int, min_int, max_int, max_int);
1134*635a8641SAndroid Build Coastguard Worker // Min rect can't be scaled up any further in any dimension.
1135*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(ScaleToEnclosingRectSafe(min_rect, 2, 3.5), min_rect);
1136*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(ScaleToEnclosingRectSafe(min_rect, max_int, max_int), min_rect);
1137*635a8641SAndroid Build Coastguard Worker // Min rect scaled by min is an empty rect at (max, max)
1138*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(ScaleToEnclosingRectSafe(min_rect, min_int, min_int), max_rect);
1139*635a8641SAndroid Build Coastguard Worker }
1140*635a8641SAndroid Build Coastguard Worker
1141*635a8641SAndroid Build Coastguard Worker } // namespace gfx
1142