Title: [251455] trunk/Source/WebCore
Revision
251455
Author
za...@apple.com
Date
2019-10-22 14:11:48 -0700 (Tue, 22 Oct 2019)

Log Message

[LFC][IFC] Add support for continuous content/commit boundary check
https://bugs.webkit.org/show_bug.cgi?id=203255
<rdar://problem/56503598>

Reviewed by Antti Koivisto.

This patch adds support for continuous content and commit boundary check.

<span style="padding-right: 10px;">textcontent</span>

The content above forms a continuous, unbreakable run of ([container start][textcontent][container end with horizontal padding of 10px]).
However at this point we don't know yet whether we are at the end of the run and we need to keep checking for the trailing content.
In general, we can't submit the run to the line breaking unless we managed to find the commit boundary for the current run.

<span style="padding-right: 10px;">textcontent</span><img src=""
    This content produces two separate runs as follows:
    1. ([container start][textcontent][container end with horizontal padding of 10px])
    2. ([img])
vs.
<span style="padding-right: 10px;">textcontent</span>moretextcontent
    This content produces only one run
    1. ([container start][textcontent][container end with horizontal padding of 10px][moretextcontent])

The idea here is that we don't commit the content on the line unless we identified the run boundary. In practice it means that we hardly commit the current inline item on the line
but instead we use it to decide whether the uncommitted content is ready to be committed.

Using the following example:
<span style="padding-right: 10px;">textcontent<img src=""

Incoming inline items are:
 [container start] -> we can't identify the run boundary -> add inline item to pending content
 [textcontent] -> we still can't identify the run boundary sine we don't know what the next inline item is -> add inline item to pending content
 [img] -> now we know that the [container start][textcontent] is on a commit boundary -> commit pending content -> however the current [img] item's boundary is unknown.
 [container end with horizontal padding of 10px] -> Now the [img] and [container end] form an unbreakable run but we don't yet know if this is a run boundary
 - End of content -> always a commit boundary -> commit pending items -> ([img][container end])

* layout/inlineformatting/InlineLineBreaker.cpp:
(WebCore::Layout::LineBreaker::breakingContext):
(WebCore::Layout::LineBreaker::breakingContextForFloat):
(WebCore::Layout::LineBreaker::wordBreakingBehavior const):
(WebCore::Layout::LineBreaker::isAtBreakingOpportunity): Deleted.
* layout/inlineformatting/InlineLineBreaker.h:
* layout/inlineformatting/InlineLineLayout.cpp:
(WebCore::Layout::LineLayout::layout):
(WebCore::Layout::LineLayout::close):
(WebCore::Layout::LineLayout::placeInlineItem):
(WebCore::Layout::LineLayout::processUncommittedContent):
(WebCore::Layout::LineLayout::shouldProcessUncommittedContent const):
* layout/inlineformatting/InlineLineLayout.h:
(WebCore::Layout::LineLayout::UncommittedContent::runs):
(WebCore::Layout::LineLayout::UncommittedContent::runs const):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (251454 => 251455)


