WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch, v2
bug-235101-20220114004128.patch (text/plain), 25.77 KB, created by
Nikolas Zimmermann
on 2022-01-14 00:41:29 PST
(
hide
)
Description:
Patch, v2
Filename:
MIME Type:
Creator:
Nikolas Zimmermann
Created:
2022-01-14 00:41:29 PST
Size:
25.77 KB
patch
obsolete
>Subversion Revision: 288010 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 3e9d4c7f7dd93722b90cd2f8ac47f1f562be8ea5..254e6b4ec45a0d58d3bf03c3760c786a31fb5b90 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,45 @@ >+2022-01-12 Nikolas Zimmermann <nzimmermann@igalia.com> >+ >+ [LBSE] Introduce SVGContainerLayout >+ https://bugs.webkit.org/show_bug.cgi?id=235101 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Upstream SVGContainerLayout, a utility class centralizing >+ the "layout children in SVG render tree" algorithm. The legacy >+ engines relies on various helper methods in SVGRenderingSupport -- for >+ LBSE it's all in one place: SVGContainerLayout. >+ >+ The actual two-pass algorithm is described in the technical document >+ covering LBSE. It's identical to the LBSE downstream version, which >+ used to pass all layout tests. >+ >+ Currently the functionality is not observable, as we don't create >+ LBSE renderers yet. >+ >+ Covered by existing tests, no change in behaviour. >+ >+ * Sources.txt: >+ * WebCore.xcodeproj/project.pbxproj: >+ * rendering/RenderObject.h: >+ (WebCore::RenderObject::isSVGLayerAwareRenderer const): >+ * rendering/svg/RenderSVGContainer.cpp: >+ (WebCore::RenderSVGContainer::layoutChildren): >+ * rendering/svg/RenderSVGRoot.cpp: >+ (WebCore::RenderSVGRoot::layout): >+ * rendering/svg/SVGContainerLayout.cpp: Added. >+ (WebCore::SVGContainerLayout::SVGContainerLayout): >+ (WebCore::SVGContainerLayout::layoutChildren): >+ (WebCore::layoutLocationFromRenderer): >+ (WebCore::setLayoutLocationForRenderer): >+ (WebCore::SVGContainerLayout::positionChildrenRelativeToContainer): >+ (WebCore::SVGContainerLayout::verifyLayoutLocationConsistency): >+ (WebCore::SVGContainerLayout::layoutDifferentRootIfNeeded): >+ (WebCore::SVGContainerLayout::invalidateResourcesOfChildren): >+ (WebCore::SVGContainerLayout::layoutSizeOfNearestViewportChanged const): >+ (WebCore::SVGContainerLayout::transformToRootChanged): >+ * rendering/svg/SVGContainerLayout.h: Added. >+ > 2022-01-13 Simon Fraser <simon.fraser@apple.com> > > Don't call invalidateRectsForAllMarkers() for every layer in the updateLayerPositions() traversal >diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt >index dd8b9632e8b48ef1dd272e7253a5aee3677ae46e..3fa0bbd9824f9a86a12fe3879abde0d3e4859af5 100644 >--- a/Source/WebCore/Sources.txt >+++ b/Source/WebCore/Sources.txt >@@ -2501,6 +2501,7 @@ rendering/svg/RenderSVGTextPath.cpp > rendering/svg/RenderSVGTransformableContainer.cpp > rendering/svg/RenderSVGViewportContainer.cpp > rendering/svg/SVGBoundingBoxComputation.cpp >+rendering/svg/SVGContainerLayout.cpp > rendering/svg/SVGInlineFlowBox.cpp > rendering/svg/SVGInlineTextBox.cpp > rendering/svg/SVGPathData.cpp >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index 151ec9bd2ff7e828e923b3b8f16b026ab1e68a22..42930a19a5790d63e8f45102d237a45b7d54ce19 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -247,6 +247,7 @@ > 0854B01B1255E4E600B9CDD0 /* RenderSVGTextPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 0854B0091255E4E600B9CDD0 /* RenderSVGTextPath.h */; }; > 0854B01D1255E4E600B9CDD0 /* RenderSVGTSpan.h in Headers */ = {isa = PBXBuildFile; fileRef = 0854B00B1255E4E600B9CDD0 /* RenderSVGTSpan.h */; }; > 0844B01D1255B4E600B9CDD0 /* SVGBoundingBoxComputation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0844B01D1255E4E600B9CDD0 /* SVGBoundingBoxComputation.h */; }; >+ 0844B01D1255B5A610B8AFD1 /* SVGContainerLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 0844B01D1255E5A610B8AFD1 /* SVGContainerLayout.h */; }; > 0854B01F1255E4E600B9CDD0 /* SVGInlineFlowBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 0854B00D1255E4E600B9CDD0 /* SVGInlineFlowBox.h */; }; > 0854B0211255E4E600B9CDD0 /* SVGInlineTextBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 0854B00F1255E4E600B9CDD0 /* SVGInlineTextBox.h */; }; > 0854B0231255E4E600B9CDD0 /* SVGRootInlineBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 0854B0111255E4E600B9CDD0 /* SVGRootInlineBox.h */; }; >@@ -6210,7 +6211,9 @@ > 0854B0091255E4E600B9CDD0 /* RenderSVGTextPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGTextPath.h; sourceTree = "<group>"; }; > 0854B00B1255E4E600B9CDD0 /* RenderSVGTSpan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGTSpan.h; sourceTree = "<group>"; }; > 0834B00C1244E4E600B9CDD0 /* SVGBoundingBoxComputation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGBoundingBoxComputation.cpp; sourceTree = "<group>"; }; >+ 0834B00C1244E5A610B8AFD1 /* SVGContainerLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGContainerLayout.cpp; sourceTree = "<group>"; }; > 0844B01D1255E4E600B9CDD0 /* SVGBoundingBoxComputation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGBoundingBoxComputation.h; sourceTree = "<group>"; }; >+ 0844B01D1255E5A610B8AFD1 /* SVGContainerLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGContainerLayout.h; sourceTree = "<group>"; }; > 0854B00C1255E4E600B9CDD0 /* SVGInlineFlowBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGInlineFlowBox.cpp; sourceTree = "<group>"; }; > 0854B00D1255E4E600B9CDD0 /* SVGInlineFlowBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGInlineFlowBox.h; sourceTree = "<group>"; }; > 0854B00E1255E4E600B9CDD0 /* SVGInlineTextBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGInlineTextBox.cpp; sourceTree = "<group>"; }; >@@ -19022,6 +19025,8 @@ > 436708AC12D9CA4B00044234 /* RenderSVGViewportContainer.h */, > 0834B00C1244E4E600B9CDD0 /* SVGBoundingBoxComputation.cpp */, > 0844B01D1255E4E600B9CDD0 /* SVGBoundingBoxComputation.h */, >+ 0834B00C1244E5A610B8AFD1 /* SVGContainerLayout.cpp */, >+ 0844B01D1255E5A610B8AFD1 /* SVGContainerLayout.h */, > 0854B00C1255E4E600B9CDD0 /* SVGInlineFlowBox.cpp */, > 0854B00D1255E4E600B9CDD0 /* SVGInlineFlowBox.h */, > 0854B00E1255E4E600B9CDD0 /* SVGInlineTextBox.cpp */, >@@ -37336,6 +37341,7 @@ > B222799C0D00BF220071B782 /* SVGCircleElement.h in Headers */, > B222799F0D00BF220071B782 /* SVGClipPathElement.h in Headers */, > B22279A50D00BF220071B782 /* SVGComponentTransferFunctionElement.h in Headers */, >+ 0844B01D1255B5A610B8AFD1 /* SVGContainerLayout.h in Headers */, > B22279A80D00BF220071B782 /* SVGCursorElement.h in Headers */, > B22279AE0D00BF220071B782 /* SVGDefsElement.h in Headers */, > B22279B10D00BF220071B782 /* SVGDescElement.h in Headers */, >diff --git a/Source/WebCore/rendering/RenderObject.h b/Source/WebCore/rendering/RenderObject.h >index 4dba9c8547d8e78a97c110f11ec02d5a66bd5dc1..c356650c5df94d6baefc09eec48554f36dc56c62 100644 >--- a/Source/WebCore/rendering/RenderObject.h >+++ b/Source/WebCore/rendering/RenderObject.h >@@ -352,6 +352,7 @@ public: > bool isSVGRootOrLegacySVGRoot() const { return isSVGRoot() || isLegacySVGRoot(); } > bool isSVGShapeOrLegacySVGShape() const { return isSVGShape() || isLegacySVGShape(); } > bool isRenderOrLegacyRenderSVGModelObject() const { return isRenderSVGModelObject() || isLegacyRenderSVGModelObject(); } >+ bool isSVGLayerAwareRenderer() const { return isSVGRoot() || isRenderSVGModelObject() || isSVGText() || isSVGInline() || isSVGForeignObject(); } > > // FIXME: Those belong into a SVG specific base-class for all renderers (see above) > // Unfortunately we don't have such a class yet, because it's not possible for all renderers >diff --git a/Source/WebCore/rendering/svg/RenderSVGContainer.cpp b/Source/WebCore/rendering/svg/RenderSVGContainer.cpp >index 2bcd5fead7195fc6c572ecb3c75ce0b128996d89..bdcc5815b46627f0ff1c5a1480240ff657b947ef 100644 >--- a/Source/WebCore/rendering/svg/RenderSVGContainer.cpp >+++ b/Source/WebCore/rendering/svg/RenderSVGContainer.cpp >@@ -34,8 +34,7 @@ > #include "RenderLayer.h" > #include "RenderTreeBuilder.h" > #include "RenderView.h" >-// FIXME: [LBSE] Upstream SVGContainerLayout >-// #include "SVGContainerLayout.h" >+#include "SVGContainerLayout.h" > #include "SVGRenderingContext.h" > #include "SVGResources.h" > #include "SVGResourcesCache.h" >@@ -88,17 +87,15 @@ void RenderSVGContainer::calculateViewport() > > void RenderSVGContainer::layoutChildren() > { >- // FIXME: [LBSE] Upstream SVGContainerLayout >- // SVGContainerLayout containerLayout(*this); >- // containerLayout.layoutChildren(selfNeedsLayout() || SVGRenderSupport::filtersForceContainerLayout(*this)); >+ SVGContainerLayout containerLayout(*this); >+ containerLayout.layoutChildren(selfNeedsLayout() || SVGRenderSupport::filtersForceContainerLayout(*this)); > > SVGBoundingBoxComputation boundingBoxComputation(*this); > m_objectBoundingBox = boundingBoxComputation.computeDecoratedBoundingBox(SVGBoundingBoxComputation::objectBoundingBoxDecoration, &m_objectBoundingBoxValid); > m_strokeBoundingBox = boundingBoxComputation.computeDecoratedBoundingBox(SVGBoundingBoxComputation::strokeBoundingBoxDecoration); > setLayoutRect(enclosingLayoutRect(m_objectBoundingBox)); > >- // FIXME: [LBSE] Upstream SVGContainerLayout >- // containerLayout.positionChildrenRelativeToContainer(); >+ containerLayout.positionChildrenRelativeToContainer(); > } > > void RenderSVGContainer::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) >diff --git a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp >index 121c637649041decceba579949f5ce6dc3ff46dd..0dc9bab67d033810e79f3d840f367e3542bc94c4 100644 >--- a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp >+++ b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp >@@ -44,8 +44,7 @@ > #include "RenderSVGText.h" > #include "RenderTreeBuilder.h" > #include "RenderView.h" >-// FIXME: [LBSE] Upstream SVGContainerLayout >-// #include "SVGContainerLayout.h" >+#include "SVGContainerLayout.h" > #include "SVGElementTypeHelpers.h" > #include "SVGImage.h" > #include "SVGRenderingContext.h" >@@ -194,19 +193,14 @@ void RenderSVGRoot::layout() > updateLayerInformation(); > > { >- /* FIXME: [LBSE] Upstream SVGContainerLayout > SVGContainerLayout containerLayout(*this); > containerLayout.layoutChildren(needsLayout || SVGRenderSupport::filtersForceContainerLayout(*this)); >- */ > > SVGBoundingBoxComputation boundingBoxComputation(*this); > m_objectBoundingBox = boundingBoxComputation.computeDecoratedBoundingBox(SVGBoundingBoxComputation::objectBoundingBoxDecoration); > m_strokeBoundingBox = boundingBoxComputation.computeDecoratedBoundingBox(SVGBoundingBoxComputation::strokeBoundingBoxDecoration); > } > >- // FIXME: [LBSE] Upstream SVGContainerLayout -- remove SVGRenderSupport::layoutChildren. >- SVGRenderSupport::layoutChildren(*this, needsLayout); >- > if (!m_resourcesNeedingToInvalidateClients.isEmpty()) { > // Invalidate resource clients, which may mark some nodes for layout. > for (auto& resource : m_resourcesNeedingToInvalidateClients) { >@@ -216,10 +210,8 @@ void RenderSVGRoot::layout() > > m_isLayoutSizeChanged = false; > >- /* FIXME: [LBSE] Upstream SVGContainerLayout > SVGContainerLayout containerLayout(*this); > containerLayout.layoutChildren(false); >- */ > } > > m_isLayoutSizeChanged = false; >diff --git a/Source/WebCore/rendering/svg/SVGContainerLayout.cpp b/Source/WebCore/rendering/svg/SVGContainerLayout.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..c53b3fc3662daf6b0e9d598054486ec8d44f22c2 >--- /dev/null >+++ b/Source/WebCore/rendering/svg/SVGContainerLayout.cpp >@@ -0,0 +1,293 @@ >+/* >+ * Copyright (C) 2007, 2008 Rob Buis <buis@kde.org> >+ * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> >+ * Copyright (C) 2007 Eric Seidel <eric@webkit.org> >+ * Copyright (C) 2009 Google, Inc. All rights reserved. >+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> >+ * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. >+ * Copyright (C) 2018 Adobe Systems Incorporated. All rights reserved. >+ * Copyright (C) 2020 Apple Inc. All rights reserved. >+ * Copyright (C) 2021 Igalia S.L. >+ * >+ * This library is free software; you can redistribute it and/or >+ * modify it under the terms of the GNU Library General Public >+ * License as published by the Free Software Foundation; either >+ * version 2 of the License, or (at your option) any later version. >+ * >+ * This library is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >+ * Library General Public License for more details. >+ * >+ * You should have received a copy of the GNU Library General Public License >+ * along with this library; see the file COPYING.LIB. If not, write to >+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, >+ * Boston, MA 02110-1301, USA. >+ */ >+ >+#include "config.h" >+#include "SVGContainerLayout.h" >+ >+#if ENABLE(LAYER_BASED_SVG_ENGINE) >+#include "Logging.h" >+#include "RenderAncestorIterator.h" >+#include "RenderChildIterator.h" >+#include "RenderSVGForeignObject.h" >+#include "RenderSVGHiddenContainer.h" >+#include "RenderSVGInline.h" >+#include "RenderSVGModelObject.h" >+#include "RenderSVGRoot.h" >+#include "RenderSVGShape.h" >+#include "RenderSVGText.h" >+#include "RenderSVGTransformableContainer.h" >+#include "RenderSVGViewportContainer.h" >+#include "SVGRenderSupport.h" >+#include "SVGRenderingContext.h" >+#include "SVGResources.h" >+#include "SVGResourcesCache.h" >+ >+namespace WebCore { >+ >+SVGContainerLayout::SVGContainerLayout(RenderLayerModelObject& container) >+ : m_container(container) >+{ >+} >+ >+void SVGContainerLayout::layoutChildren(bool containerNeedsLayout) >+{ >+ bool layoutSizeChanged = layoutSizeOfNearestViewportChanged(); >+ bool transformChanged = transformToRootChanged(&m_container); >+ HashSet<RenderElement*> elementsThatDidNotReceiveLayout; >+ >+ m_positionedChildren.clear(); >+ for (auto& child : childrenOfType<RenderObject>(m_container)) { >+ if (child.isSVGLayerAwareRenderer()) { >+ ASSERT(child.hasLayer()); >+ m_positionedChildren.append(downcast<RenderLayerModelObject>(child)); >+ } >+ >+ bool needsLayout = containerNeedsLayout; >+ bool childEverHadLayout = child.everHadLayout(); >+ >+ if (transformChanged) { >+ // If the transform changed we need to update the text metrics (note: this also happens for layoutSizeChanged=true). >+ if (is<RenderSVGText>(child)) >+ downcast<RenderSVGText>(child).setNeedsTextMetricsUpdate(); >+ needsLayout = true; >+ } >+ >+ if (layoutSizeChanged && child.node() && is<SVGElement>(*child.node())) { >+ // When containerNeedsLayout is false and the layout size changed, we have to check whether this child uses relative lengths >+ auto& element = downcast<SVGElement>(*child.node()); >+ if (element.hasRelativeLengths() && 1) { >+ // When the layout size changed and when using relative values tell the RenderSVGShape to update its shape object >+ if (is<RenderSVGShape>(child)) >+ downcast<RenderSVGShape>(child).setNeedsShapeUpdate(); >+ else if (is<RenderSVGText>(child)) { >+ auto& svgText = downcast<RenderSVGText>(child); >+ svgText.setNeedsTextMetricsUpdate(); >+ svgText.setNeedsPositioningValuesUpdate(); >+ } >+ >+ needsLayout = true; >+ } >+ } >+ >+ if (needsLayout) >+ child.setNeedsLayout(MarkOnlyThis); >+ >+ bool childNeededLayout = child.needsLayout(); >+ if (is<RenderElement>(child)) { >+ auto& element = downcast<RenderElement>(child); >+ if (childNeededLayout) { >+ layoutDifferentRootIfNeeded(element); >+ element.layout(); >+ } else if (layoutSizeChanged) >+ elementsThatDidNotReceiveLayout.add(&element); >+ >+ if (!childEverHadLayout && element.checkForRepaintDuringLayout()) >+ child.repaint(); >+ } >+ >+ ASSERT(!child.needsLayout()); >+ } >+ >+ if (layoutSizeChanged) { >+ // If the layout size changed, invalidate all resources of all children that didn't go through the layout() code path. >+ for (auto* element : elementsThatDidNotReceiveLayout) >+ invalidateResourcesOfChildren(*element); >+ } else >+ ASSERT(elementsThatDidNotReceiveLayout.isEmpty()); >+} >+ >+static inline LayoutPoint layoutLocationFromRenderer(const RenderObject& renderer) >+{ >+ if (is<RenderSVGModelObject>(renderer)) >+ return downcast<RenderSVGModelObject>(renderer).layoutLocation(); >+ >+ if (is<RenderSVGBlock>(renderer)) // <foreignObject> / <text> >+ return downcast<RenderSVGBlock>(renderer).location(); >+ >+ if (is<RenderSVGInline>(renderer)) // <tspan> / <textPath> >+ return { }; >+ >+ ASSERT_NOT_REACHED(); >+ return { }; >+} >+ >+static inline void setLayoutLocationForRenderer(RenderObject& renderer, const LayoutPoint& newLocation) >+{ >+ if (is<RenderSVGModelObject>(renderer)) { >+ downcast<RenderSVGModelObject>(renderer).setLayoutLocation(newLocation); >+ return; >+ } >+ >+ // <foreignObject> / <text> >+ if (is<RenderSVGBlock>(renderer)) { >+ downcast<RenderSVGBlock>(renderer).setLocation(newLocation); >+ return; >+ } >+ >+ // <tspan> / <textPath> >+ if (is<RenderSVGInline>(renderer)) >+ return; >+ >+ ASSERT_NOT_REACHED(); >+} >+ >+void SVGContainerLayout::positionChildrenRelativeToContainer() >+{ >+ if (m_positionedChildren.isEmpty()) >+ return; >+ >+ auto verifyPositionedChildRendererExpectation = [](RenderObject& renderer) { >+#if !defined(NDEBUG) >+ ASSERT(renderer.isSVGLayerAwareRenderer()); // Pre-condition to enter m_positionedChildren >+ ASSERT(!renderer.isSVGRoot()); // There is only one outermost RenderSVGRoot object >+ ASSERT(!renderer.isSVGInline()); // Inlines are only allowed within a RenderSVGText tree >+ >+ if (is<RenderSVGModelObject>(renderer) || is<RenderSVGBlock>(renderer)) >+ return; >+ >+ ASSERT_NOT_REACHED(); >+ return; >+#else >+ UNUSED_PARAM(renderer); >+#endif >+ }; >+ >+ // Arrange layout location for all child renderers relative to the container layout location. >+ auto parentLayoutLocation = flooredLayoutPoint(m_container.objectBoundingBox().minXMinYCorner()); >+ for (RenderObject& child : m_positionedChildren) { >+ verifyPositionedChildRendererExpectation(child); >+ >+ auto objectBoundingBoxChild = child.objectBoundingBox(); >+ auto layoutLocation = flooredLayoutPoint(objectBoundingBoxChild.minXMinYCorner()); >+ auto desiredLayoutLocation = toLayoutPoint(layoutLocation - parentLayoutLocation); >+ auto currentLayoutLocation = layoutLocationFromRenderer(child); >+ if (currentLayoutLocation == desiredLayoutLocation) >+ continue; >+ setLayoutLocationForRenderer(child, desiredLayoutLocation); >+ } >+} >+ >+void SVGContainerLayout::verifyLayoutLocationConsistency(const RenderElement& renderer) >+{ >+ if (renderer.isSVGLayerAwareRenderer() && !renderer.isSVGRoot()) { >+ auto currentLayoutLocation = layoutLocationFromRenderer(renderer); >+ >+ auto expectedLayoutLocation = currentLayoutLocation; >+ for (auto& ancestor : ancestorsOfType<RenderElement>(renderer)) { >+ ASSERT(ancestor.isSVGLayerAwareRenderer()); >+ if (ancestor.isSVGRoot()) >+ break; >+ expectedLayoutLocation.moveBy(layoutLocationFromRenderer(ancestor)); >+ } >+ >+ auto initialLayoutLocation = flooredLayoutPoint(renderer.objectBoundingBox().minXMinYCorner()); >+ if (expectedLayoutLocation == initialLayoutLocation) { >+ LOG_WITH_STREAM(SVG, stream << "--> SVGContainerLayout renderer " << &renderer << " (" << renderer.renderName() << ")" >+ << " - verifyLayoutLocationConsistency() objectBoundingBox / layoutLocation are in sync."); >+ } else { >+ LOG_WITH_STREAM(SVG, stream << "--> SVGContainerLayout renderer " << &renderer << " (" << renderer.renderName() << ")" >+ << " - verifyLayoutLocationConsistency() objectBoundingBox / layoutLocation invariant violated -- out of sync due to partial layout?" >+ << " currentLayoutLocation=" << currentLayoutLocation >+ << " (expectedLayoutLocation=" << expectedLayoutLocation >+ << " != initialLayoutLocation=" << initialLayoutLocation << ")" >+ << " -> aborting with a render tree dump"); >+ >+#if ENABLE(TREE_DEBUGGING) >+ showRenderTree(&renderer); >+#endif >+ >+ ASSERT_NOT_REACHED(); >+ } >+ } >+ >+ for (auto& child : childrenOfType<RenderElement>(renderer)) { >+ if (child.isSVGLayerAwareRenderer()) >+ verifyLayoutLocationConsistency(child); >+ } >+ >+#if !defined(NDEBUG) >+ if (renderer.isSVGRoot()) { >+ LOG_WITH_STREAM(SVG, stream << "--> SVGContainerLayout renderer " << &renderer << " (" << renderer.renderName() << ")" >+ << " - verifyLayoutLocationConsistency() end"); >+ } >+#endif >+} >+ >+void SVGContainerLayout::layoutDifferentRootIfNeeded(const RenderElement& renderer) >+{ >+ if (auto* resources = SVGResourcesCache::cachedResourcesForRenderer(renderer)) { >+ auto* svgRoot = SVGRenderSupport::findTreeRootObject(renderer); >+ ASSERT(svgRoot); >+ resources->layoutDifferentRootIfNeeded(svgRoot); >+ } >+} >+ >+void SVGContainerLayout::invalidateResourcesOfChildren(RenderElement& renderer) >+{ >+ ASSERT(!renderer.needsLayout()); >+ if (auto* resources = SVGResourcesCache::cachedResourcesForRenderer(renderer)) >+ resources->removeClientFromCache(renderer, false); >+ >+ for (auto& child : childrenOfType<RenderElement>(renderer)) >+ invalidateResourcesOfChildren(child); >+} >+ >+bool SVGContainerLayout::layoutSizeOfNearestViewportChanged() const >+{ >+ RenderElement* ancestor = &m_container; >+ while (ancestor && !is<RenderSVGRoot>(*ancestor) && !is<RenderSVGViewportContainer>(*ancestor)) >+ ancestor = ancestor->parent(); >+ >+ ASSERT(ancestor); >+ if (is<RenderSVGViewportContainer>(*ancestor)) >+ return downcast<RenderSVGViewportContainer>(*ancestor).isLayoutSizeChanged(); >+ >+ return downcast<RenderSVGRoot>(*ancestor).isLayoutSizeChanged(); >+} >+ >+bool SVGContainerLayout::transformToRootChanged(const RenderObject* ancestor) >+{ >+ while (ancestor) { >+ // FIXME: [LBSE] Upstream RenderSVGTransformableContainer changes >+ // if (is<RenderSVGTransformableContainer>(*ancestor)) >+ // return downcast<const RenderSVGTransformableContainer>(*ancestor).didTransformToRootUpdate(); >+ >+ // FIXME: [LBSE] Upstream RenderSVGTransformableContainer changes >+ // if (is<RenderSVGViewportContainer>(*ancestor)) >+ // return downcast<const RenderSVGViewportContainer>(*ancestor).didTransformToRootUpdate(); >+ >+ if (is<RenderSVGRoot>(*ancestor)) >+ return downcast<const RenderSVGRoot>(*ancestor).didTransformToRootUpdate(); >+ ancestor = ancestor->parent(); >+ } >+ >+ return false; >+} >+ >+} >+ >+#endif // ENABLE(LAYER_BASED_SVG_ENGINE) >diff --git a/Source/WebCore/rendering/svg/SVGContainerLayout.h b/Source/WebCore/rendering/svg/SVGContainerLayout.h >new file mode 100644 >index 0000000000000000000000000000000000000000..ec130935126cf7ece159992a8db71c11673026e7 >--- /dev/null >+++ b/Source/WebCore/rendering/svg/SVGContainerLayout.h >@@ -0,0 +1,58 @@ >+/** >+ * Copyright (C) 2021 Igalia S.L. >+ * >+ * This library is free software; you can redistribute it and/or >+ * modify it under the terms of the GNU Library General Public >+ * License as published by the Free Software Foundation; either >+ * version 2 of the License, or (at your option) any later version. >+ * >+ * This library is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >+ * Library General Public License for more details. >+ * >+ * You should have received a copy of the GNU Library General Public License >+ * along with this library; see the file COPYING.LIB. If not, write to >+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, >+ * Boston, MA 02110-1301, USA. >+ */ >+ >+#pragma once >+ >+#if ENABLE(LAYER_BASED_SVG_ENGINE) >+#include "RenderLayerModelObject.h" >+ >+#include <functional> >+#include <wtf/Noncopyable.h> >+#include <wtf/Vector.h> >+ >+namespace WebCore { >+ >+class SVGContainerLayout { >+ WTF_MAKE_NONCOPYABLE(SVGContainerLayout); >+public: >+ explicit SVGContainerLayout(RenderLayerModelObject&); >+ ~SVGContainerLayout() = default; >+ >+ // 'containerNeedsLayout' denotes if the container for which the >+ // SVGContainerLayout object was created needs to be laid out or not. >+ void layoutChildren(bool containerNeedsLayout); >+ >+ void positionChildrenRelativeToContainer(); >+ >+ static void verifyLayoutLocationConsistency(const RenderElement&); >+ static bool transformToRootChanged(const RenderObject* ancestor); >+ >+private: >+ void layoutDifferentRootIfNeeded(const RenderElement&); >+ void invalidateResourcesOfChildren(RenderElement&); >+ >+ bool layoutSizeOfNearestViewportChanged() const; >+ >+ RenderLayerModelObject& m_container; >+ Vector<std::reference_wrapper<RenderLayerModelObject>> m_positionedChildren; >+}; >+ >+} // namespace WebCore >+ >+#endif // ENABLE(LAYER_BASED_SVG_ENGINE)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
rbuis
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 235101
:
448935
| 449144