Title: [266888] trunk
Revision
266888
Author
[email protected]
Date
2020-09-10 13:08:40 -0700 (Thu, 10 Sep 2020)

Log Message

[LFC][IFC] Construct LineBox::InlineBoxes for nested inline level boxes when they overlap multiple lines
https://bugs.webkit.org/show_bug.cgi?id=216369

Reviewed by Antti Koivisto.

Source/WebCore:

An inline box may not necessarily start on the current line:

<span id=outer>line break
  <br>
  this content's parent inline box('outer') <span id=inner>starts on the previous line</span>
</span>

We need to make sure that there's an LineBox::InlineBox for every inline box that's present on the current line.
(both 'outer' and 'inner' inline boxes have to have a corresponding LineBox::InlineBox here to be able to compute their geometry)
They normally get constructed when when we see a [container start] run, but when the nesting level > 1 at the start of the line,
we will not see those [container start] runs.
In such cases we need to create LineBox::InlineBoxes for the inline box ancestors.
We only have to do it on the first run as any subsequent inline content is either at the same/higher nesting level or
nested with a [container start] run.

Test: fast/layoutformattingcontext/inline-box-overlaps-multiple-lines.html

* layout/inlineformatting/InlineLineBox.cpp:
(WebCore::Layout::LineBox::constructInlineBoxes):

LayoutTests:

* fast/layoutformattingcontext/inline-box-overlaps-multiple-lines-expected.html: Added.
* fast/layoutformattingcontext/inline-box-overlaps-multiple-lines.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (266887 => 266888)


--- trunk/LayoutTests/ChangeLog	2020-09-10 19:56:07 UTC (rev 266887)
+++ trunk/LayoutTests/ChangeLog	2020-09-10 20:08:40 UTC (rev 266888)
@@ -1,3 +1,13 @@
+2020-09-10  Zalan Bujtas  <[email protected]>
+
+        [LFC][IFC] Construct LineBox::InlineBoxes for nested inline level boxes when they overlap multiple lines
+        https://bugs.webkit.org/show_bug.cgi?id=216369
+
+        Reviewed by Antti Koivisto.
+
+        * fast/layoutformattingcontext/inline-box-overlaps-multiple-lines-expected.html: Added.
+        * fast/layoutformattingcontext/inline-box-overlaps-multiple-lines.html: Added.
+
 2020-09-10  Wenson Hsieh  <[email protected]>
 
         REGRESSION (r257839): clickpay.com - password placeholder text cannot be replaced

Added: trunk/LayoutTests/fast/layoutformattingcontext/inline-box-overlaps-multiple-lines-expected.html (0 => 266888)


--- trunk/LayoutTests/fast/layoutformattingcontext/inline-box-overlaps-multiple-lines-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/layoutformattingcontext/inline-box-overlaps-multiple-lines-expected.html	2020-09-10 20:08:40 UTC (rev 266888)
@@ -0,0 +1,8 @@
+<!-- webkit-test-runner [ internal:LayoutFormattingContextEnabled=true internal:LayoutFormattingContextIntegrationEnabled=false ] -->
+<style>
+div {
+    background: green;
+    font-size: 20px;
+}
+</style>
+<div>line break<br>this text's parent inline box starts at the previous line</div>

Added: trunk/LayoutTests/fast/layoutformattingcontext/inline-box-overlaps-multiple-lines.html (0 => 266888)


--- trunk/LayoutTests/fast/layoutformattingcontext/inline-box-overlaps-multiple-lines.html	                        (rev 0)
+++ trunk/LayoutTests/fast/layoutformattingcontext/inline-box-overlaps-multiple-lines.html	2020-09-10 20:08:40 UTC (rev 266888)
@@ -0,0 +1,8 @@
+<!-- webkit-test-runner [ internal:LayoutFormattingContextEnabled=true internal:LayoutFormattingContextIntegrationEnabled=false ] -->
+<style>
+div {
+    background: green;
+    font-size: 20px;
+}
+</style>
+<div><span>line break<br>this text's parent inline box <span>starts at the previous line</span></span></div>

Modified: trunk/Source/WebCore/ChangeLog (266887 => 266888)


