Title: [270215] trunk/Source/WebCore
Revision
270215
Author
[email protected]
Date
2020-11-27 21:17:21 -0800 (Fri, 27 Nov 2020)

Log Message

[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):

Modified Paths

Added Paths

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;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to