<!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>[281746] 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/281746">281746</a></dd>
<dt>Author</dt> <dd>zalan@apple.com</dd>
<dt>Date</dt> <dd>2021-08-29 11:57:47 -0700 (Sun, 29 Aug 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>[LFC][IFC] Add ink overflow to the line runs
https://bugs.webkit.org/show_bug.cgi?id=229653

Reviewed by Antti Koivisto.

Let's move the ink overflow computation from the integration layer to IFC.
This is in preparation for merging display runs (IFC) and the integration layer runs.

* layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp:
(WebCore::Layout::InlineDisplayContentBuilder::build):
(WebCore::Layout::InlineDisplayContentBuilder::createRunsAndUpdateGeometryForLineContent):
(WebCore::Layout::InlineDisplayContentBuilder::createRunsAndUpdateGeometryForLineSpanningInlineBoxes):
* layout/formattingContexts/inline/InlineLineRun.h:
(WebCore::Layout::LineRun::inkOverflow const):
(WebCore::Layout::LineRun::LineRun):
* layout/integration/LayoutIntegrationInlineContentBuilder.cpp:
(WebCore::LayoutIntegration::InlineContentBuilder::createDisplayLineRuns const):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorelayoutformattingContextsinlineInlineDisplayContentBuildercpp">trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp</a></li>
<li><a href="#trunkSourceWebCorelayoutformattingContextsinlineInlineLineRunh">trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineRun.h</a></li>
<li><a href="#trunkSourceWebCorelayoutintegrationLayoutIntegrationInlineContentBuildercpp">trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (281745 => 281746)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2021-08-29 17:38:29 UTC (rev 281745)
+++ trunk/Source/WebCore/ChangeLog      2021-08-29 18:57:47 UTC (rev 281746)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2021-08-29  Alan Bujtas  <zalan@apple.com>
+
+        [LFC][IFC] Add ink overflow to the line runs
+        https://bugs.webkit.org/show_bug.cgi?id=229653
+
+        Reviewed by Antti Koivisto.
+
+        Let's move the ink overflow computation from the integration layer to IFC.
+        This is in preparation for merging display runs (IFC) and the integration layer runs.
+
+        * layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp:
+        (WebCore::Layout::InlineDisplayContentBuilder::build):
+        (WebCore::Layout::InlineDisplayContentBuilder::createRunsAndUpdateGeometryForLineContent):
+        (WebCore::Layout::InlineDisplayContentBuilder::createRunsAndUpdateGeometryForLineSpanningInlineBoxes):
+        * layout/formattingContexts/inline/InlineLineRun.h:
+        (WebCore::Layout::LineRun::inkOverflow const):
+        (WebCore::Layout::LineRun::LineRun):
+        * layout/integration/LayoutIntegrationInlineContentBuilder.cpp:
+        (WebCore::LayoutIntegration::InlineContentBuilder::createDisplayLineRuns const):
+
</ins><span class="cx"> 2021-08-29  Rob Buis  <rbuis@igalia.com>
</span><span class="cx"> 
</span><span class="cx">         Nullptr crash in ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline
</span></span></pre></div>
<a id="trunkSourceWebCorelayoutformattingContextsinlineInlineDisplayContentBuildercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp (281745 => 281746)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp    2021-08-29 17:38:29 UTC (rev 281745)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp       2021-08-29 18:57:47 UTC (rev 281746)
</span><span class="lines">@@ -28,7 +28,10 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
</span><span class="cx"> 
</span><ins>+#include "FontCascade.h"
</ins><span class="cx"> #include "LayoutBoxGeometry.h"
</span><ins>+#include "LayoutInitialContainingBlock.h"
+#include "RuntimeEnabledFeatures.h"
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> namespace Layout {
</span><span class="lines">@@ -47,7 +50,7 @@
</span><span class="cx">     // Every line starts with a root run, even the empty ones.
</span><span class="cx">     auto rootInlineBoxRect = lineBox.logicalRectForRootInlineBox();
</span><span class="cx">     rootInlineBoxRect.moveBy(lineBoxLogicalTopLeft);
</span><del>-    formattingState.addLineRun({ lineIndex, LineRun::Type::RootInlineBox, root(), rootInlineBoxRect, { }, { },  lineBox.rootInlineBox().hasContent()});
</del><ins>+    formattingState.addLineRun({ lineIndex, LineRun::Type::RootInlineBox, root(), rootInlineBoxRect, rootInlineBoxRect, { }, { },  lineBox.rootInlineBox().hasContent()});
</ins><span class="cx"> 
</span><span class="cx">     // Spanning inline boxes start at the very beginning of the line.
</span><span class="cx">     auto lineSpanningInlineBoxIndex = formattingState.lineRuns().size();
</span><span class="lines">@@ -65,13 +68,29 @@
</span><span class="cx">         case InlineItem::Type::Text: {
</span><span class="cx">             auto textRunRect = lineBox.logicalRectForTextRun(lineRun);
</span><span class="cx">             textRunRect.moveBy(lineBoxLogicalTopLeft);
</span><del>-            formattingState.addLineRun({ lineIndex, LineRun::Type::Text, layoutBox, textRunRect, lineRun.expansion(), lineRun.textContent() });
</del><ins>+
+            auto inkOverflow = [&] {
+                auto& style = layoutBox.style();
+                auto initialContaingBlockSize = RuntimeEnabledFeatures::sharedFeatures().layoutFormattingContextIntegrationEnabled()
+                    ? formattingState.layoutState().viewportSize()
+                    : formattingState.layoutState().geometryForBox(layoutBox.initialContainingBlock()).contentBox().size();
+                auto strokeOverflow = std::ceil(style.computedStrokeWidth(ceiledIntSize(initialContaingBlockSize)));
+                auto inkOverflow = textRunRect;
+                inkOverflow.inflate(strokeOverflow);
+                auto letterSpacing = style.fontCascade().letterSpacing();
+                if (letterSpacing < 0) {
+                    // Last letter's negative spacing shrinks logical rect. Push it to ink overflow.
+                    inkOverflow.expand(-letterSpacing, { });
+                }
+                return inkOverflow;
+            };
+            formattingState.addLineRun({ lineIndex, LineRun::Type::Text, layoutBox, textRunRect, inkOverflow(), lineRun.expansion(), lineRun.textContent() });
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case InlineItem::Type::SoftLineBreak: {
</span><span class="cx">             auto softLineBreakRunRect = lineBox.logicalRectForTextRun(lineRun);
</span><span class="cx">             softLineBreakRunRect.moveBy(lineBoxLogicalTopLeft);
</span><del>-            formattingState.addLineRun({ lineIndex, LineRun::Type::SoftLineBreak, layoutBox, softLineBreakRunRect, lineRun.expansion(), lineRun.textContent() });
</del><ins>+            formattingState.addLineRun({ lineIndex, LineRun::Type::SoftLineBreak, layoutBox, softLineBreakRunRect, softLineBreakRunRect, lineRun.expansion(), lineRun.textContent() });
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case InlineItem::Type::HardLineBreak: {
</span><span class="lines">@@ -78,7 +97,7 @@
</span><span class="cx">             // Only hard linebreaks have associated layout boxes.
</span><span class="cx">             auto lineBreakBoxRect = lineBox.logicalRectForLineBreakBox(layoutBox);
</span><span class="cx">             lineBreakBoxRect.moveBy(lineBoxLogicalTopLeft);
</span><del>-            formattingState.addLineRun({ lineIndex, LineRun::Type::LineBreakBox, layoutBox, lineBreakBoxRect, lineRun.expansion(), { } });
</del><ins>+            formattingState.addLineRun({ lineIndex, LineRun::Type::LineBreakBox, layoutBox, lineBreakBoxRect, lineBreakBoxRect, lineRun.expansion(), { } });
</ins><span class="cx"> 
</span><span class="cx">             auto& boxGeometry = formattingState.boxGeometry(layoutBox);
</span><span class="cx">             boxGeometry.setLogicalTopLeft(toLayoutPoint(lineBreakBoxRect.topLeft()));
</span><span class="lines">@@ -90,7 +109,7 @@
</span><span class="cx">             auto& boxGeometry = formattingState.boxGeometry(layoutBox);
</span><span class="cx">             auto logicalBorderBox = lineBox.logicalBorderBoxForAtomicInlineLevelBox(layoutBox, boxGeometry);
</span><span class="cx">             logicalBorderBox.moveBy(lineBoxLogicalTopLeft);
</span><del>-            formattingState.addLineRun({ lineIndex, LineRun::Type::AtomicInlineLevelBox, layoutBox, logicalBorderBox, lineRun.expansion(), { } });
</del><ins>+            formattingState.addLineRun({ lineIndex, LineRun::Type::AtomicInlineLevelBox, layoutBox, logicalBorderBox, logicalBorderBox, lineRun.expansion(), { } });
</ins><span class="cx"> 
</span><span class="cx">             auto borderBoxLogicalTopLeft = logicalBorderBox.topLeft();
</span><span class="cx">             // Note that inline boxes are relative to the line and their top position can be negative.
</span><span class="lines">@@ -105,7 +124,7 @@
</span><span class="cx">             inlineBoxBorderBox.moveBy(lineBoxLogicalTopLeft);
</span><span class="cx">             if (lineBox.hasContent()) {
</span><span class="cx">                 // FIXME: It's expected to not have any runs on empty lines. We should reconsider this.
</span><del>-                formattingState.addLineRun({ lineIndex, LineRun::Type::NonRootInlineBox, layoutBox, inlineBoxBorderBox, { }, { }, lineBox.inlineLevelBoxForLayoutBox(layoutBox).hasContent() });
</del><ins>+                formattingState.addLineRun({ lineIndex, LineRun::Type::NonRootInlineBox, layoutBox, inlineBoxBorderBox, inlineBoxBorderBox, { }, { }, lineBox.inlineLevelBoxForLayoutBox(layoutBox).hasContent() });
</ins><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             auto inlineBoxSize = LayoutSize { LayoutUnit::fromFloatCeil(inlineBoxBorderBox.width()), LayoutUnit::fromFloatCeil(inlineBoxBorderBox.height()) };
</span><span class="lines">@@ -143,7 +162,7 @@
</span><span class="cx">         auto inlineBoxBorderBox = lineBox.logicalBorderBoxForInlineBox(layoutBox, boxGeometry);
</span><span class="cx">         inlineBoxBorderBox.moveBy(lineBoxLogicalTopLeft);
</span><span class="cx"> 
</span><del>-        formattingState.lineRuns().insert(lineSpanningInlineBoxIndex++, { lineIndex, LineRun::Type::NonRootInlineBox, layoutBox, inlineBoxBorderBox, { }, { }, inlineLevelBox.hasContent(), true });
</del><ins>+        formattingState.lineRuns().insert(lineSpanningInlineBoxIndex++, { lineIndex, LineRun::Type::NonRootInlineBox, layoutBox, inlineBoxBorderBox, inlineBoxBorderBox, { }, { }, inlineLevelBox.hasContent(), true });
</ins><span class="cx"> 
</span><span class="cx">         auto inlineBoxSize = LayoutSize { LayoutUnit::fromFloatCeil(inlineBoxBorderBox.width()), LayoutUnit::fromFloatCeil(inlineBoxBorderBox.height()) };
</span><span class="cx">         auto logicalRect = Rect { LayoutPoint { inlineBoxBorderBox.topLeft() }, inlineBoxSize };
</span></span></pre></div>
<a id="trunkSourceWebCorelayoutformattingContextsinlineInlineLineRunh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineRun.h (281745 => 281746)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineRun.h    2021-08-29 17:38:29 UTC (rev 281745)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineRun.h       2021-08-29 18:57:47 UTC (rev 281746)
</span><span class="lines">@@ -69,7 +69,7 @@
</span><span class="cx">         GenericInlineLevelBox
</span><span class="cx">     };
</span><span class="cx">     struct Expansion;
</span><del>-    LineRun(size_t lineIndex, Type, const Box&, const InlineRect&, Expansion, std::optional<Text> = std::nullopt, bool hasContent = true, bool isLineSpanning = false);
</del><ins>+    LineRun(size_t lineIndex, Type, const Box&, const InlineRect&, const InlineRect& inkOverflow, Expansion, std::optional<Text> = std::nullopt, bool hasContent = true, bool isLineSpanning = false);
</ins><span class="cx"> 
</span><span class="cx">     bool isText() const { return m_type == Type::Text; }
</span><span class="cx">     bool isSoftLineBreak() const { return m_type == Type::SoftLineBreak; }
</span><span class="lines">@@ -88,6 +88,7 @@
</span><span class="cx">     bool isLineSpanning() const { return m_isLineSpanning; }
</span><span class="cx"> 
</span><span class="cx">     const InlineRect& logicalRect() const { return m_logicalRect; }
</span><ins>+    const InlineRect& inkOverflow() const { return m_inkOverflow; }
</ins><span class="cx"> 
</span><span class="cx">     InlineLayoutUnit logicalTop() const { return logicalRect().top(); }
</span><span class="cx">     InlineLayoutUnit logicalBottom() const { return logicalRect().bottom(); }
</span><span class="lines">@@ -115,6 +116,7 @@
</span><span class="cx">     const Type m_type;
</span><span class="cx">     WeakPtr<const Layout::Box> m_layoutBox;
</span><span class="cx">     InlineRect m_logicalRect;
</span><ins>+    InlineRect m_inkOverflow;
</ins><span class="cx">     bool m_hasContent { true };
</span><span class="cx">     // FIXME: This is temporary until after iterators can skip over line spanning/root inline boxes.
</span><span class="cx">     bool m_isLineSpanning { false };
</span><span class="lines">@@ -122,11 +124,12 @@
</span><span class="cx">     std::optional<Text> m_text;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-inline LineRun::LineRun(size_t lineIndex, Type type, const Layout::Box& layoutBox, const InlineRect& logicalRect, Expansion expansion, std::optional<Text> text, bool hasContent, bool isLineSpanning)
</del><ins>+inline LineRun::LineRun(size_t lineIndex, Type type, const Layout::Box& layoutBox, const InlineRect& logicalRect, const InlineRect& inkOverflow, Expansion expansion, std::optional<Text> text, bool hasContent, bool isLineSpanning)
</ins><span class="cx">     : m_lineIndex(lineIndex)
</span><span class="cx">     , m_type(type)
</span><span class="cx">     , m_layoutBox(makeWeakPtr(layoutBox))
</span><span class="cx">     , m_logicalRect(logicalRect)
</span><ins>+    , m_inkOverflow(inkOverflow)
</ins><span class="cx">     , m_hasContent(hasContent)
</span><span class="cx">     , m_isLineSpanning(isLineSpanning)
</span><span class="cx">     , m_expansion(expansion)
</span></span></pre></div>
<a id="trunkSourceWebCorelayoutintegrationLayoutIntegrationInlineContentBuildercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp (281745 => 281746)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp        2021-08-29 17:38:29 UTC (rev 281745)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp   2021-08-29 18:57:47 UTC (rev 281746)
</span><span class="lines">@@ -258,10 +258,13 @@
</span><span class="cx">         // Inline boxes are relative to the line box while final runs need to be relative to the parent box
</span><span class="cx">         // FIXME: Shouldn't we just leave them be relative to the line box?
</span><span class="cx">         auto runRect = FloatRect { lineRun.logicalRect() };
</span><ins>+        auto inkOverflow = FloatRect { lineRun.inkOverflow() };
</ins><span class="cx">         auto& geometry = m_layoutState.geometryForBox(layoutBox);
</span><span class="cx">         runRect.setSize({ geometry.borderBoxWidth(), geometry.borderBoxHeight() });
</span><del>-        if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition)
</del><ins>+        if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition) {
</ins><span class="cx">             runRect.setY(roundToInt(runRect.y()));
</span><ins>+            inkOverflow.setY(roundToInt(inkOverflow.y()));
+        }
</ins><span class="cx">         // FIXME: Add support for non-text ink overflow.
</span><span class="cx">         // FIXME: Add support for cases when the run is after ellipsis.
</span><span class="cx">         if (lineRun.isInlineBox()) {
</span><span class="lines">@@ -273,10 +276,10 @@
</span><span class="cx">             inlineContent.nonRootInlineBoxes.append({ lineIndex, layoutBox, lineRunRect, hasScrollableContent() });
</span><span class="cx">             if (!lineRun.isLineSpanning()) {
</span><span class="cx">                 // FIXME: Run iterators with (text)runs spanning over multiple lines expect no "in-between" runs (e.g. line spanning or root inline boxes).
</span><del>-                inlineContent.runs.append({ lineIndex, layoutBox, runRect, runRect, { }, { } });
</del><ins>+                inlineContent.runs.append({ lineIndex, layoutBox, runRect, inkOverflow, { }, { } });
</ins><span class="cx">             }
</span><span class="cx">         } else
</span><del>-            inlineContent.runs.append({ lineIndex, layoutBox, runRect, runRect, { }, { } });
</del><ins>+            inlineContent.runs.append({ lineIndex, layoutBox, runRect, inkOverflow, { }, { } });
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     auto createDisplayTextRunForRange = [&](auto& lineRun, auto startOffset, auto endOffset) {
</span><span class="lines">@@ -285,8 +288,11 @@
</span><span class="cx">         auto lineIndex = lineRun.lineIndex();
</span><span class="cx">         auto& lineBoxLogicalRect = lines[lineIndex].lineBoxLogicalRect();
</span><span class="cx">         auto runRect = FloatRect { lineRun.logicalRect() };
</span><del>-        if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition)
</del><ins>+        auto inkOverflow = FloatRect { lineRun.inkOverflow() };
+        if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition) {
</ins><span class="cx">             runRect.setY(roundToInt(runRect.y()));
</span><ins>+            inkOverflow.setY(roundToInt(inkOverflow.y()));
+        }
</ins><span class="cx"> 
</span><span class="cx">         auto& style = layoutBox.style();
</span><span class="cx">         auto text = lineRun.text();
</span><span class="lines">@@ -314,24 +320,11 @@
</span><span class="cx">             return String();
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        auto computedInkOverflow = [&] (auto runRect) {
-            auto inkOverflow = runRect;
-            auto initialContaingBlockSize = m_layoutState.viewportSize();
-            auto strokeOverflow = std::ceil(style.computedStrokeWidth(ceiledIntSize(initialContaingBlockSize)));
-            inkOverflow.inflate(strokeOverflow);
-            auto letterSpacing = style.fontCascade().letterSpacing();
-            if (letterSpacing < 0) {
-                // Last letter's negative spacing shrinks logical rect. Push it to ink overflow.
-                inkOverflow.expand(-letterSpacing, { });
-            }
-            return inkOverflow;
-        };
</del><span class="cx">         RELEASE_ASSERT(startOffset >= text->start() && startOffset < text->end());
</span><span class="cx">         RELEASE_ASSERT(endOffset > text->start() && endOffset <= text->end());
</span><span class="cx">         auto textContent = Run::TextContent { startOffset, endOffset - startOffset, text->content(), adjustedContentToRender(), text->needsHyphen() };
</span><span class="cx">         auto expansion = Run::Expansion { lineRun.expansion().behavior, lineRun.expansion().horizontalExpansion };
</span><del>-        auto displayRun = Run { lineIndex, layoutBox, runRect, computedInkOverflow(runRect), expansion, textContent };
-        inlineContent.runs.append(displayRun);
</del><ins>+        inlineContent.runs.append({ lineIndex, layoutBox, runRect, inkOverflow, expansion, textContent });
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     inlineContent.runs.reserveInitialCapacity(lineRuns.size());
</span></span></pre>
</div>
</div>

</body>
</html>