15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/geometry/quad_f.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/geometry/rect_f.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx { 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(QuadTest, Construction) { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify constructors. 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF a(1, 1); 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF b(2, 1); 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF c(2, 2); 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF d(1, 2); 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF e; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuadF q1; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuadF q2(e, e, e, e); 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuadF q3(a, b, c, d); 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuadF q4(BoundingRect(a, c)); 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(q1, q2); 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(q3, q4); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify getters. 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(q3.p1(), a); 28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(q3.p2(), b); 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(q3.p3(), c); 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(q3.p4(), d); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify setters. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q3.set_p1(b); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q3.set_p2(c); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q3.set_p3(d); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q3.set_p4(a); 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(q3.p1(), b); 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(q3.p2(), c); 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(q3.p3(), d); 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(q3.p4(), a); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify operator=(Rect) 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_NE(q1, q4); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q1 = BoundingRect(a, c); 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(q1, q4); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify operator=(Quad) 48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_NE(q1, q3); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q1 = q3; 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(q1, q3); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(QuadTest, AddingVectors) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF a(1, 1); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF b(2, 1); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF c(2, 2); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF d(1, 2); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Vector2dF v(3.5f, -2.5f); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuadF q1(a, b, c, d); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuadF added = q1 + v; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q1 += v; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuadF expected1(PointF(4.5f, -1.5f), 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(5.5f, -1.5f), 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(5.5f, -0.5f), 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(4.5f, -0.5f)); 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(expected1, added); 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(expected1, q1); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuadF q2(a, b, c, d); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuadF subtracted = q2 - v; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q2 -= v; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuadF expected2(PointF(-2.5f, 3.5f), 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(-1.5f, 3.5f), 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(-1.5f, 4.5f), 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(-2.5f, 4.5f)); 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(expected2, subtracted); 78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(expected2, q2); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuadF q3(a, b, c, d); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q3 += v; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q3 -= v; 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(QuadF(a, b, c, d), q3); 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(q3, (q3 + v - v)); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(QuadTest, IsRectilinear) { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF a(1, 1); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF b(2, 1); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF c(2, 2); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF d(1, 2); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Vector2dF v(3.5f, -2.5f); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF().IsRectilinear()); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a, b, c, d).IsRectilinear()); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE((QuadF(a, b, c, d) + v).IsRectilinear()); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float epsilon = std::numeric_limits<float>::epsilon(); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF a2(1 + epsilon / 2, 1 + epsilon / 2); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF b2(2 + epsilon / 2, 1 + epsilon / 2); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF c2(2 + epsilon / 2, 2 + epsilon / 2); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF d2(1 + epsilon / 2, 2 + epsilon / 2); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a2, b, c, d).IsRectilinear()); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE((QuadF(a2, b, c, d) + v).IsRectilinear()); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a, b2, c, d).IsRectilinear()); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE((QuadF(a, b2, c, d) + v).IsRectilinear()); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a, b, c2, d).IsRectilinear()); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE((QuadF(a, b, c2, d) + v).IsRectilinear()); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a, b, c, d2).IsRectilinear()); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE((QuadF(a, b, c, d2) + v).IsRectilinear()); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF a_off, b_off, c_off, d_off; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } tests[] = { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(1, 1.00001f), 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(2, 1.00001f), 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(2, 2.00001f), 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(1, 2.00001f) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(1.00001f, 1), 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(2.00001f, 1), 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(2.00001f, 2), 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(1.00001f, 2) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(1.00001f, 1.00001f), 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(2.00001f, 1.00001f), 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(2.00001f, 2.00001f), 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(1.00001f, 2.00001f) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(1, 0.99999f), 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(2, 0.99999f), 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(2, 1.99999f), 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(1, 1.99999f) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(0.99999f, 1), 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(1.99999f, 1), 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(1.99999f, 2), 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(0.99999f, 2) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(0.99999f, 0.99999f), 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(1.99999f, 0.99999f), 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(1.99999f, 1.99999f), 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF(0.99999f, 1.99999f) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF a_off = tests[i].a_off; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF b_off = tests[i].b_off; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF c_off = tests[i].c_off; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF d_off = tests[i].d_off; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a_off, b, c, d).IsRectilinear()); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE((QuadF(a_off, b, c, d) + v).IsRectilinear()); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a, b_off, c, d).IsRectilinear()); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE((QuadF(a, b_off, c, d) + v).IsRectilinear()); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a, b, c_off, d).IsRectilinear()); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE((QuadF(a, b, c_off, d) + v).IsRectilinear()); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a, b, c, d_off).IsRectilinear()); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE((QuadF(a, b, c, d_off) + v).IsRectilinear()); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a_off, b, c_off, d).IsRectilinear()); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE((QuadF(a_off, b, c_off, d) + v).IsRectilinear()); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a, b_off, c, d_off).IsRectilinear()); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE((QuadF(a, b_off, c, d_off) + v).IsRectilinear()); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a, b_off, c_off, d_off).IsRectilinear()); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE((QuadF(a, b_off, c_off, d_off) + v).IsRectilinear()); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a_off, b, c_off, d_off).IsRectilinear()); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE((QuadF(a_off, b, c_off, d_off) + v).IsRectilinear()); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a_off, b_off, c, d_off).IsRectilinear()); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE((QuadF(a_off, b_off, c, d_off) + v).IsRectilinear()); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a_off, b_off, c_off, d).IsRectilinear()); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE((QuadF(a_off, b_off, c_off, d) + v).IsRectilinear()); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a_off, b_off, c_off, d_off).IsRectilinear()); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE((QuadF(a_off, b_off, c_off, d_off) + v).IsRectilinear()); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(QuadTest, IsCounterClockwise) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF a1(1, 1); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF b1(2, 1); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF c1(2, 2); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF d1(1, 2); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a1, b1, c1, d1).IsCounterClockwise()); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(b1, c1, d1, a1).IsCounterClockwise()); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a1, d1, c1, b1).IsCounterClockwise()); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(c1, b1, a1, d1).IsCounterClockwise()); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Slightly more complicated quads should work just as easily. 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF a2(1.3f, 1.4f); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF b2(-0.7f, 4.9f); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF c2(1.8f, 6.2f); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF d2(2.1f, 1.6f); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a2, b2, c2, d2).IsCounterClockwise()); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(b2, c2, d2, a2).IsCounterClockwise()); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a2, d2, c2, b2).IsCounterClockwise()); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(c2, b2, a2, d2).IsCounterClockwise()); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Quads with 3 collinear points should work correctly, too. 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF a3(0, 0); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF b3(1, 0); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF c3(2, 0); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF d3(1, 1); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a3, b3, c3, d3).IsCounterClockwise()); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(b3, c3, d3, a3).IsCounterClockwise()); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a3, d3, c3, b3).IsCounterClockwise()); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The next expectation in particular would fail for an implementation 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that incorrectly uses only a cross product of the first 3 vertices. 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(c3, b3, a3, d3).IsCounterClockwise()); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Non-convex quads should work correctly, too. 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF a4(0, 0); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF b4(1, 1); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF c4(2, 0); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF d4(1, 3); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a4, b4, c4, d4).IsCounterClockwise()); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(b4, c4, d4, a4).IsCounterClockwise()); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a4, d4, c4, b4).IsCounterClockwise()); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(c4, b4, a4, d4).IsCounterClockwise()); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A quad with huge coordinates should not fail this check due to 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // single-precision overflow. 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF a5(1e30f, 1e30f); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF b5(1e35f, 1e30f); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF c5(1e35f, 1e35f); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF d5(1e30f, 1e35f); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a5, b5, c5, d5).IsCounterClockwise()); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(b5, c5, d5, a5).IsCounterClockwise()); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a5, d5, c5, b5).IsCounterClockwise()); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(c5, b5, a5, d5).IsCounterClockwise()); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(QuadTest, BoundingBox) { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RectF r(3.2f, 5.4f, 7.007f, 12.01f); 240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(r, QuadF(r).BoundingBox()); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF a(1.3f, 1.4f); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF b(-0.7f, 4.9f); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF c(1.8f, 6.2f); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF d(2.1f, 1.6f); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float left = -0.7f; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float top = 1.4f; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float right = 2.1f; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float bottom = 6.2f; 250116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(RectF(left, top, right - left, bottom - top), 251116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch QuadF(a, b, c, d).BoundingBox()); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(QuadTest, ContainsPoint) { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF a(1.3f, 1.4f); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF b(-0.8f, 4.4f); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF c(1.8f, 6.1f); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF d(2.1f, 1.6f); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Vector2dF epsilon_x(2 * std::numeric_limits<float>::epsilon(), 0); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Vector2dF epsilon_y(0, 2 * std::numeric_limits<float>::epsilon()); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Vector2dF ac_center = c - a; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ac_center.Scale(0.5f); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Vector2dF bd_center = d - b; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bd_center.Scale(0.5f); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a, b, c, d).Contains(a + ac_center)); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a, b, c, d).Contains(b + bd_center)); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a, b, c, d).Contains(c - ac_center)); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a, b, c, d).Contains(d - bd_center)); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a, b, c, d).Contains(a - ac_center)); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a, b, c, d).Contains(b - bd_center)); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a, b, c, d).Contains(c + ac_center)); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a, b, c, d).Contains(d + bd_center)); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a, b, c, d).Contains(a)); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a, b, c, d).Contains(a - epsilon_x)); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a, b, c, d).Contains(a - epsilon_y)); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a, b, c, d).Contains(a + epsilon_x)); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a, b, c, d).Contains(a + epsilon_y)); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a, b, c, d).Contains(b)); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a, b, c, d).Contains(b - epsilon_x)); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a, b, c, d).Contains(b - epsilon_y)); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a, b, c, d).Contains(b + epsilon_x)); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a, b, c, d).Contains(b + epsilon_y)); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a, b, c, d).Contains(c)); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a, b, c, d).Contains(c - epsilon_x)); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a, b, c, d).Contains(c - epsilon_y)); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a, b, c, d).Contains(c + epsilon_x)); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a, b, c, d).Contains(c + epsilon_y)); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a, b, c, d).Contains(d)); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(a, b, c, d).Contains(d - epsilon_x)); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a, b, c, d).Contains(d - epsilon_y)); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a, b, c, d).Contains(d + epsilon_x)); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(a, b, c, d).Contains(d + epsilon_y)); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test a simple square. 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF s1(-1, -1); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF s2(1, -1); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF s3(1, 1); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF s4(-1, 1); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Top edge. 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.1f, -1.0f))); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.0f, -1.0f))); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(0.0f, -1.0f))); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(1.0f, -1.0f))); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(1.1f, -1.0f))); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Bottom edge. 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.1f, 1.0f))); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.0f, 1.0f))); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(0.0f, 1.0f))); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(1.0f, 1.0f))); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(1.1f, 1.0f))); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Left edge. 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.0f, -1.1f))); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.0f, -1.0f))); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.0f, 0.0f))); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.0f, 1.0f))); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.0f, 1.1f))); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Right edge. 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(1.0f, -1.1f))); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(1.0f, -1.0f))); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(1.0f, 0.0f))); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(1.0f, 1.0f))); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(1.0f, 1.1f))); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Centered inside. 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(QuadF(s1, s2, s3, s4).Contains(PointF(0, 0))); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Centered outside. 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(-1.1f, 0))); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(1.1f, 0))); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(0, -1.1f))); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(QuadF(s1, s2, s3, s4).Contains(PointF(0, 1.1f))); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(QuadTest, Scale) { 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF a(1.3f, 1.4f); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF b(-0.8f, 4.4f); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF c(1.8f, 6.1f); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF d(2.1f, 1.6f); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuadF q1(a, b, c, d); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q1.Scale(1.5f); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF a_scaled = ScalePoint(a, 1.5f); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF b_scaled = ScalePoint(b, 1.5f); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF c_scaled = ScalePoint(c, 1.5f); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointF d_scaled = ScalePoint(d, 1.5f); 351116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(q1, QuadF(a_scaled, b_scaled, c_scaled, d_scaled)); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuadF q2; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q2.Scale(1.5f); 355116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(q2, q2); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gfx 359