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