Title: [289204] trunk/Source/WebCore
Revision
289204
Author
[email protected]
Date
2022-02-07 03:36:31 -0800 (Mon, 07 Feb 2022)

Log Message

[LBSE] Extend overflow/clip rect handling for SVG layers
https://bugs.webkit.org/show_bug.cgi?id=236188

Reviewed by Rob Buis.

Non-visible overflow implies a clip, that potentially influences the layer
geometry. The 'foregroundRect' is intersected with the 'overflowClipRect'
of the renderer - usually provided via RenderBox::overflowClipRect().

The CSS overflow handling is applicable to SVG as well, most noticeable
the outermost <svg> element (RenderSVGRoot), already uses the CSS overflow
handling, as it is RenderBox derived (via its RenderReplaced inheritance)
and not RenderSVGModelObject derived.

However inner <svg> elements (RenderSVGViewportContainer) and <marker>
elements also require overflow handling -- this patch allows them to
participate in the layer overflow handling and therefore extends both
RenderLayer::calculateClipRects() and RenderLayer::calculateRects()
to support RenderSVGModelObject.

Covered by existing tests, no change in behaviour.

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::calculateClipRects const):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (289203 => 289204)


--- trunk/Source/WebCore/ChangeLog	2022-02-07 11:12:58 UTC (rev 289203)
+++ trunk/Source/WebCore/ChangeLog	2022-02-07 11:36:31 UTC (rev 289204)
@@ -1,3 +1,30 @@
+2022-02-07  Nikolas Zimmermann  <[email protected]>
+
+        [LBSE] Extend overflow/clip rect handling for SVG layers
+        https://bugs.webkit.org/show_bug.cgi?id=236188
+
+        Reviewed by Rob Buis.
+
+        Non-visible overflow implies a clip, that potentially influences the layer
+        geometry. The 'foregroundRect' is intersected with the 'overflowClipRect'
+        of the renderer - usually provided via RenderBox::overflowClipRect().
+
+        The CSS overflow handling is applicable to SVG as well, most noticeable
+        the outermost <svg> element (RenderSVGRoot), already uses the CSS overflow
+        handling, as it is RenderBox derived (via its RenderReplaced inheritance)
+        and not RenderSVGModelObject derived.
+
+        However inner <svg> elements (RenderSVGViewportContainer) and <marker>
+        elements also require overflow handling -- this patch allows them to
+        participate in the layer overflow handling and therefore extends both
+        RenderLayer::calculateClipRects() and RenderLayer::calculateRects()
+        to support RenderSVGModelObject.
+
+        Covered by existing tests, no change in behaviour.
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::calculateClipRects const):
+
 2022-02-07  Rob Buis  <[email protected]>
 
         Bail out early in stopForUserCancel

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (289203 => 289204)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2022-02-07 11:12:58 UTC (rev 289203)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2022-02-07 11:36:31 UTC (rev 289204)
@@ -106,6 +106,7 @@
 #include "RenderMultiColumnFlow.h"
 #include "RenderReplica.h"
 #include "RenderSVGForeignObject.h"
+#include "RenderSVGModelObject.h"
 #include "RenderSVGResourceClipper.h"
 #include "RenderScrollbar.h"
 #include "RenderScrollbarPart.h"
@@ -4557,7 +4558,18 @@
             offset -= toLayoutSize(renderer().view().frameView().scrollPositionForFixedPosition());
 
         if (renderer().hasNonVisibleOverflow()) {
-            ClipRect newOverflowClip = downcast<RenderBox>(renderer()).overflowClipRectForChildLayers(offset, nullptr, clipRectsContext.overlayScrollbarSizeRelevancy);
+            ClipRect newOverflowClip;
+            if (is<RenderBox>(renderer()))
+                newOverflowClip = downcast<RenderBox>(renderer()).overflowClipRectForChildLayers(offset, nullptr, clipRectsContext.overlayScrollbarSizeRelevancy);
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+            else if (is<RenderSVGModelObject>(renderer()))
+                newOverflowClip = downcast<RenderSVGModelObject>(renderer()).overflowClipRectForChildLayers(offset, nullptr, clipRectsContext.overlayScrollbarSizeRelevancy);
+#endif
+            else {
+                ASSERT_NOT_REACHED();
+                return;
+            }
+
             newOverflowClip.setAffectedByRadius(renderer().style().hasBorderRadius());
             clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.overflowClipRect()));
             if (renderer().isPositioned())
