summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/shapes/BoxShape.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/rendering/shapes/BoxShape.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/rendering/shapes/BoxShape.cpp')
-rw-r--r--Source/WebCore/rendering/shapes/BoxShape.cpp161
1 files changed, 77 insertions, 84 deletions
diff --git a/Source/WebCore/rendering/shapes/BoxShape.cpp b/Source/WebCore/rendering/shapes/BoxShape.cpp
index 25c966875..dba19e76f 100644
--- a/Source/WebCore/rendering/shapes/BoxShape.cpp
+++ b/Source/WebCore/rendering/shapes/BoxShape.cpp
@@ -12,7 +12,7 @@
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@@ -30,10 +30,70 @@
#include "config.h"
#include "BoxShape.h"
+#include "RenderBox.h"
#include <wtf/MathExtras.h>
namespace WebCore {
+static inline LayoutUnit adjustRadiusForMarginBoxShape(LayoutUnit radius, LayoutUnit margin)
+{
+ // This algorithm is defined in the CSS Shapes specifcation
+ if (!margin)
+ return radius;
+
+ LayoutUnit ratio = radius / margin;
+ if (ratio < 1)
+ return radius + (margin * (1 + pow(ratio - 1, 3.0)));
+
+ return radius + margin;
+}
+
+static inline LayoutSize computeMarginBoxShapeRadius(const LayoutSize& radius, const LayoutSize& adjacentMargins)
+{
+ return LayoutSize(adjustRadiusForMarginBoxShape(radius.width(), adjacentMargins.width()),
+ adjustRadiusForMarginBoxShape(radius.height(), adjacentMargins.height()));
+}
+
+static inline RoundedRect::Radii computeMarginBoxShapeRadii(const RoundedRect::Radii& radii, const RenderBox& renderer)
+{
+ return RoundedRect::Radii(computeMarginBoxShapeRadius(radii.topLeft(), LayoutSize(renderer.marginLeft(), renderer.marginTop())),
+ computeMarginBoxShapeRadius(radii.topRight(), LayoutSize(renderer.marginRight(), renderer.marginTop())),
+ computeMarginBoxShapeRadius(radii.bottomLeft(), LayoutSize(renderer.marginLeft(), renderer.marginBottom())),
+ computeMarginBoxShapeRadius(radii.bottomRight(), LayoutSize(renderer.marginRight(), renderer.marginBottom())));
+}
+
+RoundedRect computeRoundedRectForBoxShape(CSSBoxType box, const RenderBox& renderer)
+{
+ const RenderStyle& style = renderer.style();
+ switch (box) {
+ case MarginBox: {
+ if (!style.hasBorderRadius())
+ return RoundedRect(renderer.marginBoxRect(), RoundedRect::Radii());
+
+ LayoutRect marginBox = renderer.marginBoxRect();
+ RoundedRect::Radii radii = computeMarginBoxShapeRadii(style.getRoundedBorderFor(renderer.borderBoxRect()).radii(), renderer);
+ radii.scale(calcBorderRadiiConstraintScaleFor(marginBox, radii));
+ return RoundedRect(marginBox, radii);
+ }
+ case PaddingBox:
+ return style.getRoundedInnerBorderFor(renderer.borderBoxRect());
+ case ContentBox:
+ return style.getRoundedInnerBorderFor(renderer.borderBoxRect(),
+ renderer.paddingTop() + renderer.borderTop(), renderer.paddingBottom() + renderer.borderBottom(),
+ renderer.paddingLeft() + renderer.borderLeft(), renderer.paddingRight() + renderer.borderRight());
+ // fill, stroke, view-box compute to border-box for HTML elements.
+ case BorderBox:
+ case Fill:
+ case Stroke:
+ case ViewBox:
+ case BoxMissing:
+ return style.getRoundedBorderFor(renderer.borderBoxRect());
+ }
+
+ ASSERT_NOT_REACHED();
+ return style.getRoundedBorderFor(renderer.borderBoxRect());
+}
+
LayoutRect BoxShape::shapeMarginLogicalBoundingBox() const
{
FloatRect marginBounds(m_bounds.rect());
@@ -42,14 +102,6 @@ LayoutRect BoxShape::shapeMarginLogicalBoundingBox() const
return static_cast<LayoutRect>(marginBounds);
}
-LayoutRect BoxShape::shapePaddingLogicalBoundingBox() const
-{
- FloatRect paddingBounds(m_bounds.rect());
- if (shapePadding() > 0)
- paddingBounds.inflate(-shapePadding());
- return static_cast<LayoutRect>(paddingBounds);
-}
-
FloatRoundedRect BoxShape::shapeMarginBounds() const
{
FloatRoundedRect marginBounds(m_bounds);
@@ -60,44 +112,36 @@ FloatRoundedRect BoxShape::shapeMarginBounds() const
return marginBounds;
}
-FloatRoundedRect BoxShape::shapePaddingBounds() const
-{
- FloatRoundedRect paddingBounds(m_bounds);
- if (shapePadding() > 0) {
- paddingBounds.inflate(-shapePadding());
- paddingBounds.expandRadii(-shapePadding());
- }
- return paddingBounds;
-}
-
-void BoxShape::getExcludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList& result) const
+LineSegment BoxShape::getExcludedInterval(LayoutUnit logicalTop, LayoutUnit logicalHeight) const
{
const FloatRoundedRect& marginBounds = shapeMarginBounds();
if (marginBounds.isEmpty() || !lineOverlapsShapeMarginBounds(logicalTop, logicalHeight))
- return;
+ return LineSegment();
float y1 = logicalTop;
float y2 = logicalTop + logicalHeight;
const FloatRect& rect = marginBounds.rect();
- if (!marginBounds.isRounded()) {
- result.append(LineSegment(rect.x(), rect.maxX()));
- return;
- }
+ if (!marginBounds.isRounded())
+ return LineSegment(rect.x(), rect.maxX());
float topCornerMaxY = std::max<float>(marginBounds.topLeftCorner().maxY(), marginBounds.topRightCorner().maxY());
float bottomCornerMinY = std::min<float>(marginBounds.bottomLeftCorner().y(), marginBounds.bottomRightCorner().y());
- if (y1 <= topCornerMaxY && y2 >= bottomCornerMinY) {
- result.append(LineSegment(rect.x(), rect.maxX()));
- return;
- }
+ if (topCornerMaxY <= bottomCornerMinY && y1 <= topCornerMaxY && y2 >= bottomCornerMinY)
+ return LineSegment(rect.x(), rect.maxX());
float x1 = rect.maxX();
float x2 = rect.x();
float minXIntercept;
float maxXIntercept;
+ if (y1 <= marginBounds.topLeftCorner().maxY() && y2 >= marginBounds.bottomLeftCorner().y())
+ x1 = rect.x();
+
+ if (y1 <= marginBounds.topRightCorner().maxY() && y2 >= marginBounds.bottomRightCorner().y())
+ x2 = rect.maxX();
+
if (marginBounds.xInterceptsAtY(y1, minXIntercept, maxXIntercept)) {
x1 = std::min<float>(x1, minXIntercept);
x2 = std::max<float>(x2, maxXIntercept);
@@ -109,65 +153,14 @@ void BoxShape::getExcludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHei
}
ASSERT(x2 >= x1);
- result.append(LineSegment(x1, x2));
-}
-
-void BoxShape::getIncludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList& result) const
-{
- const FloatRoundedRect& paddingBounds = shapePaddingBounds();
- if (paddingBounds.isEmpty())
- return;
-
- const FloatRect& rect = paddingBounds.rect();
- float y1 = logicalTop;
- float y2 = logicalTop + logicalHeight;
-
- if (y1 < rect.y() || y2 > rect.maxY())
- return;
-
- if (!paddingBounds.isRounded()) {
- result.append(LineSegment(rect.x(), rect.maxX()));
- return;
- }
-
- float x1 = rect.x();
- float x2 = rect.maxX();
- float minXIntercept;
- float maxXIntercept;
-
- if (paddingBounds.xInterceptsAtY(y1, minXIntercept, maxXIntercept)) {
- x1 = std::max<float>(x1, minXIntercept);
- x2 = std::min<float>(x2, maxXIntercept);
- }
-
- if (paddingBounds.xInterceptsAtY(y2, minXIntercept, maxXIntercept)) {
- x1 = std::max<float>(x1, minXIntercept);
- x2 = std::min<float>(x2, maxXIntercept);
- }
-
- result.append(LineSegment(x1, x2));
-}
-
-bool BoxShape::firstIncludedIntervalLogicalTop(LayoutUnit minLogicalIntervalTop, const FloatSize&, LayoutUnit& result) const
-{
- // FIXME: this method is only a stub, https://bugs.webkit.org/show_bug.cgi?id=124606.
-
- result = minLogicalIntervalTop;
- return true;
-}
-
-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);
+ return LineSegment(x1, x2);
}
void BoxShape::buildDisplayPaths(DisplayPaths& paths) const
{
- addRoundedRect(paths.shape, m_bounds.rect(), m_bounds.radii());
- if (shapeMargin()) {
- const FloatRoundedRect& marginBounds = shapeMarginBounds();
- addRoundedRect(paths.marginShape, marginBounds.rect(), marginBounds.radii());
- }
+ paths.shape.addRoundedRect(m_bounds, Path::PreferBezierRoundedRect);
+ if (shapeMargin())
+ paths.marginShape.addRoundedRect(shapeMarginBounds(), Path::PreferBezierRoundedRect);
}
} // namespace WebCore