Home | History | Annotate | Download | only in geometry
      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
    924