/*
 * FloatRoundedRect geometry for this test. Corner radii are in parens, x and y intercepts
 * for the elliptical corners are noted. The rectangle itself is at 0,0 with width and height 100.
 *
 *         (10, 15)  x=10      x=90 (10, 20)
 *                (--+---------+--)
 *           y=15 +--|         |-+ y=20
 *                |               |
 *                |               |
 *           y=85 + -|         |- + y=70
 *                (--+---------+--)
 *       (25, 15)  x=25      x=80  (20, 30)
 */
TEST(FloatRoundedRectTest, ellipticalCorners)
{
    FloatSize cornerSize(10, 20);
    FloatRoundedRect::Radii cornerRadii;
    cornerRadii.setTopLeft(FloatSize(10, 15));
    cornerRadii.setTopRight(FloatSize(10, 20));
    cornerRadii.setBottomLeft(FloatSize(25, 15));
    cornerRadii.setBottomRight(FloatSize(20, 30));

    FloatRoundedRect r(FloatRect(0, 0, 100, 100), cornerRadii);

    EXPECT_EQ(r.radii(), FloatRoundedRect::Radii(FloatSize(10, 15), FloatSize(10, 20), FloatSize(25, 15), FloatSize(20, 30)));
    EXPECT_EQ(r, FloatRoundedRect(FloatRect(0, 0, 100, 100), cornerRadii));

    EXPECT_EQ(FloatRect(0, 0, 10, 15), r.topLeftCorner());
    EXPECT_EQ(FloatRect(90, 0, 10, 20), r.topRightCorner());
    EXPECT_EQ(FloatRect(0, 85, 25, 15), r.bottomLeftCorner());
    EXPECT_EQ(FloatRect(80, 70, 20, 30), r.bottomRightCorner());

    TEST_INTERCEPTS(r, 5, 2.5464401, 96.61438);
    TEST_INTERCEPTS(r, 15, 0, 99.682457);
    TEST_INTERCEPTS(r, 20, 0, 100);
    TEST_INTERCEPTS(r, 50, 0, 100);
    TEST_INTERCEPTS(r, 70, 0, 100);
    TEST_INTERCEPTS(r, 85, 0, 97.320511);
    TEST_INTERCEPTS(r, 95, 6.3661003, 91.05542);

    float minXIntercept;
    float maxXIntercept;

    EXPECT_FALSE(r.xInterceptsAtY(-1, minXIntercept, maxXIntercept));
    EXPECT_FALSE(r.xInterceptsAtY(101, minXIntercept, maxXIntercept));
}
void PrintTo(const FloatRoundedRect::Radii& radii, std::ostream* os)
{
    *os << "FloatRoundedRect::Radii("
        << ::testing::PrintToString(radii.topLeft()) << ", "
        << ::testing::PrintToString(radii.topRight()) << ", "
        << ::testing::PrintToString(radii.bottomRight()) << ", "
        << ::testing::PrintToString(radii.bottomLeft()) << ")";
}
void PrintTo(const FloatRoundedRect::Radii& radii, std::ostream* os)
{
    *os << "FloatRoundedRect::Radii(";
    PrintTo(radii.topLeft(), os);
    *os << ", ";
    PrintTo(radii.topRight(), os);
    *os << ", ";
    PrintTo(radii.bottomLeft(), os);
    *os << ", ";
    PrintTo(radii.bottomRight(), os);
    *os << ")";
}
float calcBorderRadiiConstraintScaleFor(const FloatRect& rect, const FloatRoundedRect::Radii& radii)
{
    float factor = 1;
    float radiiSum;

    // top
    radiiSum = radii.topLeft().width() + radii.topRight().width(); // Casts to avoid integer overflow.
    if (radiiSum > rect.width())
        factor = std::min(rect.width() / radiiSum, factor);

    // bottom
    radiiSum = radii.bottomLeft().width() + radii.bottomRight().width();
    if (radiiSum > rect.width())
        factor = std::min(rect.width() / radiiSum, factor);

    // left
    radiiSum = radii.topLeft().height() + radii.bottomLeft().height();
    if (radiiSum > rect.height())
        factor = std::min(rect.height() / radiiSum, factor);

    // right
    radiiSum = radii.topRight().height() + radii.bottomRight().height();
    if (radiiSum > rect.height())
        factor = std::min(rect.height() / radiiSum, factor);

    ASSERT(factor <= 1);
    return factor;
}
void ClipDisplayItem::appendToWebDisplayItemList(const IntRect& visualRect, WebDisplayItemList* list) const
{
    WebVector<SkRRect> webRoundedRects(m_roundedRectClips.size());
    for (size_t i = 0; i < m_roundedRectClips.size(); ++i) {
        FloatRoundedRect::Radii rectRadii = m_roundedRectClips[i].radii();
        SkVector skRadii[4];
        skRadii[SkRRect::kUpperLeft_Corner].set(SkIntToScalar(rectRadii.topLeft().width()),
            SkIntToScalar(rectRadii.topLeft().height()));
        skRadii[SkRRect::kUpperRight_Corner].set(SkIntToScalar(rectRadii.topRight().width()),
            SkIntToScalar(rectRadii.topRight().height()));
        skRadii[SkRRect::kLowerRight_Corner].set(SkIntToScalar(rectRadii.bottomRight().width()),
            SkIntToScalar(rectRadii.bottomRight().height()));
        skRadii[SkRRect::kLowerLeft_Corner].set(SkIntToScalar(rectRadii.bottomLeft().width()),
            SkIntToScalar(rectRadii.bottomLeft().height()));
        SkRRect skRoundedRect;
        skRoundedRect.setRectRadii(m_roundedRectClips[i].rect(), skRadii);
        webRoundedRects[i] = skRoundedRect;
    }
    list->appendClipItem(visualRect, m_clipRect, webRoundedRects);
}
RoundedInnerRectClipper::RoundedInnerRectClipper(LayoutObject& layoutObject, const PaintInfo& paintInfo, const LayoutRect& rect, const FloatRoundedRect& clipRect, RoundedInnerRectClipperBehavior behavior)
    : m_layoutObject(layoutObject)
    , m_paintInfo(paintInfo)
    , m_useDisplayItemList(RuntimeEnabledFeatures::slimmingPaintEnabled() && behavior == ApplyToDisplayListIfEnabled)
    , m_clipType(m_useDisplayItemList ? m_paintInfo.displayItemTypeForClipping() : DisplayItem::ClipBoxPaintPhaseFirst)
{
    Vector<FloatRoundedRect> roundedRectClips;
    if (clipRect.isRenderable()) {
        roundedRectClips.append(clipRect);
    } else {
        // We create a rounded rect for each of the corners and clip it, while making sure we clip opposing corners together.
        if (!clipRect.radii().topLeft().isEmpty() || !clipRect.radii().bottomRight().isEmpty()) {
            FloatRect topCorner(clipRect.rect().x(), clipRect.rect().y(), rect.maxX() - clipRect.rect().x(), rect.maxY() - clipRect.rect().y());
            FloatRoundedRect::Radii topCornerRadii;
            topCornerRadii.setTopLeft(clipRect.radii().topLeft());
            roundedRectClips.append(FloatRoundedRect(topCorner, topCornerRadii));

            FloatRect bottomCorner(rect.x().toFloat(), rect.y().toFloat(), clipRect.rect().maxX() - rect.x().toFloat(), clipRect.rect().maxY() - rect.y().toFloat());
            FloatRoundedRect::Radii bottomCornerRadii;
            bottomCornerRadii.setBottomRight(clipRect.radii().bottomRight());
            roundedRectClips.append(FloatRoundedRect(bottomCorner, bottomCornerRadii));
        }

        if (!clipRect.radii().topRight().isEmpty() || !clipRect.radii().bottomLeft().isEmpty()) {
            FloatRect topCorner(rect.x().toFloat(), clipRect.rect().y(), clipRect.rect().maxX() - rect.x().toFloat(), rect.maxY() - clipRect.rect().y());
            FloatRoundedRect::Radii topCornerRadii;
            topCornerRadii.setTopRight(clipRect.radii().topRight());
            roundedRectClips.append(FloatRoundedRect(topCorner, topCornerRadii));

            FloatRect bottomCorner(clipRect.rect().x(), rect.y().toFloat(), rect.maxX() - clipRect.rect().x(), clipRect.rect().maxY() - rect.y().toFloat());
            FloatRoundedRect::Radii bottomCornerRadii;
            bottomCornerRadii.setBottomLeft(clipRect.radii().bottomLeft());
            roundedRectClips.append(FloatRoundedRect(bottomCorner, bottomCornerRadii));
        }
    }

    if (m_useDisplayItemList) {
        ASSERT(m_paintInfo.context->displayItemList());
        if (m_paintInfo.context->displayItemList()->displayItemConstructionIsDisabled())
            return;
        m_paintInfo.context->displayItemList()->createAndAppend<ClipDisplayItem>(layoutObject, m_clipType, LayoutRect::infiniteIntRect(), roundedRectClips);
    } else {
        ClipDisplayItem clipDisplayItem(layoutObject, m_clipType, LayoutRect::infiniteIntRect(), roundedRectClips);
        clipDisplayItem.replay(*paintInfo.context);
    }
}
void FloatRoundedRect::Radii::includeLogicalEdges(const FloatRoundedRect::Radii& edges, bool isHorizontal, bool includeLogicalLeftEdge, bool includeLogicalRightEdge)
{
    if (includeLogicalLeftEdge) {
        if (isHorizontal)
            m_bottomLeft = edges.bottomLeft();
        else
            m_topRight = edges.topRight();
        m_topLeft = edges.topLeft();
    }

    if (includeLogicalRightEdge) {
        if (isHorizontal)
            m_topRight = edges.topRight();
        else
            m_bottomLeft = edges.bottomLeft();
        m_bottomRight = edges.bottomRight();
    }
}
Exemple #8
0
static void addRoundedRect(Path& path, const FloatRect& rect, const FloatRoundedRect::Radii& radii)
{
    path.addRoundedRect(rect, radii.topLeft(), radii.topRight(), radii.bottomLeft(), radii.bottomRight(), Path::PreferBezierRoundedRect);
}
Exemple #9
0
void PrintTo(const FloatRoundedRect::Radii& radii, std::ostream* os) {
  *os << radii.toString();
}