Linux: Depend on liberation-fonts package for RPMs.
[chromium-blink-merge.git] / ui / gfx / geometry / rect_unittest.cc
blob0ecde65c91b373ec5b0d47938e6cf36bedc2e1d4
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.
5 #include <limits>
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"
13 #if defined(OS_WIN)
14 #include <windows.h>
15 #endif
17 namespace gfx {
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
40 for (size_t i = 0; i < arraysize(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));
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 }
70 for (size_t i = 0; i < arraysize(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));
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 }
112 for (size_t i = 0; i < arraysize(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());
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 }
161 for (size_t i = 0; i < arraysize(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());
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));
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 }
213 for (size_t i = 0; i < arraysize(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());
226 TEST(RectTest, Subtract) {
227 Rect result;
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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());
303 TEST(RectTest, SplitVertically) {
304 Rect left_half, right_half;
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));
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));
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));
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));
327 TEST(RectTest, CenterPoint) {
328 Point center;
330 // When origin is (0, 0).
331 center = Rect(0, 0, 20, 20).CenterPoint();
332 EXPECT_TRUE(center == Point(10, 10));
334 // When origin is even.
335 center = Rect(10, 10, 20, 20).CenterPoint();
336 EXPECT_TRUE(center == Point(20, 20));
338 // When origin is odd.
339 center = Rect(11, 11, 20, 20).CenterPoint();
340 EXPECT_TRUE(center == Point(21, 21));
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));
348 // When an odd size.
349 center = Rect(10, 10, 21, 21).CenterPoint();
350 EXPECT_TRUE(center == Point(20, 20));
352 // When an odd size and position.
353 center = Rect(11, 11, 21, 21).CenterPoint();
354 EXPECT_TRUE(center == Point(21, 21));
357 TEST(RectTest, CenterPointF) {
358 PointF center;
360 // When origin is (0, 0).
361 center = RectF(0, 0, 20, 20).CenterPoint();
362 EXPECT_TRUE(center == PointF(10, 10));
364 // When origin is even.
365 center = RectF(10, 10, 20, 20).CenterPoint();
366 EXPECT_TRUE(center == PointF(20, 20));
368 // When origin is odd.
369 center = RectF(11, 11, 20, 20).CenterPoint();
370 EXPECT_TRUE(center == PointF(21, 21));
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));
378 // When an odd size.
379 center = RectF(10, 10, 21, 21).CenterPoint();
380 EXPECT_TRUE(center == PointF(20.5f, 20.5f));
382 // When an odd size and position.
383 center = RectF(11, 11, 21, 21).CenterPoint();
384 EXPECT_TRUE(center == PointF(21.5f, 21.5f));
387 TEST(RectTest, SharesEdgeWith) {
388 Rect r(2, 3, 4, 5);
390 // Must be non-overlapping
391 EXPECT_FALSE(r.SharesEdgeWith(r));
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);
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));
403 // Wrong placement
404 Rect same_height_no_edge(0, 0, 1, 5);
405 Rect same_width_no_edge(0, 0, 4, 1);
407 EXPECT_FALSE(r.SharesEdgeWith(same_height_no_edge));
408 EXPECT_FALSE(r.SharesEdgeWith(same_width_no_edge));
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
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));
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); } }
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() }
457 for (size_t i = 0; i < arraysize(tests); ++i) {
458 RectF 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);
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());
469 TEST(RectTest, ToEnclosedRect) {
470 static const int max_int = std::numeric_limits<int>::max();
471 static const int min_int = std::numeric_limits<int>::min();
472 static const float max_float = std::numeric_limits<float>::max();
473 static const struct Test {
474 float x1; // source
475 float y1;
476 float w1;
477 float h1;
478 int x2; // target
479 int y2;
480 int w2;
481 int h2;
482 } tests[] = {{0.0f, 0.0f, 0.0f, 0.0f, 0, 0, 0, 0},
483 {-1.5f, -1.5f, 3.0f, 3.0f, -1, -1, 2, 2},
484 {-1.5f, -1.5f, 3.5f, 3.5f, -1, -1, 3, 3},
485 {max_float, max_float, 2.0f, 2.0f, max_int, max_int, 0, 0},
486 {0.0f, 0.0f, max_float, max_float, 0, 0, max_int, max_int},
487 {20000.5f, 20000.5f, 0.5f, 0.5f, 20001, 20001, 0, 0},
488 {static_cast<float>(min_int),
489 static_cast<float>(min_int),
490 max_int * 2.f,
491 max_int * 2.f,
492 min_int,
493 min_int,
494 max_int,
495 max_int},
496 {static_cast<float>(max_int),
497 static_cast<float>(max_int),
498 static_cast<float>(max_int),
499 static_cast<float>(max_int),
500 max_int,
501 max_int,
503 0}};
505 for (size_t i = 0; i < arraysize(tests); ++i) {
506 RectF r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
507 Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
509 Rect enclosed = ToEnclosedRect(r1);
510 EXPECT_FLOAT_AND_NAN_EQ(r2.x(), enclosed.x());
511 EXPECT_FLOAT_AND_NAN_EQ(r2.y(), enclosed.y());
512 EXPECT_FLOAT_AND_NAN_EQ(r2.width(), enclosed.width());
513 EXPECT_FLOAT_AND_NAN_EQ(r2.height(), enclosed.height());
517 TEST(RectTest, ToEnclosingRect) {
518 static const int max_int = std::numeric_limits<int>::max();
519 static const int min_int = std::numeric_limits<int>::min();
520 static const float max_float = std::numeric_limits<float>::max();
521 static const struct Test {
522 float x1; // source
523 float y1;
524 float w1;
525 float h1;
526 int x2; // target
527 int y2;
528 int w2;
529 int h2;
530 } tests[] = {{0.0f, 0.0f, 0.0f, 0.0f, 0, 0, 0, 0},
531 {5.5f, 5.5f, 0.0f, 0.0f, 5, 5, 0, 0},
532 {-1.5f, -1.5f, 3.0f, 3.0f, -2, -2, 4, 4},
533 {-1.5f, -1.5f, 3.5f, 3.5f, -2, -2, 4, 4},
534 {max_float, max_float, 2.0f, 2.0f, max_int, max_int, 0, 0},
535 {0.0f, 0.0f, max_float, max_float, 0, 0, max_int, max_int},
536 {20000.5f, 20000.5f, 0.5f, 0.5f, 20000, 20000, 1, 1},
537 {static_cast<float>(min_int),
538 static_cast<float>(min_int),
539 max_int * 2.f,
540 max_int * 2.f,
541 min_int,
542 min_int,
543 max_int,
544 max_int},
545 {static_cast<float>(max_int),
546 static_cast<float>(max_int),
547 static_cast<float>(max_int),
548 static_cast<float>(max_int),
549 max_int,
550 max_int,
552 0}};
554 for (size_t i = 0; i < arraysize(tests); ++i) {
555 RectF r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
556 Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
558 Rect enclosed = ToEnclosingRect(r1);
559 EXPECT_FLOAT_AND_NAN_EQ(r2.x(), enclosed.x());
560 EXPECT_FLOAT_AND_NAN_EQ(r2.y(), enclosed.y());
561 EXPECT_FLOAT_AND_NAN_EQ(r2.width(), enclosed.width());
562 EXPECT_FLOAT_AND_NAN_EQ(r2.height(), enclosed.height());
566 TEST(RectTest, ToNearestRect) {
567 Rect rect;
568 EXPECT_EQ(rect, ToNearestRect(RectF(rect)));
570 rect = Rect(-1, -1, 3, 3);
571 EXPECT_EQ(rect, ToNearestRect(RectF(rect)));
573 RectF rectf(-1.00001f, -0.999999f, 3.0000001f, 2.999999f);
574 EXPECT_EQ(rect, ToNearestRect(rectf));
577 TEST(RectTest, ToFlooredRect) {
578 static const struct Test {
579 float x1; // source
580 float y1;
581 float w1;
582 float h1;
583 int x2; // target
584 int y2;
585 int w2;
586 int h2;
587 } tests [] = {
588 { 0.0f, 0.0f, 0.0f, 0.0f,
589 0, 0, 0, 0 },
590 { -1.5f, -1.5f, 3.0f, 3.0f,
591 -2, -2, 3, 3 },
592 { -1.5f, -1.5f, 3.5f, 3.5f,
593 -2, -2, 3, 3 },
594 { 20000.5f, 20000.5f, 0.5f, 0.5f,
595 20000, 20000, 0, 0 },
598 for (size_t i = 0; i < arraysize(tests); ++i) {
599 RectF r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
600 Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
602 Rect floored = ToFlooredRectDeprecated(r1);
603 EXPECT_FLOAT_EQ(r2.x(), floored.x());
604 EXPECT_FLOAT_EQ(r2.y(), floored.y());
605 EXPECT_FLOAT_EQ(r2.width(), floored.width());
606 EXPECT_FLOAT_EQ(r2.height(), floored.height());
610 TEST(RectTest, ScaleToEnclosedRect) {
611 static const struct Test {
612 Rect input_rect;
613 float input_scale;
614 Rect expected_rect;
615 } tests[] = {
617 Rect(),
618 5.f,
619 Rect(),
620 }, {
621 Rect(1, 1, 1, 1),
622 5.f,
623 Rect(5, 5, 5, 5),
624 }, {
625 Rect(-1, -1, 0, 0),
626 5.f,
627 Rect(-5, -5, 0, 0),
628 }, {
629 Rect(1, -1, 0, 1),
630 5.f,
631 Rect(5, -5, 0, 5),
632 }, {
633 Rect(-1, 1, 1, 0),
634 5.f,
635 Rect(-5, 5, 5, 0),
636 }, {
637 Rect(1, 2, 3, 4),
638 1.5f,
639 Rect(2, 3, 4, 6),
640 }, {
641 Rect(-1, -2, 0, 0),
642 1.5f,
643 Rect(-1, -3, 0, 0),
647 for (size_t i = 0; i < arraysize(tests); ++i) {
648 Rect result = ScaleToEnclosedRect(tests[i].input_rect,
649 tests[i].input_scale);
650 EXPECT_EQ(tests[i].expected_rect, result);
654 TEST(RectTest, ScaleToEnclosingRect) {
655 static const struct Test {
656 Rect input_rect;
657 float input_scale;
658 Rect expected_rect;
659 } tests[] = {
661 Rect(),
662 5.f,
663 Rect(),
664 }, {
665 Rect(1, 1, 1, 1),
666 5.f,
667 Rect(5, 5, 5, 5),
668 }, {
669 Rect(-1, -1, 0, 0),
670 5.f,
671 Rect(-5, -5, 0, 0),
672 }, {
673 Rect(1, -1, 0, 1),
674 5.f,
675 Rect(5, -5, 0, 5),
676 }, {
677 Rect(-1, 1, 1, 0),
678 5.f,
679 Rect(-5, 5, 5, 0),
680 }, {
681 Rect(1, 2, 3, 4),
682 1.5f,
683 Rect(1, 3, 5, 6),
684 }, {
685 Rect(-1, -2, 0, 0),
686 1.5f,
687 Rect(-2, -3, 0, 0),
691 for (size_t i = 0; i < arraysize(tests); ++i) {
692 Rect result = ScaleToEnclosingRect(tests[i].input_rect,
693 tests[i].input_scale);
694 EXPECT_EQ(tests[i].expected_rect, result);
698 #if defined(OS_WIN)
699 TEST(RectTest, ConstructAndAssign) {
700 const RECT rect_1 = { 0, 0, 10, 10 };
701 const RECT rect_2 = { 0, 0, -10, -10 };
702 Rect test1(rect_1);
703 Rect test2(rect_2);
705 #endif
707 TEST(RectTest, ToRectF) {
708 // Check that explicit conversion from integer to float compiles.
709 Rect a(10, 20, 30, 40);
710 RectF b(10, 20, 30, 40);
712 RectF c = RectF(a);
713 EXPECT_EQ(b, c);
716 TEST(RectTest, BoundingRect) {
717 struct {
718 Point a;
719 Point b;
720 Rect expected;
721 } int_tests[] = {
722 // If point B dominates A, then A should be the origin.
723 { Point(4, 6), Point(4, 6), Rect(4, 6, 0, 0) },
724 { Point(4, 6), Point(8, 6), Rect(4, 6, 4, 0) },
725 { Point(4, 6), Point(4, 9), Rect(4, 6, 0, 3) },
726 { Point(4, 6), Point(8, 9), Rect(4, 6, 4, 3) },
727 // If point A dominates B, then B should be the origin.
728 { Point(4, 6), Point(4, 6), Rect(4, 6, 0, 0) },
729 { Point(8, 6), Point(4, 6), Rect(4, 6, 4, 0) },
730 { Point(4, 9), Point(4, 6), Rect(4, 6, 0, 3) },
731 { Point(8, 9), Point(4, 6), Rect(4, 6, 4, 3) },
732 // If neither point dominates, then the origin is a combination of the two.
733 { Point(4, 6), Point(6, 4), Rect(4, 4, 2, 2) },
734 { Point(-4, -6), Point(-6, -4), Rect(-6, -6, 2, 2) },
735 { Point(-4, 6), Point(6, -4), Rect(-4, -4, 10, 10) },
738 for (size_t i = 0; i < arraysize(int_tests); ++i) {
739 Rect actual = BoundingRect(int_tests[i].a, int_tests[i].b);
740 EXPECT_EQ(int_tests[i].expected, actual);
743 struct {
744 PointF a;
745 PointF b;
746 RectF expected;
747 } float_tests[] = {
748 // If point B dominates A, then A should be the origin.
749 { PointF(4.2f, 6.8f), PointF(4.2f, 6.8f),
750 RectF(4.2f, 6.8f, 0, 0) },
751 { PointF(4.2f, 6.8f), PointF(8.5f, 6.8f),
752 RectF(4.2f, 6.8f, 4.3f, 0) },
753 { PointF(4.2f, 6.8f), PointF(4.2f, 9.3f),
754 RectF(4.2f, 6.8f, 0, 2.5f) },
755 { PointF(4.2f, 6.8f), PointF(8.5f, 9.3f),
756 RectF(4.2f, 6.8f, 4.3f, 2.5f) },
757 // If point A dominates B, then B should be the origin.
758 { PointF(4.2f, 6.8f), PointF(4.2f, 6.8f),
759 RectF(4.2f, 6.8f, 0, 0) },
760 { PointF(8.5f, 6.8f), PointF(4.2f, 6.8f),
761 RectF(4.2f, 6.8f, 4.3f, 0) },
762 { PointF(4.2f, 9.3f), PointF(4.2f, 6.8f),
763 RectF(4.2f, 6.8f, 0, 2.5f) },
764 { PointF(8.5f, 9.3f), PointF(4.2f, 6.8f),
765 RectF(4.2f, 6.8f, 4.3f, 2.5f) },
766 // If neither point dominates, then the origin is a combination of the two.
767 { PointF(4.2f, 6.8f), PointF(6.8f, 4.2f),
768 RectF(4.2f, 4.2f, 2.6f, 2.6f) },
769 { PointF(-4.2f, -6.8f), PointF(-6.8f, -4.2f),
770 RectF(-6.8f, -6.8f, 2.6f, 2.6f) },
771 { PointF(-4.2f, 6.8f), PointF(6.8f, -4.2f),
772 RectF(-4.2f, -4.2f, 11.0f, 11.0f) }
775 for (size_t i = 0; i < arraysize(float_tests); ++i) {
776 RectF actual = BoundingRect(float_tests[i].a, float_tests[i].b);
777 EXPECT_RECTF_EQ(float_tests[i].expected, actual);
781 TEST(RectTest, IsExpressibleAsRect) {
782 EXPECT_TRUE(RectF().IsExpressibleAsRect());
784 float min = std::numeric_limits<int>::min();
785 float max = std::numeric_limits<int>::max();
786 float infinity = std::numeric_limits<float>::infinity();
788 EXPECT_TRUE(RectF(
789 min + 200, min + 200, max - 200, max - 200).IsExpressibleAsRect());
790 EXPECT_FALSE(RectF(
791 min - 200, min + 200, max + 200, max + 200).IsExpressibleAsRect());
792 EXPECT_FALSE(RectF(
793 min + 200 , min - 200, max + 200, max + 200).IsExpressibleAsRect());
794 EXPECT_FALSE(RectF(
795 min + 200, min + 200, max + 200, max - 200).IsExpressibleAsRect());
796 EXPECT_FALSE(RectF(
797 min + 200, min + 200, max - 200, max + 200).IsExpressibleAsRect());
799 EXPECT_TRUE(RectF(0, 0, max - 200, max - 200).IsExpressibleAsRect());
800 EXPECT_FALSE(RectF(200, 0, max + 200, max - 200).IsExpressibleAsRect());
801 EXPECT_FALSE(RectF(0, 200, max - 200, max + 200).IsExpressibleAsRect());
802 EXPECT_FALSE(RectF(0, 0, max + 200, max - 200).IsExpressibleAsRect());
803 EXPECT_FALSE(RectF(0, 0, max - 200, max + 200).IsExpressibleAsRect());
805 EXPECT_FALSE(RectF(infinity, 0, 1, 1).IsExpressibleAsRect());
806 EXPECT_FALSE(RectF(0, infinity, 1, 1).IsExpressibleAsRect());
807 EXPECT_FALSE(RectF(0, 0, infinity, 1).IsExpressibleAsRect());
808 EXPECT_FALSE(RectF(0, 0, 1, infinity).IsExpressibleAsRect());
811 TEST(RectTest, Offset) {
812 Rect i(1, 2, 3, 4);
814 EXPECT_EQ(Rect(2, 1, 3, 4), (i + Vector2d(1, -1)));
815 EXPECT_EQ(Rect(2, 1, 3, 4), (Vector2d(1, -1) + i));
816 i += Vector2d(1, -1);
817 EXPECT_EQ(Rect(2, 1, 3, 4), i);
818 EXPECT_EQ(Rect(1, 2, 3, 4), (i - Vector2d(1, -1)));
819 i -= Vector2d(1, -1);
820 EXPECT_EQ(Rect(1, 2, 3, 4), i);
822 RectF f(1.1f, 2.2f, 3.3f, 4.4f);
823 EXPECT_EQ(RectF(2.2f, 1.1f, 3.3f, 4.4f), (f + Vector2dF(1.1f, -1.1f)));
824 EXPECT_EQ(RectF(2.2f, 1.1f, 3.3f, 4.4f), (Vector2dF(1.1f, -1.1f) + f));
825 f += Vector2dF(1.1f, -1.1f);
826 EXPECT_EQ(RectF(2.2f, 1.1f, 3.3f, 4.4f), f);
827 EXPECT_EQ(RectF(1.1f, 2.2f, 3.3f, 4.4f), (f - Vector2dF(1.1f, -1.1f)));
828 f -= Vector2dF(1.1f, -1.1f);
829 EXPECT_EQ(RectF(1.1f, 2.2f, 3.3f, 4.4f), f);
832 TEST(RectTest, Corners) {
833 Rect i(1, 2, 3, 4);
834 RectF f(1.1f, 2.1f, 3.1f, 4.1f);
836 EXPECT_EQ(Point(1, 2), i.origin());
837 EXPECT_EQ(Point(4, 2), i.top_right());
838 EXPECT_EQ(Point(1, 6), i.bottom_left());
839 EXPECT_EQ(Point(4, 6), i.bottom_right());
841 EXPECT_EQ(PointF(1.1f, 2.1f), f.origin());
842 EXPECT_EQ(PointF(4.2f, 2.1f), f.top_right());
843 EXPECT_EQ(PointF(1.1f, 6.2f), f.bottom_left());
844 EXPECT_EQ(PointF(4.2f, 6.2f), f.bottom_right());
847 TEST(RectTest, ManhattanDistanceToPoint) {
848 Rect i(1, 2, 3, 4);
849 EXPECT_EQ(0, i.ManhattanDistanceToPoint(Point(1, 2)));
850 EXPECT_EQ(0, i.ManhattanDistanceToPoint(Point(4, 6)));
851 EXPECT_EQ(0, i.ManhattanDistanceToPoint(Point(2, 4)));
852 EXPECT_EQ(3, i.ManhattanDistanceToPoint(Point(0, 0)));
853 EXPECT_EQ(2, i.ManhattanDistanceToPoint(Point(2, 0)));
854 EXPECT_EQ(3, i.ManhattanDistanceToPoint(Point(5, 0)));
855 EXPECT_EQ(1, i.ManhattanDistanceToPoint(Point(5, 4)));
856 EXPECT_EQ(3, i.ManhattanDistanceToPoint(Point(5, 8)));
857 EXPECT_EQ(2, i.ManhattanDistanceToPoint(Point(3, 8)));
858 EXPECT_EQ(2, i.ManhattanDistanceToPoint(Point(0, 7)));
859 EXPECT_EQ(1, i.ManhattanDistanceToPoint(Point(0, 3)));
861 RectF f(1.1f, 2.1f, 3.1f, 4.1f);
862 EXPECT_FLOAT_EQ(0.f, f.ManhattanDistanceToPoint(PointF(1.1f, 2.1f)));
863 EXPECT_FLOAT_EQ(0.f, f.ManhattanDistanceToPoint(PointF(4.2f, 6.f)));
864 EXPECT_FLOAT_EQ(0.f, f.ManhattanDistanceToPoint(PointF(2.f, 4.f)));
865 EXPECT_FLOAT_EQ(3.2f, f.ManhattanDistanceToPoint(PointF(0.f, 0.f)));
866 EXPECT_FLOAT_EQ(2.1f, f.ManhattanDistanceToPoint(PointF(2.f, 0.f)));
867 EXPECT_FLOAT_EQ(2.9f, f.ManhattanDistanceToPoint(PointF(5.f, 0.f)));
868 EXPECT_FLOAT_EQ(.8f, f.ManhattanDistanceToPoint(PointF(5.f, 4.f)));
869 EXPECT_FLOAT_EQ(2.6f, f.ManhattanDistanceToPoint(PointF(5.f, 8.f)));
870 EXPECT_FLOAT_EQ(1.8f, f.ManhattanDistanceToPoint(PointF(3.f, 8.f)));
871 EXPECT_FLOAT_EQ(1.9f, f.ManhattanDistanceToPoint(PointF(0.f, 7.f)));
872 EXPECT_FLOAT_EQ(1.1f, f.ManhattanDistanceToPoint(PointF(0.f, 3.f)));
875 TEST(RectTest, ManhattanInternalDistance) {
876 Rect i(0, 0, 400, 400);
877 EXPECT_EQ(0, i.ManhattanInternalDistance(gfx::Rect(-1, 0, 2, 1)));
878 EXPECT_EQ(1, i.ManhattanInternalDistance(gfx::Rect(400, 0, 1, 400)));
879 EXPECT_EQ(2, i.ManhattanInternalDistance(gfx::Rect(-100, -100, 100, 100)));
880 EXPECT_EQ(2, i.ManhattanInternalDistance(gfx::Rect(-101, 100, 100, 100)));
881 EXPECT_EQ(4, i.ManhattanInternalDistance(gfx::Rect(-101, -101, 100, 100)));
882 EXPECT_EQ(435, i.ManhattanInternalDistance(gfx::Rect(630, 603, 100, 100)));
884 RectF f(0.0f, 0.0f, 400.0f, 400.0f);
885 static const float kEpsilon = std::numeric_limits<float>::epsilon();
887 EXPECT_FLOAT_EQ(
888 0.0f, f.ManhattanInternalDistance(gfx::RectF(-1.0f, 0.0f, 2.0f, 1.0f)));
889 EXPECT_FLOAT_EQ(
890 kEpsilon,
891 f.ManhattanInternalDistance(gfx::RectF(400.0f, 0.0f, 1.0f, 400.0f)));
892 EXPECT_FLOAT_EQ(2.0f * kEpsilon,
893 f.ManhattanInternalDistance(
894 gfx::RectF(-100.0f, -100.0f, 100.0f, 100.0f)));
895 EXPECT_FLOAT_EQ(
896 1.0f + kEpsilon,
897 f.ManhattanInternalDistance(gfx::RectF(-101.0f, 100.0f, 100.0f, 100.0f)));
898 EXPECT_FLOAT_EQ(2.0f + 2.0f * kEpsilon,
899 f.ManhattanInternalDistance(
900 gfx::RectF(-101.0f, -101.0f, 100.0f, 100.0f)));
901 EXPECT_FLOAT_EQ(
902 433.0f + 2.0f * kEpsilon,
903 f.ManhattanInternalDistance(gfx::RectF(630.0f, 603.0f, 100.0f, 100.0f)));
905 EXPECT_FLOAT_EQ(
906 0.0f, f.ManhattanInternalDistance(gfx::RectF(-1.0f, 0.0f, 1.1f, 1.0f)));
907 EXPECT_FLOAT_EQ(
908 0.1f + kEpsilon,
909 f.ManhattanInternalDistance(gfx::RectF(-1.5f, 0.0f, 1.4f, 1.0f)));
910 EXPECT_FLOAT_EQ(
911 kEpsilon,
912 f.ManhattanInternalDistance(gfx::RectF(-1.5f, 0.0f, 1.5f, 1.0f)));
915 } // namespace gfx