--- trunk/Source/WebCore/ChangeLog	2019-10-22 21:03:30 UTC (rev 251454)
+++ trunk/Source/WebCore/ChangeLog	2019-10-22 21:11:48 UTC (rev 251455)
@@ -1,3 +1,57 @@
+2019-10-22  Zalan Bujtas  <za...@apple.com>
+
+        [LFC][IFC] Add support for continuous content/commit boundary check
+        https://bugs.webkit.org/show_bug.cgi?id=203255
+        <rdar://problem/56503598>
+
+        Reviewed by Antti Koivisto.
+
+        This patch adds support for continuous content and commit boundary check.
+        
+        <span style="padding-right: 10px;">textcontent</span>
+
+        The content above forms a continuous, unbreakable run of ([container start][textcontent][container end with horizontal padding of 10px]).
+        However at this point we don't know yet whether we are at the end of the run and we need to keep checking for the trailing content.
+        In general, we can't submit the run to the line breaking unless we managed to find the commit boundary for the current run.
+
+        <span style="padding-right: 10px;">textcontent</span><img src=""
+            This content produces two separate runs as follows:
+            1. ([container start][textcontent][container end with horizontal padding of 10px])
+            2. ([img])
+        vs.
+        <span style="padding-right: 10px;">textcontent</span>moretextcontent
+            This content produces only one run
+            1. ([container start][textcontent][container end with horizontal padding of 10px][moretextcontent])
+
+        The idea here is that we don't commit the content on the line unless we identified the run boundary. In practice it means that we hardly commit the current inline item on the line
+        but instead we use it to decide whether the uncommitted content is ready to be committed.
+
+        Using the following example:        
+        <span style="padding-right: 10px;">textcontent<img src=""
+        
+        Incoming inline items are:
+         [container start] -> we can't identify the run boundary -> add inline item to pending content
+         [textcontent] -> we still can't identify the run boundary sine we don't know what the next inline item is -> add inline item to pending content
+         [img] -> now we know that the [container start][textcontent] is on a commit boundary -> commit pending content -> however the current [img] item's boundary is unknown.
+         [container end with horizontal padding of 10px] -> Now the [img] and [container end] form an unbreakable run but we don't yet know if this is a run boundary
+         - End of content -> always a commit boundary -> commit pending items -> ([img][container end])  
+
+        * layout/inlineformatting/InlineLineBreaker.cpp:
+        (WebCore::Layout::LineBreaker::breakingContext):
+        (WebCore::Layout::LineBreaker::breakingContextForFloat):
+        (WebCore::Layout::LineBreaker::wordBreakingBehavior const):
+        (WebCore::Layout::LineBreaker::isAtBreakingOpportunity): Deleted.
+        * layout/inlineformatting/InlineLineBreaker.h:
+        * layout/inlineformatting/InlineLineLayout.cpp:
+        (WebCore::Layout::LineLayout::layout):
+        (WebCore::Layout::LineLayout::close):
+        (WebCore::Layout::LineLayout::placeInlineItem):
+        (WebCore::Layout::LineLayout::processUncommittedContent):
+        (WebCore::Layout::LineLayout::shouldProcessUncommittedContent const):
+        * layout/inlineformatting/InlineLineLayout.h:
+        (WebCore::Layout::LineLayout::UncommittedContent::runs):
+        (WebCore::Layout::LineLayout::UncommittedContent::runs const):
+
 2019-10-22  Dean Jackson  <d...@apple.com>
 
         WebCoreDecompressionSession needs padding on all platforms to avoid link warnings

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.cpp (251454 => 251455)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.cpp	2019-10-22 21:03:30 UTC (rev 251454)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.cpp	2019-10-22 21:11:48 UTC (rev 251455)
@@ -35,27 +35,31 @@
 namespace WebCore {
 namespace Layout {
 
-LineBreaker::BreakingContext LineBreaker::breakingContext(const InlineItem& inlineItem, LayoutUnit logicalWidth, const LineContext& lineContext)
+LineBreaker::BreakingBehavior LineBreaker::breakingContext(const Vector<LineLayout::Run>& runs, LayoutUnit logicalWidth, LayoutUnit availableWidth, bool lineIsEmpty)
 {
     // First content always stays on line.
-    if (lineContext.isEmpty || logicalWidth <= lineContext.availableWidth)
-        return { BreakingBehavior::Keep, isAtBreakingOpportunity(inlineItem) };
+    if (lineIsEmpty || logicalWidth <= availableWidth)
+        return BreakingBehavior::Keep;
 
-    if (inlineItem.isHardLineBreak())
-        return { BreakingBehavior::Keep, isAtBreakingOpportunity(inlineItem) };
-
+    // FIXME: Look inside the list to find out whether it requires text content related line breaking (e.g <span>text</span> <- the first inline item here is a 'container start' but the content is text only).
+    auto& inlineItem = runs.first().inlineItem;
     if (is<InlineTextItem>(inlineItem))
-        return { wordBreakingBehavior(downcast<InlineTextItem>(inlineItem), lineContext.isEmpty), isAtBreakingOpportunity(inlineItem) };
+        return wordBreakingBehavior(runs, lineIsEmpty);
 
-    // Wrap non-text boxes to the next line unless we can trim trailing whitespace.
-    auto availableWidth = lineContext.availableWidth + lineContext.trimmableWidth;
-    if (logicalWidth <= availableWidth)
-        return { BreakingBehavior::Keep, isAtBreakingOpportunity(inlineItem) };
-    return { BreakingBehavior::Wrap, isAtBreakingOpportunity(inlineItem) };
+    return BreakingBehavior::Wrap;
 }
 
-LineBreaker::BreakingBehavior LineBreaker::wordBreakingBehavior(const InlineTextItem& inlineItem, bool lineIsEmpty) const
+LineBreaker::BreakingBehavior LineBreaker::breakingContextForFloat(LayoutUnit floatLogicalWidth, LayoutUnit availableWidth, bool lineIsEmpty)
 {
+    return (lineIsEmpty || floatLogicalWidth <= availableWidth) ? BreakingBehavior::Keep : BreakingBehavior::Wrap;
+}
+
+LineBreaker::BreakingBehavior LineBreaker::wordBreakingBehavior(const Vector<LineLayout::Run>& runs, bool lineIsEmpty) const
+{
+    // FIXME: Check where the overflow occurs and use the corresponding style to figure out the breaking behaviour.
+    // <span style="word-break: normal">first</span><span style="word-break: break-all">second</span><span style="word-break: normal">third</span>
+    auto& inlineItem = downcast<InlineTextItem>(runs.first().inlineItem);
+
     // Word breaking behaviour:
     // 1. Whitesapce collapse on -> push whitespace to next line.
     // 2. Whitespace collapse off -> whitespace is split where possible.
@@ -86,16 +90,6 @@
     return lineIsEmpty ? BreakingBehavior::Keep : BreakingBehavior::Wrap;
 }
 
-bool LineBreaker::isAtBreakingOpportunity(const InlineItem& inlineItem)
-{
-    if (inlineItem.isHardLineBreak())
-        return true;
-
-    if (is<InlineTextItem>(inlineItem))
-        return downcast<InlineTextItem>(inlineItem).isWhitespace();
-    return !inlineItem.isFloat() && !inlineItem.isContainerStart() && !inlineItem.isContainerEnd();
 }
-
 }
-}
 #endif

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.h (251454 => 251455)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.h	2019-10-22 21:03:30 UTC (rev 251454)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.h	2019-10-22 21:11:48 UTC (rev 251455)
@@ -27,6 +27,7 @@
 
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
+#include "InlineLineLayout.h"
 #include "LayoutUnit.h"
 
 namespace WebCore {
@@ -38,23 +39,12 @@
 class LineBreaker {
 public:
     enum class BreakingBehavior { Keep, Split, Wrap };
-    struct BreakingContext {
-        BreakingBehavior breakingBehavior;
-        bool isAtBreakingOpportunity { false };
-    };
-    struct LineContext {
-        LayoutUnit availableWidth;
-        LayoutUnit logicalLeft;
-        LayoutUnit trimmableWidth;
-        bool isEmpty { false };
-    };
-    BreakingContext breakingContext(const InlineItem&, LayoutUnit logicalWidth, const LineContext&);
+    BreakingBehavior breakingContext(const Vector<LineLayout::Run>&, LayoutUnit logicalWidth, LayoutUnit availableWidth, bool lineIsEmpty);
+    BreakingBehavior breakingContextForFloat(LayoutUnit floatLogicalWidth, LayoutUnit availableWidth, bool lineIsEmpty);
 
 private:
 
-    BreakingBehavior wordBreakingBehavior(const InlineTextItem&, bool lineIsEmpty) const;
-    bool isAtBreakingOpportunity(const InlineItem&);
-
+    BreakingBehavior wordBreakingBehavior(const Vector<LineLayout::Run>&, bool lineIsEmpty) const;
     bool m_hyphenationIsDisabled { true };
 };
 

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.cpp (251454 => 251455)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.cpp	2019-10-22 21:03:30 UTC (rev 251454)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.cpp	2019-10-22 21:11:48 UTC (rev 251455)
@@ -28,6 +28,7 @@
 
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
+#include "InlineLineBreaker.h"
 #include "LayoutBox.h"
 #include "TextUtil.h"
 
@@ -121,10 +122,13 @@
     }
 
     for (auto inlineItemIndex = firstNonPartialIndex; inlineItemIndex < m_lineInput.inlineItems.size(); ++inlineItemIndex) {
+        // FIXME: We should not need to re-measure the dropped, uncommitted content when re-using them on the next line.
         if (placeInlineItem(*m_lineInput.inlineItems[inlineItemIndex]) == IsEndOfLine::Yes)
             return close();
     }