@@ -4567,7 +4579,7 @@
                 clipRects.setFixedClipRect(intersection(newOverflowClip, clipRects.fixedClipRect()));
             }
         }
-        if (renderer().hasClip()) {
+        if (renderer().hasClip() && is<RenderBox>(renderer())) {
             LayoutRect newPosClip = downcast<RenderBox>(renderer()).clipRect(offset, nullptr);
             clipRects.setPosClipRect(intersection(newPosClip, clipRects.posClipRect()));
             clipRects.setOverflowClipRect(intersection(newPosClip, clipRects.overflowClipRect()));
@@ -4647,13 +4659,26 @@
         // This layer establishes a clip of some kind.
         if (renderer().hasNonVisibleOverflow()) {
             if (this != clipRectsContext.rootLayer || clipRectsContext.respectOverflowClip == RespectOverflowClip) {
-                foregroundRect.intersect(downcast<RenderBox>(renderer()).overflowClipRect(toLayoutPoint(offsetFromRootLocal), nullptr, clipRectsContext.overlayScrollbarSizeRelevancy));
+                LayoutRect overflowClipRect;
+
+                if (is<RenderBox>(renderer()))
+                    overflowClipRect = downcast<RenderBox>(renderer()).overflowClipRect(toLayoutPoint(offsetFromRootLocal), nullptr, clipRectsContext.overlayScrollbarSizeRelevancy);
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+                else if (is<RenderSVGModelObject>(renderer()))
+                    overflowClipRect = downcast<RenderSVGModelObject>(renderer()).overflowClipRect(toLayoutPoint(offsetFromRootLocal), nullptr, clipRectsContext.overlayScrollbarSizeRelevancy);
+#endif
+                else {
+                    ASSERT_NOT_REACHED();
+                    return;
+                }
+
+                foregroundRect.intersect(overflowClipRect);
                 foregroundRect.setAffectedByRadius(true);
             } else if (transform() && renderer().style().hasBorderRadius())
                 foregroundRect.setAffectedByRadius(true);
         }
 
-        if (renderer().hasClip()) {
+        if (renderer().hasClip() && is<RenderBox>(renderer())) {
             // Clip applies to *us* as well, so update the damageRect.
             LayoutRect newPosClip = downcast<RenderBox>(renderer()).clipRect(toLayoutPoint(offsetFromRootLocal), nullptr);
             backgroundRect.intersect(newPosClip);
@@ -4662,7 +4687,7 @@
 
         // If we establish a clip at all, then make sure our background rect is intersected with our layer's bounds including our visual overflow,
         // since any visual overflow like box-shadow or border-outset is not clipped by overflow:auto/hidden.
-        if (renderBox()->hasVisualOverflow()) {
+        if (renderBox() && renderBox()->hasVisualOverflow()) {
             // FIXME: Does not do the right thing with CSS regions yet, since we don't yet factor in the
             // individual region boxes as overflow.
             LayoutRect layerBoundsWithVisualOverflow = renderBox()->visualOverflowRect();
@@ -4730,7 +4755,7 @@
     if (clipRect.isInfinite())
         return clipRect;
 
-    if (renderer().hasClip()) {
+    if (renderer().hasClip() && is<RenderBox>(renderer())) {
         // CSS clip may be larger than our border box.
         LayoutRect cssClipRect = downcast<RenderBox>(renderer()).clipRect({ }, nullptr);
         clipExceedsBounds = !cssClipRect.isEmpty() && (clipRect.width() < cssClipRect.width() || clipRect.height() < cssClipRect.height());
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to