1/* 2 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer. 11 * 2. Redistributions in binary form must reproduce the above 12 * copyright notice, this list of conditions and the following 13 * disclaimer in the documentation and/or other materials 14 * provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 20 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 27 * OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#include "config.h" 31 32#include "platform/geometry/FloatRoundedRect.h" 33 34#include <gtest/gtest.h> 35 36using namespace WebCore; 37 38namespace WebCore { 39 40void PrintTo(const FloatSize& size, std::ostream* os) 41{ 42 *os << "FloatSize(" 43 << size.width() << ", " 44 << size.height() << ")"; 45} 46 47void PrintTo(const FloatRect& rect, std::ostream* os) 48{ 49 *os << "FloatRect(" 50 << rect.x() << ", " 51 << rect.y() << ", " 52 << rect.width() << ", " 53 << rect.height() << ")"; 54} 55 56void PrintTo(const FloatRoundedRect::Radii& radii, std::ostream* os) 57{ 58 *os << "FloatRoundedRect::Radii(" 59 << ::testing::PrintToString(radii.topLeft()) << ", " 60 << ::testing::PrintToString(radii.topRight()) << ", " 61 << ::testing::PrintToString(radii.bottomRight()) << ", " 62 << ::testing::PrintToString(radii.bottomLeft()) << ")"; 63} 64 65void PrintTo(const FloatRoundedRect& roundedRect, std::ostream* os) 66{ 67 *os << "FloatRoundedRect(" 68 << ::testing::PrintToString(roundedRect.rect()) << ", " 69 << ::testing::PrintToString(roundedRect.radii()) << ")"; 70} 71 72} // namespace WebCore 73 74namespace { 75 76#define TEST_INTERCEPTS(roundedRect, yCoordinate, expectedMinXIntercept, expectedMaxXIntercept) \ 77{ \ 78 float minXIntercept; \ 79 float maxXIntercept; \ 80 EXPECT_TRUE(roundedRect.xInterceptsAtY(yCoordinate, minXIntercept, maxXIntercept)); \ 81 EXPECT_FLOAT_EQ(expectedMinXIntercept, minXIntercept); \ 82 EXPECT_FLOAT_EQ(expectedMaxXIntercept, maxXIntercept); \ 83} 84 85TEST(FloatRoundedRectTest, zeroRadii) 86{ 87 FloatRoundedRect r = FloatRoundedRect(1, 2, 3, 4); 88 89 EXPECT_EQ(FloatRect(1, 2, 3, 4), r.rect()); 90 EXPECT_EQ(FloatSize(), r.radii().topLeft()); 91 EXPECT_EQ(FloatSize(), r.radii().topRight()); 92 EXPECT_EQ(FloatSize(), r.radii().bottomLeft()); 93 EXPECT_EQ(FloatSize(), r.radii().bottomRight()); 94 EXPECT_TRUE(r.radii().isZero()); 95 EXPECT_FALSE(r.isRounded()); 96 EXPECT_FALSE(r.isEmpty()); 97 98 EXPECT_EQ(FloatRect(1, 2, 0, 0), r.topLeftCorner()); 99 EXPECT_EQ(FloatRect(4, 2, 0, 0), r.topRightCorner()); 100 EXPECT_EQ(FloatRect(4, 6, 0, 0), r.bottomRightCorner()); 101 EXPECT_EQ(FloatRect(1, 6, 0, 0), r.bottomLeftCorner()); 102 103 TEST_INTERCEPTS(r, 2, r.rect().x(), r.rect().maxX()); 104 TEST_INTERCEPTS(r, 4, r.rect().x(), r.rect().maxX()); 105 TEST_INTERCEPTS(r, 6, r.rect().x(), r.rect().maxX()); 106 107 float minXIntercept; 108 float maxXIntercept; 109 110 EXPECT_FALSE(r.xInterceptsAtY(1, minXIntercept, maxXIntercept)); 111 EXPECT_FALSE(r.xInterceptsAtY(7, minXIntercept, maxXIntercept)); 112 113 // The FloatRoundedRect::expandRadii() function doesn't change radii FloatSizes that 114 // are <= zero. Same as RoundedRect::expandRadii(). 115 r.expandRadii(20); 116 r.shrinkRadii(10); 117 EXPECT_TRUE(r.radii().isZero()); 118} 119 120TEST(FloatRoundedRectTest, circle) 121{ 122 FloatSize cornerRadii(50, 50); 123 FloatRoundedRect r(FloatRect(0, 0, 100, 100), cornerRadii, cornerRadii, cornerRadii, cornerRadii); 124 125 EXPECT_EQ(FloatRect(0, 0, 100, 100), r.rect()); 126 EXPECT_EQ(cornerRadii, r.radii().topLeft()); 127 EXPECT_EQ(cornerRadii, r.radii().topRight()); 128 EXPECT_EQ(cornerRadii, r.radii().bottomLeft()); 129 EXPECT_EQ(cornerRadii, r.radii().bottomRight()); 130 EXPECT_FALSE(r.radii().isZero()); 131 EXPECT_TRUE(r.isRounded()); 132 EXPECT_FALSE(r.isEmpty()); 133 134 EXPECT_EQ(FloatRect(0, 0, 50, 50), r.topLeftCorner()); 135 EXPECT_EQ(FloatRect(50, 0, 50, 50), r.topRightCorner()); 136 EXPECT_EQ(FloatRect(0, 50, 50, 50), r.bottomLeftCorner()); 137 EXPECT_EQ(FloatRect(50, 50, 50, 50), r.bottomRightCorner()); 138 139 TEST_INTERCEPTS(r, 0, 50, 50); 140 TEST_INTERCEPTS(r, 25, 6.69873, 93.3013); 141 TEST_INTERCEPTS(r, 50, 0, 100); 142 TEST_INTERCEPTS(r, 75, 6.69873, 93.3013); 143 TEST_INTERCEPTS(r, 100, 50, 50); 144 145 float minXIntercept; 146 float maxXIntercept; 147 148 EXPECT_FALSE(r.xInterceptsAtY(-1, minXIntercept, maxXIntercept)); 149 EXPECT_FALSE(r.xInterceptsAtY(101, minXIntercept, maxXIntercept)); 150} 151 152/* 153 * FloatRoundedRect geometry for this test. Corner radii are in parens, x and y intercepts 154 * for the elliptical corners are noted. The rectangle itself is at 0,0 with width and height 100. 155 * 156 * (10, 15) x=10 x=90 (10, 20) 157 * (--+---------+--) 158 * y=15 +--| |-+ y=20 159 * | | 160 * | | 161 * y=85 + -| |- + y=70 162 * (--+---------+--) 163 * (25, 15) x=25 x=80 (20, 30) 164 */ 165TEST(FloatRoundedRectTest, ellipticalCorners) 166{ 167 FloatSize cornerSize(10, 20); 168 FloatRoundedRect::Radii cornerRadii; 169 cornerRadii.setTopLeft(FloatSize(10, 15)); 170 cornerRadii.setTopRight(FloatSize(10, 20)); 171 cornerRadii.setBottomLeft(FloatSize(25, 15)); 172 cornerRadii.setBottomRight(FloatSize(20, 30)); 173 174 FloatRoundedRect r(FloatRect(0, 0, 100, 100), cornerRadii); 175 176 EXPECT_EQ(r.radii(), FloatRoundedRect::Radii(FloatSize(10, 15), FloatSize(10, 20), FloatSize(25, 15), FloatSize(20, 30))); 177 EXPECT_EQ(r, FloatRoundedRect(FloatRect(0, 0, 100, 100), cornerRadii)); 178 179 EXPECT_EQ(FloatRect(0, 0, 10, 15), r.topLeftCorner()); 180 EXPECT_EQ(FloatRect(90, 0, 10, 20), r.topRightCorner()); 181 EXPECT_EQ(FloatRect(0, 85, 25, 15), r.bottomLeftCorner()); 182 EXPECT_EQ(FloatRect(80, 70, 20, 30), r.bottomRightCorner()); 183 184 TEST_INTERCEPTS(r, 5, 2.5464401, 96.61438); 185 TEST_INTERCEPTS(r, 15, 0, 99.682457); 186 TEST_INTERCEPTS(r, 20, 0, 100); 187 TEST_INTERCEPTS(r, 50, 0, 100); 188 TEST_INTERCEPTS(r, 70, 0, 100); 189 TEST_INTERCEPTS(r, 85, 0, 97.320511); 190 TEST_INTERCEPTS(r, 95, 6.3661003, 91.05542); 191 192 float minXIntercept; 193 float maxXIntercept; 194 195 EXPECT_FALSE(r.xInterceptsAtY(-1, minXIntercept, maxXIntercept)); 196 EXPECT_FALSE(r.xInterceptsAtY(101, minXIntercept, maxXIntercept)); 197} 198 199} // namespace 200 201