<!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>[286500] 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/286500">286500</a></dd>
<dt>Author</dt> <dd>zalan@apple.com</dd>
<dt>Date</dt> <dd>2021-12-03 10:15:04 -0800 (Fri, 03 Dec 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>[LFC][IFC] Set the first/last box flag on the (bidi fragmented) inline box type of display boxes
https://bugs.webkit.org/show_bug.cgi?id=233743

Reviewed by Antti Koivisto.

Keep track of the last constructed inline box type of display box position so that when we
happen to create another fragment for this same inline box, we can change the 'isLastBox' box to false.

* layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp:
(WebCore::Layout::InlineDisplayContentBuilder::insertInlineBoxDisplayBoxForBidiBoundary):
(WebCore::Layout::InlineDisplayContentBuilder::processBidiContent):
* layout/formattingContexts/inline/InlineDisplayContentBuilder.h:</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="#trunkSourceWebCorelayoutformattingContextsinlineInlineDisplayContentBuilderh">trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.h</a></li>
<li><a href="#trunkSourceWebCorelayoutformattingContextsinlinedisplayInlineDisplayBoxh">trunk/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayBox.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (286499 => 286500)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2021-12-03 18:00:42 UTC (rev 286499)
+++ trunk/Source/WebCore/ChangeLog      2021-12-03 18:15:04 UTC (rev 286500)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2021-12-03  Alan Bujtas  <zalan@apple.com>
+
+        [LFC][IFC] Set the first/last box flag on the (bidi fragmented) inline box type of display boxes
+        https://bugs.webkit.org/show_bug.cgi?id=233743
+
+        Reviewed by Antti Koivisto.
+
+        Keep track of the last constructed inline box type of display box position so that when we
+        happen to create another fragment for this same inline box, we can change the 'isLastBox' box to false.
+
+        * layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp:
+        (WebCore::Layout::InlineDisplayContentBuilder::insertInlineBoxDisplayBoxForBidiBoundary):
+        (WebCore::Layout::InlineDisplayContentBuilder::processBidiContent):
+        * layout/formattingContexts/inline/InlineDisplayContentBuilder.h:
+
</ins><span class="cx"> 2021-12-03  Chris Dumez  <cdumez@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Introduce WorkerGlobalScope::type() function
</span></span></pre></div>
<a id="trunkSourceWebCorelayoutformattingContextsinlineInlineDisplayContentBuildercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp (286499 => 286500)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp    2021-12-03 18:00:42 UTC (rev 286499)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp       2021-12-03 18:15:04 UTC (rev 286500)
</span><span class="lines">@@ -270,9 +270,16 @@
</span><span class="cx">     setInlineBoxGeometry(layoutBox, inlineBoxBorderBox, false);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void InlineDisplayContentBuilder::insertInlineBoxDisplayBoxForBidiBoundary(const InlineLevelBox& inlineBox, const InlineRect& inlineBoxRect, size_t insertionPoint, DisplayBoxes& boxes)
</del><ins>+void InlineDisplayContentBuilder::insertInlineBoxDisplayBoxForBidiBoundary(const InlineLevelBox& inlineBox, const InlineRect& inlineBoxRect, bool isFirstInlineBoxFragment, size_t insertionPoint, DisplayBoxes& boxes)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(inlineBox.isInlineBox());
</span><ins>+
+    auto isFirstLastBox = OptionSet<InlineDisplay::Box::PositionWithinInlineLevelBox> { };
+    if (inlineBox.isFirstBox() && isFirstInlineBoxFragment)
+        isFirstLastBox.add({ InlineDisplay::Box::PositionWithinInlineLevelBox::First });
+    if (inlineBox.isLastBox())
+        isFirstLastBox.add({ InlineDisplay::Box::PositionWithinInlineLevelBox::Last });
+
</ins><span class="cx">     // FIXME: Compute ink overflow.
</span><span class="cx">     boxes.insert(insertionPoint, { m_lineIndex
</span><span class="cx">         , InlineDisplay::Box::Type::NonRootInlineBox
</span><span class="lines">@@ -283,7 +290,7 @@
</span><span class="cx">         , { }
</span><span class="cx">         , { }
</span><span class="cx">         , true
</span><del>-        , isFirstLastBox(inlineBox) });
</del><ins>+        , isFirstLastBox });
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InlineDisplayContentBuilder::adjustInlineBoxDisplayBoxForBidiBoundary(InlineDisplay::Box& displayBox, const InlineRect& inlineBoxRect)
</span><span class="lines">@@ -422,6 +429,7 @@
</span><span class="cx">         // abcdefg
</span><span class="cx">         // with the following, fragmented inline boxes:
</span><span class="cx">         // a[first open]b[first close][second open]c[second close]d[second open]e[second close]f[first open]g[first close]
</span><ins>+        HashMap<const Box*, size_t> inlineBoxDisplayBoxMap;
</ins><span class="cx">         ListHashSet<const Box*> parentBoxStack;
</span><span class="cx">         parentBoxStack.add(&root());
</span><span class="cx"> 
</span><span class="lines">@@ -458,6 +466,13 @@
</span><span class="cx">                         parentBoxStack.add(inlineBox);
</span><span class="cx"> 
</span><span class="cx">                         auto createAndInsertDisplayBoxForInlineBoxFragment = [&] {
</span><ins>+                            // Make sure that the "previous" display box for this particular inline box is not tracked as the "last box".
+                            auto lastDisplayBoxForInlineBoxIndex = inlineBoxDisplayBoxMap.take(inlineBox);
+                            auto isFirstFragment = !lastDisplayBoxForInlineBoxIndex;
+                            if (!isFirstFragment)
+                                boxes[lastDisplayBoxForInlineBoxIndex].setIsLastBox(false);
+                            inlineBoxDisplayBoxMap.set(inlineBox, index);
+
</ins><span class="cx">                             auto& boxGeometry = formattingState().boxGeometry(*inlineBox);
</span><span class="cx">                             auto visualRect = lineBox.logicalBorderBoxForInlineBox(*inlineBox, boxGeometry);
</span><span class="cx">                             // Use the current content left as the starting point for this display box.
</span><span class="lines">@@ -465,7 +480,7 @@
</span><span class="cx">                             visualRect.moveVertically(lineBoxLogicalTopLeft.y());
</span><span class="cx">                             // Visual width is not yet known.
</span><span class="cx">                             visualRect.setWidth({ });
</span><del>-                            insertInlineBoxDisplayBoxForBidiBoundary(lineBox.inlineLevelBoxForLayoutBox(*inlineBox), visualRect, index, boxes);
</del><ins>+                            insertInlineBoxDisplayBoxForBidiBoundary(lineBox.inlineLevelBoxForLayoutBox(*inlineBox), visualRect, isFirstFragment, index, boxes);
</ins><span class="cx">                             ++index;
</span><span class="cx">                             // Need to push the rest of the content when this inline box has margin/border/padding.
</span><span class="cx">                             needsDisplayBoxHorizontalAdjustment = needsDisplayBoxHorizontalAdjustment
</span></span></pre></div>
<a id="trunkSourceWebCorelayoutformattingContextsinlineInlineDisplayContentBuilderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.h (286499 => 286500)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.h      2021-12-03 18:00:42 UTC (rev 286499)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.h 2021-12-03 18:15:04 UTC (rev 286500)
</span><span class="lines">@@ -55,7 +55,7 @@
</span><span class="cx">     void appendAtomicInlineLevelDisplayBox(const Line::Run&, const InlineRect& , DisplayBoxes&);
</span><span class="cx">     void appendInlineBoxDisplayBox(const Line::Run&, const InlineLevelBox&, const InlineRect&, bool linehasContent, DisplayBoxes&);
</span><span class="cx">     void appendSpanningInlineBoxDisplayBox(const Line::Run&, const InlineLevelBox&, const InlineRect&, DisplayBoxes&);
</span><del>-    void insertInlineBoxDisplayBoxForBidiBoundary(const InlineLevelBox&, const InlineRect&, size_t insertionPoint, DisplayBoxes&);
</del><ins>+    void insertInlineBoxDisplayBoxForBidiBoundary(const InlineLevelBox&, const InlineRect&, bool isFirstInlineBoxFragment, size_t insertionPoint, DisplayBoxes&);
</ins><span class="cx">     void adjustInlineBoxDisplayBoxForBidiBoundary(InlineDisplay::Box&, const InlineRect&);
</span><span class="cx"> 
</span><span class="cx">     void setInlineBoxGeometry(const Box&, const InlineRect&, bool isFirstInlineBoxFragment);
</span></span></pre></div>
<a id="trunkSourceWebCorelayoutformattingContextsinlinedisplayInlineDisplayBoxh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayBox.h (286499 => 286500)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayBox.h 2021-12-03 18:00:42 UTC (rev 286499)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayBox.h    2021-12-03 18:15:04 UTC (rev 286500)
</span><span class="lines">@@ -128,6 +128,8 @@
</span><span class="cx">     bool isFirstBox() const { return m_isFirstWithinInlineLevelBox; }
</span><span class="cx">     bool isLastBox() const { return m_isLastWithinInlineLevelBox; }
</span><span class="cx"> 
</span><ins>+    void setIsLastBox(bool isLastBox) { m_isLastWithinInlineLevelBox = isLastBox; }
+
</ins><span class="cx"> private:
</span><span class="cx">     const size_t m_lineIndex { 0 };
</span><span class="cx">     const Type m_type { Type::GenericInlineLevelBox };
</span></span></pre>
</div>
</div>

</body>
</html>