/* * 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(); } }
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); }
void PrintTo(const FloatRoundedRect::Radii& radii, std::ostream* os) { *os << radii.toString(); }