Diff
Modified: trunk/Source/WebCore/ChangeLog (270214 => 270215)
--- trunk/Source/WebCore/ChangeLog 2020-11-28 04:31:41 UTC (rev 270214)
+++ trunk/Source/WebCore/ChangeLog 2020-11-28 05:17:21 UTC (rev 270215)
@@ -1,5 +1,67 @@
2020-11-27 Simon Fraser <[email protected]>
+ [LFC Display] Implement basic overflow:hidden clipping
+ https://bugs.webkit.org/show_bug.cgi?id=219311
+
+ Reviewed by Zalan Bujtas.
+
+ Add BoxClip which represents the clip generated by walking the containing block ancestor chain
+ of a box. Display::BoxModelBox optionally has a BoxClip if it's a box that paints out of order
+ (i.e. participates in z-order sorting, so positioned or stacking context). That BoxClip
+ represents the clip contributed by ancestors, and it's applied before painting this box.
+ If a Box has overflow clip, then that is also additionally applied before painting the
+ in-flow descendants of the box.
+
+ To compute BoxClip, ask the display box for the relevant containing block for its clip,
+ which takes the clip from ancestors and appends the clip for that box (if any).
+
+ Also move accessors for borderRoundedRect() and innerBorderRoundedRect() onto Display::BoxModelBox
+ since they are needed for clipping as well as painting.
+
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * display/css/DisplayBoxClip.cpp: Copied from Source/WebCore/display/css/DisplayBoxModelBox.cpp.
+ (WebCore::Display::BoxClip::BoxClip):
+ (WebCore::Display::BoxClip::copy const):
+ (WebCore::Display::BoxClip::pushClip):
+ (WebCore::Display::BoxClip::pushRoundedClip):
+ * display/css/DisplayBoxClip.h: Copied from Source/WebCore/display/css/DisplayBoxModelBox.cpp.
+ (WebCore::Display::BoxClip::create):
+ (WebCore::Display::BoxClip::clipRect const):
+ (WebCore::Display::BoxClip::affectedByBorderRadius const):
+ (WebCore::Display::BoxClip::clipStack const):
+ * display/css/DisplayBoxDecorationData.cpp:
+ (WebCore::Display::roundedRectWithIncludedRadii):
+ (WebCore::Display::roundedInsetBorderForRect):
+ * display/css/DisplayBoxDecorationData.h:
+ * display/css/DisplayBoxDecorationPainter.cpp:
+ (WebCore::Display::BoxDecorationPainter::innerBorderRoundedRect const):
+ (WebCore::Display::roundedRectWithIncludedRadii): Deleted.
+ (WebCore::Display::roundedInsetBorderForRect): Deleted.
+ * display/css/DisplayBoxFactory.cpp:
+ (WebCore::Display::BoxFactory::setupBoxModelBox const):
+ * display/css/DisplayBoxModelBox.cpp:
+ (WebCore::Display::BoxModelBox::borderRoundedRect const):
+ (WebCore::Display::BoxModelBox::innerBorderRoundedRect const):
+ (WebCore::Display::BoxModelBox::setAncestorClip):
+ (WebCore::Display::BoxModelBox::clipForDescendants const):
+ (WebCore::Display::BoxModelBox::debugDescription const):
+ * display/css/DisplayBoxModelBox.h:
+ (WebCore::Display::BoxModelBox::ancestorClip const):
+ * display/css/DisplayCSSPainter.cpp:
+ (WebCore::Display::applyClipIfNecessary):
+ (WebCore::Display::applyAncestorClip):
+ (WebCore::Display::CSSPainter::recursivePaintDescendantsForPhase):
+ (WebCore::Display::CSSPainter::paintAtomicallyPaintedBox):
+ * display/css/DisplayContainerBox.cpp:
+ (WebCore::Display::ContainerBox::debugDescription const):
+ * display/css/DisplayStyle.cpp:
+ (WebCore::Display::Style::Style):
+ * display/css/DisplayStyle.h:
+ (WebCore::Display::Style::hasClippedOverflow const):
+
+2020-11-27 Simon Fraser <[email protected]>
+
[LFC Display] Fix box locations for positioned elements
https://bugs.webkit.org/show_bug.cgi?id=219310
Modified: trunk/Source/WebCore/Sources.txt (270214 => 270215)
--- trunk/Source/WebCore/Sources.txt 2020-11-28 04:31:41 UTC (rev 270214)
+++ trunk/Source/WebCore/Sources.txt 2020-11-28 05:17:21 UTC (rev 270215)
@@ -834,6 +834,7 @@
css/typedom/TypedOMCSSUnparsedValue.cpp
cssjit/SelectorCompiler.cpp
display/css/DisplayBox.cpp
+display/css/DisplayBoxClip.cpp
display/css/DisplayBoxDecorationData.cpp
display/css/DisplayBoxDecorationPainter.cpp
display/css/DisplayBoxFactory.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (270214 => 270215)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2020-11-28 04:31:41 UTC (rev 270214)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2020-11-28 05:17:21 UTC (rev 270215)
@@ -6103,6 +6103,8 @@
0FB6252D18DE1B1500A07C05 /* GeometryUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GeometryUtilities.h; sourceTree = "<group>"; };
0FB8890C167D30160010CDA5 /* ScrollingStateStickyNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollingStateStickyNode.cpp; sourceTree = "<group>"; };
0FB8890D167D30160010CDA5 /* ScrollingStateStickyNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollingStateStickyNode.h; sourceTree = "<group>"; };
+ 0FBFCE24256CBD9A00A0B489 /* DisplayBoxClip.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DisplayBoxClip.cpp; sourceTree = "<group>"; };
+ 0FBFCE26256CBD9A00A0B489 /* DisplayBoxClip.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DisplayBoxClip.h; sourceTree = "<group>"; };
0FC05168219B5EBE0031C39E /* ScrollingTreeOverflowScrollingNodeMac.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ScrollingTreeOverflowScrollingNodeMac.mm; sourceTree = "<group>"; };
0FC0516A219B5EBE0031C39E /* ScrollingTreeOverflowScrollingNodeMac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScrollingTreeOverflowScrollingNodeMac.h; sourceTree = "<group>"; };
0FC4B00422B9A02C00CF3B1E /* ScrollingTreeOverflowScrollProxyNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollingTreeOverflowScrollProxyNode.h; sourceTree = "<group>"; };
@@ -17810,6 +17812,8 @@
children = (
0FFF1B72251BC6570098795A /* DisplayBox.cpp */,
0FFF1B78251BC6570098795A /* DisplayBox.h */,
+ 0FBFCE24256CBD9A00A0B489 /* DisplayBoxClip.cpp */,
+ 0FBFCE26256CBD9A00A0B489 /* DisplayBoxClip.h */,
0F94722B2534B04500F153C8 /* DisplayBoxDecorationData.cpp */,
0F9472292534B04500F153C8 /* DisplayBoxDecorationData.h */,
0F638E462557237700974668 /* DisplayBoxDecorationPainter.cpp */,
@@ -18022,7 +18026,6 @@
A1CC564A1F4613BB00A4555B /* PaymentRequest */,
1D00269A2374B9F800CA6CDF /* PictureInPicture */,
A9D247F90D757E4100FDF959 /* Plugins */,
- 89F60B17157F6A020075E157 /* Quota */,
BC9854460CD3DA5F00069BC1 /* Ranges */,
CD8C6C2422FDDA6400A720AB /* RemotePlayback */,
5182C24C1F3142090059BA7C /* ServiceWorkers */,
Copied: trunk/Source/WebCore/display/css/DisplayBoxClip.cpp (from rev 270214, trunk/Source/WebCore/display/css/DisplayBoxModelBox.cpp) (0 => 270215)
--- trunk/Source/WebCore/display/css/DisplayBoxClip.cpp (rev 0)
+++ trunk/Source/WebCore/display/css/DisplayBoxClip.cpp 2020-11-28 05:17:21 UTC (rev 270215)
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above 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 APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DisplayBoxClip.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "RenderStyle.h"
+
+namespace WebCore {
+namespace Display {
+
+BoxClip::BoxClip() = default;
+BoxClip::~BoxClip() = default;
+
+BoxClip::BoxClip(const BoxClip& other)
+ : m_clipRect(other.clipRect())
+ , m_clipStack(other.clipStack())
+ , m_affectedByBorderRadius(other.affectedByBorderRadius())
+{
+}
+
+Ref<BoxClip> BoxClip::copy() const
+{
+ return adoptRef(*new BoxClip(*this));
+}
+
+void BoxClip::pushClip(const AbsoluteFloatRect& rect)
+{
+ if (m_clipRect) {
+ m_clipRect->intersect(rect);
+ return;
+ }
+
+ m_clipRect = rect;
+}
+
+void BoxClip::pushRoundedClip(const FloatRoundedRect& roundedRect)
+{
+ ASSERT(roundedRect.isRounded());
+ pushClip(roundedRect.rect());
+
+ m_affectedByBorderRadius = true;
+ m_clipStack.append(roundedRect);
+}
+
+
+
+} // namespace Display
+} // namespace WebCore
+
+#endif // ENABLE(LAYOUT_FORMATTING_CONTEXT)
Copied: trunk/Source/WebCore/display/css/DisplayBoxClip.h (from rev 270214, trunk/Source/WebCore/display/css/DisplayBoxModelBox.cpp) (0 => 270215)
--- trunk/Source/WebCore/display/css/DisplayBoxClip.h (rev 0)
+++ trunk/Source/WebCore/display/css/DisplayBoxClip.h 2020-11-28 05:17:21 UTC (rev 270215)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above 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 APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "DisplayBox.h"
+#include "FloatRoundedRect.h"
+#include "RectEdges.h"
+#include <utility>
+#include <wtf/IsoMalloc.h>
+#include <wtf/Optional.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class RenderStyle;
+
+namespace Layout {
+class Box;
+class BoxGeometry;
+}
+
+namespace Display {
+
+class BoxClip : public RefCounted<BoxClip> {
+ WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(BoxClip);
+public:
+ ~BoxClip();
+
+ static Ref<BoxClip> create() { return adoptRef(*new BoxClip); }
+ Ref<BoxClip> copy() const;
+
+ Optional<AbsoluteFloatRect> clipRect() const { return m_clipRect; }
+
+ bool affectedByBorderRadius() const { return m_affectedByBorderRadius; }
+ const Vector<FloatRoundedRect>& clipStack() const { return m_clipStack; }
+
+ void pushClip(const AbsoluteFloatRect&);
+ void pushRoundedClip(const FloatRoundedRect&);
+
+private:
+ BoxClip();
+ BoxClip(const BoxClip&);
+
+ Optional<AbsoluteFloatRect> m_clipRect;
+ Vector<FloatRoundedRect> m_clipStack;
+ bool m_affectedByBorderRadius { false };
+};
+
+} // namespace Display
+} // namespace WebCore
+
+
+#endif // ENABLE(LAYOUT_FORMATTING_CONTEXT)
Modified: trunk/Source/WebCore/display/css/DisplayBoxDecorationData.cpp (270214 => 270215)
--- trunk/Source/WebCore/display/css/DisplayBoxDecorationData.cpp 2020-11-28 04:31:41 UTC (rev 270214)
+++ trunk/Source/WebCore/display/css/DisplayBoxDecorationData.cpp 2020-11-28 05:17:21 UTC (rev 270215)
@@ -98,6 +98,38 @@
};
}
+FloatRoundedRect roundedRectWithIncludedRadii(const FloatRect& rect, const FloatRoundedRect::Radii& radii, bool includeLeftEdge, bool includeRightEdge)
+{
+ FloatRoundedRect::Radii resultRadii;
+
+ if (includeLeftEdge) {
+ resultRadii.setTopLeft(radii.topLeft());
+ resultRadii.setBottomLeft(radii.bottomLeft());
+ }
+
+ if (includeRightEdge) {
+ resultRadii.setTopRight(radii.topRight());
+ resultRadii.setBottomRight(radii.bottomRight());
+ }
+
+ resultRadii.scale(calcBorderRadiiConstraintScaleFor(rect, resultRadii));
+ return FloatRoundedRect { rect, resultRadii };
+}
+
+FloatRoundedRect roundedInsetBorderForRect(const FloatRect& borderRect, const FloatRoundedRect::Radii& radii, const RectEdges<float>& borderWidth, bool includeLeftEdge, bool includeRightEdge)
+{
+ auto insetRect = FloatRect { borderRect.x() + borderWidth.left(), borderRect.y() + borderWidth.top(),
+ borderRect.width() - borderWidth.left() - borderWidth.right(), borderRect.height() - borderWidth.top() - borderWidth.bottom() };
+
+ if (!radii.isZero()) {
+ auto adjustedRadii = radii;
+ adjustedRadii.shrink(borderWidth.top(), borderWidth.bottom(), borderWidth.left(), borderWidth.right());
+ return roundedRectWithIncludedRadii(insetRect, adjustedRadii, includeLeftEdge, includeRightEdge);
+ }
+
+ return FloatRoundedRect { insetRect, { } };
+}
+
std::pair<BoxSide, BoxSide> adjacentSidesForSide(BoxSide side)
{
switch (side) {
Modified: trunk/Source/WebCore/display/css/DisplayBoxDecorationData.h (270214 => 270215)
--- trunk/Source/WebCore/display/css/DisplayBoxDecorationData.h 2020-11-28 04:31:41 UTC (rev 270214)
+++ trunk/Source/WebCore/display/css/DisplayBoxDecorationData.h 2020-11-28 05:17:21 UTC (rev 270215)
@@ -120,6 +120,9 @@
std::unique_ptr<FloatRoundedRect::Radii> m_borderRadii;
};
+FloatRoundedRect roundedRectWithIncludedRadii(const FloatRect&, const FloatRoundedRect::Radii&, bool includeLeftEdge = true, bool includeRightEdge = true);
+FloatRoundedRect roundedInsetBorderForRect(const FloatRect&, const FloatRoundedRect::Radii&, const RectEdges<float>&, bool includeLeftEdge = true, bool includeRightEdge = true);
+
} // namespace Display
} // namespace WebCore
Modified: trunk/Source/WebCore/display/css/DisplayBoxDecorationPainter.cpp (270214 => 270215)
--- trunk/Source/WebCore/display/css/DisplayBoxDecorationPainter.cpp 2020-11-28 04:31:41 UTC (rev 270214)
+++ trunk/Source/WebCore/display/css/DisplayBoxDecorationPainter.cpp 2020-11-28 05:17:21 UTC (rev 270215)
@@ -117,38 +117,6 @@
const bool m_includeRightEdge;
};
-static FloatRoundedRect roundedRectWithIncludedRadii(const FloatRect& rect, const FloatRoundedRect::Radii& radii, bool includeLeftEdge, bool includeRightEdge)
-{
- FloatRoundedRect::Radii resultRadii;
-
- if (includeLeftEdge) {
- resultRadii.setTopLeft(radii.topLeft());
- resultRadii.setBottomLeft(radii.bottomLeft());
- }
-
- if (includeRightEdge) {
- resultRadii.setTopRight(radii.topRight());
- resultRadii.setBottomRight(radii.bottomRight());
- }
-
- resultRadii.scale(calcBorderRadiiConstraintScaleFor(rect, resultRadii));
- return FloatRoundedRect { rect, resultRadii };
-}
-
-static FloatRoundedRect roundedInsetBorderForRect(const FloatRect& borderRect, const FloatRoundedRect::Radii& radii, const RectEdges<float>& borderWidth, bool includeLeftEdge, bool includeRightEdge)
-{
- auto insetRect = FloatRect { borderRect.x() + borderWidth.left(), borderRect.y() + borderWidth.top(),
- borderRect.width() - borderWidth.left() - borderWidth.right(), borderRect.height() - borderWidth.top() - borderWidth.bottom() };
-
- if (!radii.isZero()) {
- auto adjustedRadii = radii;
- adjustedRadii.shrink(borderWidth.top(), borderWidth.bottom(), borderWidth.left(), borderWidth.right());
- return roundedRectWithIncludedRadii(insetRect, adjustedRadii, includeLeftEdge, includeRightEdge);
- }
-
- return FloatRoundedRect { insetRect, { } };
-}
-
// BorderStyle::Outset darkens the bottom and right (and maybe lightens the top and left)
// BorderStyle::Inset darkens the top and left (and maybe lightens the bottom and right)
bool BorderPainter::borderStyleHasUnmatchedColorsAtCorner(BorderStyle style, BoxSide side, BoxSide adjacentSide)
@@ -1502,10 +1470,7 @@
FloatRoundedRect BoxDecorationPainter::innerBorderRoundedRect() const
{
- if (auto* boxDecorationData = m_box.boxDecorationData())
- return roundedInsetBorderForRect(m_borderRect.rect(), m_borderRect.radii(), borderWidths(boxDecorationData->borderEdges()), m_includeLeftEdge, m_includeRightEdge);
-
- return borderRoundedRect();
+ return m_box.innerBorderRoundedRect();
}
FloatRoundedRect BoxDecorationPainter::backgroundRoundedRectAdjustedForBleedAvoidance(const PaintingContext& paintingContext) const
Modified: trunk/Source/WebCore/display/css/DisplayBoxFactory.cpp (270214 => 270215)
--- trunk/Source/WebCore/display/css/DisplayBoxFactory.cpp 2020-11-28 04:31:41 UTC (rev 270214)
+++ trunk/Source/WebCore/display/css/DisplayBoxFactory.cpp 2020-11-28 05:17:21 UTC (rev 270215)
@@ -209,6 +209,11 @@
auto boxDecorationData = constructBoxDecorationData(layoutBox, layoutGeometry, styleForBackground, containingBlockContext.offsetFromRoot);
box.setBoxDecorationData(WTFMove(boxDecorationData));
+
+ if (box.style().participatesInZOrderSorting()) {
+ RefPtr<BoxClip> clip = containingBlockContext.box.clipForDescendants();
+ box.setAncestorClip(WTFMove(clip));
+ }
}
const Layout::ContainerBox* BoxFactory::documentElementBoxFromRootBox(const Layout::ContainerBox& rootLayoutBox)
Modified: trunk/Source/WebCore/display/css/DisplayBoxModelBox.cpp (270214 => 270215)
--- trunk/Source/WebCore/display/css/DisplayBoxModelBox.cpp 2020-11-28 04:31:41 UTC (rev 270214)
+++ trunk/Source/WebCore/display/css/DisplayBoxModelBox.cpp 2020-11-28 05:17:21 UTC (rev 270215)
@@ -28,6 +28,7 @@
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+#include "DisplayBoxClip.h"
#include "DisplayBoxDecorationData.h"
#include <wtf/IsoMallocInlines.h>
#include <wtf/text/TextStream.h>
@@ -47,10 +48,65 @@
m_boxDecorationData = WTFMove(decorationData);
}
+FloatRoundedRect BoxModelBox::borderRoundedRect() const
+{
+ auto borderRect = FloatRoundedRect { absoluteBorderBoxRect(), { } };
+ auto* borderRadii = m_boxDecorationData ? m_boxDecorationData->borderRadii() : nullptr;
+ if (borderRadii)
+ borderRect.setRadii(*borderRadii);
+
+ return borderRect;
+}
+
+FloatRoundedRect BoxModelBox::innerBorderRoundedRect() const
+{
+ if (!m_boxDecorationData)
+ return borderRoundedRect();
+
+ if (!m_boxDecorationData->borderRadii())
+ return roundedInsetBorderForRect(absoluteBorderBoxRect(), { }, borderWidths(m_boxDecorationData->borderEdges()));
+
+ return roundedInsetBorderForRect(absoluteBorderBoxRect(), *m_boxDecorationData->borderRadii(), borderWidths(m_boxDecorationData->borderEdges()));
+}
+
+void BoxModelBox::setAncestorClip(RefPtr<BoxClip>&& clip)
+{
+ m_ancestorClip = WTFMove(clip);
+}
+
+RefPtr<BoxClip> BoxModelBox::clipForDescendants() const
+{
+ if (!style().hasClippedOverflow())
+ return m_ancestorClip;
+
+ auto clip = m_ancestorClip ? m_ancestorClip->copy() : BoxClip::create();
+
+ auto pushClip = [&](BoxClip& boxClip) {
+ if (m_boxDecorationData && m_boxDecorationData->hasBorderRadius()) {
+ auto roundedInnerBorder = innerBorderRoundedRect();
+ if (roundedInnerBorder.isRounded()) {
+ boxClip.pushRoundedClip(roundedInnerBorder);
+ return;
+ }
+
+ boxClip.pushClip(roundedInnerBorder.rect());
+ return;
+ }
+
+ boxClip.pushClip(absolutePaddingBoxRect());
+ };
+ pushClip(clip);
+
+ return clip;
+}
+
String BoxModelBox::debugDescription() const
{
TextStream stream;
stream << "display box model box " << absoluteBorderBoxRect() << " (" << this << ")";
+ if (m_ancestorClip)
+ stream << " ancestor clip " << m_ancestorClip->clipRect() << " affected by radius " << m_ancestorClip->affectedByBorderRadius();
+
return stream.release();
}
Modified: trunk/Source/WebCore/display/css/DisplayBoxModelBox.h (270214 => 270215)
--- trunk/Source/WebCore/display/css/DisplayBoxModelBox.h 2020-11-28 04:31:41 UTC (rev 270214)
+++ trunk/Source/WebCore/display/css/DisplayBoxModelBox.h 2020-11-28 05:17:21 UTC (rev 270215)
@@ -28,10 +28,12 @@
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
#include "DisplayBox.h"
+#include <wtf/RefPtr.h>
namespace WebCore {
namespace Display {
+class BoxClip;
class BoxDecorationData;
// A box in the sense of the CSS Box Model.
@@ -47,7 +49,11 @@
AbsoluteFloatRect absoluteContentBoxRect() const { return m_contentBoxRect; }
const BoxDecorationData* boxDecorationData() const { return m_boxDecorationData.get(); }
+ const BoxClip* ancestorClip() const { return m_ancestorClip.get(); }
+ FloatRoundedRect borderRoundedRect() const;
+ FloatRoundedRect innerBorderRoundedRect() const;
+
virtual String debugDescription() const;
private:
@@ -54,12 +60,17 @@
friend class BoxFactory;
void setAbsolutePaddingBoxRect(const AbsoluteFloatRect& box) { m_paddingBoxRect = box; }
void setAbsoluteContentBoxRect(const AbsoluteFloatRect& box) { m_contentBoxRect = box; }
+
void setBoxDecorationData(std::unique_ptr<BoxDecorationData>&&);
+ void setAncestorClip(RefPtr<BoxClip>&&);
+ RefPtr<BoxClip> clipForDescendants() const;
+
AbsoluteFloatRect m_paddingBoxRect;
AbsoluteFloatRect m_contentBoxRect;
std::unique_ptr<BoxDecorationData> m_boxDecorationData;
+ RefPtr<BoxClip> m_ancestorClip;
};
} // namespace Display
Modified: trunk/Source/WebCore/display/css/DisplayCSSPainter.cpp (270214 => 270215)
--- trunk/Source/WebCore/display/css/DisplayCSSPainter.cpp 2020-11-28 04:31:41 UTC (rev 270214)
+++ trunk/Source/WebCore/display/css/DisplayCSSPainter.cpp 2020-11-28 05:17:21 UTC (rev 270215)
@@ -39,9 +39,38 @@
namespace WebCore {
namespace Display {
+static void applyClipIfNecessary(const Box& box, PaintingContext& paintingContext, GraphicsContextStateSaver& stateSaver)
+{
+ if (is<BoxModelBox>(box) && box.style().hasClippedOverflow()) {
+ stateSaver.save();
+ auto roundedInnerBorder = downcast<BoxModelBox>(box).innerBorderRoundedRect();
+ paintingContext.context.clipRoundedRect(roundedInnerBorder);
+ }
+}
+
+static void applyAncestorClip(const BoxModelBox& box, PaintingContext& paintingContext, GraphicsContextStateSaver& stateSaver)
+{
+ auto* boxClip = box.ancestorClip();
+ if (!boxClip || !boxClip->clipRect())
+ return;
+
+ stateSaver.save();
+
+ if (!boxClip->affectedByBorderRadius()) {
+ paintingContext.context.clip(*boxClip->clipRect());
+ return;
+ }
+
+ for (auto& roundedRect : boxClip->clipStack())
+ paintingContext.context.clipRoundedRect(roundedRect);
+}
+
// FIXME: Make this an iterator.
void CSSPainter::recursivePaintDescendantsForPhase(const ContainerBox& containerBox, PaintingContext& paintingContext, PaintPhase paintPhase)
{
+ auto stateSaver = GraphicsContextStateSaver { paintingContext.context, false };
+ applyClipIfNecessary(containerBox, paintingContext, stateSaver);
+
for (const auto* child = containerBox.firstChild(); child; child = child->nextSibling()) {
auto& box = *child;
if (participatesInZOrderSorting(box))
@@ -89,7 +118,12 @@
void CSSPainter::paintAtomicallyPaintedBox(const Box& box, PaintingContext& paintingContext, const IntRect& dirtyRect, IncludeStackingContextDescendants includeStackingContextDescendants)
{
UNUSED_PARAM(dirtyRect);
-
+
+ auto stateSaver = GraphicsContextStateSaver { paintingContext.context, false };
+
+ if (is<BoxModelBox>(box))
+ applyAncestorClip(downcast<BoxModelBox>(box), paintingContext, stateSaver);
+
BoxPainter::paintBox(box, paintingContext, dirtyRect);
if (!is<ContainerBox>(box))
return;
Modified: trunk/Source/WebCore/display/css/DisplayContainerBox.cpp (270214 => 270215)
--- trunk/Source/WebCore/display/css/DisplayContainerBox.cpp 2020-11-28 04:31:41 UTC (rev 270214)
+++ trunk/Source/WebCore/display/css/DisplayContainerBox.cpp 2020-11-28 05:17:21 UTC (rev 270215)
@@ -48,6 +48,9 @@
{
TextStream stream;
stream << "container box " << absoluteBorderBoxRect() << " (" << this << ")";
+ if (auto* clip = ancestorClip())
+ stream << " ancestor clip " << clip->clipRect() << " affected by radius " << clip->affectedByBorderRadius();
+
return stream.release();
}
Modified: trunk/Source/WebCore/display/css/DisplayStyle.cpp (270214 => 270215)
--- trunk/Source/WebCore/display/css/DisplayStyle.cpp 2020-11-28 04:31:41 UTC (rev 270214)
+++ trunk/Source/WebCore/display/css/DisplayStyle.cpp 2020-11-28 05:17:21 UTC (rev 270215)
@@ -95,6 +95,9 @@
setupBackground(*styleForBackground);
m_boxShadow = deepCopy(style.boxShadow(), style);
+
+ m_overflowX = style.overflowX();
+ m_overflowY = style.overflowY();
if (!style.hasAutoUsedZIndex())
m_zIndex = style.usedZIndex();
Modified: trunk/Source/WebCore/display/css/DisplayStyle.h (270214 => 270215)
--- trunk/Source/WebCore/display/css/DisplayStyle.h 2020-11-28 04:31:41 UTC (rev 270214)
+++ trunk/Source/WebCore/display/css/DisplayStyle.h 2020-11-28 05:17:21 UTC (rev 270215)
@@ -82,6 +82,10 @@
const FontCascade& fontCascade() const { return m_fontCascade; }
const FontMetrics& fontMetrics() const { return m_fontCascade.fontMetrics(); }
+
+ Overflow overflowX() const;
+ Overflow overflowY() const;
+ bool hasClippedOverflow() const { return m_overflowX != Overflow::Visible || m_overflowY != Overflow::Visible; }
WhiteSpace whiteSpace() const { return m_whiteSpace; }
bool autoWrap() const;
@@ -101,6 +105,9 @@
RefPtr<FillLayer> m_backgroundLayers;
std::unique_ptr<ShadowData> m_boxShadow;
+
+ Overflow m_overflowX;
+ Overflow m_overflowY;
FontCascade m_fontCascade;
WhiteSpace m_whiteSpace;