<!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>[277556] 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/277556">277556</a></dd>
<dt>Author</dt> <dd>zalan@apple.com</dd>
<dt>Date</dt> <dd>2021-05-15 18:56:55 -0700 (Sat, 15 May 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>[LFC] Move base formatting geometry to its own class
https://bugs.webkit.org/show_bug.cgi?id=225752

Reviewed by Antti Koivisto.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* layout/formattingContexts/FormattingContext.cpp:
(WebCore::Layout::FormattingContext::geometry const):
* layout/formattingContexts/FormattingContext.h:
(WebCore::Layout::FormattingContext::Geometry::layoutState const): Deleted.
(WebCore::Layout::FormattingContext::Geometry::layoutState): Deleted.
(WebCore::Layout::FormattingContext::Geometry::formattingContext const): Deleted.
(WebCore::Layout::FormattingContext::geometry const): Deleted.
(WebCore::Layout::FormattingContext::Geometry::Geometry): Deleted.
* layout/formattingContexts/FormattingContextGeometry.cpp: Removed.
* layout/formattingContexts/block/BlockFormattingGeometry.cpp:
(WebCore::Layout::BlockFormattingGeometry::BlockFormattingGeometry):
(WebCore::Layout::BlockFormattingGeometry::inFlowNonReplacedContentHeightAndMargin):
(WebCore::Layout::BlockFormattingGeometry::inFlowNonReplacedContentWidthAndMargin):
* layout/formattingContexts/block/BlockFormattingGeometry.h:
(WebCore::Layout::BlockFormattingGeometry::formattingContext const):
* layout/formattingContexts/flex/FlexFormattingGeometry.cpp:
(WebCore::Layout::FlexFormattingGeometry::FlexFormattingGeometry):
* layout/formattingContexts/flex/FlexFormattingGeometry.h:
(WebCore::Layout::FlexFormattingGeometry::formattingContext const):
* layout/formattingContexts/inline/InlineFormattingGeometry.cpp:
(WebCore::Layout::InlineFormattingGeometry::InlineFormattingGeometry):
(WebCore::Layout::InlineFormattingGeometry::inlineBlockContentWidthAndMargin):
* layout/formattingContexts/inline/InlineFormattingGeometry.h:
(WebCore::Layout::InlineFormattingGeometry::formattingContext const):
* layout/formattingContexts/table/TableFormattingGeometry.cpp:
(WebCore::Layout::TableFormattingGeometry::TableFormattingGeometry):
* layout/formattingContexts/table/TableFormattingGeometry.h:
(WebCore::Layout::TableFormattingGeometry::formattingContext const):
* layout/formattingContexts/table/TableFormattingQuirks.h:
(WebCore::Layout::TableFormattingQuirks::geometry const):</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="#trunkSourceWebCorelayoutformattingContextsFormattingContextcpp">trunk/Source/WebCore/layout/formattingContexts/FormattingContext.cpp</a></li>
<li><a href="#trunkSourceWebCorelayoutformattingContextsFormattingContexth">trunk/Source/WebCore/layout/formattingContexts/FormattingContext.h</a></li>
<li><a href="#trunkSourceWebCorelayoutformattingContextsblockBlockFormattingGeometrycpp">trunk/Source/WebCore/layout/formattingContexts/block/BlockFormattingGeometry.cpp</a></li>
<li><a href="#trunkSourceWebCorelayoutformattingContextsblockBlockFormattingGeometryh">trunk/Source/WebCore/layout/formattingContexts/block/BlockFormattingGeometry.h</a></li>
<li><a href="#trunkSourceWebCorelayoutformattingContextsflexFlexFormattingGeometrycpp">trunk/Source/WebCore/layout/formattingContexts/flex/FlexFormattingGeometry.cpp</a></li>
<li><a href="#trunkSourceWebCorelayoutformattingContextsflexFlexFormattingGeometryh">trunk/Source/WebCore/layout/formattingContexts/flex/FlexFormattingGeometry.h</a></li>
<li><a href="#trunkSourceWebCorelayoutformattingContextsinlineInlineFormattingGeometrycpp">trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingGeometry.cpp</a></li>
<li><a href="#trunkSourceWebCorelayoutformattingContextsinlineInlineFormattingGeometryh">trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingGeometry.h</a></li>
<li><a href="#trunkSourceWebCorelayoutformattingContextstableTableFormattingGeometrycpp">trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingGeometry.cpp</a></li>
<li><a href="#trunkSourceWebCorelayoutformattingContextstableTableFormattingGeometryh">trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingGeometry.h</a></li>
<li><a href="#trunkSourceWebCorelayoutformattingContextstableTableFormattingQuirksh">trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingQuirks.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCorelayoutformattingContextsFormattingGeometrycpp">trunk/Source/WebCore/layout/formattingContexts/FormattingGeometry.cpp</a></li>
<li><a href="#trunkSourceWebCorelayoutformattingContextsFormattingGeometryh">trunk/Source/WebCore/layout/formattingContexts/FormattingGeometry.h</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceWebCorelayoutformattingContextsFormattingContextGeometrycpp">trunk/Source/WebCore/layout/formattingContexts/FormattingContextGeometry.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (277555 => 277556)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2021-05-16 01:50:34 UTC (rev 277555)
+++ trunk/Source/WebCore/ChangeLog      2021-05-16 01:56:55 UTC (rev 277556)
</span><span class="lines">@@ -1,5 +1,45 @@
</span><span class="cx"> 2021-05-15  Alan Bujtas  <zalan@apple.com>
</span><span class="cx"> 
</span><ins>+        [LFC] Move base formatting geometry to its own class
+        https://bugs.webkit.org/show_bug.cgi?id=225752
+
+        Reviewed by Antti Koivisto.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * layout/formattingContexts/FormattingContext.cpp:
+        (WebCore::Layout::FormattingContext::geometry const):
+        * layout/formattingContexts/FormattingContext.h:
+        (WebCore::Layout::FormattingContext::Geometry::layoutState const): Deleted.
+        (WebCore::Layout::FormattingContext::Geometry::layoutState): Deleted.
+        (WebCore::Layout::FormattingContext::Geometry::formattingContext const): Deleted.
+        (WebCore::Layout::FormattingContext::geometry const): Deleted.
+        (WebCore::Layout::FormattingContext::Geometry::Geometry): Deleted.
+        * layout/formattingContexts/FormattingContextGeometry.cpp: Removed.
+        * layout/formattingContexts/block/BlockFormattingGeometry.cpp:
+        (WebCore::Layout::BlockFormattingGeometry::BlockFormattingGeometry):
+        (WebCore::Layout::BlockFormattingGeometry::inFlowNonReplacedContentHeightAndMargin):
+        (WebCore::Layout::BlockFormattingGeometry::inFlowNonReplacedContentWidthAndMargin):
+        * layout/formattingContexts/block/BlockFormattingGeometry.h:
+        (WebCore::Layout::BlockFormattingGeometry::formattingContext const):
+        * layout/formattingContexts/flex/FlexFormattingGeometry.cpp:
+        (WebCore::Layout::FlexFormattingGeometry::FlexFormattingGeometry):
+        * layout/formattingContexts/flex/FlexFormattingGeometry.h:
+        (WebCore::Layout::FlexFormattingGeometry::formattingContext const):
+        * layout/formattingContexts/inline/InlineFormattingGeometry.cpp:
+        (WebCore::Layout::InlineFormattingGeometry::InlineFormattingGeometry):
+        (WebCore::Layout::InlineFormattingGeometry::inlineBlockContentWidthAndMargin):
+        * layout/formattingContexts/inline/InlineFormattingGeometry.h:
+        (WebCore::Layout::InlineFormattingGeometry::formattingContext const):
+        * layout/formattingContexts/table/TableFormattingGeometry.cpp:
+        (WebCore::Layout::TableFormattingGeometry::TableFormattingGeometry):
+        * layout/formattingContexts/table/TableFormattingGeometry.h:
+        (WebCore::Layout::TableFormattingGeometry::formattingContext const):
+        * layout/formattingContexts/table/TableFormattingQuirks.h:
+        (WebCore::Layout::TableFormattingQuirks::geometry const):
+
+2021-05-15  Alan Bujtas  <zalan@apple.com>
+
</ins><span class="cx">         [LFC] Move table formatting geometry to its own class
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=225753
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreSourcestxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Sources.txt (277555 => 277556)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Sources.txt 2021-05-16 01:50:34 UTC (rev 277555)
+++ trunk/Source/WebCore/Sources.txt    2021-05-16 01:56:55 UTC (rev 277556)
</span><span class="lines">@@ -1510,7 +1510,7 @@
</span><span class="cx"> inspector/agents/worker/WorkerNetworkAgent.cpp
</span><span class="cx"> inspector/agents/worker/WorkerRuntimeAgent.cpp
</span><span class="cx"> layout/formattingContexts/FormattingContext.cpp
</span><del>-layout/formattingContexts/FormattingContextGeometry.cpp
</del><ins>+layout/formattingContexts/FormattingGeometry.cpp
</ins><span class="cx"> layout/formattingContexts/FormattingQuirks.cpp
</span><span class="cx"> layout/FormattingState.cpp
</span><span class="cx"> layout/LayoutContext.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (277555 => 277556)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj   2021-05-16 01:50:34 UTC (rev 277555)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj      2021-05-16 01:56:55 UTC (rev 277556)
</span><span class="lines">@@ -1333,6 +1333,7 @@
</span><span class="cx">          46EFAF121E5FB9F100E7F34B /* LowPowerModeNotifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EFAF101E5FB9E100E7F34B /* LowPowerModeNotifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          46F02A1A23737F8300106A64 /* EventLoop.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B0ABCA123679AB300B45085 /* EventLoop.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          46FCB6181A70820E00C5A21E /* DiagnosticLoggingKeys.h in Headers */ = {isa = PBXBuildFile; fileRef = CD37B37515C1A7E1006DC898 /* DiagnosticLoggingKeys.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+               475C89A42650AC3C00F3B456 /* FormattingGeometry.h in Headers */ = {isa = PBXBuildFile; fileRef = 475C89A32650AC3B00F3B456 /* FormattingGeometry.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">           4786356526507A3800C5E2E0 /* BlockFormattingGeometry.h in Headers */ = {isa = PBXBuildFile; fileRef = 4786356426507A3700C5E2E0 /* BlockFormattingGeometry.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          47C4D57D26508BCB00C7AB1F /* InlineFormattingGeometry.h in Headers */ = {isa = PBXBuildFile; fileRef = 47C4D57C26508BCA00C7AB1F /* InlineFormattingGeometry.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          47F947DB26502F2F0087968C /* BlockFormattingQuirks.h in Headers */ = {isa = PBXBuildFile; fileRef = 47F947DA26502F2F0087968C /* BlockFormattingQuirks.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -8390,6 +8391,7 @@
</span><span class="cx">          46EFAF0F1E5FB9E100E7F34B /* LowPowerModeNotifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LowPowerModeNotifier.cpp; sourceTree = "<group>"; };
</span><span class="cx">          46EFAF101E5FB9E100E7F34B /* LowPowerModeNotifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LowPowerModeNotifier.h; sourceTree = "<group>"; };
</span><span class="cx">          46F91BC91FCDD0FE001599C3 /* JSWorkerNavigatorCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWorkerNavigatorCustom.cpp; sourceTree = "<group>"; };
</span><ins>+               475C89A32650AC3B00F3B456 /* FormattingGeometry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormattingGeometry.h; sourceTree = "<group>"; };
</ins><span class="cx">           4786356426507A3700C5E2E0 /* BlockFormattingGeometry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlockFormattingGeometry.h; sourceTree = "<group>"; };
</span><span class="cx">          47C4D57C26508BCA00C7AB1F /* InlineFormattingGeometry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineFormattingGeometry.h; sourceTree = "<group>"; };
</span><span class="cx">          47F947DA26502F2F0087968C /* BlockFormattingQuirks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlockFormattingQuirks.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -10030,7 +10032,7 @@
</span><span class="cx">          6FB7D2D8250FD7EF000207AA /* FlexFormattingState.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FlexFormattingState.cpp; sourceTree = "<group>"; };
</span><span class="cx">          6FB7D2D9250FD7FC000207AA /* FlexFormattingContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FlexFormattingContext.h; sourceTree = "<group>"; };
</span><span class="cx">          6FB7D2DA250FD7FC000207AA /* FlexFormattingState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FlexFormattingState.h; sourceTree = "<group>"; };
</span><del>-               6FBB860520B464B600DAD938 /* FormattingContextGeometry.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FormattingContextGeometry.cpp; sourceTree = "<group>"; };
</del><ins>+                6FBB860520B464B600DAD938 /* FormattingGeometry.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FormattingGeometry.cpp; sourceTree = "<group>"; };
</ins><span class="cx">           6FC3F9452516756600A49BEA /* InlineLineRun.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineLineRun.h; sourceTree = "<group>"; };
</span><span class="cx">          6FC53AEB24AF7A8E006059FE /* TableFormattingQuirks.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TableFormattingQuirks.cpp; sourceTree = "<group>"; };
</span><span class="cx">          6FC5CA9222E3599300B13E11 /* TableFormattingState.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TableFormattingState.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -22645,7 +22647,8 @@
</span><span class="cx">                          6FC5CA9122E3593300B13E11 /* table */,
</span><span class="cx">                          115CFA69208AF7D0001E6991 /* FormattingContext.cpp */,
</span><span class="cx">                          115CFA68208AF7D0001E6991 /* FormattingContext.h */,
</span><del>-                               6FBB860520B464B600DAD938 /* FormattingContextGeometry.cpp */,
</del><ins>+                                6FBB860520B464B600DAD938 /* FormattingGeometry.cpp */,
+                               475C89A32650AC3B00F3B456 /* FormattingGeometry.h */,
</ins><span class="cx">                           6F8F460121B03BB40041AC3A /* FormattingQuirks.cpp */,
</span><span class="cx">                          6F56B44626479E6100AAE257 /* FormattingQuirks.h */,
</span><span class="cx">                  );
</span><span class="lines">@@ -32554,6 +32557,7 @@
</span><span class="cx">                          D05CED2A0A40BB2C00C5AF38 /* FormatBlockCommand.h in Headers */,
</span><span class="cx">                          7CE6CBFB187F370700D46BF5 /* FormatConverter.h in Headers */,
</span><span class="cx">                          115CFA6A208AF7D0001E6991 /* FormattingContext.h in Headers */,
</span><ins>+                               475C89A42650AC3C00F3B456 /* FormattingGeometry.h in Headers */,
</ins><span class="cx">                           6F56B44726479E6200AAE257 /* FormattingQuirks.h in Headers */,
</span><span class="cx">                          115CFA76208AFE30001E6991 /* FormattingState.h in Headers */,
</span><span class="cx">                          F50664F8157F52DC00AC226F /* FormController.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceWebCorelayoutformattingContextsFormattingContextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/layout/formattingContexts/FormattingContext.cpp (277555 => 277556)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/formattingContexts/FormattingContext.cpp     2021-05-16 01:50:34 UTC (rev 277555)
+++ trunk/Source/WebCore/layout/formattingContexts/FormattingContext.cpp        2021-05-16 01:56:55 UTC (rev 277556)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
</span><span class="cx"> 
</span><ins>+#include "FormattingGeometry.h"
</ins><span class="cx"> #include "FormattingQuirks.h"
</span><span class="cx"> #include "FormattingState.h"
</span><span class="cx"> #include "InvalidationState.h"
</span><span class="lines">@@ -271,6 +272,11 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+FormattingGeometry FormattingContext::geometry() const
+{
+    return FormattingGeometry(*this);
+}
+
</ins><span class="cx"> FormattingQuirks FormattingContext::quirks() const
</span><span class="cx"> {
</span><span class="cx">     return FormattingQuirks(*this);
</span></span></pre></div>
<a id="trunkSourceWebCorelayoutformattingContextsFormattingContexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/layout/formattingContexts/FormattingContext.h (277555 => 277556)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/formattingContexts/FormattingContext.h       2021-05-16 01:50:34 UTC (rev 277555)
+++ trunk/Source/WebCore/layout/formattingContexts/FormattingContext.h  2021-05-16 01:56:55 UTC (rev 277556)
</span><span class="lines">@@ -41,21 +41,12 @@
</span><span class="cx"> namespace Layout {
</span><span class="cx"> 
</span><span class="cx"> class BoxGeometry;
</span><del>-class ReplacedBox;
-struct ComputedHorizontalMargin;
-struct ComputedVerticalMargin;
</del><span class="cx"> class ContainerBox;
</span><del>-struct ContentHeightAndMargin;
-struct ContentWidthAndMargin;
-struct Edges;
</del><ins>+class FormattingGeometry;
</ins><span class="cx"> class FormattingState;
</span><span class="cx"> class FormattingQuirks;
</span><del>-struct HorizontalGeometry;
</del><span class="cx"> class InvalidationState;
</span><span class="cx"> class LayoutState;
</span><del>-struct OverriddenHorizontalValues;
-struct OverriddenVerticalValues;
-struct VerticalGeometry;
</del><span class="cx"> 
</span><span class="cx"> class FormattingContext {
</span><span class="cx">     WTF_MAKE_ISO_ALLOCATED(FormattingContext);
</span><span class="lines">@@ -111,83 +102,9 @@
</span><span class="cx">     LayoutState& layoutState() const;
</span><span class="cx">     const FormattingState& formattingState() const { return m_formattingState; }
</span><span class="cx"> 
</span><ins>+    FormattingGeometry geometry() const;
</ins><span class="cx">     FormattingQuirks quirks() const;
</span><span class="cx"> 
</span><del>-    // This class implements generic positioning and sizing.
-    class Geometry {
-    public:
-        VerticalGeometry outOfFlowVerticalGeometry(const Box&, const HorizontalConstraints&, const VerticalConstraints&, const OverriddenVerticalValues&) const;
-        HorizontalGeometry outOfFlowHorizontalGeometry(const Box&, const HorizontalConstraints&, const VerticalConstraints&, const OverriddenHorizontalValues&);
-
-        ContentHeightAndMargin floatingContentHeightAndMargin(const Box&, const HorizontalConstraints&, const OverriddenVerticalValues&) const;
-        ContentWidthAndMargin floatingContentWidthAndMargin(const Box&, const HorizontalConstraints&, const OverriddenHorizontalValues&);
-
-        ContentHeightAndMargin inlineReplacedContentHeightAndMargin(const ReplacedBox&, const HorizontalConstraints&, Optional<VerticalConstraints>, const OverriddenVerticalValues&) const;
-        ContentWidthAndMargin inlineReplacedContentWidthAndMargin(const ReplacedBox&, const HorizontalConstraints&, Optional<VerticalConstraints>, const OverriddenHorizontalValues&);
-
-        LayoutSize inFlowPositionedPositionOffset(const Box&, const HorizontalConstraints&) const;
-
-        ContentHeightAndMargin complicatedCases(const Box&, const HorizontalConstraints&, const OverriddenVerticalValues&) const;
-        LayoutUnit shrinkToFitWidth(const Box&, LayoutUnit availableWidth);
-
-        Edges computedBorder(const Box&) const;
-        Optional<Edges> computedPadding(const Box&, LayoutUnit containingBlockWidth) const;
-
-        ComputedHorizontalMargin computedHorizontalMargin(const Box&, const HorizontalConstraints&) const;
-        ComputedVerticalMargin computedVerticalMargin(const Box&, const HorizontalConstraints&) const;
-
-        Optional<LayoutUnit> computedValue(const Length& geometryProperty, LayoutUnit containingBlockWidth) const;
-        Optional<LayoutUnit> fixedValue(const Length& geometryProperty) const;
-
-        Optional<LayoutUnit> computedMinHeight(const Box&, Optional<LayoutUnit> containingBlockHeight = WTF::nullopt) const;
-        Optional<LayoutUnit> computedMaxHeight(const Box&, Optional<LayoutUnit> containingBlockHeight = WTF::nullopt) const;
-
-        Optional<LayoutUnit> computedMinWidth(const Box&, LayoutUnit containingBlockWidth);
-        Optional<LayoutUnit> computedMaxWidth(const Box&, LayoutUnit containingBlockWidth);
-
-        FormattingContext::IntrinsicWidthConstraints constrainByMinMaxWidth(const Box&, IntrinsicWidthConstraints) const;
-
-        LayoutUnit contentHeightForFormattingContextRoot(const ContainerBox&) const;
-
-        ConstraintsForOutOfFlowContent constraintsForOutOfFlowContent(const ContainerBox&);
-        ConstraintsForInFlowContent constraintsForInFlowContent(const ContainerBox&, Optional<EscapeReason> = WTF::nullopt);
-
-        Optional<LayoutUnit> computedHeight(const Box&, Optional<LayoutUnit> containingBlockHeight = WTF::nullopt) const;
-        Optional<LayoutUnit> computedWidth(const Box&, LayoutUnit containingBlockWidth);
-
-    protected:
-        friend class FormattingContext;
-        Geometry(const FormattingContext&);
-
-        const LayoutState& layoutState() const { return m_formattingContext.layoutState(); }
-        LayoutState& layoutState() { return m_formattingContext.layoutState(); }
-        const FormattingContext& formattingContext() const { return m_formattingContext; }
-
-    private:
-        VerticalGeometry outOfFlowReplacedVerticalGeometry(const ReplacedBox&, const HorizontalConstraints&, const VerticalConstraints&, const OverriddenVerticalValues&) const;
-        HorizontalGeometry outOfFlowReplacedHorizontalGeometry(const ReplacedBox&, const HorizontalConstraints&, const VerticalConstraints&, const OverriddenHorizontalValues&);
-
-        VerticalGeometry outOfFlowNonReplacedVerticalGeometry(const ContainerBox&, const HorizontalConstraints&, const VerticalConstraints&, const OverriddenVerticalValues&) const;
-        HorizontalGeometry outOfFlowNonReplacedHorizontalGeometry(const ContainerBox&, const HorizontalConstraints&, const OverriddenHorizontalValues&);
-
-        ContentHeightAndMargin floatingReplacedContentHeightAndMargin(const ReplacedBox&, const HorizontalConstraints&, const OverriddenVerticalValues&) const;
-        ContentWidthAndMargin floatingReplacedContentWidthAndMargin(const ReplacedBox&, const HorizontalConstraints&, const OverriddenHorizontalValues&);
-
-        ContentWidthAndMargin floatingNonReplacedContentWidthAndMargin(const Box&, const HorizontalConstraints&, const OverriddenHorizontalValues&);
-
-        LayoutUnit staticVerticalPositionForOutOfFlowPositioned(const Box&, const VerticalConstraints&) const;
-        LayoutUnit staticHorizontalPositionForOutOfFlowPositioned(const Box&, const HorizontalConstraints&) const;
-
-        enum class HeightType { Min, Max, Normal };
-        Optional<LayoutUnit> computedHeightValue(const Box&, HeightType, Optional<LayoutUnit> containingBlockHeight) const;
-
-        enum class WidthType { Min, Max, Normal };
-        Optional<LayoutUnit> computedWidthValue(const Box&, WidthType, LayoutUnit containingBlockWidth);
-
-        const FormattingContext& m_formattingContext;
-    };
-    FormattingContext::Geometry geometry() const { return Geometry(*this); }
-
</del><span class="cx"> protected:
</span><span class="cx">     using LayoutQueue = Vector<const Box*>;
</span><span class="cx"> 
</span><span class="lines">@@ -208,11 +125,6 @@
</span><span class="cx">     FormattingState& m_formattingState;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-inline FormattingContext::Geometry::Geometry(const FormattingContext& formattingContext)
-    : m_formattingContext(formattingContext)
-{
-}
-
</del><span class="cx"> inline void FormattingContext::IntrinsicWidthConstraints::expand(LayoutUnit horizontalValue)
</span><span class="cx"> {
</span><span class="cx">     minimum += horizontalValue;
</span></span></pre></div>
<a id="trunkSourceWebCorelayoutformattingContextsFormattingContextGeometrycpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/layout/formattingContexts/FormattingContextGeometry.cpp (277555 => 277556)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/formattingContexts/FormattingContextGeometry.cpp     2021-05-16 01:50:34 UTC (rev 277555)
+++ trunk/Source/WebCore/layout/formattingContexts/FormattingContextGeometry.cpp        2021-05-16 01:56:55 UTC (rev 277556)
</span><span class="lines">@@ -1,1165 +0,0 @@
</span><del>-/*
- * Copyright (C) 2018 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 "FormattingContext.h"
-
-#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
-
-#include "BlockFormattingState.h"
-#include "FlexFormattingState.h"
-#include "FloatingContext.h"
-#include "FloatingState.h"
-#include "InlineFormattingState.h"
-#include "LayoutContext.h"
-#include "LayoutInitialContainingBlock.h"
-#include "LayoutReplacedBox.h"
-#include "Logging.h"
-#include "TableFormattingState.h"
-
-namespace WebCore {
-namespace Layout {
-
-static inline bool isHeightAuto(const Box& layoutBox)
-{
-    // 10.5 Content height: the 'height' property
-    //
-    // The percentage is calculated with respect to the height of the generated box's containing block.
-    // If the height of the containing block is not specified explicitly (i.e., it depends on content height),
-    // and this element is not absolutely positioned, the used height is calculated as if 'auto' was specified.
-
-    auto height = layoutBox.style().logicalHeight();
-    if (height.isAuto())
-        return true;
-
-    if (height.isPercent()) {
-        if (layoutBox.isOutOfFlowPositioned())
-            return false;
-
-        return !layoutBox.containingBlock().style().logicalHeight().isFixed();
-    }
-
-    return false;
-}
-
-Optional<LayoutUnit> FormattingContext::Geometry::computedHeightValue(const Box& layoutBox, HeightType heightType, Optional<LayoutUnit> containingBlockHeight) const
-{
-    auto& style = layoutBox.style();
-    auto height = heightType == HeightType::Normal ? style.logicalHeight() : heightType == HeightType::Min ? style.logicalMinHeight() : style.logicalMaxHeight();
-    if (height.isUndefined() || height.isAuto() || height.isMaxContent() || height.isMinContent() || height.isFitContent())
-        return { };
-
-    if (height.isFixed())
-        return LayoutUnit { height.value() };
-
-    if (!containingBlockHeight) {
-        if (layoutState().inQuirksMode())
-            containingBlockHeight = formattingContext().quirks().heightValueOfNearestContainingBlockWithFixedHeight(layoutBox);
-        else {
-            auto nonAnonymousContainingBlockLogicalHeight = [&] {
-                // When the block level box is a direct child of an inline level box (<span><div></div></span>) and we wrap it into a continuation,
-                // the containing block (anonymous wrapper) is not the box we need to check for fixed height.
-                auto& initialContainingBlock = layoutBox.initialContainingBlock();
-                for (auto* containingBlock = &layoutBox.containingBlock(); containingBlock != &initialContainingBlock; containingBlock = &containingBlock->containingBlock()) {
-                    if (containingBlock->isAnonymous())
-                        continue;
-                    return containingBlock->style().logicalHeight();
-                }
-                return initialContainingBlock.style().logicalHeight();
-            };
-            containingBlockHeight = fixedValue(nonAnonymousContainingBlockLogicalHeight());
-        }
-    }
-
-    if (!containingBlockHeight)
-        return { };
-
-    return valueForLength(height, *containingBlockHeight);
-}
-
-Optional<LayoutUnit> FormattingContext::Geometry::computedHeight(const Box& layoutBox, Optional<LayoutUnit> containingBlockHeight) const
-{
-    if (auto height = computedHeightValue(layoutBox, HeightType::Normal, containingBlockHeight)) {
-        if (layoutBox.style().boxSizing() == BoxSizing::ContentBox)
-            return height;
-        auto& boxGeometry = formattingContext().geometryForBox(layoutBox);
-        return *height - (boxGeometry.verticalBorder() + boxGeometry.verticalPadding().valueOr(0));
-    }
-    return { };
-}
-
-Optional<LayoutUnit> FormattingContext::Geometry::computedWidthValue(const Box& layoutBox, WidthType widthType, LayoutUnit containingBlockWidth)
-{
-    // Applies to: all elements except non-replaced inlines (out-of-flow check is required for positioned <br> as for some reason we don't blockify them).
-    ASSERT(!layoutBox.isInlineBox() || layoutBox.isOutOfFlowPositioned());
-
-    auto width = [&] {
-        auto& style = layoutBox.style();
-        switch (widthType) {
-        case WidthType::Normal:
-            return style.logicalWidth();
-        case WidthType::Min:
-            return style.logicalMinWidth();
-        case WidthType::Max:
-            return style.logicalMaxWidth();
-        }
-        ASSERT_NOT_REACHED();
-        return style.logicalWidth();
-    }();
-    if (auto computedValue = this->computedValue(width, containingBlockWidth))
-        return computedValue;
-
-    if (width.isMinContent() || width.isMaxContent() || width.isFitContent()) {
-        if (!is<ContainerBox>(layoutBox))
-            return { };
-        auto& containerBox = downcast<ContainerBox>(layoutBox);
-        // FIXME: Consider splitting up computedIntrinsicWidthConstraints so that we could computed the min and max values separately.
-        auto intrinsicWidthConstraints = [&] {
-            if (!containerBox.hasInFlowOrFloatingChild())
-                return IntrinsicWidthConstraints { 0_lu, containingBlockWidth };
-            ASSERT(containerBox.establishesFormattingContext());
-            auto& formattingState = layoutState().ensureFormattingState(containerBox);
-            if (auto intrinsicWidthConstraints = formattingState.intrinsicWidthConstraints())
-                return *intrinsicWidthConstraints;
-            return LayoutContext::createFormattingContext(containerBox, layoutState())->computedIntrinsicWidthConstraints();
-        }();
-        if (width.isMinContent())
-            return intrinsicWidthConstraints.minimum;
-        if (width.isMaxContent())
-            return intrinsicWidthConstraints.maximum;
-        ASSERT(width.isFitContent());
-        // If the available space in a given axis is definite, equal to min(max-content size,
-        // max(min-content size, stretch-fit size)). Otherwise, equal to the max-content size in that axis.
-        // FIXME: We don't yet have indefinite available size.
-        return std::min(intrinsicWidthConstraints.maximum, std::max(intrinsicWidthConstraints.minimum, containingBlockWidth));
-    }
-    return { };
-}
-
-Optional<LayoutUnit> FormattingContext::Geometry::computedWidth(const Box& layoutBox, LayoutUnit containingBlockWidth)
-{
-    if (auto computedWidth = computedWidthValue(layoutBox, WidthType::Normal, containingBlockWidth)) {
-        auto& style = layoutBox.style();
-        // Non-quantitative values such as auto and min-content are not influenced by the box-sizing property.
-        if (style.boxSizing() == BoxSizing::ContentBox || style.width().isIntrinsicOrAuto())
-            return computedWidth;
-        auto& boxGeometry = formattingContext().geometryForBox(layoutBox);
-        return *computedWidth - (boxGeometry.horizontalBorder() + boxGeometry.horizontalPadding().valueOr(0));
-    }
-    return { };
-}
-
-LayoutUnit FormattingContext::Geometry::contentHeightForFormattingContextRoot(const ContainerBox& formattingContextRoot) const
-{
-    ASSERT(formattingContextRoot.establishesFormattingContext());
-    ASSERT(isHeightAuto(formattingContextRoot) || formattingContextRoot.establishesTableFormattingContext() || formattingContextRoot.isTableCell());
-    auto usedContentHeight = LayoutUnit { }; 
-    auto hasContent = formattingContextRoot.hasInFlowOrFloatingChild();
-    // The used height of the containment box is determined as if performing a normal layout of the box, except that it is treated as having no content.
-    auto shouldIgnoreContent = formattingContextRoot.isSizeContainmentBox();
-    if (hasContent && !shouldIgnoreContent)
-        usedContentHeight = LayoutContext::createFormattingContext(formattingContextRoot, const_cast<LayoutState&>(layoutState()))->usedContentHeight();
-    return usedContentHeight;
-}
-
-Optional<LayoutUnit> FormattingContext::Geometry::computedValue(const Length& geometryProperty, LayoutUnit containingBlockWidth) const
-{
-    //  In general, the computed value resolves the specified value as far as possible without laying out the content.
-    if (geometryProperty.isFixed() || geometryProperty.isPercent() || geometryProperty.isCalculated())
-        return valueForLength(geometryProperty, containingBlockWidth);
-    return { };
-}
-
-Optional<LayoutUnit> FormattingContext::Geometry::fixedValue(const Length& geometryProperty) const
-{
-    if (!geometryProperty.isFixed())
-        return { };
-    return LayoutUnit { geometryProperty.value() };
-}
-
-// https://www.w3.org/TR/CSS22/visudet.html#min-max-heights
-// Specifies a percentage for determining the used value. The percentage is calculated with respect to the height of the generated box's containing block.
-// If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned,
-// the percentage value is treated as '0' (for 'min-height') or 'none' (for 'max-height').
-Optional<LayoutUnit> FormattingContext::Geometry::computedMaxHeight(const Box& layoutBox, Optional<LayoutUnit> containingBlockHeight) const
-{
-    return computedHeightValue(layoutBox, HeightType::Max, containingBlockHeight);
-}
-
-Optional<LayoutUnit> FormattingContext::Geometry::computedMinHeight(const Box& layoutBox, Optional<LayoutUnit> containingBlockHeight) const
-{
-    return computedHeightValue(layoutBox, HeightType::Min, containingBlockHeight);
-}
-
-Optional<LayoutUnit> FormattingContext::Geometry::computedMinWidth(const Box& layoutBox, LayoutUnit containingBlockWidth)
-{
-    return computedWidthValue(layoutBox, WidthType::Min, containingBlockWidth);
-}
-
-Optional<LayoutUnit> FormattingContext::Geometry::computedMaxWidth(const Box& layoutBox, LayoutUnit containingBlockWidth)
-{
-    return computedWidthValue(layoutBox, WidthType::Max, containingBlockWidth);
-}
-
-LayoutUnit FormattingContext::Geometry::staticVerticalPositionForOutOfFlowPositioned(const Box& layoutBox, const VerticalConstraints& verticalConstraints) const
-{
-    ASSERT(layoutBox.isOutOfFlowPositioned());
-
-    // For the purposes of this section and the next, the term "static position" (of an element) refers, roughly, to the position an element would have
-    // had in the normal flow. More precisely, the static position for 'top' is the distance from the top edge of the containing block to the top margin
-    // edge of a hypothetical box that would have been the first box of the element if its specified 'position' value had been 'static' and its specified
-    // 'float' had been 'none' and its specified 'clear' had been 'none'. (Note that due to the rules in section 9.7 this might require also assuming a different
-    // computed value for 'display'.) The value is negative if the hypothetical box is above the containing block.
-
-    // Start with this box's border box offset from the parent's border box.
-    auto& formattingContext = this->formattingContext();
-    LayoutUnit top;
-    if (layoutBox.previousInFlowSibling() && layoutBox.previousInFlowSibling()->isBlockLevelBox()) {
-        // Add sibling offset
-        auto& previousInFlowSibling = *layoutBox.previousInFlowSibling();
-        auto& previousInFlowBoxGeometry = formattingContext.geometryForBox(previousInFlowSibling, EscapeReason::OutOfFlowBoxNeedsInFlowGeometry);
-        auto& formattingState = downcast<BlockFormattingState>(layoutState().formattingStateForBox(previousInFlowSibling));
-        auto usedVerticalMarginForPreviousBox = formattingState.usedVerticalMargin(previousInFlowSibling);
-
-        top += BoxGeometry::borderBoxRect(previousInFlowBoxGeometry).bottom() + usedVerticalMarginForPreviousBox.nonCollapsedValues.after;
-    } else
-        top = formattingContext.geometryForBox(layoutBox.parent(), EscapeReason::OutOfFlowBoxNeedsInFlowGeometry).contentBoxTop();
-
-    // Resolve top all the way up to the containing block.
-    auto& containingBlock = layoutBox.containingBlock();
-    // Start with the parent since we pretend that this box is normal flow.
-    for (auto* ancestor = &layoutBox.parent(); ancestor != &containingBlock; ancestor = &ancestor->containingBlock()) {
-        auto& boxGeometry = formattingContext.geometryForBox(*ancestor, EscapeReason::OutOfFlowBoxNeedsInFlowGeometry);
-        // BoxGeometry::top is the border box top position in its containing block's coordinate system.
-        top += BoxGeometry::borderBoxTop(boxGeometry);
-        ASSERT(!ancestor->isPositioned() || layoutBox.isFixedPositioned());
-    }
-    // Move the static position relative to the padding box. This is very specific to abolutely positioned boxes.
-    return top - verticalConstraints.logicalTop;
-}
-
-LayoutUnit FormattingContext::Geometry::staticHorizontalPositionForOutOfFlowPositioned(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints) const
-{
-    ASSERT(layoutBox.isOutOfFlowPositioned());
-    // See staticVerticalPositionForOutOfFlowPositioned for the definition of the static position.
-
-    // Start with this box's border box offset from the parent's border box.
-    auto& formattingContext = this->formattingContext();
-    auto left = formattingContext.geometryForBox(layoutBox.parent(), EscapeReason::OutOfFlowBoxNeedsInFlowGeometry).contentBoxLeft();
-
-    // Resolve left all the way up to the containing block.
-    auto& containingBlock = layoutBox.containingBlock();
-    // Start with the parent since we pretend that this box is normal flow.
-    for (auto* ancestor = &layoutBox.parent(); ancestor != &containingBlock; ancestor = &ancestor->containingBlock()) {
-        auto& boxGeometry = formattingContext.geometryForBox(*ancestor, EscapeReason::OutOfFlowBoxNeedsInFlowGeometry);
-        // BoxGeometry::left is the border box left position in its containing block's coordinate system.
-        left += BoxGeometry::borderBoxLeft(boxGeometry);
-        ASSERT(!ancestor->isPositioned() || layoutBox.isFixedPositioned());
-    }
-    // Move the static position relative to the padding box. This is very specific to abolutely positioned boxes.
-    return left - horizontalConstraints.logicalLeft;
-}
-
-LayoutUnit FormattingContext::Geometry::shrinkToFitWidth(const Box& formattingContextRoot, LayoutUnit availableWidth)
-{
-    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Width] -> shrink to fit -> unsupported -> width(" << LayoutUnit { } << "px) layoutBox: " << &formattingContextRoot << ")");
-    ASSERT(formattingContextRoot.establishesFormattingContext());
-
-    // Calculation of the shrink-to-fit width is similar to calculating the width of a table cell using the automatic table layout algorithm.
-    // Roughly: calculate the preferred width by formatting the content without breaking lines other than where explicit line breaks occur,
-    // and also calculate the preferred minimum width, e.g., by trying all possible line breaks. CSS 2.2 does not define the exact algorithm.
-    // Thirdly, find the available width: in this case, this is the width of the containing block minus the used values of 'margin-left', 'border-left-width',
-    // 'padding-left', 'padding-right', 'border-right-width', 'margin-right', and the widths of any relevant scroll bars.
-
-    // Then the shrink-to-fit width is: min(max(preferred minimum width, available width), preferred width).
-    auto intrinsicWidthConstraints = IntrinsicWidthConstraints { };
-    auto hasContent = is<ContainerBox>(formattingContextRoot) && downcast<ContainerBox>(formattingContextRoot).hasInFlowOrFloatingChild();
-    // The used width of the containment box is determined as if performing a normal layout of the box, except that it is treated as having no content.
-    auto shouldIgnoreContent = formattingContextRoot.isSizeContainmentBox();  
-    if (hasContent && !shouldIgnoreContent) {
-        auto& root = downcast<ContainerBox>(formattingContextRoot);
-        auto& formattingStateForRoot = layoutState().ensureFormattingState(root);
-        auto precomputedIntrinsicWidthConstraints = formattingStateForRoot.intrinsicWidthConstraints();
-        if (!precomputedIntrinsicWidthConstraints)
-            intrinsicWidthConstraints = LayoutContext::createFormattingContext(root, layoutState())->computedIntrinsicWidthConstraints();
-        else
-            intrinsicWidthConstraints = *precomputedIntrinsicWidthConstraints;
-    }
-    return std::min(std::max(intrinsicWidthConstraints.minimum, availableWidth), intrinsicWidthConstraints.maximum);
-}
-
-VerticalGeometry FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry(const ContainerBox& layoutBox, const HorizontalConstraints& horizontalConstraints, const VerticalConstraints& verticalConstraints, const OverriddenVerticalValues& overriddenVerticalValues) const
-{
-    ASSERT(layoutBox.isOutOfFlowPositioned() && !layoutBox.isReplacedBox());
-    ASSERT(verticalConstraints.logicalHeight);
-
-    // 10.6.4 Absolutely positioned, non-replaced elements
-    //
-    // For absolutely positioned elements, the used values of the vertical dimensions must satisfy this constraint:
-    // 'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom'
-    // = height of containing block
-
-    // If all three of 'top', 'height', and 'bottom' are auto, set 'top' to the static position and apply rule number three below.
-
-    // If none of the three are 'auto': If both 'margin-top' and 'margin-bottom' are 'auto', solve the equation under the extra
-    // constraint that the two margins get equal values. If one of 'margin-top' or 'margin-bottom' is 'auto', solve the equation for that value.
-    // If the values are over-constrained, ignore the value for 'bottom' and solve for that value.
-
-    // Otherwise, pick the one of the following six rules that applies.
-
-    // 1. 'top' and 'height' are 'auto' and 'bottom' is not 'auto', then the height is based on the content per 10.6.7,
-    //     set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'top'
-    // 2. 'top' and 'bottom' are 'auto' and 'height' is not 'auto', then set 'top' to the static position, set 'auto' values for
-    //    'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'
-    // 3. 'height' and 'bottom' are 'auto' and 'top' is not 'auto', then the height is based on the content per 10.6.7, set 'auto'
-    //     values for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'
-    // 4. 'top' is 'auto', 'height' and 'bottom' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'top'
-    // 5. 'height' is 'auto', 'top' and 'bottom' are not 'auto', then 'auto' values for 'margin-top' and 'margin-bottom' are set to 0 and solve for 'height'
-    // 6. 'bottom' is 'auto', 'top' and 'height' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0 and solve for 'bottom'
-
-    auto& formattingContext = this->formattingContext();
-    auto& style = layoutBox.style();
-    auto& boxGeometry = formattingContext.geometryForBox(layoutBox);
-    auto containingBlockHeight = *verticalConstraints.logicalHeight;
-    auto containingBlockWidth = horizontalConstraints.logicalWidth;
-
-    auto top = computedValue(style.logicalTop(), containingBlockWidth);
-    auto bottom = computedValue(style.logicalBottom(), containingBlockWidth);
-    auto height = overriddenVerticalValues.height ? overriddenVerticalValues.height.value() : computedHeight(layoutBox, containingBlockHeight);
-    auto computedVerticalMargin = Geometry::computedVerticalMargin(layoutBox, horizontalConstraints);
-    UsedVerticalMargin::NonCollapsedValues usedVerticalMargin; 
-    auto paddingTop = boxGeometry.paddingTop().valueOr(0);
-    auto paddingBottom = boxGeometry.paddingBottom().valueOr(0);
-    auto borderTop = boxGeometry.borderTop();
-    auto borderBottom = boxGeometry.borderBottom();
-
-    if (!top && !height && !bottom)
-        top = staticVerticalPositionForOutOfFlowPositioned(layoutBox, verticalConstraints);
-
-    if (top && height && bottom) {
-        if (!computedVerticalMargin.before && !computedVerticalMargin.after) {
-            auto marginBeforeAndAfter = containingBlockHeight - (*top + borderTop + paddingTop + *height + paddingBottom + borderBottom + *bottom);
-            usedVerticalMargin = { marginBeforeAndAfter / 2, marginBeforeAndAfter / 2 };
-        } else if (!computedVerticalMargin.before) {
-            usedVerticalMargin.after = *computedVerticalMargin.after;
-            usedVerticalMargin.before = containingBlockHeight - (*top + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after + *bottom);
-        } else if (!computedVerticalMargin.after) {
-            usedVerticalMargin.before = *computedVerticalMargin.before;
-            usedVerticalMargin.after = containingBlockHeight - (*top + usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + *bottom);
-        } else
-            usedVerticalMargin = { *computedVerticalMargin.before, *computedVerticalMargin.after };
-        // Over-constrained?
-        auto boxHeight = *top + usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after + *bottom;
-        if (boxHeight != containingBlockHeight)
-            bottom = containingBlockHeight - (*top + usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after);
-    }
-
-    if (!top && !height && bottom) {
-        // #1
-        height = contentHeightForFormattingContextRoot(layoutBox);
-        usedVerticalMargin = { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) };
-        top = containingBlockHeight - (usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after + *bottom); 
-    }
-
-    if (!top && !bottom && height) {
-        // #2
-        top = staticVerticalPositionForOutOfFlowPositioned(layoutBox, verticalConstraints);
-        usedVerticalMargin = { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) };
-        bottom = containingBlockHeight - (*top + usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after);
-    }
-
-    if (!height && !bottom && top) {
-        // #3
-        height = contentHeightForFormattingContextRoot(layoutBox);
-        usedVerticalMargin = { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) };
-        bottom = containingBlockHeight - (*top + usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after);
-    }
-
-    if (!top && height && bottom) {
-        // #4
-        usedVerticalMargin = { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) };
-        top = containingBlockHeight - (usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after + *bottom);
-    }
-
-    if (!height && top && bottom) {
-        // #5
-        usedVerticalMargin = { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) };
-        height = containingBlockHeight - (*top + usedVerticalMargin.before + borderTop + paddingTop + paddingBottom + borderBottom + usedVerticalMargin.after + *bottom);
-    }
-
-    if (!bottom && top && height) {
-        // #6
-        usedVerticalMargin = { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) };
-        bottom = containingBlockHeight - (*top + usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after);
-    }
-
-    ASSERT(top);
-    ASSERT(bottom);
-    ASSERT(height);
-
-    // For out-of-flow elements the containing block is formed by the padding edge of the ancestor.
-    // At this point the positioned value is in the coordinate system of the padding box. Let's convert it to border box coordinate system.
-    auto containingBlockPaddingVerticalEdge = verticalConstraints.logicalTop;
-    *top += containingBlockPaddingVerticalEdge;
-    *bottom += containingBlockPaddingVerticalEdge;
-
-    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position][Height][Margin] -> out-of-flow non-replaced -> top(" << *top << "px) bottom("  << *bottom << "px) height(" << *height << "px) margin(" << usedVerticalMargin.before << "px, "  << usedVerticalMargin.after << "px) layoutBox(" << &layoutBox << ")");
-    return { *top, *bottom, { *height, usedVerticalMargin } };
-}
-
-HorizontalGeometry FormattingContext::Geometry::outOfFlowNonReplacedHorizontalGeometry(const ContainerBox& layoutBox, const HorizontalConstraints& horizontalConstraints, const OverriddenHorizontalValues& overriddenHorizontalValues)
-{
-    ASSERT(layoutBox.isOutOfFlowPositioned() && !layoutBox.isReplacedBox());
-    
-    // 10.3.7 Absolutely positioned, non-replaced elements
-    //
-    // 'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right'
-    // = width of containing block
-
-    // If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0.
-    // Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static
-    // position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below.
-    //
-    // If none of the three is 'auto': If both 'margin-left' and 'margin-right' are 'auto', solve the equation under the extra constraint that the two margins get equal values,
-    // unless this would make them negative, in which case when direction of the containing block is 'ltr' ('rtl'), set 'margin-left' ('margin-right') to zero and
-    // solve for 'margin-right' ('margin-left'). If one of 'margin-left' or 'margin-right' is 'auto', solve the equation for that value.
-    // If the values are over-constrained, ignore the value for 'left' (in case the 'direction' property of the containing block is 'rtl') or 'right'
-    // (in case 'direction' is 'ltr') and solve for that value.
-    //
-    // Otherwise, set 'auto' values for 'margin-left' and 'margin-right' to 0, and pick the one of the following six rules that applies.
-    //
-    // 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left'
-    // 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if the 'direction' property of the element establishing the static-position 
-    //    containing block is 'ltr' set 'left' to the static position, otherwise set 'right' to the static position.
-    //    Then solve for 'left' (if 'direction is 'rtl') or 'right' (if 'direction' is 'ltr').
-    // 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right'
-    // 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve for 'left'
-    // 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve for 'width'
-    // 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve for 'right'
-
-    auto& formattingContext = this->formattingContext();
-    auto& style = layoutBox.style();
-    auto& boxGeometry = formattingContext.geometryForBox(layoutBox);
-    auto containingBlockWidth = horizontalConstraints.logicalWidth;
-    auto isLeftToRightDirection = layoutBox.containingBlock().style().isLeftToRightDirection();
-    
-    auto left = computedValue(style.logicalLeft(), containingBlockWidth);
-    auto right = computedValue(style.logicalRight(), containingBlockWidth);
-    auto width = overriddenHorizontalValues.width ? overriddenHorizontalValues.width : computedWidth(layoutBox, containingBlockWidth);
-    auto computedHorizontalMargin = Geometry::computedHorizontalMargin(layoutBox, horizontalConstraints);
-    UsedHorizontalMargin usedHorizontalMargin;
-    auto paddingLeft = boxGeometry.paddingLeft().valueOr(0);
-    auto paddingRight = boxGeometry.paddingRight().valueOr(0);
-    auto borderLeft = boxGeometry.borderLeft();
-    auto borderRight = boxGeometry.borderRight();
-    if (!left && !width && !right) {
-        // If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0.
-        // Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static
-        // position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below.
-        usedHorizontalMargin = { computedHorizontalMargin.start.valueOr(0), computedHorizontalMargin.end.valueOr(0) };
-
-        auto staticHorizontalPosition = staticHorizontalPositionForOutOfFlowPositioned(layoutBox, horizontalConstraints);
-        if (isLeftToRightDirection)
-            left = staticHorizontalPosition;
-        else
-            right = staticHorizontalPosition;
-    } else if (left && width && right) {
-        // If none of the three is 'auto': If both 'margin-left' and 'margin-right' are 'auto', solve the equation under the extra constraint that the two margins get equal values,
-        // unless this would make them negative, in which case when direction of the containing block is 'ltr' ('rtl'), set 'margin-left' ('margin-right') to zero and
-        // solve for 'margin-right' ('margin-left'). If one of 'margin-left' or 'margin-right' is 'auto', solve the equation for that value.
-        // If the values are over-constrained, ignore the value for 'left' (in case the 'direction' property of the containing block is 'rtl') or 'right'
-        // (in case 'direction' is 'ltr') and solve for that value.
-        if (!computedHorizontalMargin.start && !computedHorizontalMargin.end) {
-            auto marginStartAndEnd = containingBlockWidth - (*left + borderLeft + paddingLeft + *width + paddingRight + borderRight + *right);
-            if (marginStartAndEnd >= 0)
-                usedHorizontalMargin = { marginStartAndEnd / 2, marginStartAndEnd / 2 };
-            else {
-                if (isLeftToRightDirection) {
-                    usedHorizontalMargin.start = 0_lu;
-                    usedHorizontalMargin.end = containingBlockWidth - (*left + usedHorizontalMargin.start + borderLeft + paddingLeft + *width + paddingRight + borderRight + *right);
-                } else {
-                    usedHorizontalMargin.end = 0_lu;
-                    usedHorizontalMargin.start = containingBlockWidth - (*left + borderLeft + paddingLeft + *width + paddingRight + borderRight + usedHorizontalMargin.end + *right);
-                }
-            }
-        } else if (!computedHorizontalMargin.start) {
-            usedHorizontalMargin.end = *computedHorizontalMargin.end;
-            usedHorizontalMargin.start = containingBlockWidth - (*left + borderLeft + paddingLeft + *width + paddingRight + borderRight + usedHorizontalMargin.end + *right);
-        } else if (!computedHorizontalMargin.end) {
-            usedHorizontalMargin.start = *computedHorizontalMargin.start;
-            usedHorizontalMargin.end = containingBlockWidth - (*left + usedHorizontalMargin.start + borderLeft + paddingLeft + *width + paddingRight + borderRight + *right);
-        } else {
-            usedHorizontalMargin = { *computedHorizontalMargin.start, *computedHorizontalMargin.end };
-            // Overconstrained? Ignore right (left).
-            if (isLeftToRightDirection)
-                right = containingBlockWidth - (usedHorizontalMargin.start + *left + borderLeft + paddingLeft + *width + paddingRight + borderRight + usedHorizontalMargin.end);
-            else
-                left = containingBlockWidth - (usedHorizontalMargin.start + borderLeft + paddingLeft + *width + paddingRight + borderRight + usedHorizontalMargin.end + *right);
-        }
-    } else {
-        // Otherwise, set 'auto' values for 'margin-left' and 'margin-right' to 0, and pick the one of the following six rules that applies.
-        usedHorizontalMargin = { computedHorizontalMargin.start.valueOr(0), computedHorizontalMargin.end.valueOr(0) };
-    }
-
-    if (!left && !width && right) {
-        // #1
-        // Calculate the available width by solving for 'width' after setting 'left' (in case 1) to 0
-        left = LayoutUnit { 0 };
-        auto availableWidth = containingBlockWidth - (*left + usedHorizontalMargin.start + borderLeft + paddingLeft + paddingRight + borderRight + usedHorizontalMargin.end + *right);
-        width = shrinkToFitWidth(layoutBox, availableWidth);
-        left = containingBlockWidth - (usedHorizontalMargin.start + borderLeft + paddingLeft + *width + paddingRight  + borderRight + usedHorizontalMargin.end + *right);
-    } else if (!left && !right && width) {
-        // #2
-        auto staticHorizontalPosition = staticHorizontalPositionForOutOfFlowPositioned(layoutBox, horizontalConstraints);
-        if (isLeftToRightDirection) {
-            left = staticHorizontalPosition;
-            right = containingBlockWidth - (*left + usedHorizontalMargin.start + borderLeft + paddingLeft + *width + paddingRight + borderRight + usedHorizontalMargin.end);
-        } else {
-            right = staticHorizontalPosition;
-            left = containingBlockWidth - (usedHorizontalMargin.start + borderLeft + paddingLeft + *width + paddingRight + borderRight + usedHorizontalMargin.end + *right);
-        }
-    } else if (!width && !right && left) {
-        // #3
-        // Calculate the available width by solving for 'width' after setting 'right' (in case 3) to 0
-        right = LayoutUnit { 0 };
-        auto availableWidth = containingBlockWidth - (*left + usedHorizontalMargin.start + borderLeft + paddingLeft + paddingRight + borderRight + usedHorizontalMargin.end + *right);
-        width = shrinkToFitWidth(layoutBox, availableWidth);
-        right = containingBlockWidth - (*left + usedHorizontalMargin.start + borderLeft + paddingLeft + *width + paddingRight + borderRight + usedHorizontalMargin.end);
-    } else if (!left && width && right) {
-        // #4
-        left = containingBlockWidth - (usedHorizontalMargin.start + borderLeft + paddingLeft + *width + paddingRight + borderRight + usedHorizontalMargin.end + *right);
-    } else if (!width && left && right) {
-        // #5
-        width = containingBlockWidth - (*left + usedHorizontalMargin.start + borderLeft + paddingLeft + paddingRight + borderRight + usedHorizontalMargin.end + *right);
-    } else if (!right && left && width) {
-        // #6
-        right = containingBlockWidth - (*left + usedHorizontalMargin.start + borderLeft + paddingLeft + *width + paddingRight + borderRight + usedHorizontalMargin.end);
-    }
-
-    ASSERT(left);
-    ASSERT(right);
-    ASSERT(width);
-
-    // For out-of-flow elements the containing block is formed by the padding edge of the ancestor.
-    // At this point the positioned value is in the coordinate system of the padding box. Let's convert it to border box coordinate system.
-    auto containingBlockPaddingVerticalEdge = horizontalConstraints.logicalLeft;
-    *left += containingBlockPaddingVerticalEdge;
-    *right += containingBlockPaddingVerticalEdge;
-
-    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position][Width][Margin] -> out-of-flow non-replaced -> left(" << *left << "px) right("  << *right << "px) width(" << *width << "px) margin(" << usedHorizontalMargin.start << "px, "  << usedHorizontalMargin.end << "px) layoutBox(" << &layoutBox << ")");
-    return { *left, *right, { *width, usedHorizontalMargin } };
-}
-
-VerticalGeometry FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry(const ReplacedBox& replacedBox, const HorizontalConstraints& horizontalConstraints, const VerticalConstraints& verticalConstraints, const OverriddenVerticalValues& overriddenVerticalValues) const
-{
-    ASSERT(replacedBox.isOutOfFlowPositioned());
-    ASSERT(verticalConstraints.logicalHeight);
-
-    // 10.6.5 Absolutely positioned, replaced elements
-    //
-    // The used value of 'height' is determined as for inline replaced elements.
-    // If 'margin-top' or 'margin-bottom' is specified as 'auto' its used value is determined by the rules below.
-    // 1. If both 'top' and 'bottom' have the value 'auto', replace 'top' with the element's static position.
-    // 2. If 'bottom' is 'auto', replace any 'auto' on 'margin-top' or 'margin-bottom' with '0'.
-    // 3. If at this point both 'margin-top' and 'margin-bottom' are still 'auto', solve the equation under the extra constraint that the two margins must get equal values.
-    // 4. If at this point there is only one 'auto' left, solve the equation for that value.
-    // 5. If at this point the values are over-constrained, ignore the value for 'bottom' and solve for that value.
-
-    auto& formattingContext = this->formattingContext();
-    auto& style = replacedBox.style();
-    auto& boxGeometry = formattingContext.geometryForBox(replacedBox);
-    auto containingBlockHeight = *verticalConstraints.logicalHeight;
-    auto containingBlockWidth = horizontalConstraints.logicalWidth;
-
-    auto top = computedValue(style.logicalTop(), containingBlockWidth);
-    auto bottom = computedValue(style.logicalBottom(), containingBlockWidth);
-    auto height = inlineReplacedContentHeightAndMargin(replacedBox, horizontalConstraints, verticalConstraints, overriddenVerticalValues).contentHeight;
-    auto computedVerticalMargin = Geometry::computedVerticalMargin(replacedBox, horizontalConstraints);
-    Optional<LayoutUnit> usedMarginBefore = computedVerticalMargin.before;
-    Optional<LayoutUnit> usedMarginAfter = computedVerticalMargin.after;
-    auto paddingTop = boxGeometry.paddingTop().valueOr(0);
-    auto paddingBottom = boxGeometry.paddingBottom().valueOr(0);
-    auto borderTop = boxGeometry.borderTop();
-    auto borderBottom = boxGeometry.borderBottom();
-
-    if (!top && !bottom) {
-        // #1
-        top = staticVerticalPositionForOutOfFlowPositioned(replacedBox, verticalConstraints);
-    }
-
-    if (!bottom) {
-        // #2
-        usedMarginBefore = computedVerticalMargin.before.valueOr(0);
-        usedMarginAfter = usedMarginBefore;
-    }
-
-    if (!usedMarginBefore && !usedMarginAfter) {
-        // #3
-        auto marginBeforeAndAfter = containingBlockHeight - (*top + borderTop + paddingTop + height + paddingBottom + borderBottom + *bottom);
-        usedMarginBefore = marginBeforeAndAfter / 2;
-        usedMarginAfter = usedMarginBefore;
-    }
-
-    // #4
-    if (!top)
-        top = containingBlockHeight - (*usedMarginBefore + borderTop + paddingTop + height + paddingBottom + borderBottom + *usedMarginAfter + *bottom);
-
-    if (!bottom)
-        bottom = containingBlockHeight - (*top + *usedMarginBefore + borderTop + paddingTop + height + paddingBottom + borderBottom + *usedMarginAfter);
-
-    if (!usedMarginBefore)
-        usedMarginBefore = containingBlockHeight - (*top + borderTop + paddingTop + height + paddingBottom + borderBottom + *usedMarginAfter + *bottom);
-
-    if (!usedMarginAfter)
-        usedMarginAfter = containingBlockHeight - (*top + *usedMarginBefore + borderTop + paddingTop + height + paddingBottom + borderBottom + *bottom);
-
-    // #5
-    auto boxHeight = *top + *usedMarginBefore + borderTop + paddingTop + height + paddingBottom + borderBottom + *usedMarginAfter + *bottom;
-    if (boxHeight > containingBlockHeight)
-        bottom = containingBlockHeight - (*top + *usedMarginBefore + borderTop + paddingTop + height + paddingBottom + borderBottom + *usedMarginAfter); 
-
-    // For out-of-flow elements the containing block is formed by the padding edge of the ancestor.
-    // At this point the positioned value is in the coordinate system of the padding box. Let's convert it to border box coordinate system.
-    auto containingBlockPaddingVerticalEdge = verticalConstraints.logicalTop;
-    *top += containingBlockPaddingVerticalEdge;
-    *bottom += containingBlockPaddingVerticalEdge;
-
-    ASSERT(top);
-    ASSERT(bottom);
-    ASSERT(usedMarginBefore);
-    ASSERT(usedMarginAfter);
-    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position][Height][Margin] -> out-of-flow replaced -> top(" << *top << "px) bottom("  << *bottom << "px) height(" << height << "px) margin(" << *usedMarginBefore << "px, "  << *usedMarginAfter << "px) layoutBox(" << &replacedBox << ")");
-    return { *top, *bottom, { height, { *usedMarginBefore, *usedMarginAfter } } };
-}
-
-HorizontalGeometry FormattingContext::Geometry::outOfFlowReplacedHorizontalGeometry(const ReplacedBox& replacedBox, const HorizontalConstraints& horizontalConstraints, const VerticalConstraints& verticalConstraints, const OverriddenHorizontalValues& overriddenHorizontalValues)
-{
-    ASSERT(replacedBox.isOutOfFlowPositioned());
-
-    // 10.3.8 Absolutely positioned, replaced elements
-    // In this case, section 10.3.7 applies up through and including the constraint equation, but the rest of section 10.3.7 is replaced by the following rules:
-    //
-    // The used value of 'width' is determined as for inline replaced elements. If 'margin-left' or 'margin-right' is specified as 'auto' its used value is determined by the rules below.
-    // 1. If both 'left' and 'right' have the value 'auto', then if the 'direction' property of the element establishing the static-position containing block is 'ltr',
-    //   set 'left' to the static position; else if 'direction' is 'rtl', set 'right' to the static position.
-    // 2. If 'left' or 'right' are 'auto', replace any 'auto' on 'margin-left' or 'margin-right' with '0'.
-    // 3. If at this point both 'margin-left' and 'margin-right' are still 'auto', solve the equation under the extra constraint that the two margins must get equal values,
-    //   unless this would make them negative, in which case when the direction of the containing block is 'ltr' ('rtl'), set 'margin-left' ('margin-right') to zero and
-    //   solve for 'margin-right' ('margin-left').
-    // 4. If at this point there is an 'auto' left, solve the equation for that value.
-    // 5. If at this point the values are over-constrained, ignore the value for either 'left' (in case the 'direction' property of the containing block is 'rtl') or
-    //   'right' (in case 'direction' is 'ltr') and solve for that value.
-
-    auto& formattingContext = this->formattingContext();
-    auto& style = replacedBox.style();
-    auto& boxGeometry = formattingContext.geometryForBox(replacedBox);
-    auto containingBlockWidth = horizontalConstraints.logicalWidth;
-    auto isLeftToRightDirection = replacedBox.containingBlock().style().isLeftToRightDirection();
-
-    auto left = computedValue(style.logicalLeft(), containingBlockWidth);
-    auto right = computedValue(style.logicalRight(), containingBlockWidth);
-    auto computedHorizontalMargin = Geometry::computedHorizontalMargin(replacedBox, horizontalConstraints);
-    Optional<LayoutUnit> usedMarginStart = computedHorizontalMargin.start;
-    Optional<LayoutUnit> usedMarginEnd = computedHorizontalMargin.end;
-    auto width = inlineReplacedContentWidthAndMargin(replacedBox, horizontalConstraints, verticalConstraints, overriddenHorizontalValues).contentWidth;
-    auto paddingLeft = boxGeometry.paddingLeft().valueOr(0);
-    auto paddingRight = boxGeometry.paddingRight().valueOr(0);
-    auto borderLeft = boxGeometry.borderLeft();
-    auto borderRight = boxGeometry.borderRight();
-
-    if (!left && !right) {
-        // #1
-        auto staticHorizontalPosition = staticHorizontalPositionForOutOfFlowPositioned(replacedBox, horizontalConstraints);
-        if (isLeftToRightDirection)
-            left = staticHorizontalPosition;
-        else
-            right = staticHorizontalPosition;
-    }
-
-    if (!left || !right) {
-        // #2
-        usedMarginStart = computedHorizontalMargin.start.valueOr(0);
-        usedMarginEnd = computedHorizontalMargin.end.valueOr(0);
-    }
-
-    if (!usedMarginStart && !usedMarginEnd) {
-        // #3
-        auto marginStartAndEnd = containingBlockWidth - (*left + borderLeft + paddingLeft + width + paddingRight + borderRight + *right);
-        if (marginStartAndEnd >= 0) {
-            usedMarginStart = marginStartAndEnd / 2;
-            usedMarginEnd = usedMarginStart;
-        } else {
-            if (isLeftToRightDirection) {
-                usedMarginStart = 0_lu;
-                usedMarginEnd = containingBlockWidth - (*left + *usedMarginStart + borderLeft + paddingLeft + width + paddingRight + borderRight + *right);
-            } else {
-                usedMarginEnd = 0_lu;
-                usedMarginStart = containingBlockWidth - (*left + borderLeft + paddingLeft + width + paddingRight + borderRight + *usedMarginEnd + *right);
-            }
-        }
-    }
-
-    // #4
-    if (!left)
-        left = containingBlockWidth - (*usedMarginStart + borderLeft + paddingLeft + width + paddingRight + borderRight + *usedMarginEnd + *right);
-
-    if (!right)
-        right = containingBlockWidth - (*left + *usedMarginStart + borderLeft + paddingLeft + width + paddingRight + borderRight + *usedMarginEnd);
-
-    if (!usedMarginStart)
-        usedMarginStart = containingBlockWidth - (*left + borderLeft + paddingLeft + width + paddingRight + borderRight + *usedMarginEnd + *right);
-
-    if (!usedMarginEnd)
-        usedMarginEnd = containingBlockWidth - (*left + *usedMarginStart + borderLeft + paddingLeft + width + paddingRight + borderRight + *right);
-
-    auto boxWidth = (*left + *usedMarginStart + borderLeft + paddingLeft + width + paddingRight + borderRight + *usedMarginEnd + *right);
-    if (boxWidth > containingBlockWidth) {
-        // #5 Over-constrained?
-        if (isLeftToRightDirection)
-            right = containingBlockWidth - (*left + *usedMarginStart + borderLeft + paddingLeft + width + paddingRight + borderRight + *usedMarginEnd);
-        else
-            left = containingBlockWidth - (*usedMarginStart + borderLeft + paddingLeft + width + paddingRight + borderRight + *usedMarginEnd + *right);
-    }
-
-    ASSERT(left);
-    ASSERT(right);
-    ASSERT(usedMarginStart);
-    ASSERT(usedMarginEnd);
-
-    // For out-of-flow elements the containing block is formed by the padding edge of the ancestor.
-    // At this point the positioned value is in the coordinate system of the padding box. Let's convert it to border box coordinate system.
-    auto containingBlockPaddingVerticalEdge = horizontalConstraints.logicalLeft;
-    *left += containingBlockPaddingVerticalEdge;
-    *right += containingBlockPaddingVerticalEdge;
-
-    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position][Width][Margin] -> out-of-flow replaced -> left(" << *left << "px) right("  << *right << "px) width(" << width << "px) margin(" << *usedMarginStart << "px, "  << *usedMarginEnd << "px) layoutBox(" << &replacedBox << ")");
-    return { *left, *right, { width, { *usedMarginStart, *usedMarginEnd } } };
-}
-
-ContentHeightAndMargin FormattingContext::Geometry::complicatedCases(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints, const OverriddenVerticalValues& overriddenVerticalValues) const
-{
-    ASSERT(!layoutBox.isReplacedBox());
-    // TODO: Use complicated-case for document renderer for now (see BlockFormattingContext::Geometry::inFlowHeightAndMargin).
-    ASSERT((layoutBox.isBlockLevelBox() && layoutBox.isInFlow() && !layoutBox.isOverflowVisible()) || layoutBox.isInlineBlockBox() || layoutBox.isFloatingPositioned() || layoutBox.isDocumentBox() || layoutBox.isTableBox());
-
-    // 10.6.6 Complicated cases
-    //
-    // Block-level, non-replaced elements in normal flow when 'overflow' does not compute to 'visible' (except if the 'overflow' property's value has been propagated to the viewport).
-    // 'Inline-block', non-replaced elements.
-    // Floating, non-replaced elements.
-    //
-    // 1. If 'margin-top', or 'margin-bottom' are 'auto', their used value is 0.
-    // 2. If 'height' is 'auto', the height depends on the element's descendants per 10.6.7.
-
-    auto height = overriddenVerticalValues.height ? overriddenVerticalValues.height.value() : computedHeight(layoutBox);
-    auto computedVerticalMargin = Geometry::computedVerticalMargin(layoutBox, horizontalConstraints);
-    // #1
-    auto usedVerticalMargin = UsedVerticalMargin::NonCollapsedValues { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) }; 
-    // #2
-    if (!height) {
-        ASSERT(isHeightAuto(layoutBox));
-        if (!is<ContainerBox>(layoutBox) || !downcast<ContainerBox>(layoutBox).hasInFlowOrFloatingChild())
-            height = 0_lu;
-        else if (layoutBox.isDocumentBox() && !layoutBox.establishesFormattingContext()) {
-            auto& documentBox = downcast<ContainerBox>(layoutBox);
-            auto top = BoxGeometry::marginBoxRect(formattingContext().geometryForBox(*documentBox.firstInFlowChild())).top();
-            auto bottom = BoxGeometry::marginBoxRect(formattingContext().geometryForBox(*documentBox.lastInFlowChild())).bottom();
-            // This is a special (quirk?) behavior since the document box is not a formatting context root and
-            // all the float boxes end up at the ICB level.
-            auto& initialContainingBlock = documentBox.formattingContextRoot();
-            auto floatingContext = FloatingContext { formattingContext(), layoutState().establishedFormattingState(initialContainingBlock).floatingState() };
-            if (auto floatBottom = floatingContext.bottom()) {
-                bottom = std::max<LayoutUnit>(*floatBottom, bottom);
-                auto floatTop = floatingContext.top();
-                ASSERT(floatTop);
-                top = std::min<LayoutUnit>(*floatTop, top);
-            }
-            height = bottom - top;
-        } else {
-            ASSERT(layoutBox.establishesFormattingContext());
-            height = contentHeightForFormattingContextRoot(downcast<ContainerBox>(layoutBox));
-        }
-    }
-
-    ASSERT(height);
-
-    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> floating non-replaced -> height(" << *height << "px) margin(" << usedVerticalMargin.before << "px, " << usedVerticalMargin.after << "px) -> layoutBox(" << &layoutBox << ")");
-    return ContentHeightAndMargin { *height, usedVerticalMargin };
-}
-
-ContentWidthAndMargin FormattingContext::Geometry::floatingNonReplacedContentWidthAndMargin(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints, const OverriddenHorizontalValues& overriddenHorizontalValues)
-{
-    ASSERT(layoutBox.isFloatingPositioned() && !layoutBox.isReplacedBox());
-
-    // 10.3.5 Floating, non-replaced elements
-    //
-    // 1. If 'margin-left', or 'margin-right' are computed as 'auto', their used value is '0'.
-    // 2. If 'width' is computed as 'auto', the used value is the "shrink-to-fit" width.
-
-    auto computedHorizontalMargin = Geometry::computedHorizontalMargin(layoutBox, horizontalConstraints);
-
-    // #1
-    auto usedHorizontallMargin = UsedHorizontalMargin { computedHorizontalMargin.start.valueOr(0), computedHorizontalMargin.end.valueOr(0) };
-    // #2
-    auto width = overriddenHorizontalValues.width ? overriddenHorizontalValues.width : computedWidth(layoutBox, horizontalConstraints.logicalWidth);
-    if (!width)
-        width = shrinkToFitWidth(layoutBox, horizontalConstraints.logicalWidth);
-
-    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Width][Margin] -> floating non-replaced -> width(" << *width << "px) margin(" << usedHorizontallMargin.start << "px, " << usedHorizontallMargin.end << "px) -> layoutBox(" << &layoutBox << ")");
-    return ContentWidthAndMargin { *width, usedHorizontallMargin };
-}
-
-ContentHeightAndMargin FormattingContext::Geometry::floatingReplacedContentHeightAndMargin(const ReplacedBox& replacedBox, const HorizontalConstraints& horizontalConstraints, const OverriddenVerticalValues& overriddenVerticalValues) const
-{
-    ASSERT(replacedBox.isFloatingPositioned());
-
-    // 10.6.2 Inline replaced elements, block-level replaced elements in normal flow, 'inline-block'
-    // replaced elements in normal flow and floating replaced elements
-    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> floating replaced -> redirected to inline replaced");
-    return inlineReplacedContentHeightAndMargin(replacedBox, horizontalConstraints, { }, overriddenVerticalValues);
-}
-
-ContentWidthAndMargin FormattingContext::Geometry::floatingReplacedContentWidthAndMargin(const ReplacedBox& replacedBox, const HorizontalConstraints& horizontalConstraints, const OverriddenHorizontalValues& overriddenHorizontalValues)
-{
-    ASSERT(replacedBox.isFloatingPositioned());
-
-    // 10.3.6 Floating, replaced elements
-    //
-    // 1. If 'margin-left' or 'margin-right' are computed as 'auto', their used value is '0'.
-    // 2. The used value of 'width' is determined as for inline replaced elements.
-    auto computedHorizontalMargin = Geometry::computedHorizontalMargin(replacedBox, horizontalConstraints);
-
-    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> floating replaced -> redirected to inline replaced");
-    auto usedMargin = UsedHorizontalMargin { computedHorizontalMargin.start.valueOr(0), computedHorizontalMargin.end.valueOr(0) };
-    return inlineReplacedContentWidthAndMargin(replacedBox, horizontalConstraints, { }, { overriddenHorizontalValues.width, usedMargin });
-}
-
-VerticalGeometry FormattingContext::Geometry::outOfFlowVerticalGeometry(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints, const VerticalConstraints& verticalConstraints, const OverriddenVerticalValues& overriddenVerticalValues) const
-{
-    ASSERT(layoutBox.isOutOfFlowPositioned());
-
-    if (!layoutBox.isReplacedBox())
-        return outOfFlowNonReplacedVerticalGeometry(downcast<ContainerBox>(layoutBox), horizontalConstraints, verticalConstraints, overriddenVerticalValues);
-    return outOfFlowReplacedVerticalGeometry(downcast<ReplacedBox>(layoutBox), horizontalConstraints, verticalConstraints, overriddenVerticalValues);
-}
-
-HorizontalGeometry FormattingContext::Geometry::outOfFlowHorizontalGeometry(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints, const VerticalConstraints& verticalConstraints, const OverriddenHorizontalValues& overriddenHorizontalValues)
-{
-    ASSERT(layoutBox.isOutOfFlowPositioned());
-
-    if (!layoutBox.isReplacedBox())
-        return outOfFlowNonReplacedHorizontalGeometry(downcast<ContainerBox>(layoutBox), horizontalConstraints, overriddenHorizontalValues);
-    return outOfFlowReplacedHorizontalGeometry(downcast<ReplacedBox>(layoutBox), horizontalConstraints, verticalConstraints, overriddenHorizontalValues);
-}
-
-ContentHeightAndMargin FormattingContext::Geometry::floatingContentHeightAndMargin(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints, const OverriddenVerticalValues& overriddenVerticalValues) const
-{
-    ASSERT(layoutBox.isFloatingPositioned());
-
-    if (!layoutBox.isReplacedBox())
-        return complicatedCases(layoutBox, horizontalConstraints, overriddenVerticalValues);
-    return floatingReplacedContentHeightAndMargin(downcast<ReplacedBox>(layoutBox), horizontalConstraints, overriddenVerticalValues);
-}
-
-ContentWidthAndMargin FormattingContext::Geometry::floatingContentWidthAndMargin(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints, const OverriddenHorizontalValues& overriddenHorizontalValues)
-{
-    ASSERT(layoutBox.isFloatingPositioned());
-
-    if (!layoutBox.isReplacedBox())
-        return floatingNonReplacedContentWidthAndMargin(layoutBox, horizontalConstraints, overriddenHorizontalValues);
-    return floatingReplacedContentWidthAndMargin(downcast<ReplacedBox>(layoutBox), horizontalConstraints, overriddenHorizontalValues);
-}
-
-ContentHeightAndMargin FormattingContext::Geometry::inlineReplacedContentHeightAndMargin(const ReplacedBox& replacedBox, const HorizontalConstraints& horizontalConstraints, Optional<VerticalConstraints> verticalConstraints, const OverriddenVerticalValues& overriddenVerticalValues) const
-{
-    // 10.6.2 Inline replaced elements, block-level replaced elements in normal flow, 'inline-block' replaced elements in normal flow and floating replaced elements
-    //
-    // 1. If 'margin-top', or 'margin-bottom' are 'auto', their used value is 0.
-    // 2. If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic height, then that intrinsic height is the used value of 'height'.
-    // 3. Otherwise, if 'height' has a computed value of 'auto', and the element has an intrinsic ratio then the used value of 'height' is:
-    //    (used width) / (intrinsic ratio)
-    // 4. Otherwise, if 'height' has a computed value of 'auto', and the element has an intrinsic height, then that intrinsic height is the used value of 'height'.
-    // 5. Otherwise, if 'height' has a computed value of 'auto', but none of the conditions above are met, then the used value of 'height' must be set to
-    //    the height of the largest rectangle that has a 2:1 ratio, has a height not greater than 150px, and has a width not greater than the device width.
-
-    // #1
-    auto& formattingContext = this->formattingContext();
-    auto computedVerticalMargin = Geometry::computedVerticalMargin(replacedBox, horizontalConstraints);
-    auto usedVerticalMargin = UsedVerticalMargin::NonCollapsedValues { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) };
-    auto& style = replacedBox.style();
-
-    auto height = overriddenVerticalValues.height ? overriddenVerticalValues.height.value() : computedHeight(replacedBox, verticalConstraints ? verticalConstraints->logicalHeight : WTF::nullopt);
-    auto heightIsAuto = !overriddenVerticalValues.height && isHeightAuto(replacedBox);
-    auto widthIsAuto = style.logicalWidth().isAuto();
-
-    if (heightIsAuto && widthIsAuto && replacedBox.hasIntrinsicHeight()) {
-        // #2
-        height = replacedBox.intrinsicHeight();
-    } else if (heightIsAuto && replacedBox.hasIntrinsicRatio()) {
-        // #3
-        auto usedWidth = formattingContext.geometryForBox(replacedBox).contentBoxWidth();
-        height = usedWidth / replacedBox.intrinsicRatio();
-    } else if (heightIsAuto && replacedBox.hasIntrinsicHeight()) {
-        // #4
-        height = replacedBox.intrinsicHeight();
-    } else if (heightIsAuto) {
-        // #5
-        height = { 150 };
-    }
-
-    ASSERT(height);
-
-    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> inflow replaced -> height(" << *height << "px) margin(" << usedVerticalMargin.before << "px, " << usedVerticalMargin.after << "px) -> layoutBox(" << &replacedBox << ")");
-    return { *height, usedVerticalMargin };
-}
-
-ContentWidthAndMargin FormattingContext::Geometry::inlineReplacedContentWidthAndMargin(const ReplacedBox& replacedBox, const HorizontalConstraints& horizontalConstraints, Optional<VerticalConstraints> verticalConstraints, const OverriddenHorizontalValues& overriddenHorizontalValues)
-{
-    // 10.3.2 Inline, replaced elements
-    //
-    // A computed value of 'auto' for 'margin-left' or 'margin-right' becomes a used value of '0'.
-    //
-    // 1. If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic width, then that intrinsic width is the used value of 'width'.
-    //
-    // 2. If 'height' and 'width' both have computed values of 'auto' and the element has no intrinsic width, but does have an intrinsic height and intrinsic ratio;
-    //    or if 'width' has a computed value of 'auto', 'height' has some other computed value, and the element does have an intrinsic ratio;
-    //    then the used value of 'width' is: (used height) * (intrinsic ratio)
-    //
-    // 3. If 'height' and 'width' both have computed values of 'auto' and the element has an intrinsic ratio but no intrinsic height or width,
-    //    then the used value of 'width' is undefined in CSS 2.2. However, it is suggested that, if the containing block's width does not itself depend on the replaced
-    //    element's width, then the used value of 'width' is calculated from the constraint equation used for block-level, non-replaced elements in normal flow.
-    //
-    // 4. Otherwise, if 'width' has a computed value of 'auto', and the element has an intrinsic width, then that intrinsic width is the used value of 'width'.
-    //
-    // 5. Otherwise, if 'width' has a computed value of 'auto', but none of the conditions above are met, then the used value of 'width' becomes 300px.
-    //    If 300px is too wide to fit the device, UAs should use the width of the largest rectangle that has a 2:1 ratio and fits the device instead.
-
-    auto computedHorizontalMargin = Geometry::computedHorizontalMargin(replacedBox, horizontalConstraints);
-
-    auto usedMarginStart = [&] {
-        if (overriddenHorizontalValues.margin)
-            return overriddenHorizontalValues.margin->start;
-        return computedHorizontalMargin.start.valueOr(0_lu);
-    };
-
-    auto usedMarginEnd = [&] {
-        if (overriddenHorizontalValues.margin)
-            return overriddenHorizontalValues.margin->end;
-        return computedHorizontalMargin.end.valueOr(0_lu);
-    };
-
-    auto width = overriddenHorizontalValues.width ? overriddenHorizontalValues.width : computedWidth(replacedBox, horizontalConstraints.logicalWidth);
-    auto heightIsAuto = isHeightAuto(replacedBox);
-    auto height = computedHeight(replacedBox, verticalConstraints ? verticalConstraints->logicalHeight : WTF::nullopt);
-
-    if (!width && heightIsAuto && replacedBox.hasIntrinsicWidth()) {
-        // #1
-        width = replacedBox.intrinsicWidth();
-    } else if ((!width && heightIsAuto && !replacedBox.hasIntrinsicWidth() && replacedBox.hasIntrinsicHeight() && replacedBox.hasIntrinsicRatio())
-        || (!width && height && replacedBox.hasIntrinsicRatio())) {
-        // #2
-        width = height.valueOr(replacedBox.hasIntrinsicHeight()) * replacedBox.intrinsicRatio();
-    } else if (!width && heightIsAuto && replacedBox.hasIntrinsicRatio() && !replacedBox.hasIntrinsicWidth() && !replacedBox.hasIntrinsicHeight()) {
-        // #3
-        // FIXME: undefined but surely doable.
-        ASSERT_NOT_IMPLEMENTED_YET();
-    } else if (!width && replacedBox.hasIntrinsicWidth()) {
-        // #4
-        width = replacedBox.intrinsicWidth();
-    } else if (!width) {
-        // #5
-        width = { 300 };
-    }
-
-    ASSERT(width);
-
-    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Width][Margin] -> inflow replaced -> width(" << *width << "px) margin(" << usedMarginStart() << "px, " << usedMarginEnd() << "px) -> layoutBox(" << &replacedBox << ")");
-    return { *width, { usedMarginStart(), usedMarginEnd() } };
-}
-
-LayoutSize FormattingContext::Geometry::inFlowPositionedPositionOffset(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints) const
-{
-    ASSERT(layoutBox.isInFlowPositioned());
-
-    // 9.4.3 Relative positioning
-    //
-    // The 'top' and 'bottom' properties move relatively positioned element(s) up or down without changing their size.
-    // Top' moves the boxes down, and 'bottom' moves them up. Since boxes are not split or stretched as a result of 'top' or 'bottom', the used values are always: top = -bottom.
-    //
-    // 1. If both are 'auto', their used values are both '0'.
-    // 2. If one of them is 'auto', it becomes the negative of the other.
-    // 3. If neither is 'auto', 'bottom' is ignored (i.e., the used value of 'bottom' will be minus the value of 'top').
-
-    auto& style = layoutBox.style();
-    auto containingBlockWidth = horizontalConstraints.logicalWidth;
-
-    auto top = computedValue(style.logicalTop(), containingBlockWidth);
-    auto bottom = computedValue(style.logicalBottom(), containingBlockWidth);
-
-    if (!top && !bottom) {
-        // #1
-        top = bottom = { 0 };
-    } else if (!top) {
-        // #2
-        top = -*bottom;
-    } else if (!bottom) {
-        // #3
-        bottom = -*top;
-    } else {
-        // #4
-        bottom = WTF::nullopt;
-    }
-
-    // For relatively positioned elements, 'left' and 'right' move the box(es) horizontally, without changing their size.
-    // 'Left' moves the boxes to the right, and 'right' moves them to the left.
-    // Since boxes are not split or stretched as a result of 'left' or 'right', the used values are always: left = -right.
-    //
-    // 1. If both 'left' and 'right' are 'auto' (their initial values), the used values are '0' (i.e., the boxes stay in their original position).
-    // 2. If 'left' is 'auto', its used value is minus the value of 'right' (i.e., the boxes move to the left by the value of 'right').
-    // 3. If 'right' is specified as 'auto', its used value is minus the value of 'left'.
-    // 4. If neither 'left' nor 'right' is 'auto', the position is over-constrained, and one of them has to be ignored.
-    //    If the 'direction' property of the containing block is 'ltr', the value of 'left' wins and 'right' becomes -'left'.
-    //    If 'direction' of the containing block is 'rtl', 'right' wins and 'left' is ignored.
-
-    auto left = computedValue(style.logicalLeft(), containingBlockWidth);
-    auto right = computedValue(style.logicalRight(), containingBlockWidth);
-
-    if (!left && !right) {
-        // #1
-        left = right = { 0 };
-    } else if (!left) {
-        // #2
-        left = -*right;
-    } else if (!right) {
-        // #3
-        right = -*left;
-    } else {
-        // #4
-        auto isLeftToRightDirection = layoutBox.containingBlock().style().isLeftToRightDirection();
-        if (isLeftToRightDirection)
-            right = -*left;
-        else
-            left = WTF::nullopt;
-    }
-
-    ASSERT(!bottom || *top == -*bottom);
-    ASSERT(!left || *left == -*right);
-
-    auto topPositionOffset = *top;
-    auto leftPositionOffset = left.valueOr(-*right);
-
-    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position] -> positioned inflow -> top offset(" << topPositionOffset << "px) left offset(" << leftPositionOffset << "px) layoutBox(" << &layoutBox << ")");
-    return { leftPositionOffset, topPositionOffset };
-}
-
-inline static WritingMode usedWritingMode(const Box& layoutBox)
-{
-    // https://www.w3.org/TR/css-writing-modes-4/#logical-direction-layout
-    // Flow-relative directions are calculated with respect to the writing mode of the containing block of the box.
-    // For inline-level boxes, the writing mode of the parent box is used instead.
-    return layoutBox.isInlineLevelBox() ? layoutBox.parent().style().writingMode() : layoutBox.containingBlock().style().writingMode();
-}
-
-Edges FormattingContext::Geometry::computedBorder(const Box& layoutBox) const
-{
-    auto& style = layoutBox.style();
-    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Border] -> layoutBox: " << &layoutBox);
-    return {
-        { LayoutUnit(style.borderLeftWidth()), LayoutUnit(style.borderRightWidth()) },
-        { LayoutUnit(style.borderTopWidth()), LayoutUnit(style.borderBottomWidth()) }
-    };
-}
-
-Optional<Edges> FormattingContext::Geometry::computedPadding(const Box& layoutBox, const LayoutUnit containingBlockWidth) const
-{
-    if (!layoutBox.isPaddingApplicable())
-        return WTF::nullopt;
-
-    auto& style = layoutBox.style();
-    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Padding] -> layoutBox: " << &layoutBox);
-    return Edges {
-        { valueForLength(style.paddingLeft(), containingBlockWidth), valueForLength(style.paddingRight(), containingBlockWidth) },
-        { valueForLength(style.paddingTop(), containingBlockWidth), valueForLength(style.paddingBottom(), containingBlockWidth) }
-    };
-}
-
-ComputedHorizontalMargin FormattingContext::Geometry::computedHorizontalMargin(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints) const
-{
-    auto& style = layoutBox.style();
-    auto containingBlockWidth = horizontalConstraints.logicalWidth;
-    if (isHorizontalWritingMode(usedWritingMode(layoutBox)))
-        return { computedValue(style.marginLeft(), containingBlockWidth), computedValue(style.marginRight(), containingBlockWidth) };
-    return { computedValue(style.marginTop(), containingBlockWidth), computedValue(style.marginBottom(), containingBlockWidth) };
-}
-
-ComputedVerticalMargin FormattingContext::Geometry::computedVerticalMargin(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints) const
-{
-    auto& style = layoutBox.style();
-    auto containingBlockWidth = horizontalConstraints.logicalWidth;
-    if (isHorizontalWritingMode(usedWritingMode(layoutBox)))
-        return { computedValue(style.marginTop(), containingBlockWidth), computedValue(style.marginBottom(), containingBlockWidth) };
-    return { computedValue(style.marginLeft(), containingBlockWidth), computedValue(style.marginRight(), containingBlockWidth) };
-}
-
-FormattingContext::IntrinsicWidthConstraints FormattingContext::Geometry::constrainByMinMaxWidth(const Box& layoutBox, IntrinsicWidthConstraints intrinsicWidth) const
-{
-    auto& style = layoutBox.style();
-    auto minWidth = fixedValue(style.logicalMinWidth());
-    auto maxWidth = fixedValue(style.logicalMaxWidth());
-    if (!minWidth && !maxWidth)
-        return intrinsicWidth;
-
-    if (maxWidth) {
-        intrinsicWidth.minimum = std::min(*maxWidth, intrinsicWidth.minimum);
-        intrinsicWidth.maximum = std::min(*maxWidth, intrinsicWidth.maximum);
-    }
-
-    if (minWidth) {
-        intrinsicWidth.minimum = std::max(*minWidth, intrinsicWidth.minimum);
-        intrinsicWidth.maximum = std::max(*minWidth, intrinsicWidth.maximum);
-    }
-
-    ASSERT(intrinsicWidth.minimum <= intrinsicWidth.maximum);
-    return intrinsicWidth;
-}
-
-FormattingContext::ConstraintsForOutOfFlowContent FormattingContext::Geometry::constraintsForOutOfFlowContent(const ContainerBox& containerBox)
-{
-    auto& boxGeometry = formattingContext().geometryForBox(containerBox);
-    return {
-        { boxGeometry.paddingBoxLeft(), boxGeometry.paddingBoxWidth() },
-        { boxGeometry.paddingBoxTop(), boxGeometry.paddingBoxHeight() },
-        boxGeometry.contentBoxWidth() };
-}
-
-FormattingContext::ConstraintsForInFlowContent FormattingContext::Geometry::constraintsForInFlowContent(const ContainerBox& containerBox, Optional<EscapeReason> escapeReason)
-{
-    auto& boxGeometry = formattingContext().geometryForBox(containerBox, escapeReason);
-    return { { boxGeometry.contentBoxLeft(), boxGeometry.contentBoxWidth() }, { boxGeometry.contentBoxTop(), computedHeight(containerBox) } };
-}
-
-}
-}
-#endif
</del></span></pre></div>
<a id="trunkSourceWebCorelayoutformattingContextsFormattingGeometrycppfromrev277555trunkSourceWebCorelayoutformattingContextsFormattingContextGeometrycpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/layout/formattingContexts/FormattingGeometry.cpp (from rev 277555, trunk/Source/WebCore/layout/formattingContexts/FormattingContextGeometry.cpp) (0 => 277556)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/formattingContexts/FormattingGeometry.cpp                            (rev 0)
+++ trunk/Source/WebCore/layout/formattingContexts/FormattingGeometry.cpp       2021-05-16 01:56:55 UTC (rev 277556)
</span><span class="lines">@@ -0,0 +1,1170 @@
</span><ins>+/*
+ * Copyright (C) 2018 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 "FormattingGeometry.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "BlockFormattingState.h"
+#include "FlexFormattingState.h"
+#include "FloatingContext.h"
+#include "FloatingState.h"
+#include "InlineFormattingState.h"
+#include "LayoutContext.h"
+#include "LayoutInitialContainingBlock.h"
+#include "LayoutReplacedBox.h"
+#include "Logging.h"
+#include "TableFormattingState.h"
+
+namespace WebCore {
+namespace Layout {
+
+static inline bool isHeightAuto(const Box& layoutBox)
+{
+    // 10.5 Content height: the 'height' property
+    //
+    // The percentage is calculated with respect to the height of the generated box's containing block.
+    // If the height of the containing block is not specified explicitly (i.e., it depends on content height),
+    // and this element is not absolutely positioned, the used height is calculated as if 'auto' was specified.
+
+    auto height = layoutBox.style().logicalHeight();
+    if (height.isAuto())
+        return true;
+
+    if (height.isPercent()) {
+        if (layoutBox.isOutOfFlowPositioned())
+            return false;
+
+        return !layoutBox.containingBlock().style().logicalHeight().isFixed();
+    }
+
+    return false;
+}
+
+FormattingGeometry::FormattingGeometry(const FormattingContext& formattingContext)
+    : m_formattingContext(formattingContext)
+{
+}
+
+Optional<LayoutUnit> FormattingGeometry::computedHeightValue(const Box& layoutBox, HeightType heightType, Optional<LayoutUnit> containingBlockHeight) const
+{
+    auto& style = layoutBox.style();
+    auto height = heightType == HeightType::Normal ? style.logicalHeight() : heightType == HeightType::Min ? style.logicalMinHeight() : style.logicalMaxHeight();
+    if (height.isUndefined() || height.isAuto() || height.isMaxContent() || height.isMinContent() || height.isFitContent())
+        return { };
+
+    if (height.isFixed())
+        return LayoutUnit { height.value() };
+
+    if (!containingBlockHeight) {
+        if (layoutState().inQuirksMode())
+            containingBlockHeight = formattingContext().quirks().heightValueOfNearestContainingBlockWithFixedHeight(layoutBox);
+        else {
+            auto nonAnonymousContainingBlockLogicalHeight = [&] {
+                // When the block level box is a direct child of an inline level box (<span><div></div></span>) and we wrap it into a continuation,
+                // the containing block (anonymous wrapper) is not the box we need to check for fixed height.
+                auto& initialContainingBlock = layoutBox.initialContainingBlock();
+                for (auto* containingBlock = &layoutBox.containingBlock(); containingBlock != &initialContainingBlock; containingBlock = &containingBlock->containingBlock()) {
+                    if (containingBlock->isAnonymous())
+                        continue;
+                    return containingBlock->style().logicalHeight();
+                }
+                return initialContainingBlock.style().logicalHeight();
+            };
+            containingBlockHeight = fixedValue(nonAnonymousContainingBlockLogicalHeight());
+        }
+    }
+
+    if (!containingBlockHeight)
+        return { };
+
+    return valueForLength(height, *containingBlockHeight);
+}
+
+Optional<LayoutUnit> FormattingGeometry::computedHeight(const Box& layoutBox, Optional<LayoutUnit> containingBlockHeight) const
+{
+    if (auto height = computedHeightValue(layoutBox, HeightType::Normal, containingBlockHeight)) {
+        if (layoutBox.style().boxSizing() == BoxSizing::ContentBox)
+            return height;
+        auto& boxGeometry = formattingContext().geometryForBox(layoutBox);
+        return *height - (boxGeometry.verticalBorder() + boxGeometry.verticalPadding().valueOr(0));
+    }
+    return { };
+}
+
+Optional<LayoutUnit> FormattingGeometry::computedWidthValue(const Box& layoutBox, WidthType widthType, LayoutUnit containingBlockWidth)
+{
+    // Applies to: all elements except non-replaced inlines (out-of-flow check is required for positioned <br> as for some reason we don't blockify them).
+    ASSERT(!layoutBox.isInlineBox() || layoutBox.isOutOfFlowPositioned());
+
+    auto width = [&] {
+        auto& style = layoutBox.style();
+        switch (widthType) {
+        case WidthType::Normal:
+            return style.logicalWidth();
+        case WidthType::Min:
+            return style.logicalMinWidth();
+        case WidthType::Max:
+            return style.logicalMaxWidth();
+        }
+        ASSERT_NOT_REACHED();
+        return style.logicalWidth();
+    }();
+    if (auto computedValue = this->computedValue(width, containingBlockWidth))
+        return computedValue;
+
+    if (width.isMinContent() || width.isMaxContent() || width.isFitContent()) {
+        if (!is<ContainerBox>(layoutBox))
+            return { };
+        auto& containerBox = downcast<ContainerBox>(layoutBox);
+        // FIXME: Consider splitting up computedIntrinsicWidthConstraints so that we could computed the min and max values separately.
+        auto intrinsicWidthConstraints = [&] {
+            if (!containerBox.hasInFlowOrFloatingChild())
+                return FormattingContext::IntrinsicWidthConstraints { 0_lu, containingBlockWidth };
+            ASSERT(containerBox.establishesFormattingContext());
+            auto& formattingState = layoutState().ensureFormattingState(containerBox);
+            if (auto intrinsicWidthConstraints = formattingState.intrinsicWidthConstraints())
+                return *intrinsicWidthConstraints;
+            return LayoutContext::createFormattingContext(containerBox, layoutState())->computedIntrinsicWidthConstraints();
+        }();
+        if (width.isMinContent())
+            return intrinsicWidthConstraints.minimum;
+        if (width.isMaxContent())
+            return intrinsicWidthConstraints.maximum;
+        ASSERT(width.isFitContent());
+        // If the available space in a given axis is definite, equal to min(max-content size,
+        // max(min-content size, stretch-fit size)). Otherwise, equal to the max-content size in that axis.
+        // FIXME: We don't yet have indefinite available size.
+        return std::min(intrinsicWidthConstraints.maximum, std::max(intrinsicWidthConstraints.minimum, containingBlockWidth));
+    }
+    return { };
+}
+
+Optional<LayoutUnit> FormattingGeometry::computedWidth(const Box& layoutBox, LayoutUnit containingBlockWidth)
+{
+    if (auto computedWidth = computedWidthValue(layoutBox, WidthType::Normal, containingBlockWidth)) {
+        auto& style = layoutBox.style();
+        // Non-quantitative values such as auto and min-content are not influenced by the box-sizing property.
+        if (style.boxSizing() == BoxSizing::ContentBox || style.width().isIntrinsicOrAuto())
+            return computedWidth;
+        auto& boxGeometry = formattingContext().geometryForBox(layoutBox);
+        return *computedWidth - (boxGeometry.horizontalBorder() + boxGeometry.horizontalPadding().valueOr(0));
+    }
+    return { };
+}
+
+LayoutUnit FormattingGeometry::contentHeightForFormattingContextRoot(const ContainerBox& formattingContextRoot) const
+{
+    ASSERT(formattingContextRoot.establishesFormattingContext());
+    ASSERT(isHeightAuto(formattingContextRoot) || formattingContextRoot.establishesTableFormattingContext() || formattingContextRoot.isTableCell());
+    auto usedContentHeight = LayoutUnit { }; 
+    auto hasContent = formattingContextRoot.hasInFlowOrFloatingChild();
+    // The used height of the containment box is determined as if performing a normal layout of the box, except that it is treated as having no content.
+    auto shouldIgnoreContent = formattingContextRoot.isSizeContainmentBox();
+    if (hasContent && !shouldIgnoreContent)
+        usedContentHeight = LayoutContext::createFormattingContext(formattingContextRoot, const_cast<LayoutState&>(layoutState()))->usedContentHeight();
+    return usedContentHeight;
+}
+
+Optional<LayoutUnit> FormattingGeometry::computedValue(const Length& geometryProperty, LayoutUnit containingBlockWidth) const
+{
+    //  In general, the computed value resolves the specified value as far as possible without laying out the content.
+    if (geometryProperty.isFixed() || geometryProperty.isPercent() || geometryProperty.isCalculated())
+        return valueForLength(geometryProperty, containingBlockWidth);
+    return { };
+}
+
+Optional<LayoutUnit> FormattingGeometry::fixedValue(const Length& geometryProperty) const
+{
+    if (!geometryProperty.isFixed())
+        return { };
+    return LayoutUnit { geometryProperty.value() };
+}
+
+// https://www.w3.org/TR/CSS22/visudet.html#min-max-heights
+// Specifies a percentage for determining the used value. The percentage is calculated with respect to the height of the generated box's containing block.
+// If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned,
+// the percentage value is treated as '0' (for 'min-height') or 'none' (for 'max-height').
+Optional<LayoutUnit> FormattingGeometry::computedMaxHeight(const Box& layoutBox, Optional<LayoutUnit> containingBlockHeight) const
+{
+    return computedHeightValue(layoutBox, HeightType::Max, containingBlockHeight);
+}
+
+Optional<LayoutUnit> FormattingGeometry::computedMinHeight(const Box& layoutBox, Optional<LayoutUnit> containingBlockHeight) const
+{
+    return computedHeightValue(layoutBox, HeightType::Min, containingBlockHeight);
+}
+
+Optional<LayoutUnit> FormattingGeometry::computedMinWidth(const Box& layoutBox, LayoutUnit containingBlockWidth)
+{
+    return computedWidthValue(layoutBox, WidthType::Min, containingBlockWidth);
+}
+
+Optional<LayoutUnit> FormattingGeometry::computedMaxWidth(const Box& layoutBox, LayoutUnit containingBlockWidth)
+{
+    return computedWidthValue(layoutBox, WidthType::Max, containingBlockWidth);
+}
+
+LayoutUnit FormattingGeometry::staticVerticalPositionForOutOfFlowPositioned(const Box& layoutBox, const VerticalConstraints& verticalConstraints) const
+{
+    ASSERT(layoutBox.isOutOfFlowPositioned());
+
+    // For the purposes of this section and the next, the term "static position" (of an element) refers, roughly, to the position an element would have
+    // had in the normal flow. More precisely, the static position for 'top' is the distance from the top edge of the containing block to the top margin
+    // edge of a hypothetical box that would have been the first box of the element if its specified 'position' value had been 'static' and its specified
+    // 'float' had been 'none' and its specified 'clear' had been 'none'. (Note that due to the rules in section 9.7 this might require also assuming a different
+    // computed value for 'display'.) The value is negative if the hypothetical box is above the containing block.
+
+    // Start with this box's border box offset from the parent's border box.
+    auto& formattingContext = this->formattingContext();
+    LayoutUnit top;
+    if (layoutBox.previousInFlowSibling() && layoutBox.previousInFlowSibling()->isBlockLevelBox()) {
+        // Add sibling offset
+        auto& previousInFlowSibling = *layoutBox.previousInFlowSibling();
+        auto& previousInFlowBoxGeometry = formattingContext.geometryForBox(previousInFlowSibling, FormattingContext::EscapeReason::OutOfFlowBoxNeedsInFlowGeometry);
+        auto& formattingState = downcast<BlockFormattingState>(layoutState().formattingStateForBox(previousInFlowSibling));
+        auto usedVerticalMarginForPreviousBox = formattingState.usedVerticalMargin(previousInFlowSibling);
+
+        top += BoxGeometry::borderBoxRect(previousInFlowBoxGeometry).bottom() + usedVerticalMarginForPreviousBox.nonCollapsedValues.after;
+    } else
+        top = formattingContext.geometryForBox(layoutBox.parent(), FormattingContext::EscapeReason::OutOfFlowBoxNeedsInFlowGeometry).contentBoxTop();
+
+    // Resolve top all the way up to the containing block.
+    auto& containingBlock = layoutBox.containingBlock();
+    // Start with the parent since we pretend that this box is normal flow.
+    for (auto* ancestor = &layoutBox.parent(); ancestor != &containingBlock; ancestor = &ancestor->containingBlock()) {
+        auto& boxGeometry = formattingContext.geometryForBox(*ancestor, FormattingContext::EscapeReason::OutOfFlowBoxNeedsInFlowGeometry);
+        // BoxGeometry::top is the border box top position in its containing block's coordinate system.
+        top += BoxGeometry::borderBoxTop(boxGeometry);
+        ASSERT(!ancestor->isPositioned() || layoutBox.isFixedPositioned());
+    }
+    // Move the static position relative to the padding box. This is very specific to abolutely positioned boxes.
+    return top - verticalConstraints.logicalTop;
+}
+
+LayoutUnit FormattingGeometry::staticHorizontalPositionForOutOfFlowPositioned(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints) const
+{
+    ASSERT(layoutBox.isOutOfFlowPositioned());
+    // See staticVerticalPositionForOutOfFlowPositioned for the definition of the static position.
+
+    // Start with this box's border box offset from the parent's border box.
+    auto& formattingContext = this->formattingContext();
+    auto left = formattingContext.geometryForBox(layoutBox.parent(), FormattingContext::EscapeReason::OutOfFlowBoxNeedsInFlowGeometry).contentBoxLeft();
+
+    // Resolve left all the way up to the containing block.
+    auto& containingBlock = layoutBox.containingBlock();
+    // Start with the parent since we pretend that this box is normal flow.
+    for (auto* ancestor = &layoutBox.parent(); ancestor != &containingBlock; ancestor = &ancestor->containingBlock()) {
+        auto& boxGeometry = formattingContext.geometryForBox(*ancestor, FormattingContext::EscapeReason::OutOfFlowBoxNeedsInFlowGeometry);
+        // BoxGeometry::left is the border box left position in its containing block's coordinate system.
+        left += BoxGeometry::borderBoxLeft(boxGeometry);
+        ASSERT(!ancestor->isPositioned() || layoutBox.isFixedPositioned());
+    }
+    // Move the static position relative to the padding box. This is very specific to abolutely positioned boxes.
+    return left - horizontalConstraints.logicalLeft;
+}
+
+LayoutUnit FormattingGeometry::shrinkToFitWidth(const Box& formattingContextRoot, LayoutUnit availableWidth)
+{
+    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Width] -> shrink to fit -> unsupported -> width(" << LayoutUnit { } << "px) layoutBox: " << &formattingContextRoot << ")");
+    ASSERT(formattingContextRoot.establishesFormattingContext());
+
+    // Calculation of the shrink-to-fit width is similar to calculating the width of a table cell using the automatic table layout algorithm.
+    // Roughly: calculate the preferred width by formatting the content without breaking lines other than where explicit line breaks occur,
+    // and also calculate the preferred minimum width, e.g., by trying all possible line breaks. CSS 2.2 does not define the exact algorithm.
+    // Thirdly, find the available width: in this case, this is the width of the containing block minus the used values of 'margin-left', 'border-left-width',
+    // 'padding-left', 'padding-right', 'border-right-width', 'margin-right', and the widths of any relevant scroll bars.
+
+    // Then the shrink-to-fit width is: min(max(preferred minimum width, available width), preferred width).
+    auto intrinsicWidthConstraints = FormattingContext::IntrinsicWidthConstraints { };
+    auto hasContent = is<ContainerBox>(formattingContextRoot) && downcast<ContainerBox>(formattingContextRoot).hasInFlowOrFloatingChild();
+    // The used width of the containment box is determined as if performing a normal layout of the box, except that it is treated as having no content.
+    auto shouldIgnoreContent = formattingContextRoot.isSizeContainmentBox();  
+    if (hasContent && !shouldIgnoreContent) {
+        auto& root = downcast<ContainerBox>(formattingContextRoot);
+        auto& formattingStateForRoot = layoutState().ensureFormattingState(root);
+        auto precomputedIntrinsicWidthConstraints = formattingStateForRoot.intrinsicWidthConstraints();
+        if (!precomputedIntrinsicWidthConstraints)
+            intrinsicWidthConstraints = LayoutContext::createFormattingContext(root, layoutState())->computedIntrinsicWidthConstraints();
+        else
+            intrinsicWidthConstraints = *precomputedIntrinsicWidthConstraints;
+    }
+    return std::min(std::max(intrinsicWidthConstraints.minimum, availableWidth), intrinsicWidthConstraints.maximum);
+}
+
+VerticalGeometry FormattingGeometry::outOfFlowNonReplacedVerticalGeometry(const ContainerBox& layoutBox, const HorizontalConstraints& horizontalConstraints, const VerticalConstraints& verticalConstraints, const OverriddenVerticalValues& overriddenVerticalValues) const
+{
+    ASSERT(layoutBox.isOutOfFlowPositioned() && !layoutBox.isReplacedBox());
+    ASSERT(verticalConstraints.logicalHeight);
+
+    // 10.6.4 Absolutely positioned, non-replaced elements
+    //
+    // For absolutely positioned elements, the used values of the vertical dimensions must satisfy this constraint:
+    // 'top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' + 'padding-bottom' + 'border-bottom-width' + 'margin-bottom' + 'bottom'
+    // = height of containing block
+
+    // If all three of 'top', 'height', and 'bottom' are auto, set 'top' to the static position and apply rule number three below.
+
+    // If none of the three are 'auto': If both 'margin-top' and 'margin-bottom' are 'auto', solve the equation under the extra
+    // constraint that the two margins get equal values. If one of 'margin-top' or 'margin-bottom' is 'auto', solve the equation for that value.
+    // If the values are over-constrained, ignore the value for 'bottom' and solve for that value.
+
+    // Otherwise, pick the one of the following six rules that applies.
+
+    // 1. 'top' and 'height' are 'auto' and 'bottom' is not 'auto', then the height is based on the content per 10.6.7,
+    //     set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'top'
+    // 2. 'top' and 'bottom' are 'auto' and 'height' is not 'auto', then set 'top' to the static position, set 'auto' values for
+    //    'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'
+    // 3. 'height' and 'bottom' are 'auto' and 'top' is not 'auto', then the height is based on the content per 10.6.7, set 'auto'
+    //     values for 'margin-top' and 'margin-bottom' to 0, and solve for 'bottom'
+    // 4. 'top' is 'auto', 'height' and 'bottom' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0, and solve for 'top'
+    // 5. 'height' is 'auto', 'top' and 'bottom' are not 'auto', then 'auto' values for 'margin-top' and 'margin-bottom' are set to 0 and solve for 'height'
+    // 6. 'bottom' is 'auto', 'top' and 'height' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0 and solve for 'bottom'
+
+    auto& formattingContext = this->formattingContext();
+    auto& style = layoutBox.style();
+    auto& boxGeometry = formattingContext.geometryForBox(layoutBox);
+    auto containingBlockHeight = *verticalConstraints.logicalHeight;
+    auto containingBlockWidth = horizontalConstraints.logicalWidth;
+
+    auto top = computedValue(style.logicalTop(), containingBlockWidth);
+    auto bottom = computedValue(style.logicalBottom(), containingBlockWidth);
+    auto height = overriddenVerticalValues.height ? overriddenVerticalValues.height.value() : computedHeight(layoutBox, containingBlockHeight);
+    auto computedVerticalMargin = FormattingGeometry::computedVerticalMargin(layoutBox, horizontalConstraints);
+    UsedVerticalMargin::NonCollapsedValues usedVerticalMargin; 
+    auto paddingTop = boxGeometry.paddingTop().valueOr(0);
+    auto paddingBottom = boxGeometry.paddingBottom().valueOr(0);
+    auto borderTop = boxGeometry.borderTop();
+    auto borderBottom = boxGeometry.borderBottom();
+
+    if (!top && !height && !bottom)
+        top = staticVerticalPositionForOutOfFlowPositioned(layoutBox, verticalConstraints);
+
+    if (top && height && bottom) {
+        if (!computedVerticalMargin.before && !computedVerticalMargin.after) {
+            auto marginBeforeAndAfter = containingBlockHeight - (*top + borderTop + paddingTop + *height + paddingBottom + borderBottom + *bottom);
+            usedVerticalMargin = { marginBeforeAndAfter / 2, marginBeforeAndAfter / 2 };
+        } else if (!computedVerticalMargin.before) {
+            usedVerticalMargin.after = *computedVerticalMargin.after;
+            usedVerticalMargin.before = containingBlockHeight - (*top + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after + *bottom);
+        } else if (!computedVerticalMargin.after) {
+            usedVerticalMargin.before = *computedVerticalMargin.before;
+            usedVerticalMargin.after = containingBlockHeight - (*top + usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + *bottom);
+        } else
+            usedVerticalMargin = { *computedVerticalMargin.before, *computedVerticalMargin.after };
+        // Over-constrained?
+        auto boxHeight = *top + usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after + *bottom;
+        if (boxHeight != containingBlockHeight)
+            bottom = containingBlockHeight - (*top + usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after);
+    }
+
+    if (!top && !height && bottom) {
+        // #1
+        height = contentHeightForFormattingContextRoot(layoutBox);
+        usedVerticalMargin = { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) };
+        top = containingBlockHeight - (usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after + *bottom); 
+    }
+
+    if (!top && !bottom && height) {
+        // #2
+        top = staticVerticalPositionForOutOfFlowPositioned(layoutBox, verticalConstraints);
+        usedVerticalMargin = { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) };
+        bottom = containingBlockHeight - (*top + usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after);
+    }
+
+    if (!height && !bottom && top) {
+        // #3
+        height = contentHeightForFormattingContextRoot(layoutBox);
+        usedVerticalMargin = { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) };
+        bottom = containingBlockHeight - (*top + usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after);
+    }
+
+    if (!top && height && bottom) {
+        // #4
+        usedVerticalMargin = { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) };
+        top = containingBlockHeight - (usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after + *bottom);
+    }
+
+    if (!height && top && bottom) {
+        // #5
+        usedVerticalMargin = { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) };
+        height = containingBlockHeight - (*top + usedVerticalMargin.before + borderTop + paddingTop + paddingBottom + borderBottom + usedVerticalMargin.after + *bottom);
+    }
+
+    if (!bottom && top && height) {
+        // #6
+        usedVerticalMargin = { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) };
+        bottom = containingBlockHeight - (*top + usedVerticalMargin.before + borderTop + paddingTop + *height + paddingBottom + borderBottom + usedVerticalMargin.after);
+    }
+
+    ASSERT(top);
+    ASSERT(bottom);
+    ASSERT(height);
+
+    // For out-of-flow elements the containing block is formed by the padding edge of the ancestor.
+    // At this point the positioned value is in the coordinate system of the padding box. Let's convert it to border box coordinate system.
+    auto containingBlockPaddingVerticalEdge = verticalConstraints.logicalTop;
+    *top += containingBlockPaddingVerticalEdge;
+    *bottom += containingBlockPaddingVerticalEdge;
+
+    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position][Height][Margin] -> out-of-flow non-replaced -> top(" << *top << "px) bottom("  << *bottom << "px) height(" << *height << "px) margin(" << usedVerticalMargin.before << "px, "  << usedVerticalMargin.after << "px) layoutBox(" << &layoutBox << ")");
+    return { *top, *bottom, { *height, usedVerticalMargin } };
+}
+
+HorizontalGeometry FormattingGeometry::outOfFlowNonReplacedHorizontalGeometry(const ContainerBox& layoutBox, const HorizontalConstraints& horizontalConstraints, const OverriddenHorizontalValues& overriddenHorizontalValues)
+{
+    ASSERT(layoutBox.isOutOfFlowPositioned() && !layoutBox.isReplacedBox());
+    
+    // 10.3.7 Absolutely positioned, non-replaced elements
+    //
+    // 'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right'
+    // = width of containing block
+
+    // If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0.
+    // Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static
+    // position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below.
+    //
+    // If none of the three is 'auto': If both 'margin-left' and 'margin-right' are 'auto', solve the equation under the extra constraint that the two margins get equal values,
+    // unless this would make them negative, in which case when direction of the containing block is 'ltr' ('rtl'), set 'margin-left' ('margin-right') to zero and
+    // solve for 'margin-right' ('margin-left'). If one of 'margin-left' or 'margin-right' is 'auto', solve the equation for that value.
+    // If the values are over-constrained, ignore the value for 'left' (in case the 'direction' property of the containing block is 'rtl') or 'right'
+    // (in case 'direction' is 'ltr') and solve for that value.
+    //
+    // Otherwise, set 'auto' values for 'margin-left' and 'margin-right' to 0, and pick the one of the following six rules that applies.
+    //
+    // 1. 'left' and 'width' are 'auto' and 'right' is not 'auto', then the width is shrink-to-fit. Then solve for 'left'
+    // 2. 'left' and 'right' are 'auto' and 'width' is not 'auto', then if the 'direction' property of the element establishing the static-position 
+    //    containing block is 'ltr' set 'left' to the static position, otherwise set 'right' to the static position.
+    //    Then solve for 'left' (if 'direction is 'rtl') or 'right' (if 'direction' is 'ltr').
+    // 3. 'width' and 'right' are 'auto' and 'left' is not 'auto', then the width is shrink-to-fit . Then solve for 'right'
+    // 4. 'left' is 'auto', 'width' and 'right' are not 'auto', then solve for 'left'
+    // 5. 'width' is 'auto', 'left' and 'right' are not 'auto', then solve for 'width'
+    // 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve for 'right'
+
+    auto& formattingContext = this->formattingContext();
+    auto& style = layoutBox.style();
+    auto& boxGeometry = formattingContext.geometryForBox(layoutBox);
+    auto containingBlockWidth = horizontalConstraints.logicalWidth;
+    auto isLeftToRightDirection = layoutBox.containingBlock().style().isLeftToRightDirection();
+    
+    auto left = computedValue(style.logicalLeft(), containingBlockWidth);
+    auto right = computedValue(style.logicalRight(), containingBlockWidth);
+    auto width = overriddenHorizontalValues.width ? overriddenHorizontalValues.width : computedWidth(layoutBox, containingBlockWidth);
+    auto computedHorizontalMargin = FormattingGeometry::computedHorizontalMargin(layoutBox, horizontalConstraints);
+    UsedHorizontalMargin usedHorizontalMargin;
+    auto paddingLeft = boxGeometry.paddingLeft().valueOr(0);
+    auto paddingRight = boxGeometry.paddingRight().valueOr(0);
+    auto borderLeft = boxGeometry.borderLeft();
+    auto borderRight = boxGeometry.borderRight();
+    if (!left && !width && !right) {
+        // If all three of 'left', 'width', and 'right' are 'auto': First set any 'auto' values for 'margin-left' and 'margin-right' to 0.
+        // Then, if the 'direction' property of the element establishing the static-position containing block is 'ltr' set 'left' to the static
+        // position and apply rule number three below; otherwise, set 'right' to the static position and apply rule number one below.
+        usedHorizontalMargin = { computedHorizontalMargin.start.valueOr(0), computedHorizontalMargin.end.valueOr(0) };
+
+        auto staticHorizontalPosition = staticHorizontalPositionForOutOfFlowPositioned(layoutBox, horizontalConstraints);
+        if (isLeftToRightDirection)
+            left = staticHorizontalPosition;
+        else
+            right = staticHorizontalPosition;
+    } else if (left && width && right) {
+        // If none of the three is 'auto': If both 'margin-left' and 'margin-right' are 'auto', solve the equation under the extra constraint that the two margins get equal values,
+        // unless this would make them negative, in which case when direction of the containing block is 'ltr' ('rtl'), set 'margin-left' ('margin-right') to zero and
+        // solve for 'margin-right' ('margin-left'). If one of 'margin-left' or 'margin-right' is 'auto', solve the equation for that value.
+        // If the values are over-constrained, ignore the value for 'left' (in case the 'direction' property of the containing block is 'rtl') or 'right'
+        // (in case 'direction' is 'ltr') and solve for that value.
+        if (!computedHorizontalMargin.start && !computedHorizontalMargin.end) {
+            auto marginStartAndEnd = containingBlockWidth - (*left + borderLeft + paddingLeft + *width + paddingRight + borderRight + *right);
+            if (marginStartAndEnd >= 0)
+                usedHorizontalMargin = { marginStartAndEnd / 2, marginStartAndEnd / 2 };
+            else {
+                if (isLeftToRightDirection) {
+                    usedHorizontalMargin.start = 0_lu;
+                    usedHorizontalMargin.end = containingBlockWidth - (*left + usedHorizontalMargin.start + borderLeft + paddingLeft + *width + paddingRight + borderRight + *right);
+                } else {
+                    usedHorizontalMargin.end = 0_lu;
+                    usedHorizontalMargin.start = containingBlockWidth - (*left + borderLeft + paddingLeft + *width + paddingRight + borderRight + usedHorizontalMargin.end + *right);
+                }
+            }
+        } else if (!computedHorizontalMargin.start) {
+            usedHorizontalMargin.end = *computedHorizontalMargin.end;
+            usedHorizontalMargin.start = containingBlockWidth - (*left + borderLeft + paddingLeft + *width + paddingRight + borderRight + usedHorizontalMargin.end + *right);
+        } else if (!computedHorizontalMargin.end) {
+            usedHorizontalMargin.start = *computedHorizontalMargin.start;
+            usedHorizontalMargin.end = containingBlockWidth - (*left + usedHorizontalMargin.start + borderLeft + paddingLeft + *width + paddingRight + borderRight + *right);
+        } else {
+            usedHorizontalMargin = { *computedHorizontalMargin.start, *computedHorizontalMargin.end };
+            // Overconstrained? Ignore right (left).
+            if (isLeftToRightDirection)
+                right = containingBlockWidth - (usedHorizontalMargin.start + *left + borderLeft + paddingLeft + *width + paddingRight + borderRight + usedHorizontalMargin.end);
+            else
+                left = containingBlockWidth - (usedHorizontalMargin.start + borderLeft + paddingLeft + *width + paddingRight + borderRight + usedHorizontalMargin.end + *right);
+        }
+    } else {
+        // Otherwise, set 'auto' values for 'margin-left' and 'margin-right' to 0, and pick the one of the following six rules that applies.
+        usedHorizontalMargin = { computedHorizontalMargin.start.valueOr(0), computedHorizontalMargin.end.valueOr(0) };
+    }
+
+    if (!left && !width && right) {
+        // #1
+        // Calculate the available width by solving for 'width' after setting 'left' (in case 1) to 0
+        left = LayoutUnit { 0 };
+        auto availableWidth = containingBlockWidth - (*left + usedHorizontalMargin.start + borderLeft + paddingLeft + paddingRight + borderRight + usedHorizontalMargin.end + *right);
+        width = shrinkToFitWidth(layoutBox, availableWidth);
+        left = containingBlockWidth - (usedHorizontalMargin.start + borderLeft + paddingLeft + *width + paddingRight  + borderRight + usedHorizontalMargin.end + *right);
+    } else if (!left && !right && width) {
+        // #2
+        auto staticHorizontalPosition = staticHorizontalPositionForOutOfFlowPositioned(layoutBox, horizontalConstraints);
+        if (isLeftToRightDirection) {
+            left = staticHorizontalPosition;
+            right = containingBlockWidth - (*left + usedHorizontalMargin.start + borderLeft + paddingLeft + *width + paddingRight + borderRight + usedHorizontalMargin.end);
+        } else {
+            right = staticHorizontalPosition;
+            left = containingBlockWidth - (usedHorizontalMargin.start + borderLeft + paddingLeft + *width + paddingRight + borderRight + usedHorizontalMargin.end + *right);
+        }
+    } else if (!width && !right && left) {
+        // #3
+        // Calculate the available width by solving for 'width' after setting 'right' (in case 3) to 0
+        right = LayoutUnit { 0 };
+        auto availableWidth = containingBlockWidth - (*left + usedHorizontalMargin.start + borderLeft + paddingLeft + paddingRight + borderRight + usedHorizontalMargin.end + *right);
+        width = shrinkToFitWidth(layoutBox, availableWidth);
+        right = containingBlockWidth - (*left + usedHorizontalMargin.start + borderLeft + paddingLeft + *width + paddingRight + borderRight + usedHorizontalMargin.end);
+    } else if (!left && width && right) {
+        // #4
+        left = containingBlockWidth - (usedHorizontalMargin.start + borderLeft + paddingLeft + *width + paddingRight + borderRight + usedHorizontalMargin.end + *right);
+    } else if (!width && left && right) {
+        // #5
+        width = containingBlockWidth - (*left + usedHorizontalMargin.start + borderLeft + paddingLeft + paddingRight + borderRight + usedHorizontalMargin.end + *right);
+    } else if (!right && left && width) {
+        // #6
+        right = containingBlockWidth - (*left + usedHorizontalMargin.start + borderLeft + paddingLeft + *width + paddingRight + borderRight + usedHorizontalMargin.end);
+    }
+
+    ASSERT(left);
+    ASSERT(right);
+    ASSERT(width);
+
+    // For out-of-flow elements the containing block is formed by the padding edge of the ancestor.
+    // At this point the positioned value is in the coordinate system of the padding box. Let's convert it to border box coordinate system.
+    auto containingBlockPaddingVerticalEdge = horizontalConstraints.logicalLeft;
+    *left += containingBlockPaddingVerticalEdge;
+    *right += containingBlockPaddingVerticalEdge;
+
+    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position][Width][Margin] -> out-of-flow non-replaced -> left(" << *left << "px) right("  << *right << "px) width(" << *width << "px) margin(" << usedHorizontalMargin.start << "px, "  << usedHorizontalMargin.end << "px) layoutBox(" << &layoutBox << ")");
+    return { *left, *right, { *width, usedHorizontalMargin } };
+}
+
+VerticalGeometry FormattingGeometry::outOfFlowReplacedVerticalGeometry(const ReplacedBox& replacedBox, const HorizontalConstraints& horizontalConstraints, const VerticalConstraints& verticalConstraints, const OverriddenVerticalValues& overriddenVerticalValues) const
+{
+    ASSERT(replacedBox.isOutOfFlowPositioned());
+    ASSERT(verticalConstraints.logicalHeight);
+
+    // 10.6.5 Absolutely positioned, replaced elements
+    //
+    // The used value of 'height' is determined as for inline replaced elements.
+    // If 'margin-top' or 'margin-bottom' is specified as 'auto' its used value is determined by the rules below.
+    // 1. If both 'top' and 'bottom' have the value 'auto', replace 'top' with the element's static position.
+    // 2. If 'bottom' is 'auto', replace any 'auto' on 'margin-top' or 'margin-bottom' with '0'.
+    // 3. If at this point both 'margin-top' and 'margin-bottom' are still 'auto', solve the equation under the extra constraint that the two margins must get equal values.
+    // 4. If at this point there is only one 'auto' left, solve the equation for that value.
+    // 5. If at this point the values are over-constrained, ignore the value for 'bottom' and solve for that value.
+
+    auto& formattingContext = this->formattingContext();
+    auto& style = replacedBox.style();
+    auto& boxGeometry = formattingContext.geometryForBox(replacedBox);
+    auto containingBlockHeight = *verticalConstraints.logicalHeight;
+    auto containingBlockWidth = horizontalConstraints.logicalWidth;
+
+    auto top = computedValue(style.logicalTop(), containingBlockWidth);
+    auto bottom = computedValue(style.logicalBottom(), containingBlockWidth);
+    auto height = inlineReplacedContentHeightAndMargin(replacedBox, horizontalConstraints, verticalConstraints, overriddenVerticalValues).contentHeight;
+    auto computedVerticalMargin = FormattingGeometry::computedVerticalMargin(replacedBox, horizontalConstraints);
+    Optional<LayoutUnit> usedMarginBefore = computedVerticalMargin.before;
+    Optional<LayoutUnit> usedMarginAfter = computedVerticalMargin.after;
+    auto paddingTop = boxGeometry.paddingTop().valueOr(0);
+    auto paddingBottom = boxGeometry.paddingBottom().valueOr(0);
+    auto borderTop = boxGeometry.borderTop();
+    auto borderBottom = boxGeometry.borderBottom();
+
+    if (!top && !bottom) {
+        // #1
+        top = staticVerticalPositionForOutOfFlowPositioned(replacedBox, verticalConstraints);
+    }
+
+    if (!bottom) {
+        // #2
+        usedMarginBefore = computedVerticalMargin.before.valueOr(0);
+        usedMarginAfter = usedMarginBefore;
+    }
+
+    if (!usedMarginBefore && !usedMarginAfter) {
+        // #3
+        auto marginBeforeAndAfter = containingBlockHeight - (*top + borderTop + paddingTop + height + paddingBottom + borderBottom + *bottom);
+        usedMarginBefore = marginBeforeAndAfter / 2;
+        usedMarginAfter = usedMarginBefore;
+    }
+
+    // #4
+    if (!top)
+        top = containingBlockHeight - (*usedMarginBefore + borderTop + paddingTop + height + paddingBottom + borderBottom + *usedMarginAfter + *bottom);
+
+    if (!bottom)
+        bottom = containingBlockHeight - (*top + *usedMarginBefore + borderTop + paddingTop + height + paddingBottom + borderBottom + *usedMarginAfter);
+
+    if (!usedMarginBefore)
+        usedMarginBefore = containingBlockHeight - (*top + borderTop + paddingTop + height + paddingBottom + borderBottom + *usedMarginAfter + *bottom);
+
+    if (!usedMarginAfter)
+        usedMarginAfter = containingBlockHeight - (*top + *usedMarginBefore + borderTop + paddingTop + height + paddingBottom + borderBottom + *bottom);
+
+    // #5
+    auto boxHeight = *top + *usedMarginBefore + borderTop + paddingTop + height + paddingBottom + borderBottom + *usedMarginAfter + *bottom;
+    if (boxHeight > containingBlockHeight)
+        bottom = containingBlockHeight - (*top + *usedMarginBefore + borderTop + paddingTop + height + paddingBottom + borderBottom + *usedMarginAfter); 
+
+    // For out-of-flow elements the containing block is formed by the padding edge of the ancestor.
+    // At this point the positioned value is in the coordinate system of the padding box. Let's convert it to border box coordinate system.
+    auto containingBlockPaddingVerticalEdge = verticalConstraints.logicalTop;
+    *top += containingBlockPaddingVerticalEdge;
+    *bottom += containingBlockPaddingVerticalEdge;
+
+    ASSERT(top);
+    ASSERT(bottom);
+    ASSERT(usedMarginBefore);
+    ASSERT(usedMarginAfter);
+    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position][Height][Margin] -> out-of-flow replaced -> top(" << *top << "px) bottom("  << *bottom << "px) height(" << height << "px) margin(" << *usedMarginBefore << "px, "  << *usedMarginAfter << "px) layoutBox(" << &replacedBox << ")");
+    return { *top, *bottom, { height, { *usedMarginBefore, *usedMarginAfter } } };
+}
+
+HorizontalGeometry FormattingGeometry::outOfFlowReplacedHorizontalGeometry(const ReplacedBox& replacedBox, const HorizontalConstraints& horizontalConstraints, const VerticalConstraints& verticalConstraints, const OverriddenHorizontalValues& overriddenHorizontalValues)
+{
+    ASSERT(replacedBox.isOutOfFlowPositioned());
+
+    // 10.3.8 Absolutely positioned, replaced elements
+    // In this case, section 10.3.7 applies up through and including the constraint equation, but the rest of section 10.3.7 is replaced by the following rules:
+    //
+    // The used value of 'width' is determined as for inline replaced elements. If 'margin-left' or 'margin-right' is specified as 'auto' its used value is determined by the rules below.
+    // 1. If both 'left' and 'right' have the value 'auto', then if the 'direction' property of the element establishing the static-position containing block is 'ltr',
+    //   set 'left' to the static position; else if 'direction' is 'rtl', set 'right' to the static position.
+    // 2. If 'left' or 'right' are 'auto', replace any 'auto' on 'margin-left' or 'margin-right' with '0'.
+    // 3. If at this point both 'margin-left' and 'margin-right' are still 'auto', solve the equation under the extra constraint that the two margins must get equal values,
+    //   unless this would make them negative, in which case when the direction of the containing block is 'ltr' ('rtl'), set 'margin-left' ('margin-right') to zero and
+    //   solve for 'margin-right' ('margin-left').
+    // 4. If at this point there is an 'auto' left, solve the equation for that value.
+    // 5. If at this point the values are over-constrained, ignore the value for either 'left' (in case the 'direction' property of the containing block is 'rtl') or
+    //   'right' (in case 'direction' is 'ltr') and solve for that value.
+
+    auto& formattingContext = this->formattingContext();
+    auto& style = replacedBox.style();
+    auto& boxGeometry = formattingContext.geometryForBox(replacedBox);
+    auto containingBlockWidth = horizontalConstraints.logicalWidth;
+    auto isLeftToRightDirection = replacedBox.containingBlock().style().isLeftToRightDirection();
+
+    auto left = computedValue(style.logicalLeft(), containingBlockWidth);
+    auto right = computedValue(style.logicalRight(), containingBlockWidth);
+    auto computedHorizontalMargin = FormattingGeometry::computedHorizontalMargin(replacedBox, horizontalConstraints);
+    Optional<LayoutUnit> usedMarginStart = computedHorizontalMargin.start;
+    Optional<LayoutUnit> usedMarginEnd = computedHorizontalMargin.end;
+    auto width = inlineReplacedContentWidthAndMargin(replacedBox, horizontalConstraints, verticalConstraints, overriddenHorizontalValues).contentWidth;
+    auto paddingLeft = boxGeometry.paddingLeft().valueOr(0);
+    auto paddingRight = boxGeometry.paddingRight().valueOr(0);
+    auto borderLeft = boxGeometry.borderLeft();
+    auto borderRight = boxGeometry.borderRight();
+
+    if (!left && !right) {
+        // #1
+        auto staticHorizontalPosition = staticHorizontalPositionForOutOfFlowPositioned(replacedBox, horizontalConstraints);
+        if (isLeftToRightDirection)
+            left = staticHorizontalPosition;
+        else
+            right = staticHorizontalPosition;
+    }
+
+    if (!left || !right) {
+        // #2
+        usedMarginStart = computedHorizontalMargin.start.valueOr(0);
+        usedMarginEnd = computedHorizontalMargin.end.valueOr(0);
+    }
+
+    if (!usedMarginStart && !usedMarginEnd) {
+        // #3
+        auto marginStartAndEnd = containingBlockWidth - (*left + borderLeft + paddingLeft + width + paddingRight + borderRight + *right);
+        if (marginStartAndEnd >= 0) {
+            usedMarginStart = marginStartAndEnd / 2;
+            usedMarginEnd = usedMarginStart;
+        } else {
+            if (isLeftToRightDirection) {
+                usedMarginStart = 0_lu;
+                usedMarginEnd = containingBlockWidth - (*left + *usedMarginStart + borderLeft + paddingLeft + width + paddingRight + borderRight + *right);
+            } else {
+                usedMarginEnd = 0_lu;
+                usedMarginStart = containingBlockWidth - (*left + borderLeft + paddingLeft + width + paddingRight + borderRight + *usedMarginEnd + *right);
+            }
+        }
+    }
+
+    // #4
+    if (!left)
+        left = containingBlockWidth - (*usedMarginStart + borderLeft + paddingLeft + width + paddingRight + borderRight + *usedMarginEnd + *right);
+
+    if (!right)
+        right = containingBlockWidth - (*left + *usedMarginStart + borderLeft + paddingLeft + width + paddingRight + borderRight + *usedMarginEnd);
+
+    if (!usedMarginStart)
+        usedMarginStart = containingBlockWidth - (*left + borderLeft + paddingLeft + width + paddingRight + borderRight + *usedMarginEnd + *right);
+
+    if (!usedMarginEnd)
+        usedMarginEnd = containingBlockWidth - (*left + *usedMarginStart + borderLeft + paddingLeft + width + paddingRight + borderRight + *right);
+
+    auto boxWidth = (*left + *usedMarginStart + borderLeft + paddingLeft + width + paddingRight + borderRight + *usedMarginEnd + *right);
+    if (boxWidth > containingBlockWidth) {
+        // #5 Over-constrained?
+        if (isLeftToRightDirection)
+            right = containingBlockWidth - (*left + *usedMarginStart + borderLeft + paddingLeft + width + paddingRight + borderRight + *usedMarginEnd);
+        else
+            left = containingBlockWidth - (*usedMarginStart + borderLeft + paddingLeft + width + paddingRight + borderRight + *usedMarginEnd + *right);
+    }
+
+    ASSERT(left);
+    ASSERT(right);
+    ASSERT(usedMarginStart);
+    ASSERT(usedMarginEnd);
+
+    // For out-of-flow elements the containing block is formed by the padding edge of the ancestor.
+    // At this point the positioned value is in the coordinate system of the padding box. Let's convert it to border box coordinate system.
+    auto containingBlockPaddingVerticalEdge = horizontalConstraints.logicalLeft;
+    *left += containingBlockPaddingVerticalEdge;
+    *right += containingBlockPaddingVerticalEdge;
+
+    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position][Width][Margin] -> out-of-flow replaced -> left(" << *left << "px) right("  << *right << "px) width(" << width << "px) margin(" << *usedMarginStart << "px, "  << *usedMarginEnd << "px) layoutBox(" << &replacedBox << ")");
+    return { *left, *right, { width, { *usedMarginStart, *usedMarginEnd } } };
+}
+
+ContentHeightAndMargin FormattingGeometry::complicatedCases(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints, const OverriddenVerticalValues& overriddenVerticalValues) const
+{
+    ASSERT(!layoutBox.isReplacedBox());
+    // TODO: Use complicated-case for document renderer for now (see BlockFormattingGeometry::inFlowHeightAndMargin).
+    ASSERT((layoutBox.isBlockLevelBox() && layoutBox.isInFlow() && !layoutBox.isOverflowVisible()) || layoutBox.isInlineBlockBox() || layoutBox.isFloatingPositioned() || layoutBox.isDocumentBox() || layoutBox.isTableBox());
+
+    // 10.6.6 Complicated cases
+    //
+    // Block-level, non-replaced elements in normal flow when 'overflow' does not compute to 'visible' (except if the 'overflow' property's value has been propagated to the viewport).
+    // 'Inline-block', non-replaced elements.
+    // Floating, non-replaced elements.
+    //
+    // 1. If 'margin-top', or 'margin-bottom' are 'auto', their used value is 0.
+    // 2. If 'height' is 'auto', the height depends on the element's descendants per 10.6.7.
+
+    auto height = overriddenVerticalValues.height ? overriddenVerticalValues.height.value() : computedHeight(layoutBox);
+    auto computedVerticalMargin = FormattingGeometry::computedVerticalMargin(layoutBox, horizontalConstraints);
+    // #1
+    auto usedVerticalMargin = UsedVerticalMargin::NonCollapsedValues { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) }; 
+    // #2
+    if (!height) {
+        ASSERT(isHeightAuto(layoutBox));
+        if (!is<ContainerBox>(layoutBox) || !downcast<ContainerBox>(layoutBox).hasInFlowOrFloatingChild())
+            height = 0_lu;
+        else if (layoutBox.isDocumentBox() && !layoutBox.establishesFormattingContext()) {
+            auto& documentBox = downcast<ContainerBox>(layoutBox);
+            auto top = BoxGeometry::marginBoxRect(formattingContext().geometryForBox(*documentBox.firstInFlowChild())).top();
+            auto bottom = BoxGeometry::marginBoxRect(formattingContext().geometryForBox(*documentBox.lastInFlowChild())).bottom();
+            // This is a special (quirk?) behavior since the document box is not a formatting context root and
+            // all the float boxes end up at the ICB level.
+            auto& initialContainingBlock = documentBox.formattingContextRoot();
+            auto floatingContext = FloatingContext { formattingContext(), layoutState().establishedFormattingState(initialContainingBlock).floatingState() };
+            if (auto floatBottom = floatingContext.bottom()) {
+                bottom = std::max<LayoutUnit>(*floatBottom, bottom);
+                auto floatTop = floatingContext.top();
+                ASSERT(floatTop);
+                top = std::min<LayoutUnit>(*floatTop, top);
+            }
+            height = bottom - top;
+        } else {
+            ASSERT(layoutBox.establishesFormattingContext());
+            height = contentHeightForFormattingContextRoot(downcast<ContainerBox>(layoutBox));
+        }
+    }
+
+    ASSERT(height);
+
+    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> floating non-replaced -> height(" << *height << "px) margin(" << usedVerticalMargin.before << "px, " << usedVerticalMargin.after << "px) -> layoutBox(" << &layoutBox << ")");
+    return ContentHeightAndMargin { *height, usedVerticalMargin };
+}
+
+ContentWidthAndMargin FormattingGeometry::floatingNonReplacedContentWidthAndMargin(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints, const OverriddenHorizontalValues& overriddenHorizontalValues)
+{
+    ASSERT(layoutBox.isFloatingPositioned() && !layoutBox.isReplacedBox());
+
+    // 10.3.5 Floating, non-replaced elements
+    //
+    // 1. If 'margin-left', or 'margin-right' are computed as 'auto', their used value is '0'.
+    // 2. If 'width' is computed as 'auto', the used value is the "shrink-to-fit" width.
+
+    auto computedHorizontalMargin = FormattingGeometry::computedHorizontalMargin(layoutBox, horizontalConstraints);
+
+    // #1
+    auto usedHorizontallMargin = UsedHorizontalMargin { computedHorizontalMargin.start.valueOr(0), computedHorizontalMargin.end.valueOr(0) };
+    // #2
+    auto width = overriddenHorizontalValues.width ? overriddenHorizontalValues.width : computedWidth(layoutBox, horizontalConstraints.logicalWidth);
+    if (!width)
+        width = shrinkToFitWidth(layoutBox, horizontalConstraints.logicalWidth);
+
+    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Width][Margin] -> floating non-replaced -> width(" << *width << "px) margin(" << usedHorizontallMargin.start << "px, " << usedHorizontallMargin.end << "px) -> layoutBox(" << &layoutBox << ")");
+    return ContentWidthAndMargin { *width, usedHorizontallMargin };
+}
+
+ContentHeightAndMargin FormattingGeometry::floatingReplacedContentHeightAndMargin(const ReplacedBox& replacedBox, const HorizontalConstraints& horizontalConstraints, const OverriddenVerticalValues& overriddenVerticalValues) const
+{
+    ASSERT(replacedBox.isFloatingPositioned());
+
+    // 10.6.2 Inline replaced elements, block-level replaced elements in normal flow, 'inline-block'
+    // replaced elements in normal flow and floating replaced elements
+    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> floating replaced -> redirected to inline replaced");
+    return inlineReplacedContentHeightAndMargin(replacedBox, horizontalConstraints, { }, overriddenVerticalValues);
+}
+
+ContentWidthAndMargin FormattingGeometry::floatingReplacedContentWidthAndMargin(const ReplacedBox& replacedBox, const HorizontalConstraints& horizontalConstraints, const OverriddenHorizontalValues& overriddenHorizontalValues)
+{
+    ASSERT(replacedBox.isFloatingPositioned());
+
+    // 10.3.6 Floating, replaced elements
+    //
+    // 1. If 'margin-left' or 'margin-right' are computed as 'auto', their used value is '0'.
+    // 2. The used value of 'width' is determined as for inline replaced elements.
+    auto computedHorizontalMargin = FormattingGeometry::computedHorizontalMargin(replacedBox, horizontalConstraints);
+
+    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> floating replaced -> redirected to inline replaced");
+    auto usedMargin = UsedHorizontalMargin { computedHorizontalMargin.start.valueOr(0), computedHorizontalMargin.end.valueOr(0) };
+    return inlineReplacedContentWidthAndMargin(replacedBox, horizontalConstraints, { }, { overriddenHorizontalValues.width, usedMargin });
+}
+
+VerticalGeometry FormattingGeometry::outOfFlowVerticalGeometry(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints, const VerticalConstraints& verticalConstraints, const OverriddenVerticalValues& overriddenVerticalValues) const
+{
+    ASSERT(layoutBox.isOutOfFlowPositioned());
+
+    if (!layoutBox.isReplacedBox())
+        return outOfFlowNonReplacedVerticalGeometry(downcast<ContainerBox>(layoutBox), horizontalConstraints, verticalConstraints, overriddenVerticalValues);
+    return outOfFlowReplacedVerticalGeometry(downcast<ReplacedBox>(layoutBox), horizontalConstraints, verticalConstraints, overriddenVerticalValues);
+}
+
+HorizontalGeometry FormattingGeometry::outOfFlowHorizontalGeometry(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints, const VerticalConstraints& verticalConstraints, const OverriddenHorizontalValues& overriddenHorizontalValues)
+{
+    ASSERT(layoutBox.isOutOfFlowPositioned());
+
+    if (!layoutBox.isReplacedBox())
+        return outOfFlowNonReplacedHorizontalGeometry(downcast<ContainerBox>(layoutBox), horizontalConstraints, overriddenHorizontalValues);
+    return outOfFlowReplacedHorizontalGeometry(downcast<ReplacedBox>(layoutBox), horizontalConstraints, verticalConstraints, overriddenHorizontalValues);
+}
+
+ContentHeightAndMargin FormattingGeometry::floatingContentHeightAndMargin(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints, const OverriddenVerticalValues& overriddenVerticalValues) const
+{
+    ASSERT(layoutBox.isFloatingPositioned());
+
+    if (!layoutBox.isReplacedBox())
+        return complicatedCases(layoutBox, horizontalConstraints, overriddenVerticalValues);
+    return floatingReplacedContentHeightAndMargin(downcast<ReplacedBox>(layoutBox), horizontalConstraints, overriddenVerticalValues);
+}
+
+ContentWidthAndMargin FormattingGeometry::floatingContentWidthAndMargin(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints, const OverriddenHorizontalValues& overriddenHorizontalValues)
+{
+    ASSERT(layoutBox.isFloatingPositioned());
+
+    if (!layoutBox.isReplacedBox())
+        return floatingNonReplacedContentWidthAndMargin(layoutBox, horizontalConstraints, overriddenHorizontalValues);
+    return floatingReplacedContentWidthAndMargin(downcast<ReplacedBox>(layoutBox), horizontalConstraints, overriddenHorizontalValues);
+}
+
+ContentHeightAndMargin FormattingGeometry::inlineReplacedContentHeightAndMargin(const ReplacedBox& replacedBox, const HorizontalConstraints& horizontalConstraints, Optional<VerticalConstraints> verticalConstraints, const OverriddenVerticalValues& overriddenVerticalValues) const
+{
+    // 10.6.2 Inline replaced elements, block-level replaced elements in normal flow, 'inline-block' replaced elements in normal flow and floating replaced elements
+    //
+    // 1. If 'margin-top', or 'margin-bottom' are 'auto', their used value is 0.
+    // 2. If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic height, then that intrinsic height is the used value of 'height'.
+    // 3. Otherwise, if 'height' has a computed value of 'auto', and the element has an intrinsic ratio then the used value of 'height' is:
+    //    (used width) / (intrinsic ratio)
+    // 4. Otherwise, if 'height' has a computed value of 'auto', and the element has an intrinsic height, then that intrinsic height is the used value of 'height'.
+    // 5. Otherwise, if 'height' has a computed value of 'auto', but none of the conditions above are met, then the used value of 'height' must be set to
+    //    the height of the largest rectangle that has a 2:1 ratio, has a height not greater than 150px, and has a width not greater than the device width.
+
+    // #1
+    auto& formattingContext = this->formattingContext();
+    auto computedVerticalMargin = FormattingGeometry::computedVerticalMargin(replacedBox, horizontalConstraints);
+    auto usedVerticalMargin = UsedVerticalMargin::NonCollapsedValues { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) };
+    auto& style = replacedBox.style();
+
+    auto height = overriddenVerticalValues.height ? overriddenVerticalValues.height.value() : computedHeight(replacedBox, verticalConstraints ? verticalConstraints->logicalHeight : WTF::nullopt);
+    auto heightIsAuto = !overriddenVerticalValues.height && isHeightAuto(replacedBox);
+    auto widthIsAuto = style.logicalWidth().isAuto();
+
+    if (heightIsAuto && widthIsAuto && replacedBox.hasIntrinsicHeight()) {
+        // #2
+        height = replacedBox.intrinsicHeight();
+    } else if (heightIsAuto && replacedBox.hasIntrinsicRatio()) {
+        // #3
+        auto usedWidth = formattingContext.geometryForBox(replacedBox).contentBoxWidth();
+        height = usedWidth / replacedBox.intrinsicRatio();
+    } else if (heightIsAuto && replacedBox.hasIntrinsicHeight()) {
+        // #4
+        height = replacedBox.intrinsicHeight();
+    } else if (heightIsAuto) {
+        // #5
+        height = { 150 };
+    }
+
+    ASSERT(height);
+
+    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> inflow replaced -> height(" << *height << "px) margin(" << usedVerticalMargin.before << "px, " << usedVerticalMargin.after << "px) -> layoutBox(" << &replacedBox << ")");
+    return { *height, usedVerticalMargin };
+}
+
+ContentWidthAndMargin FormattingGeometry::inlineReplacedContentWidthAndMargin(const ReplacedBox& replacedBox, const HorizontalConstraints& horizontalConstraints, Optional<VerticalConstraints> verticalConstraints, const OverriddenHorizontalValues& overriddenHorizontalValues)
+{
+    // 10.3.2 Inline, replaced elements
+    //
+    // A computed value of 'auto' for 'margin-left' or 'margin-right' becomes a used value of '0'.
+    //
+    // 1. If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic width, then that intrinsic width is the used value of 'width'.
+    //
+    // 2. If 'height' and 'width' both have computed values of 'auto' and the element has no intrinsic width, but does have an intrinsic height and intrinsic ratio;
+    //    or if 'width' has a computed value of 'auto', 'height' has some other computed value, and the element does have an intrinsic ratio;
+    //    then the used value of 'width' is: (used height) * (intrinsic ratio)
+    //
+    // 3. If 'height' and 'width' both have computed values of 'auto' and the element has an intrinsic ratio but no intrinsic height or width,
+    //    then the used value of 'width' is undefined in CSS 2.2. However, it is suggested that, if the containing block's width does not itself depend on the replaced
+    //    element's width, then the used value of 'width' is calculated from the constraint equation used for block-level, non-replaced elements in normal flow.
+    //
+    // 4. Otherwise, if 'width' has a computed value of 'auto', and the element has an intrinsic width, then that intrinsic width is the used value of 'width'.
+    //
+    // 5. Otherwise, if 'width' has a computed value of 'auto', but none of the conditions above are met, then the used value of 'width' becomes 300px.
+    //    If 300px is too wide to fit the device, UAs should use the width of the largest rectangle that has a 2:1 ratio and fits the device instead.
+
+    auto computedHorizontalMargin = FormattingGeometry::computedHorizontalMargin(replacedBox, horizontalConstraints);
+
+    auto usedMarginStart = [&] {
+        if (overriddenHorizontalValues.margin)
+            return overriddenHorizontalValues.margin->start;
+        return computedHorizontalMargin.start.valueOr(0_lu);
+    };
+
+    auto usedMarginEnd = [&] {
+        if (overriddenHorizontalValues.margin)
+            return overriddenHorizontalValues.margin->end;
+        return computedHorizontalMargin.end.valueOr(0_lu);
+    };
+
+    auto width = overriddenHorizontalValues.width ? overriddenHorizontalValues.width : computedWidth(replacedBox, horizontalConstraints.logicalWidth);
+    auto heightIsAuto = isHeightAuto(replacedBox);
+    auto height = computedHeight(replacedBox, verticalConstraints ? verticalConstraints->logicalHeight : WTF::nullopt);
+
+    if (!width && heightIsAuto && replacedBox.hasIntrinsicWidth()) {
+        // #1
+        width = replacedBox.intrinsicWidth();
+    } else if ((!width && heightIsAuto && !replacedBox.hasIntrinsicWidth() && replacedBox.hasIntrinsicHeight() && replacedBox.hasIntrinsicRatio())
+        || (!width && height && replacedBox.hasIntrinsicRatio())) {
+        // #2
+        width = height.valueOr(replacedBox.hasIntrinsicHeight()) * replacedBox.intrinsicRatio();
+    } else if (!width && heightIsAuto && replacedBox.hasIntrinsicRatio() && !replacedBox.hasIntrinsicWidth() && !replacedBox.hasIntrinsicHeight()) {
+        // #3
+        // FIXME: undefined but surely doable.
+        ASSERT_NOT_IMPLEMENTED_YET();
+    } else if (!width && replacedBox.hasIntrinsicWidth()) {
+        // #4
+        width = replacedBox.intrinsicWidth();
+    } else if (!width) {
+        // #5
+        width = { 300 };
+    }
+
+    ASSERT(width);
+
+    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Width][Margin] -> inflow replaced -> width(" << *width << "px) margin(" << usedMarginStart() << "px, " << usedMarginEnd() << "px) -> layoutBox(" << &replacedBox << ")");
+    return { *width, { usedMarginStart(), usedMarginEnd() } };
+}
+
+LayoutSize FormattingGeometry::inFlowPositionedPositionOffset(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints) const
+{
+    ASSERT(layoutBox.isInFlowPositioned());
+
+    // 9.4.3 Relative positioning
+    //
+    // The 'top' and 'bottom' properties move relatively positioned element(s) up or down without changing their size.
+    // Top' moves the boxes down, and 'bottom' moves them up. Since boxes are not split or stretched as a result of 'top' or 'bottom', the used values are always: top = -bottom.
+    //
+    // 1. If both are 'auto', their used values are both '0'.
+    // 2. If one of them is 'auto', it becomes the negative of the other.
+    // 3. If neither is 'auto', 'bottom' is ignored (i.e., the used value of 'bottom' will be minus the value of 'top').
+
+    auto& style = layoutBox.style();
+    auto containingBlockWidth = horizontalConstraints.logicalWidth;
+
+    auto top = computedValue(style.logicalTop(), containingBlockWidth);
+    auto bottom = computedValue(style.logicalBottom(), containingBlockWidth);
+
+    if (!top && !bottom) {
+        // #1
+        top = bottom = { 0 };
+    } else if (!top) {
+        // #2
+        top = -*bottom;
+    } else if (!bottom) {
+        // #3
+        bottom = -*top;
+    } else {
+        // #4
+        bottom = WTF::nullopt;
+    }
+
+    // For relatively positioned elements, 'left' and 'right' move the box(es) horizontally, without changing their size.
+    // 'Left' moves the boxes to the right, and 'right' moves them to the left.
+    // Since boxes are not split or stretched as a result of 'left' or 'right', the used values are always: left = -right.
+    //
+    // 1. If both 'left' and 'right' are 'auto' (their initial values), the used values are '0' (i.e., the boxes stay in their original position).
+    // 2. If 'left' is 'auto', its used value is minus the value of 'right' (i.e., the boxes move to the left by the value of 'right').
+    // 3. If 'right' is specified as 'auto', its used value is minus the value of 'left'.
+    // 4. If neither 'left' nor 'right' is 'auto', the position is over-constrained, and one of them has to be ignored.
+    //    If the 'direction' property of the containing block is 'ltr', the value of 'left' wins and 'right' becomes -'left'.
+    //    If 'direction' of the containing block is 'rtl', 'right' wins and 'left' is ignored.
+
+    auto left = computedValue(style.logicalLeft(), containingBlockWidth);
+    auto right = computedValue(style.logicalRight(), containingBlockWidth);
+
+    if (!left && !right) {
+        // #1
+        left = right = { 0 };
+    } else if (!left) {
+        // #2
+        left = -*right;
+    } else if (!right) {
+        // #3
+        right = -*left;
+    } else {
+        // #4
+        auto isLeftToRightDirection = layoutBox.containingBlock().style().isLeftToRightDirection();
+        if (isLeftToRightDirection)
+            right = -*left;
+        else
+            left = WTF::nullopt;
+    }
+
+    ASSERT(!bottom || *top == -*bottom);
+    ASSERT(!left || *left == -*right);
+
+    auto topPositionOffset = *top;
+    auto leftPositionOffset = left.valueOr(-*right);
+
+    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position] -> positioned inflow -> top offset(" << topPositionOffset << "px) left offset(" << leftPositionOffset << "px) layoutBox(" << &layoutBox << ")");
+    return { leftPositionOffset, topPositionOffset };
+}
+
+inline static WritingMode usedWritingMode(const Box& layoutBox)
+{
+    // https://www.w3.org/TR/css-writing-modes-4/#logical-direction-layout
+    // Flow-relative directions are calculated with respect to the writing mode of the containing block of the box.
+    // For inline-level boxes, the writing mode of the parent box is used instead.
+    return layoutBox.isInlineLevelBox() ? layoutBox.parent().style().writingMode() : layoutBox.containingBlock().style().writingMode();
+}
+
+Edges FormattingGeometry::computedBorder(const Box& layoutBox) const
+{
+    auto& style = layoutBox.style();
+    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Border] -> layoutBox: " << &layoutBox);
+    return {
+        { LayoutUnit(style.borderLeftWidth()), LayoutUnit(style.borderRightWidth()) },
+        { LayoutUnit(style.borderTopWidth()), LayoutUnit(style.borderBottomWidth()) }
+    };
+}
+
+Optional<Edges> FormattingGeometry::computedPadding(const Box& layoutBox, const LayoutUnit containingBlockWidth) const
+{
+    if (!layoutBox.isPaddingApplicable())
+        return WTF::nullopt;
+
+    auto& style = layoutBox.style();
+    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Padding] -> layoutBox: " << &layoutBox);
+    return Edges {
+        { valueForLength(style.paddingLeft(), containingBlockWidth), valueForLength(style.paddingRight(), containingBlockWidth) },
+        { valueForLength(style.paddingTop(), containingBlockWidth), valueForLength(style.paddingBottom(), containingBlockWidth) }
+    };
+}
+
+ComputedHorizontalMargin FormattingGeometry::computedHorizontalMargin(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints) const
+{
+    auto& style = layoutBox.style();
+    auto containingBlockWidth = horizontalConstraints.logicalWidth;
+    if (isHorizontalWritingMode(usedWritingMode(layoutBox)))
+        return { computedValue(style.marginLeft(), containingBlockWidth), computedValue(style.marginRight(), containingBlockWidth) };
+    return { computedValue(style.marginTop(), containingBlockWidth), computedValue(style.marginBottom(), containingBlockWidth) };
+}
+
+ComputedVerticalMargin FormattingGeometry::computedVerticalMargin(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints) const
+{
+    auto& style = layoutBox.style();
+    auto containingBlockWidth = horizontalConstraints.logicalWidth;
+    if (isHorizontalWritingMode(usedWritingMode(layoutBox)))
+        return { computedValue(style.marginTop(), containingBlockWidth), computedValue(style.marginBottom(), containingBlockWidth) };
+    return { computedValue(style.marginLeft(), containingBlockWidth), computedValue(style.marginRight(), containingBlockWidth) };
+}
+
+FormattingContext::IntrinsicWidthConstraints FormattingGeometry::constrainByMinMaxWidth(const Box& layoutBox, FormattingContext::IntrinsicWidthConstraints intrinsicWidth) const
+{
+    auto& style = layoutBox.style();
+    auto minWidth = fixedValue(style.logicalMinWidth());
+    auto maxWidth = fixedValue(style.logicalMaxWidth());
+    if (!minWidth && !maxWidth)
+        return intrinsicWidth;
+
+    if (maxWidth) {
+        intrinsicWidth.minimum = std::min(*maxWidth, intrinsicWidth.minimum);
+        intrinsicWidth.maximum = std::min(*maxWidth, intrinsicWidth.maximum);
+    }
+
+    if (minWidth) {
+        intrinsicWidth.minimum = std::max(*minWidth, intrinsicWidth.minimum);
+        intrinsicWidth.maximum = std::max(*minWidth, intrinsicWidth.maximum);
+    }
+
+    ASSERT(intrinsicWidth.minimum <= intrinsicWidth.maximum);
+    return intrinsicWidth;
+}
+
+FormattingContext::ConstraintsForOutOfFlowContent FormattingGeometry::constraintsForOutOfFlowContent(const ContainerBox& containerBox)
+{
+    auto& boxGeometry = formattingContext().geometryForBox(containerBox);
+    return {
+        { boxGeometry.paddingBoxLeft(), boxGeometry.paddingBoxWidth() },
+        { boxGeometry.paddingBoxTop(), boxGeometry.paddingBoxHeight() },
+        boxGeometry.contentBoxWidth() };
+}
+
+FormattingContext::ConstraintsForInFlowContent FormattingGeometry::constraintsForInFlowContent(const ContainerBox& containerBox, Optional<FormattingContext::EscapeReason> escapeReason)
+{
+    auto& boxGeometry = formattingContext().geometryForBox(containerBox, escapeReason);
+    return { { boxGeometry.contentBoxLeft(), boxGeometry.contentBoxWidth() }, { boxGeometry.contentBoxTop(), computedHeight(containerBox) } };
+}
+
+}
+}
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebCorelayoutformattingContextsFormattingGeometryh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/layout/formattingContexts/FormattingGeometry.h (0 => 277556)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/formattingContexts/FormattingGeometry.h                              (rev 0)
+++ trunk/Source/WebCore/layout/formattingContexts/FormattingGeometry.h 2021-05-16 01:56:55 UTC (rev 277556)
</span><span class="lines">@@ -0,0 +1,125 @@
</span><ins>+/*
+ * Copyright (C) 2021 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 "FormattingContext.h"
+
+namespace WebCore {
+namespace Layout {
+
+class ReplacedBox;
+struct ComputedHorizontalMargin;
+struct ComputedVerticalMargin;
+class ContainerBox;
+struct ContentHeightAndMargin;
+struct ContentWidthAndMargin;
+struct Edges;
+struct HorizontalGeometry;
+class LayoutState;
+struct OverriddenHorizontalValues;
+struct OverriddenVerticalValues;
+struct VerticalGeometry;
+
+// This class implements generic positioning and sizing.
+class FormattingGeometry {
+public:
+    VerticalGeometry outOfFlowVerticalGeometry(const Box&, const HorizontalConstraints&, const VerticalConstraints&, const OverriddenVerticalValues&) const;
+    HorizontalGeometry outOfFlowHorizontalGeometry(const Box&, const HorizontalConstraints&, const VerticalConstraints&, const OverriddenHorizontalValues&);
+
+    ContentHeightAndMargin floatingContentHeightAndMargin(const Box&, const HorizontalConstraints&, const OverriddenVerticalValues&) const;
+    ContentWidthAndMargin floatingContentWidthAndMargin(const Box&, const HorizontalConstraints&, const OverriddenHorizontalValues&);
+
+    ContentHeightAndMargin inlineReplacedContentHeightAndMargin(const ReplacedBox&, const HorizontalConstraints&, Optional<VerticalConstraints>, const OverriddenVerticalValues&) const;
+    ContentWidthAndMargin inlineReplacedContentWidthAndMargin(const ReplacedBox&, const HorizontalConstraints&, Optional<VerticalConstraints>, const OverriddenHorizontalValues&);
+
+    LayoutSize inFlowPositionedPositionOffset(const Box&, const HorizontalConstraints&) const;
+
+    ContentHeightAndMargin complicatedCases(const Box&, const HorizontalConstraints&, const OverriddenVerticalValues&) const;
+    LayoutUnit shrinkToFitWidth(const Box&, LayoutUnit availableWidth);
+
+    Edges computedBorder(const Box&) const;
+    Optional<Edges> computedPadding(const Box&, LayoutUnit containingBlockWidth) const;
+
+    ComputedHorizontalMargin computedHorizontalMargin(const Box&, const HorizontalConstraints&) const;
+    ComputedVerticalMargin computedVerticalMargin(const Box&, const HorizontalConstraints&) const;
+
+    Optional<LayoutUnit> computedValue(const Length& geometryProperty, LayoutUnit containingBlockWidth) const;
+    Optional<LayoutUnit> fixedValue(const Length& geometryProperty) const;
+
+    Optional<LayoutUnit> computedMinHeight(const Box&, Optional<LayoutUnit> containingBlockHeight = WTF::nullopt) const;
+    Optional<LayoutUnit> computedMaxHeight(const Box&, Optional<LayoutUnit> containingBlockHeight = WTF::nullopt) const;
+
+    Optional<LayoutUnit> computedMinWidth(const Box&, LayoutUnit containingBlockWidth);
+    Optional<LayoutUnit> computedMaxWidth(const Box&, LayoutUnit containingBlockWidth);
+
+    FormattingContext::IntrinsicWidthConstraints constrainByMinMaxWidth(const Box&, FormattingContext::IntrinsicWidthConstraints) const;
+
+    LayoutUnit contentHeightForFormattingContextRoot(const ContainerBox&) const;
+
+    FormattingContext::ConstraintsForOutOfFlowContent constraintsForOutOfFlowContent(const ContainerBox&);
+    FormattingContext::ConstraintsForInFlowContent constraintsForInFlowContent(const ContainerBox&, Optional<FormattingContext::EscapeReason> = WTF::nullopt);
+
+    Optional<LayoutUnit> computedHeight(const Box&, Optional<LayoutUnit> containingBlockHeight = WTF::nullopt) const;
+    Optional<LayoutUnit> computedWidth(const Box&, LayoutUnit containingBlockWidth);
+
+protected:
+    friend class FormattingContext;
+    FormattingGeometry(const FormattingContext&);
+
+    const LayoutState& layoutState() const { return m_formattingContext.layoutState(); }
+    LayoutState& layoutState() { return m_formattingContext.layoutState(); }
+    const FormattingContext& formattingContext() const { return m_formattingContext; }
+
+private:
+    VerticalGeometry outOfFlowReplacedVerticalGeometry(const ReplacedBox&, const HorizontalConstraints&, const VerticalConstraints&, const OverriddenVerticalValues&) const;
+    HorizontalGeometry outOfFlowReplacedHorizontalGeometry(const ReplacedBox&, const HorizontalConstraints&, const VerticalConstraints&, const OverriddenHorizontalValues&);
+
+    VerticalGeometry outOfFlowNonReplacedVerticalGeometry(const ContainerBox&, const HorizontalConstraints&, const VerticalConstraints&, const OverriddenVerticalValues&) const;
+    HorizontalGeometry outOfFlowNonReplacedHorizontalGeometry(const ContainerBox&, const HorizontalConstraints&, const OverriddenHorizontalValues&);
+
+    ContentHeightAndMargin floatingReplacedContentHeightAndMargin(const ReplacedBox&, const HorizontalConstraints&, const OverriddenVerticalValues&) const;
+    ContentWidthAndMargin floatingReplacedContentWidthAndMargin(const ReplacedBox&, const HorizontalConstraints&, const OverriddenHorizontalValues&);
+
+    ContentWidthAndMargin floatingNonReplacedContentWidthAndMargin(const Box&, const HorizontalConstraints&, const OverriddenHorizontalValues&);
+
+    LayoutUnit staticVerticalPositionForOutOfFlowPositioned(const Box&, const VerticalConstraints&) const;
+    LayoutUnit staticHorizontalPositionForOutOfFlowPositioned(const Box&, const HorizontalConstraints&) const;
+
+    enum class HeightType { Min, Max, Normal };
+    Optional<LayoutUnit> computedHeightValue(const Box&, HeightType, Optional<LayoutUnit> containingBlockHeight) const;
+
+    enum class WidthType { Min, Max, Normal };
+    Optional<LayoutUnit> computedWidthValue(const Box&, WidthType, LayoutUnit containingBlockWidth);
+
+    const FormattingContext& m_formattingContext;
+};
+
+}
+}
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebCorelayoutformattingContextsblockBlockFormattingGeometrycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/layout/formattingContexts/block/BlockFormattingGeometry.cpp (277555 => 277556)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/formattingContexts/block/BlockFormattingGeometry.cpp 2021-05-16 01:50:34 UTC (rev 277555)
+++ trunk/Source/WebCore/layout/formattingContexts/block/BlockFormattingGeometry.cpp    2021-05-16 01:56:55 UTC (rev 277556)
</span><span class="lines">@@ -43,7 +43,7 @@
</span><span class="cx"> namespace Layout {
</span><span class="cx"> 
</span><span class="cx"> BlockFormattingGeometry::BlockFormattingGeometry(const BlockFormattingContext& blockFormattingContext)
</span><del>-    : FormattingContext::Geometry(blockFormattingContext)
</del><ins>+    : FormattingGeometry(blockFormattingContext)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -68,7 +68,7 @@
</span><span class="cx">         // and relatively positioned boxes are considered without their offset). Note that the child box may be an anonymous block box.
</span><span class="cx"> 
</span><span class="cx">         auto& boxGeometry = formattingContext().geometryForBox(layoutBox);
</span><del>-        auto computedVerticalMargin = Geometry::computedVerticalMargin(layoutBox, horizontalConstraints);
</del><ins>+        auto computedVerticalMargin = FormattingGeometry::computedVerticalMargin(layoutBox, horizontalConstraints);
</ins><span class="cx">         auto nonCollapsedMargin = UsedVerticalMargin::NonCollapsedValues { computedVerticalMargin.before.valueOr(0), computedVerticalMargin.after.valueOr(0) }; 
</span><span class="cx">         auto borderAndPaddingTop = boxGeometry.borderTop() + boxGeometry.paddingTop().valueOr(0);
</span><span class="cx">         auto height = overriddenVerticalValues.height ? overriddenVerticalValues.height.value() : computedHeight(layoutBox);
</span><span class="lines">@@ -149,7 +149,7 @@
</span><span class="cx">         auto& boxGeometry = formattingContext().geometryForBox(layoutBox);
</span><span class="cx"> 
</span><span class="cx">         auto width = overriddenHorizontalValues.width ? overriddenHorizontalValues.width : computedWidth(layoutBox, containingBlockWidth);
</span><del>-        auto computedHorizontalMargin = Geometry::computedHorizontalMargin(layoutBox, horizontalConstraints);
</del><ins>+        auto computedHorizontalMargin = FormattingGeometry::computedHorizontalMargin(layoutBox, horizontalConstraints);
</ins><span class="cx">         UsedHorizontalMargin usedHorizontalMargin;
</span><span class="cx">         auto borderLeft = boxGeometry.borderLeft();
</span><span class="cx">         auto borderRight = boxGeometry.borderRight();
</span></span></pre></div>
<a id="trunkSourceWebCorelayoutformattingContextsblockBlockFormattingGeometryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/layout/formattingContexts/block/BlockFormattingGeometry.h (277555 => 277556)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/formattingContexts/block/BlockFormattingGeometry.h   2021-05-16 01:50:34 UTC (rev 277555)
+++ trunk/Source/WebCore/layout/formattingContexts/block/BlockFormattingGeometry.h      2021-05-16 01:56:55 UTC (rev 277556)
</span><span class="lines">@@ -27,13 +27,13 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
</span><span class="cx"> 
</span><del>-#include "FormattingContext.h"
</del><ins>+#include "FormattingGeometry.h"
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> namespace Layout {
</span><span class="cx"> 
</span><span class="cx"> // This class implements positioning and sizing for boxes participating in a block formatting context.
</span><del>-class BlockFormattingGeometry : public FormattingContext::Geometry {
</del><ins>+class BlockFormattingGeometry : public FormattingGeometry {
</ins><span class="cx"> public:
</span><span class="cx">     BlockFormattingGeometry(const BlockFormattingContext&);
</span><span class="cx"> 
</span><span class="lines">@@ -53,7 +53,7 @@
</span><span class="cx">     ContentWidthAndMargin inFlowNonReplacedContentWidthAndMargin(const Box&, const HorizontalConstraints&, const OverriddenHorizontalValues&);
</span><span class="cx">     ContentWidthAndMargin inFlowReplacedContentWidthAndMargin(const ReplacedBox&, const HorizontalConstraints&, const OverriddenHorizontalValues&);
</span><span class="cx"> 
</span><del>-    const BlockFormattingContext& formattingContext() const { return downcast<BlockFormattingContext>(FormattingContext::Geometry::formattingContext()); }
</del><ins>+    const BlockFormattingContext& formattingContext() const { return downcast<BlockFormattingContext>(FormattingGeometry::formattingContext()); }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorelayoutformattingContextsflexFlexFormattingGeometrycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/layout/formattingContexts/flex/FlexFormattingGeometry.cpp (277555 => 277556)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/formattingContexts/flex/FlexFormattingGeometry.cpp   2021-05-16 01:50:34 UTC (rev 277555)
+++ trunk/Source/WebCore/layout/formattingContexts/flex/FlexFormattingGeometry.cpp      2021-05-16 01:56:55 UTC (rev 277556)
</span><span class="lines">@@ -36,7 +36,7 @@
</span><span class="cx"> namespace Layout {
</span><span class="cx"> 
</span><span class="cx"> FlexFormattingGeometry::FlexFormattingGeometry(const FlexFormattingContext& flexFormattingContext)
</span><del>-    : FormattingContext::Geometry(flexFormattingContext)
</del><ins>+    : FormattingGeometry(flexFormattingContext)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorelayoutformattingContextsflexFlexFormattingGeometryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/layout/formattingContexts/flex/FlexFormattingGeometry.h (277555 => 277556)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/formattingContexts/flex/FlexFormattingGeometry.h     2021-05-16 01:50:34 UTC (rev 277555)
+++ trunk/Source/WebCore/layout/formattingContexts/flex/FlexFormattingGeometry.h        2021-05-16 01:56:55 UTC (rev 277556)
</span><span class="lines">@@ -27,15 +27,13 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
</span><span class="cx"> 
</span><del>-#include "FlexFormattingState.h"
-#include "FormattingContext.h"
-#include <wtf/IsoMalloc.h>
</del><ins>+#include "FormattingGeometry.h"
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> namespace Layout {
</span><span class="cx"> 
</span><span class="cx"> // This class implements positioning and sizing for flex items.
</span><del>-class FlexFormattingGeometry : public FormattingContext::Geometry {
</del><ins>+class FlexFormattingGeometry : public FormattingGeometry {
</ins><span class="cx"> public:
</span><span class="cx">     FlexFormattingGeometry(const FlexFormattingContext&);
</span><span class="cx"> 
</span><span class="lines">@@ -42,7 +40,7 @@
</span><span class="cx">     FormattingContext::IntrinsicWidthConstraints intrinsicWidthConstraints(const ContainerBox&);
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    const FlexFormattingContext& formattingContext() const { return downcast<FlexFormattingContext>(FormattingContext::Geometry::formattingContext()); }
</del><ins>+    const FlexFormattingContext& formattingContext() const { return downcast<FlexFormattingContext>(FormattingGeometry::formattingContext()); }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorelayoutformattingContextsinlineInlineFormattingGeometrycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingGeometry.cpp (277555 => 277556)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingGeometry.cpp       2021-05-16 01:50:34 UTC (rev 277555)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingGeometry.cpp  2021-05-16 01:56:55 UTC (rev 277556)
</span><span class="lines">@@ -664,7 +664,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> InlineFormattingGeometry::InlineFormattingGeometry(const InlineFormattingContext& inlineFormattingContext)
</span><del>-    : FormattingContext::Geometry(inlineFormattingContext)
</del><ins>+    : FormattingGeometry(inlineFormattingContext)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -708,7 +708,7 @@
</span><span class="cx">         width = shrinkToFitWidth(formattingContextRoot, horizontalConstraints.logicalWidth);
</span><span class="cx"> 
</span><span class="cx">     // #2
</span><del>-    auto computedHorizontalMargin = Geometry::computedHorizontalMargin(formattingContextRoot, horizontalConstraints);
</del><ins>+    auto computedHorizontalMargin = FormattingGeometry::computedHorizontalMargin(formattingContextRoot, horizontalConstraints);
</ins><span class="cx"> 
</span><span class="cx">     return ContentWidthAndMargin { *width, { computedHorizontalMargin.start.valueOr(0_lu), computedHorizontalMargin.end.valueOr(0_lu) } };
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorelayoutformattingContextsinlineInlineFormattingGeometryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingGeometry.h (277555 => 277556)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingGeometry.h 2021-05-16 01:50:34 UTC (rev 277555)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingGeometry.h    2021-05-16 01:56:55 UTC (rev 277556)
</span><span class="lines">@@ -27,12 +27,12 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
</span><span class="cx"> 
</span><del>-#include "FormattingContext.h"
</del><ins>+#include "FormattingGeometry.h"
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> namespace Layout {
</span><span class="cx"> 
</span><del>-class InlineFormattingGeometry : public FormattingContext::Geometry {
</del><ins>+class InlineFormattingGeometry : public FormattingGeometry {
</ins><span class="cx"> public:
</span><span class="cx">     LineBox lineBoxForLineContent(const LineBuilder::LineContent&);
</span><span class="cx">     InlineLayoutUnit logicalTopForNextLine(const LineBuilder::LineContent&, InlineLayoutUnit previousLineLogicalBottom, const FloatingContext&) const;
</span><span class="lines">@@ -44,7 +44,7 @@
</span><span class="cx">     friend class InlineFormattingContext;
</span><span class="cx">     InlineFormattingGeometry(const InlineFormattingContext&);
</span><span class="cx"> 
</span><del>-    const InlineFormattingContext& formattingContext() const { return downcast<InlineFormattingContext>(FormattingContext::Geometry::formattingContext()); }
</del><ins>+    const InlineFormattingContext& formattingContext() const { return downcast<InlineFormattingContext>(FormattingGeometry::formattingContext()); }
</ins><span class="cx"> 
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorelayoutformattingContextstableTableFormattingGeometrycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingGeometry.cpp (277555 => 277556)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingGeometry.cpp 2021-05-16 01:50:34 UTC (rev 277555)
+++ trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingGeometry.cpp    2021-05-16 01:56:55 UTC (rev 277556)
</span><span class="lines">@@ -39,7 +39,7 @@
</span><span class="cx"> namespace Layout {
</span><span class="cx"> 
</span><span class="cx"> TableFormattingGeometry::TableFormattingGeometry(const TableFormattingContext& tableFormattingContext, const TableGrid& grid)
</span><del>-    : FormattingContext::Geometry(tableFormattingContext)
</del><ins>+    : FormattingGeometry(tableFormattingContext)
</ins><span class="cx">     , m_grid(grid)
</span><span class="cx"> {
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorelayoutformattingContextstableTableFormattingGeometryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingGeometry.h (277555 => 277556)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingGeometry.h   2021-05-16 01:50:34 UTC (rev 277555)
+++ trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingGeometry.h      2021-05-16 01:56:55 UTC (rev 277556)
</span><span class="lines">@@ -27,12 +27,12 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
</span><span class="cx"> 
</span><del>-#include "FormattingContext.h"
</del><ins>+#include "FormattingGeometry.h"
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> namespace Layout {
</span><span class="cx"> 
</span><del>-class TableFormattingGeometry : public FormattingContext::Geometry {
</del><ins>+class TableFormattingGeometry : public FormattingGeometry {
</ins><span class="cx"> public:
</span><span class="cx">     LayoutUnit cellHeigh(const ContainerBox&) const;
</span><span class="cx">     Edges computedCellBorder(const TableGrid::Cell&) const;
</span><span class="lines">@@ -44,7 +44,7 @@
</span><span class="cx">     friend class TableFormattingContext;
</span><span class="cx">     TableFormattingGeometry(const TableFormattingContext&, const TableGrid&);
</span><span class="cx"> 
</span><del>-    const TableFormattingContext& formattingContext() const { return downcast<TableFormattingContext>(FormattingContext::Geometry::formattingContext()); }
</del><ins>+    const TableFormattingContext& formattingContext() const { return downcast<TableFormattingContext>(FormattingGeometry::formattingContext()); }
</ins><span class="cx">     const TableGrid& m_grid;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorelayoutformattingContextstableTableFormattingQuirksh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingQuirks.h (277555 => 277556)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingQuirks.h     2021-05-16 01:50:34 UTC (rev 277555)
+++ trunk/Source/WebCore/layout/formattingContexts/table/TableFormattingQuirks.h        2021-05-16 01:56:55 UTC (rev 277556)
</span><span class="lines">@@ -40,7 +40,7 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     const TableFormattingContext& formattingContext() const { return downcast<TableFormattingContext>(FormattingQuirks::formattingContext()); }
</span><del>-    TableFormattingContext::Geometry geometry() const { return formattingContext().geometry(); }
</del><ins>+    TableFormattingGeometry geometry() const { return formattingContext().geometry(); }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>