83597ec30fb1e3f9360c2f4c7374433c99db5849
[platform/framework/web/crosswalk.git] / src / ui / gfx / geometry / rect_unittest.cc
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <limits>
6
7 #include "base/basictypes.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "ui/gfx/geometry/rect.h"
10 #include "ui/gfx/geometry/rect_conversions.h"
11 #include "ui/gfx/test/gfx_util.h"
12
13 #if defined(OS_WIN)
14 #include <windows.h>
15 #endif
16
17 namespace gfx {
18
19 TEST(RectTest, Contains) {
20   static const struct ContainsCase {
21     int rect_x;
22     int rect_y;
23     int rect_width;
24     int rect_height;
25     int point_x;
26     int point_y;
27     bool contained;
28   } contains_cases[] = {
29     {0, 0, 10, 10, 0, 0, true},
30     {0, 0, 10, 10, 5, 5, true},
31     {0, 0, 10, 10, 9, 9, true},
32     {0, 0, 10, 10, 5, 10, false},
33     {0, 0, 10, 10, 10, 5, false},
34     {0, 0, 10, 10, -1, -1, false},
35     {0, 0, 10, 10, 50, 50, false},
36   #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
37     {0, 0, -10, -10, 0, 0, false},
38   #endif
39   };
40   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(contains_cases); ++i) {
41     const ContainsCase& value = contains_cases[i];
42     Rect rect(value.rect_x, value.rect_y, value.rect_width, value.rect_height);
43     EXPECT_EQ(value.contained, rect.Contains(value.point_x, value.point_y));
44   }
45 }
46
47 TEST(RectTest, Intersects) {
48   static const struct {
49     int x1;  // rect 1
50     int y1;
51     int w1;
52     int h1;
53     int x2;  // rect 2
54     int y2;
55     int w2;
56     int h2;
57     bool intersects;
58   } tests[] = {
59     { 0, 0, 0, 0, 0, 0, 0, 0, false },
60     { 0, 0, 0, 0, -10, -10, 20, 20, false },
61     { -10, 0, 0, 20, 0, -10, 20, 0, false },
62     { 0, 0, 10, 10, 0, 0, 10, 10, true },
63     { 0, 0, 10, 10, 10, 10, 10, 10, false },
64     { 10, 10, 10, 10, 0, 0, 10, 10, false },
65     { 10, 10, 10, 10, 5, 5, 10, 10, true },
66     { 10, 10, 10, 10, 15, 15, 10, 10, true },
67     { 10, 10, 10, 10, 20, 15, 10, 10, false },
68     { 10, 10, 10, 10, 21, 15, 10, 10, false }
69   };
70   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
71     Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
72     Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
73     EXPECT_EQ(tests[i].intersects, r1.Intersects(r2));
74     EXPECT_EQ(tests[i].intersects, r2.Intersects(r1));
75   }
76 }
77
78 TEST(RectTest, Intersect) {
79   static const struct {
80     int x1;  // rect 1
81     int y1;
82     int w1;
83     int h1;
84     int x2;  // rect 2
85     int y2;
86     int w2;
87     int h2;
88     int x3;  // rect 3: the union of rects 1 and 2
89     int y3;
90     int w3;
91     int h3;
92   } tests[] = {
93     { 0, 0, 0, 0,   // zeros
94       0, 0, 0, 0,
95       0, 0, 0, 0 },
96     { 0, 0, 4, 4,   // equal
97       0, 0, 4, 4,
98       0, 0, 4, 4 },
99     { 0, 0, 4, 4,   // neighboring
100       4, 4, 4, 4,
101       0, 0, 0, 0 },
102     { 0, 0, 4, 4,   // overlapping corners
103       2, 2, 4, 4,
104       2, 2, 2, 2 },
105     { 0, 0, 4, 4,   // T junction
106       3, 1, 4, 2,
107       3, 1, 1, 2 },
108     { 3, 0, 2, 2,   // gap
109       0, 0, 2, 2,
110       0, 0, 0, 0 }
111   };
112   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
113     Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
114     Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
115     Rect r3(tests[i].x3, tests[i].y3, tests[i].w3, tests[i].h3);
116     Rect ir = IntersectRects(r1, r2);
117     EXPECT_EQ(r3.x(), ir.x());
118     EXPECT_EQ(r3.y(), ir.y());
119     EXPECT_EQ(r3.width(), ir.width());
120     EXPECT_EQ(r3.height(), ir.height());
121   }
122 }
123
124 TEST(RectTest, Union) {
125   static const struct Test {
126     int x1;  // rect 1
127     int y1;
128     int w1;
129     int h1;
130     int x2;  // rect 2
131     int y2;
132     int w2;
133     int h2;
134     int x3;  // rect 3: the union of rects 1 and 2
135     int y3;
136     int w3;
137     int h3;
138   } tests[] = {
139     { 0, 0, 0, 0,
140       0, 0, 0, 0,
141       0, 0, 0, 0 },
142     { 0, 0, 4, 4,
143       0, 0, 4, 4,
144       0, 0, 4, 4 },
145     { 0, 0, 4, 4,
146       4, 4, 4, 4,
147       0, 0, 8, 8 },
148     { 0, 0, 4, 4,
149       0, 5, 4, 4,
150       0, 0, 4, 9 },
151     { 0, 0, 2, 2,
152       3, 3, 2, 2,
153       0, 0, 5, 5 },
154     { 3, 3, 2, 2,   // reverse r1 and r2 from previous test
155       0, 0, 2, 2,
156       0, 0, 5, 5 },
157     { 0, 0, 0, 0,   // union with empty rect
158       2, 2, 2, 2,
159       2, 2, 2, 2 }
160   };
161   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
162     Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
163     Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
164     Rect r3(tests[i].x3, tests[i].y3, tests[i].w3, tests[i].h3);
165     Rect u = UnionRects(r1, r2);
166     EXPECT_EQ(r3.x(), u.x());
167     EXPECT_EQ(r3.y(), u.y());
168     EXPECT_EQ(r3.width(), u.width());
169     EXPECT_EQ(r3.height(), u.height());
170   }
171 }
172
173 TEST(RectTest, Equals) {
174   ASSERT_TRUE(Rect(0, 0, 0, 0) == Rect(0, 0, 0, 0));
175   ASSERT_TRUE(Rect(1, 2, 3, 4) == Rect(1, 2, 3, 4));
176   ASSERT_FALSE(Rect(0, 0, 0, 0) == Rect(0, 0, 0, 1));
177   ASSERT_FALSE(Rect(0, 0, 0, 0) == Rect(0, 0, 1, 0));
178   ASSERT_FALSE(Rect(0, 0, 0, 0) == Rect(0, 1, 0, 0));
179   ASSERT_FALSE(Rect(0, 0, 0, 0) == Rect(1, 0, 0, 0));
180 }
181
182 TEST(RectTest, AdjustToFit) {
183   static const struct Test {
184     int x1;  // source
185     int y1;
186     int w1;
187     int h1;
188     int x2;  // target
189     int y2;
190     int w2;
191     int h2;
192     int x3;  // rect 3: results of invoking AdjustToFit
193     int y3;
194     int w3;
195     int h3;
196   } tests[] = {
197     { 0, 0, 2, 2,
198       0, 0, 2, 2,
199       0, 0, 2, 2 },
200     { 2, 2, 3, 3,
201       0, 0, 4, 4,
202       1, 1, 3, 3 },
203     { -1, -1, 5, 5,
204       0, 0, 4, 4,
205       0, 0, 4, 4 },
206     { 2, 2, 4, 4,
207       0, 0, 3, 3,
208       0, 0, 3, 3 },
209     { 2, 2, 1, 1,
210       0, 0, 3, 3,
211       2, 2, 1, 1 }
212   };
213   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
214     Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
215     Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
216     Rect r3(tests[i].x3, tests[i].y3, tests[i].w3, tests[i].h3);
217     Rect u = r1;
218     u.AdjustToFit(r2);
219     EXPECT_EQ(r3.x(), u.x());
220     EXPECT_EQ(r3.y(), u.y());
221     EXPECT_EQ(r3.width(), u.width());
222     EXPECT_EQ(r3.height(), u.height());
223   }
224 }
225
226 TEST(RectTest, Subtract) {
227   Rect result;
228
229   // Matching
230   result = Rect(10, 10, 20, 20);
231   result.Subtract(Rect(10, 10, 20, 20));
232   EXPECT_EQ(Rect(0, 0, 0, 0), result);
233
234   // Contains
235   result = Rect(10, 10, 20, 20);
236   result.Subtract(Rect(5, 5, 30, 30));
237   EXPECT_EQ(Rect(0, 0, 0, 0), result);
238
239   // No intersection
240   result = Rect(10, 10, 20, 20);
241   result.Subtract(Rect(30, 30, 30, 30));
242   EXPECT_EQ(Rect(10, 10, 20, 20), result);
243
244   // Not a complete intersection in either direction
245   result = Rect(10, 10, 20, 20);
246   result.Subtract(Rect(15, 15, 20, 20));
247   EXPECT_EQ(Rect(10, 10, 20, 20), result);
248
249   // Complete intersection in the x-direction, top edge is fully covered.
250   result = Rect(10, 10, 20, 20);
251   result.Subtract(Rect(10, 15, 20, 20));
252   EXPECT_EQ(Rect(10, 10, 20, 5), result);
253
254   // Complete intersection in the x-direction, top edge is fully covered.
255   result = Rect(10, 10, 20, 20);
256   result.Subtract(Rect(5, 15, 30, 20));
257   EXPECT_EQ(Rect(10, 10, 20, 5), result);
258
259   // Complete intersection in the x-direction, bottom edge is fully covered.
260   result = Rect(10, 10, 20, 20);
261   result.Subtract(Rect(5, 5, 30, 20));
262   EXPECT_EQ(Rect(10, 25, 20, 5), result);
263
264   // Complete intersection in the x-direction, none of the edges is fully
265   // covered.
266   result = Rect(10, 10, 20, 20);
267   result.Subtract(Rect(5, 15, 30, 1));
268   EXPECT_EQ(Rect(10, 10, 20, 20), result);
269
270   // Complete intersection in the y-direction, left edge is fully covered.
271   result = Rect(10, 10, 20, 20);
272   result.Subtract(Rect(10, 10, 10, 30));
273   EXPECT_EQ(Rect(20, 10, 10, 20), result);
274
275   // Complete intersection in the y-direction, left edge is fully covered.
276   result = Rect(10, 10, 20, 20);
277   result.Subtract(Rect(5, 5, 20, 30));
278   EXPECT_EQ(Rect(25, 10, 5, 20), result);
279
280   // Complete intersection in the y-direction, right edge is fully covered.
281   result = Rect(10, 10, 20, 20);
282   result.Subtract(Rect(20, 5, 20, 30));
283   EXPECT_EQ(Rect(10, 10, 10, 20), result);
284
285   // Complete intersection in the y-direction, none of the edges is fully
286   // covered.
287   result = Rect(10, 10, 20, 20);
288   result.Subtract(Rect(15, 5, 1, 30));
289   EXPECT_EQ(Rect(10, 10, 20, 20), result);
290 }
291
292 TEST(RectTest, IsEmpty) {
293   EXPECT_TRUE(Rect(0, 0, 0, 0).IsEmpty());
294   EXPECT_TRUE(Rect(0, 0, 0, 0).size().IsEmpty());
295   EXPECT_TRUE(Rect(0, 0, 10, 0).IsEmpty());
296   EXPECT_TRUE(Rect(0, 0, 10, 0).size().IsEmpty());
297   EXPECT_TRUE(Rect(0, 0, 0, 10).IsEmpty());
298   EXPECT_TRUE(Rect(0, 0, 0, 10).size().IsEmpty());
299   EXPECT_FALSE(Rect(0, 0, 10, 10).IsEmpty());
300   EXPECT_FALSE(Rect(0, 0, 10, 10).size().IsEmpty());
301 }
302
303 TEST(RectTest, SplitVertically) {
304   Rect left_half, right_half;
305
306   // Splitting when origin is (0, 0).
307   Rect(0, 0, 20, 20).SplitVertically(&left_half, &right_half);
308   EXPECT_TRUE(left_half == Rect(0, 0, 10, 20));
309   EXPECT_TRUE(right_half == Rect(10, 0, 10, 20));
310
311   // Splitting when origin is arbitrary.
312   Rect(10, 10, 20, 10).SplitVertically(&left_half, &right_half);
313   EXPECT_TRUE(left_half == Rect(10, 10, 10, 10));
314   EXPECT_TRUE(right_half == Rect(20, 10, 10, 10));
315
316   // Splitting a rectangle of zero width.
317   Rect(10, 10, 0, 10).SplitVertically(&left_half, &right_half);
318   EXPECT_TRUE(left_half == Rect(10, 10, 0, 10));
319   EXPECT_TRUE(right_half == Rect(10, 10, 0, 10));
320
321   // Splitting a rectangle of odd width.
322   Rect(10, 10, 5, 10).SplitVertically(&left_half, &right_half);
323   EXPECT_TRUE(left_half == Rect(10, 10, 2, 10));
324   EXPECT_TRUE(right_half == Rect(12, 10, 3, 10));
325 }
326
327 TEST(RectTest, CenterPoint) {
328   Point center;
329
330   // When origin is (0, 0).
331   center = Rect(0, 0, 20, 20).CenterPoint();
332   EXPECT_TRUE(center == Point(10, 10));
333
334   // When origin is even.
335   center = Rect(10, 10, 20, 20).CenterPoint();
336   EXPECT_TRUE(center == Point(20, 20));
337
338   // When origin is odd.
339   center = Rect(11, 11, 20, 20).CenterPoint();
340   EXPECT_TRUE(center == Point(21, 21));
341
342   // When 0 width or height.
343   center = Rect(10, 10, 0, 20).CenterPoint();
344   EXPECT_TRUE(center == Point(10, 20));
345   center = Rect(10, 10, 20, 0).CenterPoint();
346   EXPECT_TRUE(center == Point(20, 10));
347
348   // When an odd size.
349   center = Rect(10, 10, 21, 21).CenterPoint();
350   EXPECT_TRUE(center == Point(20, 20));
351
352   // When an odd size and position.
353   center = Rect(11, 11, 21, 21).CenterPoint();
354   EXPECT_TRUE(center == Point(21, 21));
355 }
356
357 TEST(RectTest, CenterPointF) {
358   PointF center;
359
360   // When origin is (0, 0).
361   center = RectF(0, 0, 20, 20).CenterPoint();
362   EXPECT_TRUE(center == PointF(10, 10));
363
364   // When origin is even.
365   center = RectF(10, 10, 20, 20).CenterPoint();
366   EXPECT_TRUE(center == PointF(20, 20));
367
368   // When origin is odd.
369   center = RectF(11, 11, 20, 20).CenterPoint();
370   EXPECT_TRUE(center == PointF(21, 21));
371
372   // When 0 width or height.
373   center = RectF(10, 10, 0, 20).CenterPoint();
374   EXPECT_TRUE(center == PointF(10, 20));
375   center = RectF(10, 10, 20, 0).CenterPoint();
376   EXPECT_TRUE(center == PointF(20, 10));
377
378   // When an odd size.
379   center = RectF(10, 10, 21, 21).CenterPoint();
380   EXPECT_TRUE(center == PointF(20.5f, 20.5f));
381
382   // When an odd size and position.
383   center = RectF(11, 11, 21, 21).CenterPoint();
384   EXPECT_TRUE(center == PointF(21.5f, 21.5f));
385 }
386
387 TEST(RectTest, SharesEdgeWith) {
388   Rect r(2, 3, 4, 5);
389
390   // Must be non-overlapping
391   EXPECT_FALSE(r.SharesEdgeWith(r));
392
393   Rect just_above(2, 1, 4, 2);
394   Rect just_below(2, 8, 4, 2);
395   Rect just_left(0, 3, 2, 5);
396   Rect just_right(6, 3, 2, 5);
397
398   EXPECT_TRUE(r.SharesEdgeWith(just_above));
399   EXPECT_TRUE(r.SharesEdgeWith(just_below));
400   EXPECT_TRUE(r.SharesEdgeWith(just_left));
401   EXPECT_TRUE(r.SharesEdgeWith(just_right));
402
403   // Wrong placement
404   Rect same_height_no_edge(0, 0, 1, 5);
405   Rect same_width_no_edge(0, 0, 4, 1);
406
407   EXPECT_FALSE(r.SharesEdgeWith(same_height_no_edge));
408   EXPECT_FALSE(r.SharesEdgeWith(same_width_no_edge));
409
410   Rect just_above_no_edge(2, 1, 5, 2);  // too wide
411   Rect just_below_no_edge(2, 8, 3, 2);  // too narrow
412   Rect just_left_no_edge(0, 3, 2, 6);   // too tall
413   Rect just_right_no_edge(6, 3, 2, 4);  // too short
414
415   EXPECT_FALSE(r.SharesEdgeWith(just_above_no_edge));
416   EXPECT_FALSE(r.SharesEdgeWith(just_below_no_edge));
417   EXPECT_FALSE(r.SharesEdgeWith(just_left_no_edge));
418   EXPECT_FALSE(r.SharesEdgeWith(just_right_no_edge));
419 }
420
421 // Similar to EXPECT_FLOAT_EQ, but lets NaN equal NaN
422 #define EXPECT_FLOAT_AND_NAN_EQ(a, b) \
423   { if (a == a || b == b) { EXPECT_FLOAT_EQ(a, b); } }
424
425 TEST(RectTest, ScaleRect) {
426   static const struct Test {
427     int x1;  // source
428     int y1;
429     int w1;
430     int h1;
431     float scale;
432     float x2;  // target
433     float y2;
434     float w2;
435     float h2;
436   } tests[] = {
437     { 3, 3, 3, 3,
438       1.5f,
439       4.5f, 4.5f, 4.5f, 4.5f },
440     { 3, 3, 3, 3,
441       0.0f,
442       0.0f, 0.0f, 0.0f, 0.0f },
443     { 3, 3, 3, 3,
444       std::numeric_limits<float>::quiet_NaN(),
445       std::numeric_limits<float>::quiet_NaN(),
446       std::numeric_limits<float>::quiet_NaN(),
447       std::numeric_limits<float>::quiet_NaN(),
448       std::numeric_limits<float>::quiet_NaN() },
449     { 3, 3, 3, 3,
450       std::numeric_limits<float>::max(),
451       std::numeric_limits<float>::max(),
452       std::numeric_limits<float>::max(),
453       std::numeric_limits<float>::max(),
454       std::numeric_limits<float>::max() }
455   };
456
457   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
458     Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
459     RectF r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
460
461     RectF scaled = ScaleRect(r1, tests[i].scale);
462     EXPECT_FLOAT_AND_NAN_EQ(r2.x(), scaled.x());
463     EXPECT_FLOAT_AND_NAN_EQ(r2.y(), scaled.y());
464     EXPECT_FLOAT_AND_NAN_EQ(r2.width(), scaled.width());
465     EXPECT_FLOAT_AND_NAN_EQ(r2.height(), scaled.height());
466   }
467 }
468
469 TEST(RectTest, ToEnclosedRect) {
470   static const struct Test {
471     float x1; // source
472     float y1;
473     float w1;
474     float h1;
475     int x2; // target
476     int y2;
477     int w2;
478     int h2;
479   } tests [] = {
480     { 0.0f, 0.0f, 0.0f, 0.0f,
481       0, 0, 0, 0 },
482     { -1.5f, -1.5f, 3.0f, 3.0f,
483       -1, -1, 2, 2 },
484     { -1.5f, -1.5f, 3.5f, 3.5f,
485       -1, -1, 3, 3 },
486     { std::numeric_limits<float>::max(),
487       std::numeric_limits<float>::max(),
488       2.0f, 2.0f,
489       std::numeric_limits<int>::max(),
490       std::numeric_limits<int>::max(),
491       0, 0 },
492     { 0.0f, 0.0f,
493       std::numeric_limits<float>::max(),
494       std::numeric_limits<float>::max(),
495       0, 0,
496       std::numeric_limits<int>::max(),
497       std::numeric_limits<int>::max() },
498     { 20000.5f, 20000.5f, 0.5f, 0.5f,
499       20001, 20001, 0, 0 },
500     { std::numeric_limits<float>::quiet_NaN(),
501       std::numeric_limits<float>::quiet_NaN(),
502       std::numeric_limits<float>::quiet_NaN(),
503       std::numeric_limits<float>::quiet_NaN(),
504       0, 0, 0, 0 }
505   };
506
507   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
508     RectF r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
509     Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
510
511     Rect enclosed = ToEnclosedRect(r1);
512     EXPECT_FLOAT_AND_NAN_EQ(r2.x(), enclosed.x());
513     EXPECT_FLOAT_AND_NAN_EQ(r2.y(), enclosed.y());
514     EXPECT_FLOAT_AND_NAN_EQ(r2.width(), enclosed.width());
515     EXPECT_FLOAT_AND_NAN_EQ(r2.height(), enclosed.height());
516   }
517 }
518
519 TEST(RectTest, ToEnclosingRect) {
520   static const struct Test {
521     float x1; // source
522     float y1;
523     float w1;
524     float h1;
525     int x2; // target
526     int y2;
527     int w2;
528     int h2;
529   } tests [] = {
530     { 0.0f, 0.0f, 0.0f, 0.0f,
531       0, 0, 0, 0 },
532     { 5.5f, 5.5f, 0.0f, 0.0f,
533       5, 5, 0, 0 },
534     { -1.5f, -1.5f, 3.0f, 3.0f,
535       -2, -2, 4, 4 },
536     { -1.5f, -1.5f, 3.5f, 3.5f,
537       -2, -2, 4, 4 },
538     { std::numeric_limits<float>::max(),
539       std::numeric_limits<float>::max(),
540       2.0f, 2.0f,
541       std::numeric_limits<int>::max(),
542       std::numeric_limits<int>::max(),
543       0, 0 },
544     { 0.0f, 0.0f,
545       std::numeric_limits<float>::max(),
546       std::numeric_limits<float>::max(),
547       0, 0,
548       std::numeric_limits<int>::max(),
549       std::numeric_limits<int>::max() },
550     { 20000.5f, 20000.5f, 0.5f, 0.5f,
551       20000, 20000, 1, 1 },
552     { std::numeric_limits<float>::quiet_NaN(),
553       std::numeric_limits<float>::quiet_NaN(),
554       std::numeric_limits<float>::quiet_NaN(),
555       std::numeric_limits<float>::quiet_NaN(),
556       0, 0, 0, 0 }
557   };
558
559   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
560     RectF r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
561     Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
562
563     Rect enclosed = ToEnclosingRect(r1);
564     EXPECT_FLOAT_AND_NAN_EQ(r2.x(), enclosed.x());
565     EXPECT_FLOAT_AND_NAN_EQ(r2.y(), enclosed.y());
566     EXPECT_FLOAT_AND_NAN_EQ(r2.width(), enclosed.width());
567     EXPECT_FLOAT_AND_NAN_EQ(r2.height(), enclosed.height());
568   }
569 }
570
571 TEST(RectTest, ToNearestRect) {
572   Rect rect;
573   EXPECT_EQ(rect, ToNearestRect(RectF(rect)));
574
575   rect = Rect(-1, -1, 3, 3);
576   EXPECT_EQ(rect, ToNearestRect(RectF(rect)));
577
578   RectF rectf(-1.00001f, -0.999999f, 3.0000001f, 2.999999f);
579   EXPECT_EQ(rect, ToNearestRect(rectf));
580 }
581
582 TEST(RectTest, ToFlooredRect) {
583   static const struct Test {
584     float x1; // source
585     float y1;
586     float w1;
587     float h1;
588     int x2; // target
589     int y2;
590     int w2;
591     int h2;
592   } tests [] = {
593     { 0.0f, 0.0f, 0.0f, 0.0f,
594       0, 0, 0, 0 },
595     { -1.5f, -1.5f, 3.0f, 3.0f,
596       -2, -2, 3, 3 },
597     { -1.5f, -1.5f, 3.5f, 3.5f,
598       -2, -2, 3, 3 },
599     { 20000.5f, 20000.5f, 0.5f, 0.5f,
600       20000, 20000, 0, 0 },
601   };
602
603   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
604     RectF r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
605     Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
606
607     Rect floored = ToFlooredRectDeprecated(r1);
608     EXPECT_FLOAT_EQ(r2.x(), floored.x());
609     EXPECT_FLOAT_EQ(r2.y(), floored.y());
610     EXPECT_FLOAT_EQ(r2.width(), floored.width());
611     EXPECT_FLOAT_EQ(r2.height(), floored.height());
612   }
613 }
614
615 TEST(RectTest, ScaleToEnclosedRect) {
616   static const struct Test {
617     Rect input_rect;
618     float input_scale;
619     Rect expected_rect;
620   } tests[] = {
621     {
622       Rect(),
623       5.f,
624       Rect(),
625     }, {
626       Rect(1, 1, 1, 1),
627       5.f,
628       Rect(5, 5, 5, 5),
629     }, {
630       Rect(-1, -1, 0, 0),
631       5.f,
632       Rect(-5, -5, 0, 0),
633     }, {
634       Rect(1, -1, 0, 1),
635       5.f,
636       Rect(5, -5, 0, 5),
637     }, {
638       Rect(-1, 1, 1, 0),
639       5.f,
640       Rect(-5, 5, 5, 0),
641     }, {
642       Rect(1, 2, 3, 4),
643       1.5f,
644       Rect(2, 3, 4, 6),
645     }, {
646       Rect(-1, -2, 0, 0),
647       1.5f,
648       Rect(-1, -3, 0, 0),
649     }
650   };
651
652   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
653     Rect result = ScaleToEnclosedRect(tests[i].input_rect,
654                                       tests[i].input_scale);
655     EXPECT_EQ(tests[i].expected_rect, result);
656   }
657 }
658
659 TEST(RectTest, ScaleToEnclosingRect) {
660   static const struct Test {
661     Rect input_rect;
662     float input_scale;
663     Rect expected_rect;
664   } tests[] = {
665     {
666       Rect(),
667       5.f,
668       Rect(),
669     }, {
670       Rect(1, 1, 1, 1),
671       5.f,
672       Rect(5, 5, 5, 5),
673     }, {
674       Rect(-1, -1, 0, 0),
675       5.f,
676       Rect(-5, -5, 0, 0),
677     }, {
678       Rect(1, -1, 0, 1),
679       5.f,
680       Rect(5, -5, 0, 5),
681     }, {
682       Rect(-1, 1, 1, 0),
683       5.f,
684       Rect(-5, 5, 5, 0),
685     }, {
686       Rect(1, 2, 3, 4),
687       1.5f,
688       Rect(1, 3, 5, 6),
689     }, {
690       Rect(-1, -2, 0, 0),
691       1.5f,
692       Rect(-2, -3, 0, 0),
693     }
694   };
695
696   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
697     Rect result = ScaleToEnclosingRect(tests[i].input_rect,
698                                        tests[i].input_scale);
699     EXPECT_EQ(tests[i].expected_rect, result);
700   }
701 }
702
703 #if defined(OS_WIN)
704 TEST(RectTest, ConstructAndAssign) {
705   const RECT rect_1 = { 0, 0, 10, 10 };
706   const RECT rect_2 = { 0, 0, -10, -10 };
707   Rect test1(rect_1);
708   Rect test2(rect_2);
709 }
710 #endif
711
712 TEST(RectTest, ToRectF) {
713   // Check that implicit conversion from integer to float compiles.
714   Rect a(10, 20, 30, 40);
715   RectF b(10, 20, 30, 40);
716
717   RectF intersect = IntersectRects(a, b);
718   EXPECT_EQ(b, intersect);
719
720   EXPECT_EQ(a, b);
721   EXPECT_EQ(b, a);
722 }
723
724 TEST(RectTest, BoundingRect) {
725   struct {
726     Point a;
727     Point b;
728     Rect expected;
729   } int_tests[] = {
730     // If point B dominates A, then A should be the origin.
731     { Point(4, 6), Point(4, 6), Rect(4, 6, 0, 0) },
732     { Point(4, 6), Point(8, 6), Rect(4, 6, 4, 0) },
733     { Point(4, 6), Point(4, 9), Rect(4, 6, 0, 3) },
734     { Point(4, 6), Point(8, 9), Rect(4, 6, 4, 3) },
735     // If point A dominates B, then B should be the origin.
736     { Point(4, 6), Point(4, 6), Rect(4, 6, 0, 0) },
737     { Point(8, 6), Point(4, 6), Rect(4, 6, 4, 0) },
738     { Point(4, 9), Point(4, 6), Rect(4, 6, 0, 3) },
739     { Point(8, 9), Point(4, 6), Rect(4, 6, 4, 3) },
740     // If neither point dominates, then the origin is a combination of the two.
741     { Point(4, 6), Point(6, 4), Rect(4, 4, 2, 2) },
742     { Point(-4, -6), Point(-6, -4), Rect(-6, -6, 2, 2) },
743     { Point(-4, 6), Point(6, -4), Rect(-4, -4, 10, 10) },
744   };
745
746   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(int_tests); ++i) {
747     Rect actual = BoundingRect(int_tests[i].a, int_tests[i].b);
748     EXPECT_EQ(int_tests[i].expected, actual);
749   }
750
751   struct {
752     PointF a;
753     PointF b;
754     RectF expected;
755   } float_tests[] = {
756     // If point B dominates A, then A should be the origin.
757     { PointF(4.2f, 6.8f), PointF(4.2f, 6.8f),
758       RectF(4.2f, 6.8f, 0, 0) },
759     { PointF(4.2f, 6.8f), PointF(8.5f, 6.8f),
760       RectF(4.2f, 6.8f, 4.3f, 0) },
761     { PointF(4.2f, 6.8f), PointF(4.2f, 9.3f),
762       RectF(4.2f, 6.8f, 0, 2.5f) },
763     { PointF(4.2f, 6.8f), PointF(8.5f, 9.3f),
764       RectF(4.2f, 6.8f, 4.3f, 2.5f) },
765     // If point A dominates B, then B should be the origin.
766     { PointF(4.2f, 6.8f), PointF(4.2f, 6.8f),
767       RectF(4.2f, 6.8f, 0, 0) },
768     { PointF(8.5f, 6.8f), PointF(4.2f, 6.8f),
769       RectF(4.2f, 6.8f, 4.3f, 0) },
770     { PointF(4.2f, 9.3f), PointF(4.2f, 6.8f),
771       RectF(4.2f, 6.8f, 0, 2.5f) },
772     { PointF(8.5f, 9.3f), PointF(4.2f, 6.8f),
773       RectF(4.2f, 6.8f, 4.3f, 2.5f) },
774     // If neither point dominates, then the origin is a combination of the two.
775     { PointF(4.2f, 6.8f), PointF(6.8f, 4.2f),
776       RectF(4.2f, 4.2f, 2.6f, 2.6f) },
777     { PointF(-4.2f, -6.8f), PointF(-6.8f, -4.2f),
778       RectF(-6.8f, -6.8f, 2.6f, 2.6f) },
779     { PointF(-4.2f, 6.8f), PointF(6.8f, -4.2f),
780       RectF(-4.2f, -4.2f, 11.0f, 11.0f) }
781   };
782
783   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(float_tests); ++i) {
784     RectF actual = BoundingRect(float_tests[i].a, float_tests[i].b);
785     EXPECT_RECTF_EQ(float_tests[i].expected, actual);
786   }
787 }
788
789 TEST(RectTest, IsExpressibleAsRect) {
790   EXPECT_TRUE(RectF().IsExpressibleAsRect());
791
792   float min = std::numeric_limits<int>::min();
793   float max = std::numeric_limits<int>::max();
794   float infinity = std::numeric_limits<float>::infinity();
795
796   EXPECT_TRUE(RectF(
797       min + 200, min + 200, max - 200, max - 200).IsExpressibleAsRect());
798   EXPECT_FALSE(RectF(
799       min - 200, min + 200, max + 200, max + 200).IsExpressibleAsRect());
800   EXPECT_FALSE(RectF(
801       min + 200 , min - 200, max + 200, max + 200).IsExpressibleAsRect());
802   EXPECT_FALSE(RectF(
803       min + 200, min + 200, max + 200, max - 200).IsExpressibleAsRect());
804   EXPECT_FALSE(RectF(
805       min + 200, min + 200, max - 200, max + 200).IsExpressibleAsRect());
806
807   EXPECT_TRUE(RectF(0, 0, max - 200, max - 200).IsExpressibleAsRect());
808   EXPECT_FALSE(RectF(200, 0, max + 200, max - 200).IsExpressibleAsRect());
809   EXPECT_FALSE(RectF(0, 200, max - 200, max + 200).IsExpressibleAsRect());
810   EXPECT_FALSE(RectF(0, 0, max + 200, max - 200).IsExpressibleAsRect());
811   EXPECT_FALSE(RectF(0, 0, max - 200, max + 200).IsExpressibleAsRect());
812
813   EXPECT_FALSE(RectF(infinity, 0, 1, 1).IsExpressibleAsRect());
814   EXPECT_FALSE(RectF(0, infinity, 1, 1).IsExpressibleAsRect());
815   EXPECT_FALSE(RectF(0, 0, infinity, 1).IsExpressibleAsRect());
816   EXPECT_FALSE(RectF(0, 0, 1, infinity).IsExpressibleAsRect());
817 }
818
819 TEST(RectTest, Offset) {
820   Rect i(1, 2, 3, 4);
821
822   EXPECT_EQ(Rect(2, 1, 3, 4), (i + Vector2d(1, -1)));
823   EXPECT_EQ(Rect(2, 1, 3, 4), (Vector2d(1, -1) + i));
824   i += Vector2d(1, -1);
825   EXPECT_EQ(Rect(2, 1, 3, 4), i);
826   EXPECT_EQ(Rect(1, 2, 3, 4), (i - Vector2d(1, -1)));
827   i -= Vector2d(1, -1);
828   EXPECT_EQ(Rect(1, 2, 3, 4), i);
829
830   RectF f(1.1f, 2.2f, 3.3f, 4.4f);
831   EXPECT_EQ(RectF(2.2f, 1.1f, 3.3f, 4.4f), (f + Vector2dF(1.1f, -1.1f)));
832   EXPECT_EQ(RectF(2.2f, 1.1f, 3.3f, 4.4f), (Vector2dF(1.1f, -1.1f) + f));
833   f += Vector2dF(1.1f, -1.1f);
834   EXPECT_EQ(RectF(2.2f, 1.1f, 3.3f, 4.4f), f);
835   EXPECT_EQ(RectF(1.1f, 2.2f, 3.3f, 4.4f), (f - Vector2dF(1.1f, -1.1f)));
836   f -= Vector2dF(1.1f, -1.1f);
837   EXPECT_EQ(RectF(1.1f, 2.2f, 3.3f, 4.4f), f);
838 }
839
840 TEST(RectTest, Corners) {
841   Rect i(1, 2, 3, 4);
842   RectF f(1.1f, 2.1f, 3.1f, 4.1f);
843
844   EXPECT_EQ(Point(1, 2), i.origin());
845   EXPECT_EQ(Point(4, 2), i.top_right());
846   EXPECT_EQ(Point(1, 6), i.bottom_left());
847   EXPECT_EQ(Point(4, 6), i.bottom_right());
848
849   EXPECT_EQ(PointF(1.1f, 2.1f), f.origin());
850   EXPECT_EQ(PointF(4.2f, 2.1f), f.top_right());
851   EXPECT_EQ(PointF(1.1f, 6.2f), f.bottom_left());
852   EXPECT_EQ(PointF(4.2f, 6.2f), f.bottom_right());
853 }
854
855 TEST(RectTest, ManhattanDistanceToPoint) {
856   Rect i(1, 2, 3, 4);
857   EXPECT_EQ(0, i.ManhattanDistanceToPoint(Point(1, 2)));
858   EXPECT_EQ(0, i.ManhattanDistanceToPoint(Point(4, 6)));
859   EXPECT_EQ(0, i.ManhattanDistanceToPoint(Point(2, 4)));
860   EXPECT_EQ(3, i.ManhattanDistanceToPoint(Point(0, 0)));
861   EXPECT_EQ(2, i.ManhattanDistanceToPoint(Point(2, 0)));
862   EXPECT_EQ(3, i.ManhattanDistanceToPoint(Point(5, 0)));
863   EXPECT_EQ(1, i.ManhattanDistanceToPoint(Point(5, 4)));
864   EXPECT_EQ(3, i.ManhattanDistanceToPoint(Point(5, 8)));
865   EXPECT_EQ(2, i.ManhattanDistanceToPoint(Point(3, 8)));
866   EXPECT_EQ(2, i.ManhattanDistanceToPoint(Point(0, 7)));
867   EXPECT_EQ(1, i.ManhattanDistanceToPoint(Point(0, 3)));
868
869   RectF f(1.1f, 2.1f, 3.1f, 4.1f);
870   EXPECT_FLOAT_EQ(0.f, f.ManhattanDistanceToPoint(PointF(1.1f, 2.1f)));
871   EXPECT_FLOAT_EQ(0.f, f.ManhattanDistanceToPoint(PointF(4.2f, 6.f)));
872   EXPECT_FLOAT_EQ(0.f, f.ManhattanDistanceToPoint(PointF(2.f, 4.f)));
873   EXPECT_FLOAT_EQ(3.2f, f.ManhattanDistanceToPoint(PointF(0.f, 0.f)));
874   EXPECT_FLOAT_EQ(2.1f, f.ManhattanDistanceToPoint(PointF(2.f, 0.f)));
875   EXPECT_FLOAT_EQ(2.9f, f.ManhattanDistanceToPoint(PointF(5.f, 0.f)));
876   EXPECT_FLOAT_EQ(.8f, f.ManhattanDistanceToPoint(PointF(5.f, 4.f)));
877   EXPECT_FLOAT_EQ(2.6f, f.ManhattanDistanceToPoint(PointF(5.f, 8.f)));
878   EXPECT_FLOAT_EQ(1.8f, f.ManhattanDistanceToPoint(PointF(3.f, 8.f)));
879   EXPECT_FLOAT_EQ(1.9f, f.ManhattanDistanceToPoint(PointF(0.f, 7.f)));
880   EXPECT_FLOAT_EQ(1.1f, f.ManhattanDistanceToPoint(PointF(0.f, 3.f)));
881 }
882
883 TEST(RectTest, ManhattanInternalDistance) {
884   Rect i(0, 0, 400, 400);
885   EXPECT_EQ(0, i.ManhattanInternalDistance(gfx::Rect(-1, 0, 2, 1)));
886   EXPECT_EQ(1, i.ManhattanInternalDistance(gfx::Rect(400, 0, 1, 400)));
887   EXPECT_EQ(2, i.ManhattanInternalDistance(gfx::Rect(-100, -100, 100, 100)));
888   EXPECT_EQ(2, i.ManhattanInternalDistance(gfx::Rect(-101, 100, 100, 100)));
889   EXPECT_EQ(4, i.ManhattanInternalDistance(gfx::Rect(-101, -101, 100, 100)));
890   EXPECT_EQ(435, i.ManhattanInternalDistance(gfx::Rect(630, 603, 100, 100)));
891
892   RectF f(0.0f, 0.0f, 400.0f, 400.0f);
893   static const float kEpsilon = std::numeric_limits<float>::epsilon();
894
895   EXPECT_FLOAT_EQ(
896       0.0f, f.ManhattanInternalDistance(gfx::RectF(-1.0f, 0.0f, 2.0f, 1.0f)));
897   EXPECT_FLOAT_EQ(
898       kEpsilon,
899       f.ManhattanInternalDistance(gfx::RectF(400.0f, 0.0f, 1.0f, 400.0f)));
900   EXPECT_FLOAT_EQ(2.0f * kEpsilon,
901                   f.ManhattanInternalDistance(
902                       gfx::RectF(-100.0f, -100.0f, 100.0f, 100.0f)));
903   EXPECT_FLOAT_EQ(
904       1.0f + kEpsilon,
905       f.ManhattanInternalDistance(gfx::RectF(-101.0f, 100.0f, 100.0f, 100.0f)));
906   EXPECT_FLOAT_EQ(2.0f + 2.0f * kEpsilon,
907                   f.ManhattanInternalDistance(
908                       gfx::RectF(-101.0f, -101.0f, 100.0f, 100.0f)));
909   EXPECT_FLOAT_EQ(
910       433.0f + 2.0f * kEpsilon,
911       f.ManhattanInternalDistance(gfx::RectF(630.0f, 603.0f, 100.0f, 100.0f)));
912
913   EXPECT_FLOAT_EQ(
914       0.0f, f.ManhattanInternalDistance(gfx::RectF(-1.0f, 0.0f, 1.1f, 1.0f)));
915   EXPECT_FLOAT_EQ(
916       0.1f + kEpsilon,
917       f.ManhattanInternalDistance(gfx::RectF(-1.5f, 0.0f, 1.4f, 1.0f)));
918   EXPECT_FLOAT_EQ(
919       kEpsilon,
920       f.ManhattanInternalDistance(gfx::RectF(-1.5f, 0.0f, 1.5f, 1.0f)));
921 }
922
923 }  // namespace gfx