-    commitPendingContent();
+    // Check the uncommitted content whether they fit now that we know we are at a commit boundary.
+    if (!m_uncommittedContent.isEmpty())
+        processUncommittedContent();
     return close();
 }
 
@@ -141,6 +145,7 @@
 LineLayout::LineContent LineLayout::close()
 {
     ASSERT(m_committedInlineItemCount || m_lineHasIntrusiveFloat);
+    m_uncommittedContent.reset();
     if (!m_committedInlineItemCount)
         return LineContent { WTF::nullopt, WTFMove(m_floats), m_line.close(), m_line.lineBox() };
 
@@ -155,53 +160,151 @@
 
 LineLayout::IsEndOfLine LineLayout::placeInlineItem(const InlineItem& inlineItem)
 {
-    auto availableWidth = m_line.availableWidth() - m_uncommittedContent.width();
-    auto currentLogicalRight = m_line.lineBox().logicalRight() + m_uncommittedContent.width();
+    auto currentLogicalRight = m_line.lineBox().logicalRight();
     auto itemLogicalWidth = inlineItemWidth(formattingContext(), inlineItem, currentLogicalRight);
-
-    // FIXME: Ensure LineContext::trimmableWidth includes uncommitted content if needed.
     auto lineIsConsideredEmpty = !m_line.hasContent() && !m_lineHasIntrusiveFloat;
-    auto breakingContext = m_lineBreaker.breakingContext(inlineItem, itemLogicalWidth, { availableWidth, currentLogicalRight, m_line.trailingTrimmableWidth(), lineIsConsideredEmpty });
-    if (breakingContext.isAtBreakingOpportunity)
-        commitPendingContent();
 
-    // Content does not fit the current line.
-    if (breakingContext.breakingBehavior == LineBreaker::BreakingBehavior::Wrap)
-        return IsEndOfLine::Yes;
+    // Floats are special, they are intrusive but they don't really participate in the line layout context.
+    if (inlineItem.isFloat()) {
+        // FIXME: It gets a bit more complicated when there's some uncommitted content whether they should be added to the current line
+        // e.g. text_content<div style="float: left"></div>continuous_text_content
+        // Not sure what to do when the float takes up the available space and we've got continuous content. Browser engines don't agree.
+        // Let's just commit the pending content and try placing the float for now.
+        if (!m_uncommittedContent.isEmpty()) {
+            if (processUncommittedContent() == IsEndOfLine::Yes)
+                return IsEndOfLine::Yes;
+        }
+        auto breakingBehavior = LineBreaker().breakingContextForFloat(itemLogicalWidth, m_line.availableWidth() + m_line.trailingTrimmableWidth(), lineIsConsideredEmpty);
+        ASSERT(breakingBehavior != LineBreaker::BreakingBehavior::Split);
+        if (breakingBehavior == LineBreaker::BreakingBehavior::Wrap)
+            return IsEndOfLine::Yes;
 
-    // Partial content stays on the current line.
-    if (breakingContext.breakingBehavior == LineBreaker::BreakingBehavior::Split) {
-        ASSERT(inlineItem.isText());
-        auto& inlineTextItem = downcast<InlineTextItem>(inlineItem);
-        auto splitData = TextUtil::split(inlineTextItem.layoutBox(), inlineTextItem.start(), inlineTextItem.length(), itemLogicalWidth, availableWidth, currentLogicalRight);
-        // Construct a partial trailing inline item.
-        ASSERT(!m_trailingPartialInlineTextItem);
-        m_trailingPartialInlineTextItem = inlineTextItem.split(splitData.start, splitData.length);
-        m_uncommittedContent.add(*m_trailingPartialInlineTextItem, splitData.logicalWidth);
-        commitPendingContent();
-        return IsEndOfLine::Yes;
-    }
-
-    ASSERT(breakingContext.breakingBehavior == LineBreaker::BreakingBehavior::Keep);
-    if (inlineItem.isFloat()) {
+        // This float can sit on the current line.
         auto& floatBox = inlineItem.layoutBox();
         // Shrink available space for current line and move existing inline runs.
-        auto floatBoxWidth = formattingContext().geometryForBox(floatBox).marginBoxWidth();
-        floatBox.isLeftFloatingPositioned() ? m_line.moveLogicalLeft(floatBoxWidth) : m_line.moveLogicalRight(floatBoxWidth);
+        floatBox.isLeftFloatingPositioned() ? m_line.moveLogicalLeft(itemLogicalWidth) : m_line.moveLogicalRight(itemLogicalWidth);
         m_floats.append(makeWeakPtr(inlineItem));
         ++m_committedInlineItemCount;
         m_lineHasIntrusiveFloat = true;
         return IsEndOfLine::No;
     }
+    // Explicit line breaks are also special.
+    if (inlineItem.isHardLineBreak()) {
+        auto isEndOfLine = !m_uncommittedContent.isEmpty() ? processUncommittedContent() : IsEndOfLine::No;
+        // When the uncommitted content fits(or the line is empty), add the line break to this line as well.
+        if (isEndOfLine == IsEndOfLine::No) {
+            m_uncommittedContent.add(inlineItem, itemLogicalWidth);
+            commitPendingContent();
+        }
+        return IsEndOfLine::Yes;
+    }
+    //
+    auto isEndOfLine = IsEndOfLine::No;
+    if (!m_uncommittedContent.isEmpty() && shouldProcessUncommittedContent(inlineItem))
+        isEndOfLine = processUncommittedContent();
+    // The current item might fit as well.
+    if (isEndOfLine == IsEndOfLine::No)
+        m_uncommittedContent.add(inlineItem, itemLogicalWidth);
+    return isEndOfLine;
+}
 
-    m_uncommittedContent.add(inlineItem, itemLogicalWidth);
-    if (breakingContext.isAtBreakingOpportunity)
+LineLayout::IsEndOfLine LineLayout::processUncommittedContent()
+{
+    // Check if the pending content fits.
+    auto lineIsConsideredEmpty = !m_line.hasContent() && !m_lineHasIntrusiveFloat;
+    auto breakingBehavior = LineBreaker().breakingContext(m_uncommittedContent.runs(), m_uncommittedContent.width(), m_line.availableWidth(), lineIsConsideredEmpty);
+
+    // The uncommitted content can fully, partially fit the current line (commit/partial commit) or not at all (reset).
+    if (breakingBehavior == LineBreaker::BreakingBehavior::Keep)
         commitPendingContent();
+    else if (breakingBehavior == LineBreaker::BreakingBehavior::Split)
+        ASSERT_NOT_IMPLEMENTED_YET();
+    else if (breakingBehavior == LineBreaker::BreakingBehavior::Wrap)
+        m_uncommittedContent.reset();
 
-    return inlineItem.isHardLineBreak() ? IsEndOfLine::Yes : IsEndOfLine::No;
+    return breakingBehavior == LineBreaker::BreakingBehavior::Keep ? IsEndOfLine::No :IsEndOfLine::Yes;
 }
 
+bool LineLayout::shouldProcessUncommittedContent(const InlineItem& inlineItem) const
+{
+    // Figure out if the new incoming content puts the uncommitted content on commit boundary.
+    // e.g. <span>continuous</span> <- uncomitted content ->
+    // [inline container start][text content][inline container end]
+    // An incoming <img> box would enable us to commit the "<span>continuous</span>" content
+    // while additional text content would not.
+    ASSERT(!inlineItem.isFloat() && !inlineItem.isHardLineBreak());
+    ASSERT(!m_uncommittedContent.isEmpty());
+
+    auto* lastUncomittedContent = &m_uncommittedContent.runs().last().inlineItem;
+    if (inlineItem.isText()) {
+        // any content' ' -> whitespace is always a commit boundary.
+        if (downcast<InlineTextItem>(inlineItem).isWhitespace())
+            return true;
+        // <span>text -> the inline container start and the text content form an unbreakable continuous content.
+        if (lastUncomittedContent->isContainerStart())
+            return false;
+        // </span>text -> need to check what's before the </span>.
+        // text</span>text -> continuous content
+        // <img></span>text -> commit bounday
+        if (lastUncomittedContent->isContainerEnd()) {
+            auto& runs = m_uncommittedContent.runs();
+            // text</span><span></span></span>text -> check all the way back until we hit either a box or some text
+            for (auto i = m_uncommittedContent.size(); i--;) {
+                auto& previousInlineItem = runs[i].inlineItem;
+                if (previousInlineItem.isContainerStart() || previousInlineItem.isContainerEnd())
+                    continue;
+                ASSERT(previousInlineItem.isText() || previousInlineItem.isBox());
+                lastUncomittedContent = &previousInlineItem;
+                break;
+            }
+            // Did not find any content (e.g. <span></span>text)
+            if (lastUncomittedContent->isContainerEnd())
+                return false;
+        }
+        // texttext -> continuous content.
+        // ' 'text -> commit boundary.
+        if (lastUncomittedContent->isText())
+            return downcast<InlineTextItem>(*lastUncomittedContent).isWhitespace();
+        // <img>text -> the inline box is on a commit boundary.
+        if (lastUncomittedContent->isBox())
+            return true;
+        ASSERT_NOT_REACHED();
+    }
+
+    if (inlineItem.isBox()) {
+        // <span><img> -> the inline container start and the content form an unbreakable continuous content.
+        if (lastUncomittedContent->isContainerStart())
+            return false;
+        // </span><img> -> ok to commit the </span>.
+        if (lastUncomittedContent->isContainerEnd())
+            return true;
+        // <img>text and <img><img> -> these combinations are ok to commit.
+        if (lastUncomittedContent->isText() || lastUncomittedContent->isBox())
+            return true;
+        ASSERT_NOT_REACHED();
+    }
+
+    if (inlineItem.isContainerStart() || inlineItem.isContainerEnd()) {
+        // <span><span> or </span><span> -> can't commit the previous content yet.
+        if (lastUncomittedContent->isContainerStart() || lastUncomittedContent->isContainerEnd())
+            return false;
+        // ' '<span> -> let's commit the whitespace
+        // text<span> -> but not yet the non-whitespace; we need to know what comes next (e.g. text<span>text or text<span><img>).
+        if (lastUncomittedContent->isText())
+            return downcast<InlineTextItem>(*lastUncomittedContent).isWhitespace();
+        // <img><span> -> it's ok to commit the inline box content.
+        // <img></span> -> the inline box and the closing inline container form an unbreakable continuous content.
+        if (lastUncomittedContent->isBox())
+            return inlineItem.isContainerStart();
+        ASSERT_NOT_REACHED();
+    }
+
+    ASSERT_NOT_REACHED();
+    return true;
 }
+
+
 }
+}
 
 #endif

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.h (251454 => 251455)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.h	2019-10-22 21:03:30 UTC (rev 251454)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.h	2019-10-22 21:11:48 UTC (rev 251455)
@@ -28,7 +28,6 @@
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
 #include "InlineLine.h"
