<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[287873] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/287873">287873</a></dd>
<dt>Author</dt> <dd>zimmermann@webkit.org</dd>
<dt>Date</dt> <dd>2022-01-11 04:57:41 -0800 (Tue, 11 Jan 2022)</dd>
</dl>

<h3>Log Message</h3>
<pre>[LBSE] Introduce SVGBoundingBoxComputation
https://bugs.webkit.org/show_bug.cgi?id=234632
<rdar://problem/87001334>

Reviewed by Rob Buis.

Upstream SVGBoundingBoxComputation, a utility class
implementing the SVG2 "bounding box computation" algorithm,
as spec'ed in https://svgwg.org/svg2-draft/coords.html#BoundingBoxes.

SVG2 also specifies a new optional argument for getBBox() & friends:
DOMRect getBBox(optional SVGBoundingBoxOptions options = {});

SVGBoundingBoxOptions can be implemented using SVGBoundingBoxComputation:
exposing this to the Web is left for the future, once more of LBSE is ready.

LBSE utilizes SVGBoundingBoxComputation whenever any kind of bounding box
needs to be computed (object / stroke / decorated (e.g. including markers).

Covered by existing tests, no change in behaviour.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* rendering/svg/LegacyRenderSVGModelObject.h:
(WebCore::LegacyRenderSVGModelObject::visualOverflowRectEquivalent const): Deleted.
* rendering/svg/RenderSVGModelObject.h:
(WebCore::RenderSVGModelObject::visualOverflowRectEquivalent const):
* rendering/svg/RenderSVGRoot.cpp:
(WebCore::RenderSVGRoot::layout):
* rendering/svg/RenderSVGRoot.h:
* rendering/svg/SVGBoundingBoxComputation.cpp: Added.
(WebCore::SVGBoundingBoxComputation::SVGBoundingBoxComputation):
(WebCore::SVGBoundingBoxComputation::~SVGBoundingBoxComputation):
(WebCore::SVGBoundingBoxComputation::computeDecoratedBoundingBox const):
(WebCore::SVGBoundingBoxComputation::handleShapeOrTextOrInline const):
(WebCore::SVGBoundingBoxComputation::handleRootOrContainer const):
(WebCore::SVGBoundingBoxComputation::handleForeignObjectOrImage const):
(WebCore::SVGBoundingBoxComputation::adjustBoxForClippingAndEffects const):
* rendering/svg/SVGBoundingBoxComputation.h: Added.
(WebCore::SVGBoundingBoxComputation::computeDecoratedBoundingBox):
(WebCore::SVGBoundingBoxComputation::computeRepaintBoundingBox):
(WebCore::SVGBoundingBoxComputation::computeVisualOverflowRect):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreSourcestxt">trunk/Source/WebCore/Sources.txt</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorerenderingsvgLegacyRenderSVGModelObjecth">trunk/Source/WebCore/rendering/svg/LegacyRenderSVGModelObject.h</a></li>
<li><a href="#trunkSourceWebCorerenderingsvgRenderSVGModelObjecth">trunk/Source/WebCore/rendering/svg/RenderSVGModelObject.h</a></li>
<li><a href="#trunkSourceWebCorerenderingsvgRenderSVGRootcpp">trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingsvgRenderSVGRooth">trunk/Source/WebCore/rendering/svg/RenderSVGRoot.h</a></li>
<li><a href="#trunkSourceWebCorerenderingsvgRenderSVGShapecpp">trunk/Source/WebCore/rendering/svg/RenderSVGShape.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingsvgRenderSVGShapeh">trunk/Source/WebCore/rendering/svg/RenderSVGShape.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCorerenderingsvgSVGBoundingBoxComputationcpp">trunk/Source/WebCore/rendering/svg/SVGBoundingBoxComputation.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingsvgSVGBoundingBoxComputationh">trunk/Source/WebCore/rendering/svg/SVGBoundingBoxComputation.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (287872 => 287873)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2022-01-11 08:53:55 UTC (rev 287872)
+++ trunk/Source/WebCore/ChangeLog      2022-01-11 12:57:41 UTC (rev 287873)
</span><span class="lines">@@ -1,3 +1,48 @@
</span><ins>+2022-01-11  Nikolas Zimmermann  <nzimmermann@igalia.com>
+
+        [LBSE] Introduce SVGBoundingBoxComputation
+        https://bugs.webkit.org/show_bug.cgi?id=234632
+        <rdar://problem/87001334>
+
+        Reviewed by Rob Buis.
+
+        Upstream SVGBoundingBoxComputation, a utility class
+        implementing the SVG2 "bounding box computation" algorithm,
+        as spec'ed in https://svgwg.org/svg2-draft/coords.html#BoundingBoxes.
+
+        SVG2 also specifies a new optional argument for getBBox() & friends:
+        DOMRect getBBox(optional SVGBoundingBoxOptions options = {});
+
+        SVGBoundingBoxOptions can be implemented using SVGBoundingBoxComputation:
+        exposing this to the Web is left for the future, once more of LBSE is ready.
+
+        LBSE utilizes SVGBoundingBoxComputation whenever any kind of bounding box
+        needs to be computed (object / stroke / decorated (e.g. including markers).
+
+        Covered by existing tests, no change in behaviour.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * rendering/svg/LegacyRenderSVGModelObject.h:
+        (WebCore::LegacyRenderSVGModelObject::visualOverflowRectEquivalent const): Deleted.
+        * rendering/svg/RenderSVGModelObject.h:
+        (WebCore::RenderSVGModelObject::visualOverflowRectEquivalent const):
+        * rendering/svg/RenderSVGRoot.cpp:
+        (WebCore::RenderSVGRoot::layout):
+        * rendering/svg/RenderSVGRoot.h:
+        * rendering/svg/SVGBoundingBoxComputation.cpp: Added.
+        (WebCore::SVGBoundingBoxComputation::SVGBoundingBoxComputation):
+        (WebCore::SVGBoundingBoxComputation::~SVGBoundingBoxComputation):
+        (WebCore::SVGBoundingBoxComputation::computeDecoratedBoundingBox const):
+        (WebCore::SVGBoundingBoxComputation::handleShapeOrTextOrInline const):
+        (WebCore::SVGBoundingBoxComputation::handleRootOrContainer const):
+        (WebCore::SVGBoundingBoxComputation::handleForeignObjectOrImage const):
+        (WebCore::SVGBoundingBoxComputation::adjustBoxForClippingAndEffects const):
+        * rendering/svg/SVGBoundingBoxComputation.h: Added.
+        (WebCore::SVGBoundingBoxComputation::computeDecoratedBoundingBox):
+        (WebCore::SVGBoundingBoxComputation::computeRepaintBoundingBox):
+        (WebCore::SVGBoundingBoxComputation::computeVisualOverflowRect):
+
</ins><span class="cx"> 2022-01-11  Carlos Garcia Campos  <cgarcia@igalia.com>
</span><span class="cx"> 
</span><span class="cx">         [GTK][a11y] WTR: do not immediately process main thread events while waiting for ax thread task
</span></span></pre></div>
<a id="trunkSourceWebCoreSourcestxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Sources.txt (287872 => 287873)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Sources.txt 2022-01-11 08:53:55 UTC (rev 287872)
+++ trunk/Source/WebCore/Sources.txt    2022-01-11 12:57:41 UTC (rev 287873)
</span><span class="lines">@@ -2501,6 +2501,7 @@
</span><span class="cx"> rendering/svg/RenderSVGTextPath.cpp
</span><span class="cx"> rendering/svg/RenderSVGTransformableContainer.cpp
</span><span class="cx"> rendering/svg/RenderSVGViewportContainer.cpp
</span><ins>+rendering/svg/SVGBoundingBoxComputation.cpp
</ins><span class="cx"> rendering/svg/SVGInlineFlowBox.cpp
</span><span class="cx"> rendering/svg/SVGInlineTextBox.cpp
</span><span class="cx"> rendering/svg/SVGPathData.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (287872 => 287873)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj   2022-01-11 08:53:55 UTC (rev 287872)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj      2022-01-11 12:57:41 UTC (rev 287873)
</span><span class="lines">@@ -244,6 +244,7 @@
</span><span class="cx">          0854B0191255E4E600B9CDD0 /* RenderSVGText.h in Headers */ = {isa = PBXBuildFile; fileRef = 0854B0071255E4E600B9CDD0 /* RenderSVGText.h */; };
</span><span class="cx">          0854B01B1255E4E600B9CDD0 /* RenderSVGTextPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 0854B0091255E4E600B9CDD0 /* RenderSVGTextPath.h */; };
</span><span class="cx">          0854B01D1255E4E600B9CDD0 /* RenderSVGTSpan.h in Headers */ = {isa = PBXBuildFile; fileRef = 0854B00B1255E4E600B9CDD0 /* RenderSVGTSpan.h */; };
</span><ins>+               0844B01D1255B4E600B9CDD0 /* SVGBoundingBoxComputation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0844B01D1255E4E600B9CDD0 /* SVGBoundingBoxComputation.h */; };
</ins><span class="cx">           0854B01F1255E4E600B9CDD0 /* SVGInlineFlowBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 0854B00D1255E4E600B9CDD0 /* SVGInlineFlowBox.h */; };
</span><span class="cx">          0854B0211255E4E600B9CDD0 /* SVGInlineTextBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 0854B00F1255E4E600B9CDD0 /* SVGInlineTextBox.h */; };
</span><span class="cx">          0854B0231255E4E600B9CDD0 /* SVGRootInlineBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 0854B0111255E4E600B9CDD0 /* SVGRootInlineBox.h */; };
</span><span class="lines">@@ -6185,6 +6186,8 @@
</span><span class="cx">          0854B0081255E4E600B9CDD0 /* RenderSVGTextPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGTextPath.cpp; sourceTree = "<group>"; };
</span><span class="cx">          0854B0091255E4E600B9CDD0 /* RenderSVGTextPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGTextPath.h; sourceTree = "<group>"; };
</span><span class="cx">          0854B00B1255E4E600B9CDD0 /* RenderSVGTSpan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGTSpan.h; sourceTree = "<group>"; };
</span><ins>+               0834B00C1244E4E600B9CDD0 /* SVGBoundingBoxComputation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGBoundingBoxComputation.cpp; sourceTree = "<group>"; };
+               0844B01D1255E4E600B9CDD0 /* SVGBoundingBoxComputation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGBoundingBoxComputation.h; sourceTree = "<group>"; };
</ins><span class="cx">           0854B00C1255E4E600B9CDD0 /* SVGInlineFlowBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGInlineFlowBox.cpp; sourceTree = "<group>"; };
</span><span class="cx">          0854B00D1255E4E600B9CDD0 /* SVGInlineFlowBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGInlineFlowBox.h; sourceTree = "<group>"; };
</span><span class="cx">          0854B00E1255E4E600B9CDD0 /* SVGInlineTextBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGInlineTextBox.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -18994,6 +18997,8 @@
</span><span class="cx">                          0854B00B1255E4E600B9CDD0 /* RenderSVGTSpan.h */,
</span><span class="cx">                          436708AB12D9CA4B00044234 /* RenderSVGViewportContainer.cpp */,
</span><span class="cx">                          436708AC12D9CA4B00044234 /* RenderSVGViewportContainer.h */,
</span><ins>+                               0834B00C1244E4E600B9CDD0 /* SVGBoundingBoxComputation.cpp */,
+                               0844B01D1255E4E600B9CDD0 /* SVGBoundingBoxComputation.h */,
</ins><span class="cx">                           0854B00C1255E4E600B9CDD0 /* SVGInlineFlowBox.cpp */,
</span><span class="cx">                          0854B00D1255E4E600B9CDD0 /* SVGInlineFlowBox.h */,
</span><span class="cx">                          0854B00E1255E4E600B9CDD0 /* SVGInlineTextBox.cpp */,
</span><span class="lines">@@ -37315,6 +37320,7 @@
</span><span class="cx">                          B22279930D00BF220071B782 /* SVGAnimateMotionElement.h in Headers */,
</span><span class="cx">                          B22279950D00BF220071B782 /* SVGAnimateTransformElement.h in Headers */,
</span><span class="cx">                          B22279980D00BF220071B782 /* SVGAnimationElement.h in Headers */,
</span><ins>+                               0844B01D1255B4E600B9CDD0 /* SVGBoundingBoxComputation.h in Headers */,
</ins><span class="cx">                           B222799C0D00BF220071B782 /* SVGCircleElement.h in Headers */,
</span><span class="cx">                          B222799F0D00BF220071B782 /* SVGClipPathElement.h in Headers */,
</span><span class="cx">                          B22279A50D00BF220071B782 /* SVGComponentTransferFunctionElement.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingsvgLegacyRenderSVGModelObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/svg/LegacyRenderSVGModelObject.h (287872 => 287873)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/svg/LegacyRenderSVGModelObject.h  2022-01-11 08:53:55 UTC (rev 287872)
+++ trunk/Source/WebCore/rendering/svg/LegacyRenderSVGModelObject.h     2022-01-11 12:57:41 UTC (rev 287873)
</span><span class="lines">@@ -62,10 +62,6 @@
</span><span class="cx"> 
</span><span class="cx">     SVGElement& element() const { return downcast<SVGElement>(nodeForNonAnonymous()); }
</span><span class="cx"> 
</span><del>-    // FIXME: [LBSE] Upstream SVGBoundingBoxComputation
-    // LayoutRect visualOverflowRectEquivalent() const { return SVGBoundingBoxComputation::computeVisualOverflowRect(*this); }
-    LayoutRect visualOverflowRectEquivalent() const { return LayoutRect(); }
-
</del><span class="cx"> protected:
</span><span class="cx">     LegacyRenderSVGModelObject(SVGElement&, RenderStyle&&);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingsvgRenderSVGModelObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/svg/RenderSVGModelObject.h (287872 => 287873)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/svg/RenderSVGModelObject.h        2022-01-11 08:53:55 UTC (rev 287872)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGModelObject.h   2022-01-11 12:57:41 UTC (rev 287873)
</span><span class="lines">@@ -34,8 +34,7 @@
</span><span class="cx"> #if ENABLE(LAYER_BASED_SVG_ENGINE)
</span><span class="cx"> #include "RenderLayer.h"
</span><span class="cx"> #include "RenderLayerModelObject.h"
</span><del>-// FIXME: [LBSE] Upstream SVGBoundingBoxComputation
-// #include "SVGBoundingBoxComputation.h"
</del><ins>+#include "SVGBoundingBoxComputation.h"
</ins><span class="cx"> #include "SVGElement.h"
</span><span class="cx"> #include "SVGRenderSupport.h"
</span><span class="cx"> 
</span><span class="lines">@@ -69,12 +68,7 @@
</span><span class="cx">     LayoutRect contentBoxRectEquivalent() const { return borderBoxRectEquivalent(); }
</span><span class="cx">     LayoutRect frameRectEquivalent() const { return m_layoutRect; }
</span><span class="cx"> 
</span><del>-    LayoutRect visualOverflowRectEquivalent() const
-    {
-        // FIXME: [LBSE] Upstream SVGBoundingBoxComputation
-        // return SVGBoundingBoxComputation::computeVisualOverflowRect(*this);
-        return LayoutRect();
-    }
</del><ins>+    LayoutRect visualOverflowRectEquivalent() const { return SVGBoundingBoxComputation::computeVisualOverflowRect(*this); }
</ins><span class="cx"> 
</span><span class="cx">     void applyTopLeftLocationOffsetEquivalent(LayoutPoint& point) const { point.moveBy(layoutLocation()); }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingsvgRenderSVGRootcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp (287872 => 287873)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp     2022-01-11 08:53:55 UTC (rev 287872)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp        2022-01-11 12:57:41 UTC (rev 287873)
</span><span class="lines">@@ -193,16 +193,16 @@
</span><span class="cx">     // SVGLayerTransformUpdater transformUpdater(*this);
</span><span class="cx">     updateLayerInformation();
</span><span class="cx"> 
</span><del>-    /* FIXME: [LBSE] Upstream SVGContainerLayout / SVGBoundingBoxComputation
</del><span class="cx">     {
</span><ins>+        /* FIXME: [LBSE] Upstream SVGContainerLayout
</ins><span class="cx">         SVGContainerLayout containerLayout(*this);
</span><span class="cx">         containerLayout.layoutChildren(needsLayout || SVGRenderSupport::filtersForceContainerLayout(*this));
</span><ins>+        */
</ins><span class="cx"> 
</span><span class="cx">         SVGBoundingBoxComputation boundingBoxComputation(*this);
</span><span class="cx">         m_objectBoundingBox = boundingBoxComputation.computeDecoratedBoundingBox(SVGBoundingBoxComputation::objectBoundingBoxDecoration);
</span><span class="cx">         m_strokeBoundingBox = boundingBoxComputation.computeDecoratedBoundingBox(SVGBoundingBoxComputation::strokeBoundingBoxDecoration);
</span><span class="cx">     }
</span><del>-    */
</del><span class="cx"> 
</span><span class="cx">     // FIXME: [LBSE] Upstream SVGContainerLayout -- remove SVGRenderSupport::layoutChildren.
</span><span class="cx">     SVGRenderSupport::layoutChildren(*this, needsLayout);
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingsvgRenderSVGRooth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/svg/RenderSVGRoot.h (287872 => 287873)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/svg/RenderSVGRoot.h       2022-01-11 08:53:55 UTC (rev 287872)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGRoot.h  2022-01-11 12:57:41 UTC (rev 287873)
</span><span class="lines">@@ -26,8 +26,7 @@
</span><span class="cx"> #if ENABLE(LAYER_BASED_SVG_ENGINE)
</span><span class="cx"> #include "FloatRect.h"
</span><span class="cx"> #include "RenderReplaced.h"
</span><del>-// FIXME: [LBSE] Upstream SVGBoundingBoxComputation
-// #include "SVGBoundingBoxComputation.h"
</del><ins>+#include "SVGBoundingBoxComputation.h"
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -72,22 +71,10 @@
</span><span class="cx"> 
</span><span class="cx">     FloatRect objectBoundingBox() const final { return m_objectBoundingBox; }
</span><span class="cx">     FloatRect strokeBoundingBox() const final { return m_strokeBoundingBox; }
</span><ins>+    FloatRect repaintRectInLocalCoordinates() const final { return SVGBoundingBoxComputation::computeRepaintBoundingBox(*this); }
</ins><span class="cx"> 
</span><del>-    // FIXME: [LBSE] Mark final, add repaintBoundingBox() to RenderObject
-    FloatRect repaintBoundingBox() const
-    {
-        // FIXME: [LBSE] Upstream SVGBoundingBoxComputation
-        // return SVGBoundingBoxComputation::computeRepaintBoundingBox(*this);
-        return m_strokeBoundingBox;
-    }
</del><ins>+    LayoutRect visualOverflowRectEquivalent() const { return SVGBoundingBoxComputation::computeVisualOverflowRect(*this); }
</ins><span class="cx"> 
</span><del>-    LayoutRect visualOverflowRectEquivalent() const
-    {
-        // FIXME: [LBSE] Upstream SVGBoundingBoxComputation
-        // return SVGBoundingBoxComputation::computeVisualOverflowRect(*this);
-        return LayoutRect();
-    }
-
</del><span class="cx"> private:
</span><span class="cx">     void element() const = delete;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingsvgRenderSVGShapecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/svg/RenderSVGShape.cpp (287872 => 287873)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/svg/RenderSVGShape.cpp    2022-01-11 08:53:55 UTC (rev 287872)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGShape.cpp       2022-01-11 12:57:41 UTC (rev 287873)
</span><span class="lines">@@ -400,7 +400,7 @@
</span><span class="cx">     return 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-FloatRect RenderSVGShape::computeMarkerBoundingBox() const
</del><ins>+FloatRect RenderSVGShape::computeMarkerBoundingBox(const SVGBoundingBoxComputation::DecorationOptions&) const
</ins><span class="cx"> {
</span><span class="cx">     if (m_markerPositions.isEmpty())
</span><span class="cx">         return FloatRect();
</span><span class="lines">@@ -417,8 +417,11 @@
</span><span class="cx">     FloatRect boundaries;
</span><span class="cx">     unsigned size = m_markerPositions.size();
</span><span class="cx">     for (unsigned i = 0; i < size; ++i) {
</span><del>-        if (RenderSVGResourceMarker* marker = markerForType(m_markerPositions[i].type, markerStart, markerMid, markerEnd))
</del><ins>+        if (auto* marker = markerForType(m_markerPositions[i].type, markerStart, markerMid, markerEnd)) {
+            // FIXME: [LBSE] Upstream RenderSVGResourceMarker changes
+            // boundaries.unite(marker->computeMarkerBoundingBox(options, marker->markerTransformation(m_markerPositions[i].origin, m_markerPositions[i].angle, strokeWidth())));
</ins><span class="cx">             boundaries.unite(marker->markerBoundaries(marker->markerTransformation(m_markerPositions[i].origin, m_markerPositions[i].angle, strokeWidth())));
</span><ins>+        }
</ins><span class="cx">     }
</span><span class="cx">     return boundaries;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingsvgRenderSVGShapeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/svg/RenderSVGShape.h (287872 => 287873)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/svg/RenderSVGShape.h      2022-01-11 08:53:55 UTC (rev 287872)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGShape.h 2022-01-11 12:57:41 UTC (rev 287873)
</span><span class="lines">@@ -30,8 +30,7 @@
</span><span class="cx"> #include "AffineTransform.h"
</span><span class="cx"> #include "FloatRect.h"
</span><span class="cx"> #include "RenderSVGModelObject.h"
</span><del>-// FIXME: [LBSE] Upstream SVGBoundingBoxComputation
-// #include "SVGBoundingBoxComputation.h"
</del><ins>+#include "SVGBoundingBoxComputation.h"
</ins><span class="cx"> #include "SVGGraphicsElement.h"
</span><span class="cx"> #include "SVGMarkerData.h"
</span><span class="cx"> #include <memory>
</span><span class="lines">@@ -80,16 +79,10 @@
</span><span class="cx"> 
</span><span class="cx">     FloatRect objectBoundingBox() const final { return m_fillBoundingBox; }
</span><span class="cx">     FloatRect strokeBoundingBox() const final { return m_strokeBoundingBox; }
</span><ins>+    FloatRect repaintRectInLocalCoordinates() const final { return SVGBoundingBoxComputation::computeRepaintBoundingBox(*this); }
</ins><span class="cx"> 
</span><del>-    FloatRect repaintRectInLocalCoordinates() const final
-    {
-        // FIXME: [LBSE] Upstream SVGBoundingBoxComputation
-        // return SVGBoundingBoxComputation::computeRepaintBoundingBox(*this); }
-        return FloatRect();
-    }
</del><ins>+    FloatRect computeMarkerBoundingBox(const SVGBoundingBoxComputation::DecorationOptions&) const;
</ins><span class="cx"> 
</span><del>-    FloatRect computeMarkerBoundingBox() const;
-
</del><span class="cx"> protected:
</span><span class="cx">     void element() const = delete;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingsvgSVGBoundingBoxComputationcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/rendering/svg/SVGBoundingBoxComputation.cpp (0 => 287873)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/svg/SVGBoundingBoxComputation.cpp                         (rev 0)
+++ trunk/Source/WebCore/rendering/svg/SVGBoundingBoxComputation.cpp    2022-01-11 12:57:41 UTC (rev 287873)
</span><span class="lines">@@ -0,0 +1,282 @@
</span><ins>+/*
+ * Copyright (C) 2021, 2022 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 "SVGBoundingBoxComputation.h"
+
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+#include "RenderChildIterator.h"
+#include "RenderSVGForeignObject.h"
+#include "RenderSVGImage.h"
+#include "RenderSVGInline.h"
+#include "RenderSVGResourceClipper.h"
+#include "RenderSVGResourceFilter.h"
+#include "RenderSVGResourceMarker.h"
+#include "RenderSVGResourceMasker.h"
+#include "RenderSVGRoot.h"
+#include "RenderSVGShape.h"
+#include "RenderSVGText.h"
+#include "SVGResources.h"
+#include "SVGResourcesCache.h"
+
+namespace WebCore {
+
+SVGBoundingBoxComputation::SVGBoundingBoxComputation(const RenderLayerModelObject& renderer)
+    : m_renderer(renderer)
+{
+}
+
+FloatRect SVGBoundingBoxComputation::computeDecoratedBoundingBox(const SVGBoundingBoxComputation::DecorationOptions& options, bool* boundingBoxValid) const
+{
+    // SVG2: Bounding boxes algorithm (https://svgwg.org/svg2-draft/coords.html#BoundingBoxes)
+
+    // The following algorithm defines how to compute a bounding box for a given element. The inputs to the algorithm are:
+    // - element, the element we are computing a bounding box for;
+    // - space, a coordinate space in which the bounding box will be computed;
+    // - fill, a boolean indicating whether the bounding box includes the geometry of the element and its descendants;
+    // - stroke, a boolean indicating whether the bounding box includes the stroke of the element and its descendants;
+    // - markers, a boolean indicating whether the bounding box includes the markers of the element and its descendants; and
+    // - clipped, a boolean indicating whether the bounding box is affected by any clipping paths applied to the element and its descendants.
+
+    // The algorithm to compute the bounding box is as follows, depending on the type of element:
+    // - a shape (RenderSVGShape)
+    // - a text content element (RenderSVGText or RenderSVGInline)
+    // - an "a" element within a text content element (-> creates RenderSVGInline)
+    if (is<RenderSVGShape>(m_renderer) || is<RenderSVGText>(m_renderer) || is<RenderSVGInline>(m_renderer))
+        return handleShapeOrTextOrInline(options, boundingBoxValid);
+
+    // - a container element (RenderSVGRoot / RenderSVGContainer)
+    // - "use" (RenderSVGTransformableContainer)
+    // FIXME: [LBSE] Upstream new RenderSVGContainer implementation
+    // if (is<RenderSVGRoot>(m_renderer) || is<RenderSVGContainer>(m_renderer))
+    if (is<RenderSVGRoot>(m_renderer))
+        return handleRootOrContainer(options, boundingBoxValid);
+
+    // - "foreignObject"
+    // - "image"
+    // FIXME: [LBSE] Upstream new RenderSVGImage implementation
+    // if (is<RenderSVGForeignObject>(m_renderer) || is<RenderSVGImage>(m_renderer))
+    if (is<RenderSVGForeignObject>(m_renderer))
+        return handleForeignObjectOrImage(options, boundingBoxValid);
+
+    ASSERT_NOT_REACHED();
+    return FloatRect();
+}
+
+FloatRect SVGBoundingBoxComputation::handleShapeOrTextOrInline(const SVGBoundingBoxComputation::DecorationOptions& options, bool* boundingBoxValid) const
+{
+    // 1. Let box be a rectangle initialized to (0, 0, 0, 0).
+    FloatRect box;
+
+    // 2. Let fill-shape be the equivalent path of element if it is a shape, or a shape that includes each of the
+    //    glyph cells corresponding to the text within the elements otherwise.
+    // 3. If fill is true, then set box to the tightest rectangle in the coordinate system space that contains fill-shape.
+    //
+    // Note: The values of the fill, fill-opacity and fill-rule properties do not affect fill-shape.
+    if (options.contains(DecorationOption::IncludeFillShape))
+        box = m_renderer.objectBoundingBox();
+
+    // 4. If stroke is true and the element's stroke is anything other than none, then set box to be the union of box
+    //    and the tightest rectangle in coordinate system space that contains the stroke shape of the element, with the
+    //    assumption that the element has no dash pattern.
+    //
+    // Note: The values of the stroke-opacity, stroke-dasharray and stroke-dashoffset do not affect the calculation of the stroke shape.
+    if (options.contains(DecorationOption::IncludeStrokeShape))
+        box.unite(m_renderer.strokeBoundingBox());
+
+    // 5. If markers is true, then for each marker marker rendered on the element:
+    // - For each descendant graphics element child of the "marker" element that defines marker's content:
+    //   - If child has an ancestor element within the "marker" that is 'display: none', has a failing conditional processing attribute,
+    //     or is not an "a", "g", "svg" or "switch" element, then continue to the next descendant graphics element.
+    //   - Otherwise, set box to be the union of box and the result of invoking the algorithm to compute a bounding box with child as
+    //     the element, space as the target coordinate space, true for fill, stroke and markers, and clipped for clipped.
+    if (options.contains(DecorationOption::IncludeMarkers) && is<RenderSVGShape>(m_renderer)) {
+        DecorationOptions optionsForMarker = { DecorationOption::IncludeFillShape, DecorationOption::IncludeStrokeShape, DecorationOption::IncludeMarkers };
+        if (options.contains(DecorationOption::IncludeClippers))
+            optionsForMarker.add(DecorationOption::IncludeClippers);
+        box.unite(downcast<RenderSVGShape>(m_renderer).computeMarkerBoundingBox(options));
+    }
+
+    // 6. If clipped is true and the value of clip-path on element is not none, then set box to be the tightest rectangle
+    //    in coordinate system space that contains the intersection of box and the clipping path.
+    adjustBoxForClippingAndEffects(options, box);
+
+    // 7. Return box.
+    if (boundingBoxValid)
+        *boundingBoxValid = true;
+    return box;
+}
+
+FloatRect SVGBoundingBoxComputation::handleRootOrContainer(const SVGBoundingBoxComputation::DecorationOptions& options, bool* boundingBoxValid) const
+{
+    auto transformationMatrixFromChild = [] (const RenderLayerModelObject& child) -> std::optional<TransformationMatrix> {
+        if (!child.hasTransform())
+            return std::nullopt;
+
+        auto* container = child.parent();
+        ASSERT(container);
+
+        bool containerSkipped = false;
+        ASSERT(container == child.container(nullptr, containerSkipped));
+        ASSERT_UNUSED(containerSkipped, !containerSkipped);
+
+        TransformationMatrix layerTransform;
+        child.getTransformFromContainer(container, LayoutSize(), layerTransform);
+        return layerTransform.isIdentity() ? std::nullopt : std::make_optional(WTFMove(layerTransform));
+    };
+
+    auto uniteBoundingBoxRespectingValidity = [] (bool& boxValid, FloatRect& box, const RenderLayerModelObject& /* child */, const FloatRect& childBoundingBox) {
+        // FIXME: [LBSE] Upstream new RenderSVGContainer implementation
+        // bool isBoundingBoxValid = is<RenderSVGContainer>(child) ? downcast<RenderSVGContainer>(child).isObjectBoundingBoxValid() : true;
+        bool isBoundingBoxValid = true;
+        if (!isBoundingBoxValid)
+            return;
+
+        if (boxValid) {
+            box.uniteEvenIfEmpty(childBoundingBox);
+            return;
+        }
+
+        box = childBoundingBox;
+        boxValid = true;
+    };
+
+    // 1. Let box be a rectangle initialized to (0, 0, 0, 0).
+    FloatRect box;
+    bool boxValid = false;
+
+    // 2. Let parent be the container element if it is one, or the root of the "use" element's shadow tree otherwise.
+
+    // 3. For each descendant graphics element child of parent:
+    //    - If child is not rendered then continue to the next descendant graphics element.
+    //    - Otherwise, set box to be the union of box and the result of invoking the algorithm to compute a bounding box with child
+    //      as the element and the same values for space, fill, stroke, markers and clipped as the corresponding algorithm input values.
+    for (auto& child : childrenOfType<RenderLayerModelObject>(m_renderer)) {
+        // FIXME: [LBSE] Upstream new RenderSVGContainer implementation
+        // if (is<RenderSVGHiddenContainer>(child) || (is<RenderSVGShape>(child) && downcast<RenderSVGShape>(child).isRenderingDisabled()))
+        if (is<RenderSVGShape>(child) && downcast<RenderSVGShape>(child).isRenderingDisabled())
+            continue;
+
+        SVGBoundingBoxComputation childBoundingBoxComputation(child);
+        auto childBox = childBoundingBoxComputation.computeDecoratedBoundingBox(options);
+        // FIXME: Upstream new RenderSVGContainer implementation
+        // if (options.contains(DecorationOption::OverrideBoxWithFilterBoxForChildren) && is<RenderSVGContainer>(child))
+        //    childBoundingBoxComputation.adjustBoxForClippingAndEffects({ DecorationOption::OverrideBoxWithFilterBox }, childBox);
+
+        if (auto layerTransform = transformationMatrixFromChild(child))
+            childBox = layerTransform->mapRect(childBox);
+
+        if (options == objectBoundingBoxDecoration)
+            uniteBoundingBoxRespectingValidity(boxValid, box, child, childBox);
+        else
+            box.unite(childBox);
+    }
+
+    // 4. If clipped is true:
+    //    - If the value of clip-path on element is not none, then set box to be the tightest rectangle in coordinate system space that
+    //      contains the intersection of box and the clipping path.
+    //    - If the overflow property applies to the element and does not have a value of visible, then set box to be the tightest rectangle
+    //      in coordinate system space that contains the intersection of box and the element's overflow bounds.
+    //    - If the clip property applies to the element and does not have a value of auto, then set box to be the tightest rectangle in coordinate
+    //      system space that contains the intersection of box and the rectangle specified by clip. (TODO!)
+    adjustBoxForClippingAndEffects(options, box, { DecorationOption::OverrideBoxWithFilterBox });
+
+    if (options.contains(DecorationOption::IncludeClippers) && m_renderer.hasNonVisibleOverflow()) {
+        ASSERT(m_renderer.hasLayer());
+
+        // FIXME: [LBSE] Upstream new RenderSVGContainer / RenderSVGResourceMarker implementation
+        // ASSERT(is<RenderSVGViewportContainer>(m_renderer) || is<RenderSVGResourceMarker>(m_renderer) || is<RenderSVGRoot>(m_renderer));
+        ASSERT(is<RenderSVGRoot>(m_renderer));
+
+        LayoutRect overflowClipRect;
+        if (is<RenderSVGModelObject>(m_renderer))
+            overflowClipRect = downcast<RenderSVGModelObject>(m_renderer).overflowClipRect(LayoutPoint());
+        else if (is<RenderBox>(m_renderer))
+            overflowClipRect = downcast<RenderBox>(m_renderer).overflowClipRect(LayoutPoint());
+        else {
+            ASSERT_NOT_REACHED();
+            return FloatRect();
+        }
+
+        box.intersect(overflowClipRect);
+    }
+
+    // 5. Return box.
+    if (boundingBoxValid)
+        *boundingBoxValid = boxValid;
+    return box;
+}
+
+FloatRect SVGBoundingBoxComputation::handleForeignObjectOrImage(const SVGBoundingBoxComputation::DecorationOptions& options, bool* boundingBoxValid) const
+{
+    // 1. Let box be the tightest rectangle in coordinate space space that contains the positioning rectangle
+    //    defined by the "x", "y", "width" and "height" geometric properties of the element.
+    //
+    // Note: The fill, stroke and markers input arguments to this algorithm do not affect the bounding box returned for these elements.
+    auto box = m_renderer.objectBoundingBox();
+
+    // 2. If clipped is true and the value of clip-path on element is not none, then set box to be the tightest rectangle
+    //    in coordinate system space that contains the intersection of box and the clipping path.
+    adjustBoxForClippingAndEffects(options, box);
+
+    // 3. Return box.
+    if (boundingBoxValid)
+        *boundingBoxValid = true;
+    return box;
+}
+
+void SVGBoundingBoxComputation::adjustBoxForClippingAndEffects(const SVGBoundingBoxComputation::DecorationOptions& options, FloatRect& box, const SVGBoundingBoxComputation::DecorationOptions& optionsToCheckForFilters) const
+{
+    bool includeFilter = false;
+    for (auto filterOption : optionsToCheckForFilters) {
+        if (options.contains(filterOption)) {
+            includeFilter = true;
+            break;
+        }
+    }
+
+    bool includeClipper = options.contains(DecorationOption::IncludeClippers);
+    bool includeMasker = options.contains(DecorationOption::IncludeMaskers);
+
+    if (includeFilter || includeClipper || includeMasker) {
+        if (auto* resources = SVGResourcesCache::cachedResourcesForRenderer(m_renderer)) {
+            if (includeFilter) {
+                if (auto* filter = resources->filter())
+                    box = filter->resourceBoundingBox(m_renderer);
+            }
+
+            if (includeClipper) {
+                if (auto* clipper = resources->clipper())
+                    box.intersect(clipper->resourceBoundingBox(m_renderer));
+            }
+
+            if (includeMasker) {
+                if (auto* masker = resources->masker())
+                    box.intersect(masker->resourceBoundingBox(m_renderer));
+            }
+        }
+    }
+
+    if (options.contains(DecorationOption::IncludeOutline))
+        box.inflate(m_renderer.outlineStyleForRepaint().outlineSize());
+}
+
+}
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebCorerenderingsvgSVGBoundingBoxComputationh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/rendering/svg/SVGBoundingBoxComputation.h (0 => 287873)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/svg/SVGBoundingBoxComputation.h                           (rev 0)
+++ trunk/Source/WebCore/rendering/svg/SVGBoundingBoxComputation.h      2022-01-11 12:57:41 UTC (rev 287873)
</span><span class="lines">@@ -0,0 +1,92 @@
</span><ins>+/**
+ * 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 <wtf/Noncopyable.h>
+#include <wtf/OptionSet.h>
+
+namespace WebCore {
+
+class FloatRect;
+
+class SVGBoundingBoxComputation {
+    WTF_MAKE_NONCOPYABLE(SVGBoundingBoxComputation);
+public:
+    explicit SVGBoundingBoxComputation(const RenderLayerModelObject&);
+    ~SVGBoundingBoxComputation() = default;
+
+    enum class DecorationOption : uint8_t {
+        IncludeFillShape                    = 1 << 0, /* corresponds to 'bool fill'     */
+        IncludeStrokeShape                  = 1 << 1, /* corresponds to 'bool stroke'   */
+        IncludeMarkers                      = 1 << 2, /* corresponds to 'bool markers'  */
+        IncludeClippers                     = 1 << 3, /* corresponds to 'bool clippers' */
+        IncludeMaskers                      = 1 << 4, /* WebKit extension - internal    */
+        IncludeOutline                      = 1 << 5, /* WebKit extension - internal    */
+        OverrideBoxWithFilterBox            = 1 << 6, /* WebKit extension - internal    */
+        OverrideBoxWithFilterBoxForChildren = 1 << 7  /* WebKit extension - internal    */
+    };
+
+    using DecorationOptions = OptionSet<DecorationOption>;
+
+    static constexpr DecorationOptions objectBoundingBoxDecoration = { DecorationOption::IncludeFillShape };
+    static constexpr DecorationOptions strokeBoundingBoxDecoration = { DecorationOption::IncludeFillShape, DecorationOption::IncludeStrokeShape };
+    static constexpr DecorationOptions filterBoundingBoxDecoration = { DecorationOption::OverrideBoxWithFilterBox, DecorationOption::OverrideBoxWithFilterBoxForChildren };
+    static constexpr DecorationOptions repaintBoundingBoxDecoration = { DecorationOption::IncludeFillShape, DecorationOption::IncludeStrokeShape, DecorationOption::IncludeMarkers, DecorationOption::IncludeClippers, DecorationOption::IncludeMaskers, DecorationOption::OverrideBoxWithFilterBox };
+
+    FloatRect computeDecoratedBoundingBox(const DecorationOptions&, bool* boundingBoxValid = nullptr) const;
+
+    static FloatRect computeDecoratedBoundingBox(const RenderLayerModelObject& renderer, const DecorationOptions& options)
+    {
+        SVGBoundingBoxComputation boundingBoxComputation(renderer);
+        return boundingBoxComputation.computeDecoratedBoundingBox(options);
+    }
+
+    static FloatRect computeRepaintBoundingBox(const RenderLayerModelObject& renderer)
+    {
+        return computeDecoratedBoundingBox(renderer, repaintBoundingBoxDecoration);
+    }
+
+    static LayoutRect computeVisualOverflowRect(const RenderLayerModelObject& renderer)
+    {
+        auto repaintBoundingBox = computeDecoratedBoundingBox(renderer, repaintBoundingBoxDecoration | DecorationOption::IncludeOutline);
+        if (repaintBoundingBox.isEmpty())
+            return LayoutRect();
+
+        auto visualOverflowRect = enclosingLayoutRect(repaintBoundingBox);
+        visualOverflowRect.moveBy(-flooredLayoutPoint(renderer.objectBoundingBox().minXMinYCorner()));
+        return visualOverflowRect;
+    }
+
+private:
+    FloatRect handleShapeOrTextOrInline(const DecorationOptions&, bool* boundingBoxValid = nullptr) const;
+    FloatRect handleRootOrContainer(const DecorationOptions&, bool* boundingBoxValid = nullptr) const;
+    FloatRect handleForeignObjectOrImage(const DecorationOptions&, bool* boundingBoxValid = nullptr) const;
+
+    void adjustBoxForClippingAndEffects(const DecorationOptions&, FloatRect& box, const DecorationOptions& optionsToCheckForFilters = filterBoundingBoxDecoration) const;
+
+    const RenderLayerModelObject& m_renderer;
+};
+
+} // namespace WebCore
+
+#endif
</ins></span></pre>
</div>
</div>

</body>
</html>