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.
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"
15 TEST(RectTest
, Contains
) {
16 static const struct ContainsCase
{
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},
36 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(contains_cases
); ++i
) {
37 const ContainsCase
& value
= contains_cases
[i
];
38 gfx::Rect
rect(value
.rect_x
, value
.rect_y
,
39 value
.rect_width
, value
.rect_height
);
40 EXPECT_EQ(value
.contained
, rect
.Contains(value
.point_x
, value
.point_y
));
44 TEST(RectTest
, Intersects
) {
56 { 0, 0, 0, 0, 0, 0, 0, 0, false },
57 { 0, 0, 10, 10, 0, 0, 10, 10, true },
58 { 0, 0, 10, 10, 10, 10, 10, 10, false },
59 { 10, 10, 10, 10, 0, 0, 10, 10, false },
60 { 10, 10, 10, 10, 5, 5, 10, 10, true },
61 { 10, 10, 10, 10, 15, 15, 10, 10, true },
62 { 10, 10, 10, 10, 20, 15, 10, 10, false },
63 { 10, 10, 10, 10, 21, 15, 10, 10, false }
65 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(tests
); ++i
) {
66 gfx::Rect
r1(tests
[i
].x1
, tests
[i
].y1
, tests
[i
].w1
, tests
[i
].h1
);
67 gfx::Rect
r2(tests
[i
].x2
, tests
[i
].y2
, tests
[i
].w2
, tests
[i
].h2
);
68 EXPECT_EQ(tests
[i
].intersects
, r1
.Intersects(r2
));
72 TEST(RectTest
, Intersect
) {
82 int x3
; // rect 3: the union of rects 1 and 2
87 { 0, 0, 0, 0, // zeros
90 { 0, 0, 4, 4, // equal
93 { 0, 0, 4, 4, // neighboring
96 { 0, 0, 4, 4, // overlapping corners
99 { 0, 0, 4, 4, // T junction
106 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(tests
); ++i
) {
107 gfx::Rect
r1(tests
[i
].x1
, tests
[i
].y1
, tests
[i
].w1
, tests
[i
].h1
);
108 gfx::Rect
r2(tests
[i
].x2
, tests
[i
].y2
, tests
[i
].w2
, tests
[i
].h2
);
109 gfx::Rect
r3(tests
[i
].x3
, tests
[i
].y3
, tests
[i
].w3
, tests
[i
].h3
);
110 gfx::Rect ir
= r1
.Intersect(r2
);
111 EXPECT_EQ(r3
.x(), ir
.x());
112 EXPECT_EQ(r3
.y(), ir
.y());
113 EXPECT_EQ(r3
.width(), ir
.width());
114 EXPECT_EQ(r3
.height(), ir
.height());
118 TEST(RectTest
, Union
) {
119 static const struct Test
{
128 int x3
; // rect 3: the union of rects 1 and 2
148 { 3, 3, 2, 2, // reverse r1 and r2 from previous test
151 { 0, 0, 0, 0, // union with empty rect
155 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(tests
); ++i
) {
156 gfx::Rect
r1(tests
[i
].x1
, tests
[i
].y1
, tests
[i
].w1
, tests
[i
].h1
);
157 gfx::Rect
r2(tests
[i
].x2
, tests
[i
].y2
, tests
[i
].w2
, tests
[i
].h2
);
158 gfx::Rect
r3(tests
[i
].x3
, tests
[i
].y3
, tests
[i
].w3
, tests
[i
].h3
);
159 gfx::Rect u
= r1
.Union(r2
);
160 EXPECT_EQ(r3
.x(), u
.x());
161 EXPECT_EQ(r3
.y(), u
.y());
162 EXPECT_EQ(r3
.width(), u
.width());
163 EXPECT_EQ(r3
.height(), u
.height());
167 TEST(RectTest
, Equals
) {
168 ASSERT_TRUE(gfx::Rect(0, 0, 0, 0).Equals(gfx::Rect(0, 0, 0, 0)));
169 ASSERT_TRUE(gfx::Rect(1, 2, 3, 4).Equals(gfx::Rect(1, 2, 3, 4)));
170 ASSERT_FALSE(gfx::Rect(0, 0, 0, 0).Equals(gfx::Rect(0, 0, 0, 1)));
171 ASSERT_FALSE(gfx::Rect(0, 0, 0, 0).Equals(gfx::Rect(0, 0, 1, 0)));
172 ASSERT_FALSE(gfx::Rect(0, 0, 0, 0).Equals(gfx::Rect(0, 1, 0, 0)));
173 ASSERT_FALSE(gfx::Rect(0, 0, 0, 0).Equals(gfx::Rect(1, 0, 0, 0)));
176 TEST(RectTest
, AdjustToFit
) {
177 static const struct Test
{
186 int x3
; // rect 3: results of invoking AdjustToFit
207 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(tests
); ++i
) {
208 gfx::Rect
r1(tests
[i
].x1
, tests
[i
].y1
, tests
[i
].w1
, tests
[i
].h1
);
209 gfx::Rect
r2(tests
[i
].x2
, tests
[i
].y2
, tests
[i
].w2
, tests
[i
].h2
);
210 gfx::Rect
r3(tests
[i
].x3
, tests
[i
].y3
, tests
[i
].w3
, tests
[i
].h3
);
211 gfx::Rect
u(r1
.AdjustToFit(r2
));
212 EXPECT_EQ(r3
.x(), u
.x());
213 EXPECT_EQ(r3
.y(), u
.y());
214 EXPECT_EQ(r3
.width(), u
.width());
215 EXPECT_EQ(r3
.height(), u
.height());
219 TEST(RectTest
, Subtract
) {
222 gfx::Rect(10, 10, 20, 20).Subtract(
223 gfx::Rect(10, 10, 20, 20)).Equals(
224 gfx::Rect(0, 0, 0, 0)));
228 gfx::Rect(10, 10, 20, 20).Subtract(
229 gfx::Rect(5, 5, 30, 30)).Equals(
230 gfx::Rect(0, 0, 0, 0)));
234 gfx::Rect(10, 10, 20, 20).Subtract(
235 gfx::Rect(30, 30, 20, 20)).Equals(
236 gfx::Rect(10, 10, 20, 20)));
238 // Not a complete intersection in either direction
240 gfx::Rect(10, 10, 20, 20).Subtract(
241 gfx::Rect(15, 15, 20, 20)).Equals(
242 gfx::Rect(10, 10, 20, 20)));
244 // Complete intersection in the x-direction
246 gfx::Rect(10, 10, 20, 20).Subtract(
247 gfx::Rect(10, 15, 20, 20)).Equals(
248 gfx::Rect(10, 10, 20, 5)));
250 // Complete intersection in the x-direction
252 gfx::Rect(10, 10, 20, 20).Subtract(
253 gfx::Rect(5, 15, 30, 20)).Equals(
254 gfx::Rect(10, 10, 20, 5)));
256 // Complete intersection in the x-direction
258 gfx::Rect(10, 10, 20, 20).Subtract(
259 gfx::Rect(5, 5, 30, 20)).Equals(
260 gfx::Rect(10, 25, 20, 5)));
262 // Complete intersection in the y-direction
264 gfx::Rect(10, 10, 20, 20).Subtract(
265 gfx::Rect(10, 10, 10, 30)).Equals(
266 gfx::Rect(20, 10, 10, 20)));
268 // Complete intersection in the y-direction
270 gfx::Rect(10, 10, 20, 20).Subtract(
271 gfx::Rect(5, 5, 20, 30)).Equals(
272 gfx::Rect(25, 10, 5, 20)));
275 TEST(RectTest
, IsEmpty
) {
276 EXPECT_TRUE(gfx::Rect(0, 0, 0, 0).IsEmpty());
277 EXPECT_TRUE(gfx::Rect(0, 0, 0, 0).size().IsEmpty());
278 EXPECT_TRUE(gfx::Rect(0, 0, 10, 0).IsEmpty());
279 EXPECT_TRUE(gfx::Rect(0, 0, 10, 0).size().IsEmpty());
280 EXPECT_TRUE(gfx::Rect(0, 0, 0, 10).IsEmpty());
281 EXPECT_TRUE(gfx::Rect(0, 0, 0, 10).size().IsEmpty());
282 EXPECT_FALSE(gfx::Rect(0, 0, 10, 10).IsEmpty());
283 EXPECT_FALSE(gfx::Rect(0, 0, 10, 10).size().IsEmpty());
286 TEST(RectTest
, SplitVertically
) {
287 gfx::Rect left_half
, right_half
;
289 // Splitting when origin is (0, 0).
290 gfx::Rect(0, 0, 20, 20).SplitVertically(&left_half
, &right_half
);
291 EXPECT_TRUE(left_half
.Equals(gfx::Rect(0, 0, 10, 20)));
292 EXPECT_TRUE(right_half
.Equals(gfx::Rect(10, 0, 10, 20)));
294 // Splitting when origin is arbitrary.
295 gfx::Rect(10, 10, 20, 10).SplitVertically(&left_half
, &right_half
);
296 EXPECT_TRUE(left_half
.Equals(gfx::Rect(10, 10, 10, 10)));
297 EXPECT_TRUE(right_half
.Equals(gfx::Rect(20, 10, 10, 10)));
299 // Splitting a rectangle of zero width.
300 gfx::Rect(10, 10, 0, 10).SplitVertically(&left_half
, &right_half
);
301 EXPECT_TRUE(left_half
.Equals(gfx::Rect(10, 10, 0, 10)));
302 EXPECT_TRUE(right_half
.Equals(gfx::Rect(10, 10, 0, 10)));
304 // Splitting a rectangle of odd width.
305 gfx::Rect(10, 10, 5, 10).SplitVertically(&left_half
, &right_half
);
306 EXPECT_TRUE(left_half
.Equals(gfx::Rect(10, 10, 2, 10)));
307 EXPECT_TRUE(right_half
.Equals(gfx::Rect(12, 10, 3, 10)));
310 TEST(RectTest
, CenterPoint
) {
313 // When origin is (0, 0).
314 center
= gfx::Rect(0, 0, 20, 20).CenterPoint();
315 EXPECT_TRUE(center
== gfx::Point(10, 10));
317 // When origin is even.
318 center
= gfx::Rect(10, 10, 20, 20).CenterPoint();
319 EXPECT_TRUE(center
== gfx::Point(20, 20));
321 // When origin is odd.
322 center
= gfx::Rect(11, 11, 20, 20).CenterPoint();
323 EXPECT_TRUE(center
== gfx::Point(21, 21));
325 // When 0 width or height.
326 center
= gfx::Rect(10, 10, 0, 20).CenterPoint();
327 EXPECT_TRUE(center
== gfx::Point(10, 20));
328 center
= gfx::Rect(10, 10, 20, 0).CenterPoint();
329 EXPECT_TRUE(center
== gfx::Point(20, 10));
332 center
= gfx::Rect(10, 10, 21, 21).CenterPoint();
333 EXPECT_TRUE(center
== gfx::Point(20, 20));
335 // When an odd size and position.
336 center
= gfx::Rect(11, 11, 21, 21).CenterPoint();
337 EXPECT_TRUE(center
== gfx::Point(21, 21));
340 TEST(RectTest
, CenterPointF
) {
343 // When origin is (0, 0).
344 center
= gfx::RectF(0, 0, 20, 20).CenterPoint();
345 EXPECT_TRUE(center
== gfx::PointF(10, 10));
347 // When origin is even.
348 center
= gfx::RectF(10, 10, 20, 20).CenterPoint();
349 EXPECT_TRUE(center
== gfx::PointF(20, 20));
351 // When origin is odd.
352 center
= gfx::RectF(11, 11, 20, 20).CenterPoint();
353 EXPECT_TRUE(center
== gfx::PointF(21, 21));
355 // When 0 width or height.
356 center
= gfx::RectF(10, 10, 0, 20).CenterPoint();
357 EXPECT_TRUE(center
== gfx::PointF(10, 20));
358 center
= gfx::RectF(10, 10, 20, 0).CenterPoint();
359 EXPECT_TRUE(center
== gfx::PointF(20, 10));
362 center
= gfx::RectF(10, 10, 21, 21).CenterPoint();
363 EXPECT_TRUE(center
== gfx::PointF(20.5f
, 20.5f
));
365 // When an odd size and position.
366 center
= gfx::RectF(11, 11, 21, 21).CenterPoint();
367 EXPECT_TRUE(center
== gfx::PointF(21.5f
, 21.5f
));
370 TEST(RectTest
, SharesEdgeWith
) {
371 gfx::Rect
r(2, 3, 4, 5);
373 // Must be non-overlapping
374 EXPECT_FALSE(r
.SharesEdgeWith(r
));
376 gfx::Rect
just_above(2, 1, 4, 2);
377 gfx::Rect
just_below(2, 8, 4, 2);
378 gfx::Rect
just_left(0, 3, 2, 5);
379 gfx::Rect
just_right(6, 3, 2, 5);
381 EXPECT_TRUE(r
.SharesEdgeWith(just_above
));
382 EXPECT_TRUE(r
.SharesEdgeWith(just_below
));
383 EXPECT_TRUE(r
.SharesEdgeWith(just_left
));
384 EXPECT_TRUE(r
.SharesEdgeWith(just_right
));
387 gfx::Rect
same_height_no_edge(0, 0, 1, 5);
388 gfx::Rect
same_width_no_edge(0, 0, 4, 1);
390 EXPECT_FALSE(r
.SharesEdgeWith(same_height_no_edge
));
391 EXPECT_FALSE(r
.SharesEdgeWith(same_width_no_edge
));
393 gfx::Rect
just_above_no_edge(2, 1, 5, 2); // too wide
394 gfx::Rect
just_below_no_edge(2, 8, 3, 2); // too narrow
395 gfx::Rect
just_left_no_edge(0, 3, 2, 6); // too tall
396 gfx::Rect
just_right_no_edge(6, 3, 2, 4); // too short
398 EXPECT_FALSE(r
.SharesEdgeWith(just_above_no_edge
));
399 EXPECT_FALSE(r
.SharesEdgeWith(just_below_no_edge
));
400 EXPECT_FALSE(r
.SharesEdgeWith(just_left_no_edge
));
401 EXPECT_FALSE(r
.SharesEdgeWith(just_right_no_edge
));
404 TEST(RectTest
, SkRectToRect
) {
405 gfx::Rect
src(10, 20, 30, 40);
406 SkRect skrect
= gfx::RectToSkRect(src
);
407 EXPECT_EQ(src
, gfx::SkRectToRect(skrect
));
410 // Similar to EXPECT_FLOAT_EQ, but lets NaN equal NaN
411 #define EXPECT_FLOAT_AND_NAN_EQ(a, b) \
412 { if (a == a || b == b) { EXPECT_FLOAT_EQ(a, b); } }
414 TEST(RectTest
, ScaleRect
) {
415 static const struct Test
{
428 4.5f
, 4.5f
, 4.5f
, 4.5f
},
431 0.0f
, 0.0f
, 0.0f
, 0.0f
},
433 std::numeric_limits
<float>::quiet_NaN(),
434 std::numeric_limits
<float>::quiet_NaN(),
435 std::numeric_limits
<float>::quiet_NaN(),
436 std::numeric_limits
<float>::quiet_NaN(),
437 std::numeric_limits
<float>::quiet_NaN() },
439 std::numeric_limits
<float>::max(),
440 std::numeric_limits
<float>::max(),
441 std::numeric_limits
<float>::max(),
442 std::numeric_limits
<float>::max(),
443 std::numeric_limits
<float>::max() },
446 -3.0f
, -3.0f
, 0.0f
, 0.0f
}
449 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(tests
); ++i
) {
450 gfx::Rect
r1(tests
[i
].x1
, tests
[i
].y1
, tests
[i
].w1
, tests
[i
].h1
);
451 gfx::RectF
r2(tests
[i
].x2
, tests
[i
].y2
, tests
[i
].w2
, tests
[i
].h2
);
453 gfx::RectF scaled
= r1
.Scale(tests
[i
].scale
);
454 EXPECT_FLOAT_AND_NAN_EQ(r2
.x(), scaled
.x());
455 EXPECT_FLOAT_AND_NAN_EQ(r2
.y(), scaled
.y());
456 EXPECT_FLOAT_AND_NAN_EQ(r2
.width(), scaled
.width());
457 EXPECT_FLOAT_AND_NAN_EQ(r2
.height(), scaled
.height());
461 TEST(RectTest
, ToEnclosedRect
) {
462 static const struct Test
{
472 { 0.0f
, 0.0f
, 0.0f
, 0.0f
,
474 { -1.5f
, -1.5f
, 3.0f
, 3.0f
,
476 { -1.5f
, -1.5f
, 3.5f
, 3.5f
,
478 { std::numeric_limits
<float>::max(),
479 std::numeric_limits
<float>::max(),
481 std::numeric_limits
<int>::max(),
482 std::numeric_limits
<int>::max(),
485 std::numeric_limits
<float>::max(),
486 std::numeric_limits
<float>::max(),
488 std::numeric_limits
<int>::max(),
489 std::numeric_limits
<int>::max() },
490 { 20000.5f
, 20000.5f
, 0.5f
, 0.5f
,
491 20001, 20001, 0, 0 },
492 { std::numeric_limits
<float>::quiet_NaN(),
493 std::numeric_limits
<float>::quiet_NaN(),
494 std::numeric_limits
<float>::quiet_NaN(),
495 std::numeric_limits
<float>::quiet_NaN(),
499 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(tests
); ++i
) {
500 gfx::RectF
r1(tests
[i
].x1
, tests
[i
].y1
, tests
[i
].w1
, tests
[i
].h1
);
501 gfx::Rect
r2(tests
[i
].x2
, tests
[i
].y2
, tests
[i
].w2
, tests
[i
].h2
);
503 gfx::Rect enclosed
= ToEnclosedRect(r1
);
504 EXPECT_FLOAT_AND_NAN_EQ(r2
.x(), enclosed
.x());
505 EXPECT_FLOAT_AND_NAN_EQ(r2
.y(), enclosed
.y());
506 EXPECT_FLOAT_AND_NAN_EQ(r2
.width(), enclosed
.width());
507 EXPECT_FLOAT_AND_NAN_EQ(r2
.height(), enclosed
.height());
511 TEST(RectTest
, ToEnclosingRect
) {
512 static const struct Test
{
522 { 0.0f
, 0.0f
, 0.0f
, 0.0f
,
524 { -1.5f
, -1.5f
, 3.0f
, 3.0f
,
526 { -1.5f
, -1.5f
, 3.5f
, 3.5f
,
528 { std::numeric_limits
<float>::max(),
529 std::numeric_limits
<float>::max(),
531 std::numeric_limits
<int>::max(),
532 std::numeric_limits
<int>::max(),
535 std::numeric_limits
<float>::max(),
536 std::numeric_limits
<float>::max(),
538 std::numeric_limits
<int>::max(),
539 std::numeric_limits
<int>::max() },
540 { 20000.5f
, 20000.5f
, 0.5f
, 0.5f
,
541 20000, 20000, 1, 1 },
542 { std::numeric_limits
<float>::quiet_NaN(),
543 std::numeric_limits
<float>::quiet_NaN(),
544 std::numeric_limits
<float>::quiet_NaN(),
545 std::numeric_limits
<float>::quiet_NaN(),
549 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(tests
); ++i
) {
550 gfx::RectF
r1(tests
[i
].x1
, tests
[i
].y1
, tests
[i
].w1
, tests
[i
].h1
);
551 gfx::Rect
r2(tests
[i
].x2
, tests
[i
].y2
, tests
[i
].w2
, tests
[i
].h2
);
553 gfx::Rect enclosed
= ToEnclosingRect(r1
);
554 EXPECT_FLOAT_AND_NAN_EQ(r2
.x(), enclosed
.x());
555 EXPECT_FLOAT_AND_NAN_EQ(r2
.y(), enclosed
.y());
556 EXPECT_FLOAT_AND_NAN_EQ(r2
.width(), enclosed
.width());
557 EXPECT_FLOAT_AND_NAN_EQ(r2
.height(), enclosed
.height());
562 TEST(RectTest
, ConstructAndAssign
) {
563 const RECT rect_1
= { 0, 0, 10, 10 };
564 const RECT rect_2
= { 0, 0, -10, -10 };
565 gfx::Rect
test1(rect_1
);
566 gfx::Rect
test2(rect_2
);