-#include "InlineLineBreaker.h"
 #include <wtf/IsoMalloc.h>
 
 namespace WebCore {
@@ -71,6 +70,11 @@
         const LineBox lineBox;
     };
 
+    struct Run {
+        const InlineItem& inlineItem;
+        LayoutUnit logicalWidth;
+    };
+
 private:
     const InlineFormattingContext& formattingContext() const { return m_inlineFormattingContext; }
     enum class IsEndOfLine { No, Yes };
@@ -77,16 +81,15 @@
     IsEndOfLine placeInlineItem(const InlineItem&);
     void commitPendingContent();
     LineContent close();
+    bool shouldProcessUncommittedContent(const InlineItem&) const;
+    IsEndOfLine processUncommittedContent();
     
     struct UncommittedContent {
-        struct Run {
-            const InlineItem& inlineItem;
-            LayoutUnit logicalWidth;
-        };
         void add(const InlineItem&, LayoutUnit logicalWidth);
         void reset();
 
-        Vector<Run> runs() { return m_uncommittedRuns; }
+        Vector<Run>& runs() { return m_uncommittedRuns; }
+        const Vector<Run>& runs() const { return m_uncommittedRuns; }
         bool isEmpty() const { return m_uncommittedRuns.isEmpty(); }
         unsigned size() const { return m_uncommittedRuns.size(); }
         LayoutUnit width() const { return m_width; }
@@ -99,7 +102,6 @@
     const InlineFormattingContext& m_inlineFormattingContext;
     const LineInput& m_lineInput;
     Line m_line;
-    LineBreaker m_lineBreaker;
     bool m_lineHasIntrusiveFloat { false };
     UncommittedContent m_uncommittedContent;
     unsigned m_committedInlineItemCount { 0 };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to