--- trunk/Source/WebCore/ChangeLog	2020-09-10 19:56:07 UTC (rev 266887)
+++ trunk/Source/WebCore/ChangeLog	2020-09-10 20:08:40 UTC (rev 266888)
@@ -1,3 +1,30 @@
+2020-09-10  Zalan Bujtas  <[email protected]>
+
+        [LFC][IFC] Construct LineBox::InlineBoxes for nested inline level boxes when they overlap multiple lines
+        https://bugs.webkit.org/show_bug.cgi?id=216369
+
+        Reviewed by Antti Koivisto.
+
+        An inline box may not necessarily start on the current line:
+
+        <span id=outer>line break
+          <br>
+          this content's parent inline box('outer') <span id=inner>starts on the previous line</span>
+        </span>
+
+        We need to make sure that there's an LineBox::InlineBox for every inline box that's present on the current line.
+        (both 'outer' and 'inner' inline boxes have to have a corresponding LineBox::InlineBox here to be able to compute their geometry)
+        They normally get constructed when when we see a [container start] run, but when the nesting level > 1 at the start of the line,
+        we will not see those [container start] runs.
+        In such cases we need to create LineBox::InlineBoxes for the inline box ancestors. 
+        We only have to do it on the first run as any subsequent inline content is either at the same/higher nesting level or
+        nested with a [container start] run.
+
+        Test: fast/layoutformattingcontext/inline-box-overlaps-multiple-lines.html
+
+        * layout/inlineformatting/InlineLineBox.cpp:
+        (WebCore::Layout::LineBox::constructInlineBoxes):
+
 2020-09-10  Wenson Hsieh  <[email protected]>
 
         REGRESSION (r257839): clickpay.com - password placeholder text cannot be replaced

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp (266887 => 266888)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp	2020-09-10 19:56:07 UTC (rev 266887)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp	2020-09-10 20:08:40 UTC (rev 266888)
@@ -159,6 +159,33 @@
         m_inlineBoxRectMap.set(&root(), &m_rootInlineBox);
     };
     constructRootInlineBox();
+    if (!runs.isEmpty()) {
+        // An inline box may not necessarily start on the current line:
+        // <span id=outer>line break<br>this content's parent inline box('outer') <span id=inner>starts on the previous line</span></span>
+        // We need to make sure that there's an LineBox::InlineBox for every inline box that's present on the current line.
+        // In nesting case we need to create LineBox::InlineBoxes for the inline box ancestors. 
+        // We only have to do it on the first run as any subsequent inline content is either at the same/higher nesting level or
+        // nested with a [container start] run.
+        auto& firstRunParentInlineBox = runs[0].layoutBox().parent();
+        // If the parent is the root(), we can stop here. This is root inline box content, there's no nesting inline box from the previous line(s).
+        if (&firstRunParentInlineBox != &root()) {
+            auto* ancestor = &firstRunParentInlineBox;
+            Vector<const Box*> ancestorsWithoutInlineBoxes;
+            while (ancestor != &root()) {
+                ancestorsWithoutInlineBoxes.append(ancestor);
+                ancestor = &ancestor->parent();
+            }
+            // Construct the missing LineBox::InlineBoxes starting with the topmost ancestor.
+            for (auto* ancestor : WTF::makeReversedRange(ancestorsWithoutInlineBoxes)) {
+                auto& fontMetrics = ancestor->style().fontMetrics();
+                InlineLayoutUnit logicalHeight = fontMetrics.height();
+                auto inlineBoxRect = Display::InlineRect { { }, m_horizontalAlignmentOffset.valueOr(InlineLayoutUnit { }), logicalWidth(), logicalHeight };
+                auto inlineBox = makeUnique<InlineBox>(*ancestor, inlineBoxRect, fontMetrics.ascent(), fontMetrics.descent(), InlineBox::IsConsideredEmpty::No);
+                m_inlineBoxRectMap.set(ancestor, inlineBox.get());
+                m_inlineBoxList.append(WTFMove(inlineBox));
+            }
+        }
+    }
 
     for (auto& run : runs) {
         auto& inlineLevelBox = run.layoutBox();
@@ -196,8 +223,8 @@
             auto& fontMetrics = inlineLevelBox.style().fontMetrics();
             InlineLayoutUnit logicalHeight = fontMetrics.height();
             InlineLayoutUnit baseline = fontMetrics.ascent();
-            auto inlineBoxRect = Display::InlineRect { { }, inlineBoxLogicalLeft, initialWidth, logicalHeight };
-            auto inlineBox = makeUnique<InlineBox>(inlineLevelBox, inlineBoxRect, baseline, logicalHeight - baseline, InlineBox::IsConsideredEmpty::Yes);
+            auto logicalRect = Display::InlineRect { { }, inlineBoxLogicalLeft, initialWidth, logicalHeight };
+            auto inlineBox = makeUnique<InlineBox>(inlineLevelBox, logicalRect, baseline, logicalHeight - baseline, InlineBox::IsConsideredEmpty::Yes);
             m_inlineBoxRectMap.set(&inlineLevelBox, inlineBox.get());
             m_inlineBoxList.append(WTFMove(inlineBox));
         } else if (run.isContainerEnd()) {
@@ -204,8 +231,8 @@
             // Adjust the logical width when the inline level container closes on this line.
             auto& inlineBox = *m_inlineBoxRectMap.get(&inlineLevelBox);
             inlineBox.setLogicalWidth(run.logicalRight() - inlineBox.logicalLeft());
-        } else if ((run.isText() || run.isLineBreak())) {
-            auto& containerBox = run.layoutBox().parent();
+        } else if (run.isText() || run.isLineBreak()) {
+            auto& containerBox = inlineLevelBox.parent();
             &containerBox == &root() ? m_rootInlineBox.setIsNonEmpty() : m_inlineBoxRectMap.get(&containerBox)->setIsNonEmpty();
         }
     }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to