Home | History | Annotate | Download | only in gfx
      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 TEST(RectTest, ManhattanInternalDistance) {
    897   Rect i(0, 0, 400, 400);
    898   EXPECT_EQ(0, i.ManhattanInternalDistance(gfx::Rect(-1, 0, 2, 1)));
    899   EXPECT_EQ(1, i.ManhattanInternalDistance(gfx::Rect(400, 0, 1, 400)));
    900   EXPECT_EQ(2, i.ManhattanInternalDistance(gfx::Rect(-100, -100, 100, 100)));
    901   EXPECT_EQ(2, i.ManhattanInternalDistance(gfx::Rect(-101, 100, 100, 100)));
    902   EXPECT_EQ(4, i.ManhattanInternalDistance(gfx::Rect(-101, -101, 100, 100)));
    903   EXPECT_EQ(435, i.ManhattanInternalDistance(gfx::Rect(630, 603, 100, 100)));
    904 
    905   RectF f(0.0f, 0.0f, 400.0f, 400.0f);
    906   static const float kEpsilon = std::numeric_limits<float>::epsilon();
    907 
    908   EXPECT_FLOAT_EQ(
    909       0.0f, f.ManhattanInternalDistance(gfx::RectF(-1.0f, 0.0f, 2.0f, 1.0f)));
    910   EXPECT_FLOAT_EQ(
    911       kEpsilon,
    912       f.ManhattanInternalDistance(gfx::RectF(400.0f, 0.0f, 1.0f, 400.0f)));
    913   EXPECT_FLOAT_EQ(2.0f * kEpsilon,
    914                   f.ManhattanInternalDistance(
    915                       gfx::RectF(-100.0f, -100.0f, 100.0f, 100.0f)));
    916   EXPECT_FLOAT_EQ(
    917       1.0f + kEpsilon,
    918       f.ManhattanInternalDistance(gfx::RectF(-101.0f, 100.0f, 100.0f, 100.0f)));
    919   EXPECT_FLOAT_EQ(2.0f + 2.0f * kEpsilon,
    920                   f.ManhattanInternalDistance(
    921                       gfx::RectF(-101.0f, -101.0f, 100.0f, 100.0f)));
    922   EXPECT_FLOAT_EQ(
    923       433.0f + 2.0f * kEpsilon,
    924       f.ManhattanInternalDistance(gfx::RectF(630.0f, 603.0f, 100.0f, 100.0f)));
    925 
    926   EXPECT_FLOAT_EQ(
    927       0.0f, f.ManhattanInternalDistance(gfx::RectF(-1.0f, 0.0f, 1.1f, 1.0f)));
    928   EXPECT_FLOAT_EQ(
    929       0.1f + kEpsilon,
    930       f.ManhattanInternalDistance(gfx::RectF(-1.5f, 0.0f, 1.4f, 1.0f)));
    931   EXPECT_FLOAT_EQ(
    932       kEpsilon,
    933       f.ManhattanInternalDistance(gfx::RectF(-1.5f, 0.0f, 1.5f, 1.0f)));
    934 }
    935 
    936 }  // namespace gfx
    937