[LFC][IFC] Take nonBreakableStart/End into use.
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 21 Nov 2018 15:41:45 +0000 (15:41 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 21 Nov 2018 15:41:45 +0000 (15:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=191873

Reviewed by Antti Koivisto.

Source/WebCore:

Offset the final inline runs with the nonBreakableStart/End values.
(This patch also fixes relative positioned run verification.)

Test: fast/inline/inline-content-with-padding-left-right.html

* layout/Verification.cpp:
(WebCore::Layout::LayoutState::verifyAndOutputMismatchingLayoutTree const):
* layout/inlineformatting/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::splitInlineRunIfNeeded const):

Tools:

* LayoutReloaded/misc/LFC-passing-tests.txt:

LayoutTests:

* fast/inline/inline-content-with-padding-left-right-expected.txt: Added.
* fast/inline/inline-content-with-padding-left-right.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238415 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/inline/inline-content-with-padding-left-right-expected.txt [new file with mode: 0644]
LayoutTests/fast/inline/inline-content-with-padding-left-right.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/layout/Verification.cpp
Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp
Tools/ChangeLog
Tools/LayoutReloaded/misc/LFC-passing-tests.txt

index 5696faa..b3b1f91 100644 (file)
@@ -1,3 +1,13 @@
+2018-11-21  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC][IFC] Take nonBreakableStart/End into use.
+        https://bugs.webkit.org/show_bug.cgi?id=191873
+
+        Reviewed by Antti Koivisto.
+
+        * fast/inline/inline-content-with-padding-left-right-expected.txt: Added.
+        * fast/inline/inline-content-with-padding-left-right.html: Added.
+
 2018-11-20  Ryosuke Niwa  <rniwa@webkit.org>
 
         Input element gains focus when a selectstart event listener on document prevents the default action
