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());