Home | History | Annotate | Download | only in geometry
      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 
     36 using namespace blink;
     37 
     38 namespace blink {
     39 
     40 void PrintTo(const FloatSize& size, std::ostream* os)
     41 {
     42     *os << "FloatSize("
     43         << size.width() << ", "
     44         << size.height() << ")";
     45 }
     46 
     47 void 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 
     56 void 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 
     65 void 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 blink
     73 
     74 namespace {
     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 
     85 TEST(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 
    120 TEST(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  */
    165 TEST(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