diff --git a/LayoutTests/fast/inline/inline-content-with-padding-left-right-expected.txt b/LayoutTests/fast/inline/inline-content-with-padding-left-right-expected.txt
new file mode 100644 (file)
index 0000000..fdc6cef
--- /dev/null
@@ -0,0 +1,225 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+layer at (8,8) size 402x22 clip at (9,9) size 400x20 scrollHeight 24
+  RenderBlock {DIV} at (0,0) size 402x22 [border: (1px solid #008000)]
+    RenderText {#text} at (1,1) size 6x14
+      text run at (1,1) width 6: "1"
+    RenderInline {SPAN} at (0,0) size 26x34
+      RenderText {#text} at (17,1) size 6x14
+        text run at (17,1) width 6: "2"
+    RenderText {#text} at (33,1) size 6x14
+      text run at (33,1) width 6: "3"
+layer at (8,30) size 402x22 clip at (9,31) size 400x20
+  RenderBlock {DIV} at (0,22) size 402x22 [border: (1px solid #008000)]
+    RenderText {#text} at (1,1) size 6x14
+      text run at (1,1) width 6: "1"
+    RenderInline {SPAN} at (0,0) size 16x14
+      RenderText {#text} at (17,1) size 6x14
+        text run at (17,1) width 6: "2"
+    RenderText {#text} at (23,1) size 6x14
+      text run at (23,1) width 6: "3"
+layer at (8,52) size 402x22 clip at (9,53) size 400x20
+  RenderBlock {DIV} at (0,44) size 402x22 [border: (1px solid #008000)]
+    RenderText {#text} at (1,1) size 6x14
+      text run at (1,1) width 6: "1"
+    RenderInline {SPAN} at (0,0) size 16x14
+      RenderText {#text} at (7,1) size 6x14
+        text run at (7,1) width 6: "2"
+    RenderText {#text} at (23,1) size 6x14
+      text run at (23,1) width 6: "3"
+layer at (8,74) size 402x22 clip at (9,75) size 400x20 scrollHeight 24
+  RenderBlock {DIV} at (0,66) size 402x22 [border: (1px solid #008000)]
+    RenderInline {SPAN} at (0,0) size 16x14
+      RenderText {#text} at (11,1) size 6x14
+        text run at (11,1) width 6: "1"
+    RenderInline {SPAN} at (0,0) size 26x34
+      RenderText {#text} at (27,1) size 6x14
+        text run at (27,1) width 6: "2"
+    RenderInline {SPAN} at (0,0) size 16x14
+      RenderText {#text} at (43,1) size 6x14
+        text run at (43,1) width 6: "3"
+layer at (8,96) size 402x22 clip at (9,97) size 400x20 scrollHeight 24
+  RenderBlock {DIV} at (0,88) size 402x22 [border: (1px solid #008000)]
+    RenderInline {SPAN} at (0,0) size 46x14
+      RenderInline {SPAN} at (0,0) size 36x14
+        RenderInline {SPAN} at (0,0) size 26x34
+          RenderText {#text} at (21,1) size 6x14
+            text run at (21,1) width 6: "1"
+layer at (8,118) size 402x22 clip at (9,119) size 400x20 scrollHeight 24
+  RenderBlock {DIV} at (0,110) size 402x22 [border: (1px solid #008000)]
+    RenderInline {SPAN} at (0,0) size 46x14
+      RenderInline {SPAN} at (0,0) size 36x14
+        RenderInline {SPAN} at (0,0) size 26x34
+          RenderText {#text} at (21,1) size 6x14
+            text run at (21,1) width 6: "1"
+layer at (8,140) size 402x22 clip at (9,141) size 400x20
+  RenderBlock {DIV} at (0,132) size 402x22 [border: (1px solid #008000)]
+    RenderInline {SPAN} at (0,0) size 16x14
+      RenderText {#text} at (11,1) size 6x14
+        text run at (11,1) width 6: "1"
+    RenderInline {SPAN} at (0,0) size 16x14
+      RenderText {#text} at (27,1) size 6x14
+        text run at (27,1) width 6: "2"
+    RenderInline {SPAN} at (0,0) size 16x14
+      RenderText {#text} at (43,1) size 6x14
+        text run at (43,1) width 6: "3"
+layer at (8,162) size 402x22 clip at (9,163) size 400x20
+  RenderBlock {DIV} at (0,154) size 402x22 [border: (1px solid #008000)]
+    RenderInline {SPAN} at (0,0) size 16x14
+      RenderText {#text} at (1,1) size 6x14
+        text run at (1,1) width 6: "1"
+    RenderInline {SPAN} at (0,0) size 16x14
+      RenderText {#text} at (17,1) size 6x14
+        text run at (17,1) width 6: "2"
+    RenderInline {SPAN} at (0,0) size 16x14
+      RenderText {#text} at (33,1) size 6x14
+        text run at (33,1) width 6: "3"
+layer at (8,184) size 402x22 clip at (9,185) size 400x20 scrollHeight 24
+  RenderBlock {DIV} at (0,176) size 402x22 [border: (1px solid #008000)]
+    RenderInline {SPAN} at (0,0) size 26x34
+      RenderText {#text} at (11,1) size 6x14
+        text run at (11,1) width 6: "1"
+    RenderInline {SPAN} at (0,0) size 26x34
+      RenderText {#text} at (37,1) size 6x14
+        text run at (37,1) width 6: "2"
+    RenderInline {SPAN} at (0,0) size 26x34
+      RenderText {#text} at (63,1) size 6x14
+        text run at (63,1) width 6: "3"
+layer at (8,206) size 402x22 clip at (9,207) size 400x20
+  RenderBlock {DIV} at (0,198) size 402x22 [border: (1px solid #008000)]
+    RenderInline {SPAN} at (0,0) size 48x14
+      RenderInline {SPAN} at (0,0) size 32x14
+        RenderInline {SPAN} at (0,0) size 16x14
+          RenderText {#text} at (31,1) size 6x14
+            text run at (31,1) width 6: "1"
+        RenderText {#text} at (37,1) size 6x14
+          text run at (37,1) width 6: "2"
+      RenderText {#text} at (43,1) size 6x14
+        text run at (43,1) width 6: "3"
+layer at (8,228) size 402x22 clip at (9,229) size 400x20
+  RenderBlock {DIV} at (0,220) size 402x22 [border: (1px solid #008000)]
+    RenderInline {SPAN} at (0,0) size 48x14
+      RenderInline {SPAN} at (0,0) size 32x14
+        RenderInline {SPAN} at (0,0) size 16x14
+          RenderText {#text} at (1,1) size 6x14
+            text run at (1,1) width 6: "1"
+        RenderText {#text} at (17,1) size 6x14
+          text run at (17,1) width 6: "2"
+      RenderText {#text} at (33,1) size 6x14
+        text run at (33,1) width 6: "3"
+layer at (8,250) size 402x22 clip at (9,251) size 400x20 scrollHeight 24
+  RenderBlock {DIV} at (0,242) size 402x22 [border: (1px solid #008000)]
+    RenderInline {SPAN} at (0,0) size 78x34
+      RenderInline {SPAN} at (0,0) size 52x34
+        RenderInline {SPAN} at (0,0) size 26x34
+          RenderText {#text} at (31,1) size 6x14
+            text run at (31,1) width 6: "1"
+        RenderText {#text} at (47,1) size 6x14
+          text run at (47,1) width 6: "2"
+      RenderText {#text} at (63,1) size 6x14
+        text run at (63,1) width 6: "3"
+layer at (8,272) size 402x22 clip at (9,273) size 400x20
+  RenderBlock {DIV} at (0,264) size 402x22 [border: (1px solid #008000)]
+    RenderText {#text} at (1,1) size 6x14
+      text run at (1,1) width 6: "1"
+    RenderInline {SPAN} at (0,0) size 54x14
+      RenderText {#text} at (17,1) size 6x14
+        text run at (17,1) width 6: "2"
+      RenderInline {SPAN} at (0,0) size 32x14
+        RenderInline {SPAN} at (0,0) size 16x14
+          RenderText {#text} at (43,1) size 6x14
+            text run at (43,1) width 6: "3"
+        RenderText {#text} at (49,1) size 6x14
+          text run at (49,1) width 6: "4"
+      RenderText {#text} at (55,1) size 6x14
+        text run at (55,1) width 6: "5"
+    RenderText {#text} at (61,1) size 6x14
+      text run at (61,1) width 6: "6"
+layer at (8,294) size 402x22 clip at (9,295) size 400x20
+  RenderBlock {DIV} at (0,286) size 402x22 [border: (1px solid #008000)]
+    RenderText {#text} at (1,1) size 6x14
+      text run at (1,1) width 6: "1"
+    RenderInline {SPAN} at (0,0) size 54x14
+      RenderText {#text} at (7,1) size 6x14
+        text run at (7,1) width 6: "2"
+      RenderInline {SPAN} at (0,0) size 32x14
+        RenderInline {SPAN} at (0,0) size 16x14
+          RenderText {#text} at (13,1) size 6x14
+            text run at (13,1) width 6: "3"
+        RenderText {#text} at (29,1) size 6x14
+          text run at (29,1) width 6: "4"
+      RenderText {#text} at (45,1) size 6x14
+        text run at (45,1) width 6: "5"
+    RenderText {#text} at (61,1) size 6x14
+      text run at (61,1) width 6: "6"
+layer at (8,316) size 402x22 clip at (9,317) size 400x20 scrollHeight 24
+  RenderBlock {DIV} at (0,308) size 402x22 [border: (1px solid #008000)]
+    RenderText {#text} at (1,1) size 6x14
+      text run at (1,1) width 6: "1"
+    RenderInline {SPAN} at (0,0) size 84x34
+      RenderText {#text} at (17,1) size 6x14
+        text run at (17,1) width 6: "2"
+      RenderInline {SPAN} at (0,0) size 52x34
+        RenderInline {SPAN} at (0,0) size 26x34
+          RenderText {#text} at (43,1) size 6x14
+            text run at (43,1) width 6: "3"
+        RenderText {#text} at (59,1) size 6x14
+          text run at (59,1) width 6: "4"
+      RenderText {#text} at (75,1) size 6x14
+        text run at (75,1) width 6: "5"
+    RenderText {#text} at (91,1) size 6x14
+      text run at (91,1) width 6: "6"
+layer at (8,338) size 402x22 clip at (9,339) size 400x20 scrollHeight 24
+  RenderBlock {DIV} at (0,330) size 402x22 [border: (1px solid #008000)]
+    RenderText {#text} at (1,1) size 6x14
+      text run at (1,1) width 6: "1"
+    RenderInline {SPAN} at (0,0) size 64x14
+      RenderText {#text} at (17,1) size 6x14
+        text run at (17,1) width 6: "2"
+      RenderInline {SPAN} at (0,0) size 42x34
+        RenderInline {SPAN} at (0,0) size 16x14
+          RenderText {#text} at (33,1) size 6x14
+            text run at (33,1) width 6: "3"
+        RenderText {#text} at (49,1) size 6x14
+          text run at (49,1) width 6: "4"
+      RenderText {#text} at (65,1) size 6x14
+        text run at (65,1) width 6: "5"
+    RenderText {#text} at (71,1) size 6x14
+      text run at (71,1) width 6: "6"
+layer at (8,360) size 402x22 clip at (9,361) size 400x20 scrollHeight 24
+  RenderBlock {DIV} at (0,352) size 402x22 [border: (1px solid #008000)]
+    RenderText {#text} at (1,1) size 6x14
+      text run at (1,1) width 6: "1"
+    RenderInline {SPAN} at (0,0) size 64x14
+      RenderText {#text} at (7,1) size 6x14
+        text run at (7,1) width 6: "2"
+      RenderInline {SPAN} at (0,0) size 42x34
+        RenderInline {SPAN} at (0,0) size 16x14
+          RenderText {#text} at (33,1) size 6x14
+            text run at (33,1) width 6: "3"
+        RenderText {#text} at (39,1) size 6x14
+          text run at (39,1) width 6: "4"
+      RenderText {#text} at (55,1) size 6x14
+        text run at (55,1) width 6: "5"
+    RenderText {#text} at (71,1) size 6x14
+      text run at (71,1) width 6: "6"
+layer at (8,382) size 402x22 clip at (9,383) size 400x20 scrollHeight 24
+  RenderBlock {DIV} at (0,374) size 402x22 [border: (1px solid #008000)]
+    RenderText {#text} at (1,1) size 6x14
+      text run at (1,1) width 6: "1"
+    RenderInline {SPAN} at (0,0) size 64x34
+      RenderText {#text} at (17,1) size 6x14
+        text run at (17,1) width 6: "2"
+      RenderInline {SPAN} at (0,0) size 32x14
+        RenderInline {SPAN} at (0,0) size 16x14
+          RenderText {#text} at (33,1) size 6x14
+            text run at (33,1) width 6: "3"
+        RenderText {#text} at (39,1) size 6x14
+          text run at (39,1) width 6: "4"
+      RenderText {#text} at (55,1) size 6x14
+        text run at (55,1) width 6: "5"
+    RenderText {#text} at (71,1) size 6x14
+      text run at (71,1) width 6: "6"
diff --git a/LayoutTests/fast/inline/inline-content-with-padding-left-right.html b/LayoutTests/fast/inline/inline-content-with-padding-left-right.html
new file mode 100644 (file)
index 0000000..b862878
--- /dev/null
@@ -0,0 +1,40 @@
+<style>
+.inlineRoot {
+       border: 1px solid green;
+       width: 400px;
+       height: 20px;
+       overflow: hidden;
+       font-size: 12px;
+}
+
+.breakStart {
+    padding-left: 10px;
+}
+
+.breakEnd {
+    padding-right: 10px;
+}
+
+.breakBoth {
+    padding: 10px;
+}
+</style>
+
+<div class=inlineRoot>1<span class=breakBoth>2</span>3</div>
+<div class=inlineRoot>1<span class=breakStart>2</span>3</div>
+<div class=inlineRoot>1<span class=breakEnd>2</span>3</div>
+<div class=inlineRoot><span class=breakStart>1</span><span class=breakBoth>2</span><span class=breakEnd>3</span></div>
+<div class=inlineRoot><span class=breakStart><span class=breakEnd><span class=breakBoth>1</span></span></span></div>
+<div class=inlineRoot><span class=breakEnd><span class=breakStart><span class=breakBoth>1</span></span></span></div>
+<div class=inlineRoot><span class=breakStart>1</span><span class=breakStart>2</span><span class=breakStart>3</span></div>
+<div class=inlineRoot><span class=breakEnd>1</span><span class=breakEnd>2</span><span class=breakEnd>3</span></div>
+<div class=inlineRoot><span class=breakBoth>1</span><span class=breakBoth>2</span><span class=breakBoth>3</span></div>
+<div class=inlineRoot><span class=breakStart><span class=breakStart><span class=breakStart>1</span>2</span>3</span></div>
+<div class=inlineRoot><span class=breakEnd><span class=breakEnd><span class=breakEnd>1</span>2</span>3</span></div>
+<div class=inlineRoot><span class=breakBoth><span class=breakBoth><span class=breakBoth>1</span>2</span>3</span></div>
+<div class=inlineRoot>1<span class=breakStart>2<span class=breakStart><span class=breakStart>3</span>4</span>5</span>6</div>
+<div class=inlineRoot>1<span class=breakEnd>2<span class=breakEnd><span class=breakEnd>3</span>4</span>5</span>6</div>
+<div class=inlineRoot>1<span class=breakBoth>2<span class=breakBoth><span class=breakBoth>3</span>4</span>5</span>6</div>
+<div class=inlineRoot>1<span class=breakStart>2<span class=breakBoth><span class=breakEnd>3</span>4</span>5</span>6</div>
+<div class=inlineRoot>1<span class=breakEnd>2<span class=breakBoth><span class=breakStart>3</span>4</span>5</span>6</div>
+<div class=inlineRoot>1<span class=breakBoth>2<span class=breakEnd><span class=breakStart>3</span>4</span>5</span>6</div>
index 230131d..e420a33 100644 (file)
@@ -1,3 +1,20 @@
+2018-11-21  Zalan Butjas  <zalan@apple.com>
+
+        [LFC][IFC] Take nonBreakableStart/End into use.
+        https://bugs.webkit.org/show_bug.cgi?id=191873
+
+        Reviewed by Antti Koivisto.
+
+        Offset the final inline runs with the nonBreakableStart/End values.
+        (This patch also fixes relative positioned run verification.)
+
+        Test: fast/inline/inline-content-with-padding-left-right.html
+
+        * layout/Verification.cpp:
+        (WebCore::Layout::LayoutState::verifyAndOutputMismatchingLayoutTree const):
+        * layout/inlineformatting/InlineFormattingContext.cpp:
+        (WebCore::Layout::InlineFormattingContext::splitInlineRunIfNeeded const):
+
 2018-11-21  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         REGRESSION(r237845): [cairo] Hyperlink underscore layout issue
index 24e4d52..e5db76b 100644 (file)
@@ -120,6 +120,19 @@ static void collectInlineBoxes(const RenderBlockFlow& root, Vector<WebCore::Inli
     }
 }
 
+static LayoutUnit resolveForRelativePositionIfNeeded(const InlineTextBox& inlineTextBox)
+{
+    LayoutUnit xOffset;
+    auto* parent = inlineTextBox.parent();
+    while (is<InlineFlowBox>(parent)) {
+        auto& renderer = parent->renderer();
+        if (renderer.isInFlowPositioned())
+            xOffset = downcast<RenderInline>(renderer).offsetForInFlowPosition().width();
+        parent = parent->parent();
+    }
+    return xOffset;
+}
+
 static bool outputMismatchingComplexLineInformationIfNeeded(TextStream& stream, const LayoutState& layoutState, const RenderBlockFlow& blockFlow, const Container& inlineFormattingRoot)
 {
     auto& inlineFormattingState = layoutState.establishedFormattingState(inlineFormattingRoot);
@@ -145,7 +158,8 @@ static bool outputMismatchingComplexLineInformationIfNeeded(TextStream& stream,
         auto& inlineRun = inlineRunList[runIndex];
         auto matchingRuns = false;
         if (inlineTextBox) {
-            matchingRuns = checkForMatchingTextRuns(inlineRun, inlineTextBox->logicalLeft(), inlineTextBox->logicalRight(), inlineTextBox->start(), inlineTextBox->end() + 1);
+            auto xOffset = resolveForRelativePositionIfNeeded(*inlineTextBox);
+            matchingRuns = checkForMatchingTextRuns(inlineRun, inlineTextBox->logicalLeft() + xOffset, inlineTextBox->logicalRight() + xOffset, inlineTextBox->start(), inlineTextBox->end() + 1);
 
             // <span>foobar</span>foobar generates 2 inline text boxes while we only generate one inline run.
             // also <div>foo<img style="float: left;">bar</div> too.
@@ -153,8 +167,8 @@ static bool outputMismatchingComplexLineInformationIfNeeded(TextStream& stream,
             auto textRunMightBeExtended = !matchingRuns && inlineTextBox->end() < inlineRunEnd && inlineBoxIndex < inlineBoxes.size() - 1;
 
             if (textRunMightBeExtended) {
-                auto logicalLeft = inlineTextBox->logicalLeft();
-                auto logicalRight = inlineTextBox->logicalRight();
+                auto logicalLeft = inlineTextBox->logicalLeft() + xOffset;
+                auto logicalRight = inlineTextBox->logicalRight() + xOffset;
                 auto start = inlineTextBox->start();
                 auto end = inlineTextBox->end() + 1;
                 auto index = ++inlineBoxIndex;
@@ -165,7 +179,8 @@ static bool outputMismatchingComplexLineInformationIfNeeded(TextStream& stream,
                     if (!inlineTextBox)
                         break;
 
-                    logicalRight = inlineTextBox->logicalRight();
+                    auto xOffset = resolveForRelativePositionIfNeeded(*inlineTextBox);
+                    logicalRight = inlineTextBox->logicalRight() + xOffset;
                     end += (inlineTextBox->end() + 1);
                     if (checkForMatchingTextRuns(inlineRun, logicalLeft, logicalRight, start, end)) {
                         matchingRuns = true;
@@ -178,13 +193,6 @@ static bool outputMismatchingComplexLineInformationIfNeeded(TextStream& stream,
                         break;
                 }
             }
-        } else if (is<InlineFlowBox>(inlineBox)) {
-            // FIXME: This does not work for nested InlineFlowBoxes and we should really look inside these flow boxes and verify the leaf nodes.
-            auto& renderer = inlineBox->renderer();
-            LayoutUnit xOffset;
-            if (renderer.isInFlowPositioned())
-                xOffset = downcast<RenderInline>(renderer).offsetForInFlowPosition().width();
-            matchingRuns = areEssentiallyEqual(inlineBox->logicalLeft() + xOffset, inlineRun.logicalLeft()) && areEssentiallyEqual(inlineBox->logicalRight() + xOffset, inlineRun.logicalRight());
         } else
             matchingRuns = checkForMatchingNonTextRuns(inlineRun, *inlineBox);
 
index 807a397..29ea1d0 100644 (file)
@@ -139,21 +139,35 @@ void InlineFormattingContext::splitInlineRunIfNeeded(const InlineRun& inlineRun,
     // 2. either find an inline item that needs a dedicated run or we reach the end of the run
     // 3. Create dedicate inline runs.
     auto& inlineContent = inlineFormattingState().inlineContent();
-
-    auto split=[&](const auto& inlineItem, auto startPosition, auto length, auto contentStart) {
-        auto width = Geometry::runWidth(inlineContent, inlineItem, startPosition, length, contentStart);
-        auto run = InlineRun { { inlineRun.logicalTop(), contentStart, width, inlineRun.height() }, inlineItem };
-        run.setTextContext({ startPosition, length });
-        splitRuns.append(run);
-        return contentStart + width;
-    };
-
     auto contentStart = inlineRun.logicalLeft();
     auto startPosition = inlineRun.textContext()->start();
     auto remaningLength = inlineRun.textContext()->length();
 
-    unsigned uncommittedLength = 0;
-    InlineItem* firstUncommittedInlineItem = nullptr;
+    struct Uncommitted {
+        const InlineItem* firstInlineItem { nullptr };
+        const InlineItem* lastInlineItem { nullptr };
+        unsigned length { 0 };
+    };
+    std::optional<Uncommitted> uncommitted;
+
+    auto commit = [&] {
+        if (!uncommitted)
+            return;
+
+        contentStart += uncommitted->firstInlineItem->nonBreakableStart();
+
+        auto runWidth = Geometry::runWidth(inlineContent, *uncommitted->firstInlineItem, startPosition, uncommitted->length, contentStart);
+        auto run = InlineRun { { inlineRun.logicalTop(), contentStart, runWidth, inlineRun.height() }, *uncommitted->firstInlineItem };
+        run.setTextContext({ startPosition, uncommitted->length });
+        splitRuns.append(run);
+
+        contentStart += runWidth + uncommitted->lastInlineItem->nonBreakableEnd();
+        remaningLength -= uncommitted->length;
+
+        startPosition = 0;
+        uncommitted = { };
+    };
+
     for (auto iterator = inlineContent.find<const InlineItem&, InlineItemHashTranslator>(inlineRun.inlineItem()); iterator != inlineContent.end() && remaningLength > 0; ++iterator) {
         auto& inlineItem = **iterator;
 
@@ -171,54 +185,33 @@ void InlineFormattingContext::splitInlineRunIfNeeded(const InlineRun& inlineRun,
         // 4. Break before/after -> requires dedicated run -> commit what we've got so far and also commit the current inline element as a separate inline run.
         auto detachingRules = inlineItem.detachingRules();
 
-        // #1
-        if (detachingRules.isEmpty()) {
-            uncommittedLength += currentLength();
-            firstUncommittedInlineItem = !firstUncommittedInlineItem ? &inlineItem : firstUncommittedInlineItem;
+        // #4
+        if (detachingRules.containsAll({ InlineItem::DetachingRule::BreakAtStart, InlineItem::DetachingRule::BreakAtEnd })) {
+            commit();
+            uncommitted = Uncommitted { &inlineItem, &inlineItem, currentLength() };
+            commit();
             continue;
         }
 
-        auto commit = [&] {
-            if (!firstUncommittedInlineItem)
-                return;
-
-            contentStart = split(*firstUncommittedInlineItem, startPosition, uncommittedLength, contentStart);
-
-            remaningLength -= uncommittedLength;
-            startPosition = 0;
-            uncommittedLength = 0;
-            firstUncommittedInlineItem = nullptr;
-        };
-
         // #2
-        if (detachingRules == InlineItem::DetachingRule::BreakAtStart) {
+        if (detachingRules == InlineItem::DetachingRule::BreakAtStart)
             commit();
-            firstUncommittedInlineItem = &inlineItem;
-            uncommittedLength = currentLength();
-            continue;
-        }
+
+        // Add current inline item to uncommitted.
+        if (!uncommitted)
+            uncommitted = Uncommitted { &inlineItem, &inlineItem, 0 };
+        uncommitted->length += currentLength();
+        uncommitted->lastInlineItem = &inlineItem;
 
         // #3
-        if (detachingRules == InlineItem::DetachingRule::BreakAtEnd) {
-            ASSERT(firstUncommittedInlineItem);
-            uncommittedLength += currentLength();
+        if (detachingRules == InlineItem::DetachingRule::BreakAtEnd)
             commit();
-            continue;
-        }
-
-        // #4
-        commit();
-        firstUncommittedInlineItem = &inlineItem;
-        uncommittedLength = currentLength();
-        commit();
     }
-
     // Either all inline elements needed dedicated runs or neither of them.
     if (!remaningLength || remaningLength == inlineRun.textContext()->length())
         return;
 
-    ASSERT(remaningLength == uncommittedLength);
-    split(*firstUncommittedInlineItem, startPosition, uncommittedLength, contentStart);
+    commit();
 }
 
 void InlineFormattingContext::createFinalRuns(Line& line) const
index 1a5715b..3c85b2d 100644 (file)
@@ -1,3 +1,12 @@
+2018-11-21  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC][IFC] Take nonBreakableStart/End into use.
+        https://bugs.webkit.org/show_bug.cgi?id=191873
+
+        Reviewed by Antti Koivisto.
+
+        * LayoutReloaded/misc/LFC-passing-tests.txt:
+
 2018-11-20  Jeff Miller  <jeffm@apple.com>
 
         Return nullptr immediately if the key doesn't exist in the HashMap.
index 6fd0279..75aa201 100644 (file)
@@ -72,6 +72,7 @@ fast/inline/simple-shrink-to-fit-inline-block.html
 fast/inline/simple-inline-inflow-positioned.html
 fast/inline/simple-inline-with-out-of-flow-descendant.html
 fast/inline/simple-inline-with-out-of-flow-descendant2.html
+fast/inline/inline-content-with-padding-left-right.html
 fast/block/basic/height-percentage-simple.html
 fast/block/basic/child-block-level-box-with-height-percent.html
 fast/block/basic/quirk-mode-percent-height.html