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