Title: [245812] trunk/Source/WebCore
Revision
245812
Author
[email protected]
Date
2019-05-28 08:36:04 -0700 (Tue, 28 May 2019)

Log Message

[LFC][IFC] Decouple line layout and processing inline runs.
https://bugs.webkit.org/show_bug.cgi?id=198282
<rdar://problem/51167954>

Reviewed by Antti Koivisto.

This is in preparation for using "createInlineRunsForLine" logic when computing preferred width.

* layout/inlineformatting/InlineFormattingContext.h:
* layout/inlineformatting/InlineFormattingContextLineLayout.cpp:
(WebCore::Layout::UncommittedContent::size const):
(WebCore::Layout::InlineFormattingContext::LineLayout::createInlineRunsForLine const):
(WebCore::Layout::InlineFormattingContext::LineLayout::layout const):
(WebCore::Layout::InlineFormattingContext::LineLayout::processInlineRuns const):
(WebCore::Layout::InlineFormattingContext::LineLayout::closeLine const): Deleted.
* layout/inlineformatting/InlineFormattingState.h:
(WebCore::Layout::InlineFormattingState::addInlineItem):
* layout/inlineformatting/InlineTextItem.cpp:
(WebCore::Layout::InlineTextItem::createAndAppendTextItems):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (245811 => 245812)


--- trunk/Source/WebCore/ChangeLog	2019-05-28 14:51:16 UTC (rev 245811)
+++ trunk/Source/WebCore/ChangeLog	2019-05-28 15:36:04 UTC (rev 245812)
@@ -1,5 +1,27 @@
 2019-05-28  Zalan Bujtas  <[email protected]>
 
+        [LFC][IFC] Decouple line layout and processing inline runs.
+        https://bugs.webkit.org/show_bug.cgi?id=198282
+        <rdar://problem/51167954>
+
+        Reviewed by Antti Koivisto.
+
+        This is in preparation for using "createInlineRunsForLine" logic when computing preferred width.
+
+        * layout/inlineformatting/InlineFormattingContext.h:
+        * layout/inlineformatting/InlineFormattingContextLineLayout.cpp:
+        (WebCore::Layout::UncommittedContent::size const):
+        (WebCore::Layout::InlineFormattingContext::LineLayout::createInlineRunsForLine const):
+        (WebCore::Layout::InlineFormattingContext::LineLayout::layout const):
+        (WebCore::Layout::InlineFormattingContext::LineLayout::processInlineRuns const):
+        (WebCore::Layout::InlineFormattingContext::LineLayout::closeLine const): Deleted.
+        * layout/inlineformatting/InlineFormattingState.h:
+        (WebCore::Layout::InlineFormattingState::addInlineItem):
+        * layout/inlineformatting/InlineTextItem.cpp:
+        (WebCore::Layout::InlineTextItem::createAndAppendTextItems):
+
+2019-05-28  Zalan Bujtas  <[email protected]>
+
         [LFC][IFC] Move intrinsic width computation from InlineFormattingContext to LineLayout
         https://bugs.webkit.org/show_bug.cgi?id=198258
 

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h (245811 => 245812)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h	2019-05-28 14:51:16 UTC (rev 245811)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h	2019-05-28 15:36:04 UTC (rev 245812)
@@ -59,7 +59,8 @@
     private:
         LayoutState& layoutState() const { return m_formattingContext.layoutState(); }
         void initializeLine(Line&, LayoutUnit lineLogicalTop, LayoutUnit widthConstraint) const;
-        void closeLine(Line&) const;
+        unsigned createInlineRunsForLine(Line&, unsigned firstInlineItemIndex) const;
+        void processInlineRuns(Line&) const;
         void commitInlineItemToLine(Line&, const InlineItem&) const;
         void handleFloat(Line&, const FloatingContext&, const InlineItem& floatBox) const;
         void alignRuns(TextAlignMode, unsigned firstRunIndex, LayoutUnit availableWidth) const;

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextLineLayout.cpp (245811 => 245812)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextLineLayout.cpp	2019-05-28 14:51:16 UTC (rev 245811)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextLineLayout.cpp	2019-05-28 15:36:04 UTC (rev 245812)
@@ -336,6 +336,7 @@
 
     Vector<InlineItem*> inlineItems() { return m_inlineItems; }
     bool isEmpty() const { return m_inlineItems.isEmpty(); }
+    unsigned size() const { return m_inlineItems.size(); }
     LayoutUnit width() const { return m_width; }
 
 private:
@@ -398,65 +399,80 @@
     line.reset({ lineLogicalLeft, lineLogicalTop }, availableWidth, mimimumLineHeight, baselineOffset);
 }
 
-void InlineFormattingContext::LineLayout::layout(LayoutUnit widthConstraint) const
+unsigned InlineFormattingContext::LineLayout::createInlineRunsForLine(Line& line, unsigned startInlineItemIndex) const
 {
     auto floatingContext = FloatingContext { m_floatingState };
-    Line line(layoutState());
-    initializeLine(line, layoutState().displayBoxForLayoutBox(m_formattingRoot).contentBoxTop(), widthConstraint);
+    Optional<unsigned> lastCommittedIndex;
 
     UncommittedContent uncommittedContent;
     auto commitPendingContent = [&] {
+        if (uncommittedContent.isEmpty())
+            return;
+
+        lastCommittedIndex = lastCommittedIndex.valueOr(startInlineItemIndex) + uncommittedContent.size();
         for (auto* uncommitted : uncommittedContent.inlineItems())
             commitInlineItemToLine(line, *uncommitted);
         uncommittedContent.reset();
     };
 
-    auto closeCurrentAndInitializeNewLine = [&] {
-        closeLine(line);
-        initializeLine(line, line.logicalBottom(), widthConstraint);
-    };
-
     LineBreaker lineBreaker(layoutState());
+    // Iterate through the inline content and place the inline boxes on the current line.
     auto& inlineContent = m_formattingState.inlineItems();
-    for (auto& inlineItem : inlineContent) {
-        // Iterate through the inline content and try to put the inline boxes on the current line.
+    for (auto inlineItemIndex = startInlineItemIndex; inlineItemIndex < inlineContent.size(); ++inlineItemIndex) {
+        auto& inlineItem = inlineContent[inlineItemIndex];
         if (inlineItem->isHardLineBreak()) {
+            uncommittedContent.add(*inlineItem);
             commitPendingContent();
-            commitInlineItemToLine(line, *inlineItem);
-            closeCurrentAndInitializeNewLine();
-        } else {
-            auto availableWidth = line.availableWidth() - uncommittedContent.width();
-            auto currentLogicalRight = line.contentLogicalRight() + uncommittedContent.width();
-            // FIXME: Ensure LineContext::trimmableWidth includes uncommitted content if needed.
-            auto breakingContext = lineBreaker.breakingContext(*inlineItem, { availableWidth, currentLogicalRight, line.trailingTrimmableWidth(), !line.hasContent() });
-            if (breakingContext.isAtBreakingOpportunity)
-                commitPendingContent();
+            return *lastCommittedIndex;
+        }
+        auto availableWidth = line.availableWidth() - uncommittedContent.width();
+        auto currentLogicalRight = line.contentLogicalRight() + uncommittedContent.width();
+        // FIXME: Ensure LineContext::trimmableWidth includes uncommitted content if needed.
+        auto breakingContext = lineBreaker.breakingContext(*inlineItem, { availableWidth, currentLogicalRight, line.trailingTrimmableWidth(), !line.hasContent() });
+        if (breakingContext.isAtBreakingOpportunity)
+            commitPendingContent();
 
-            if (breakingContext.breakingBehavior == LineBreaker::BreakingBehavior::Break) {
-                ASSERT_NOT_IMPLEMENTED_YET();
-                continue;
-            }
+        // Content does not fit the current line.
+        if (breakingContext.breakingBehavior == LineBreaker::BreakingBehavior::Wrap)
+            return *lastCommittedIndex;
 
-            if (breakingContext.breakingBehavior == LineBreaker::BreakingBehavior::Wrap)
-                closeCurrentAndInitializeNewLine();
+        // Partial content stays on the current line. 
+        if (breakingContext.breakingBehavior == LineBreaker::BreakingBehavior::Break) {
+            ASSERT(inlineItem->isText());
 
-            if (inlineItem->isFloat())
-                handleFloat(line, floatingContext, *inlineItem);
-            else {
-                if (breakingContext.isAtBreakingOpportunity)
-                    commitInlineItemToLine(line, *inlineItem);
-                else
-                    uncommittedContent.add(*inlineItem);
-            }
+            ASSERT_NOT_IMPLEMENTED_YET();
+            return *lastCommittedIndex;
         }
+
+        if (inlineItem->isFloat()) {
+            handleFloat(line, floatingContext, *inlineItem);
+            continue;
+        }
+
+        uncommittedContent.add(*inlineItem);
+        if (breakingContext.isAtBreakingOpportunity)
+            commitPendingContent();
     }
-    // Process remaining uncommitted content.
-    if (!uncommittedContent.isEmpty()) {
-        if (line.availableWidth() < uncommittedContent.width())
-            closeCurrentAndInitializeNewLine();
-        commitPendingContent();
+    commitPendingContent();
+    return *lastCommittedIndex;
+}
+
+void InlineFormattingContext::LineLayout::layout(LayoutUnit widthConstraint) const
+{
+    ASSERT(!m_formattingState.inlineItems().isEmpty());
+
+    Line line(layoutState());
+    initializeLine(line, layoutState().displayBoxForLayoutBox(m_formattingRoot).contentBoxTop(), widthConstraint);
+
+    unsigned startInlineItemIndex = 0;
+    while (true) {
+        auto nextInlineItemIndex = createInlineRunsForLine(line, startInlineItemIndex);
+        processInlineRuns(line);
+        if (nextInlineItemIndex == m_formattingState.inlineItems().size())
+            break;
+        startInlineItemIndex = nextInlineItemIndex;
+        initializeLine(line, line.logicalBottom(), widthConstraint);
     }
-    closeLine(line);
 }
 
 LayoutUnit InlineFormattingContext::LineLayout::computedIntrinsicWidth(LayoutUnit widthConstraint) const
@@ -487,7 +503,7 @@
     return std::max(maximumLineWidth, lineLogicalRight - trimmableTrailingWidth);
 }
 
-void InlineFormattingContext::LineLayout::closeLine(Line& line) const
+void InlineFormattingContext::LineLayout::processInlineRuns(Line& line) const
 {
     auto& lineItems = line.close();
     if (lineItems.isEmpty()) {

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingState.h (245811 => 245812)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingState.h	2019-05-28 14:51:16 UTC (rev 245811)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingState.h	2019-05-28 15:36:04 UTC (rev 245812)
@@ -38,7 +38,7 @@
 namespace Layout {
 
 // Temp
-using InlineItems = ListHashSet<std::unique_ptr<InlineItem>>;
+using InlineItems = Vector<std::unique_ptr<InlineItem>>;
 using InlineRuns = Vector<std::unique_ptr<Display::Run>>;
 using LineBoxes = Vector<LineBox>;
 // InlineFormattingState holds the state for a particular inline formatting context tree.
@@ -54,7 +54,7 @@
     InlineRuns& inlineRuns() { return m_inlineRuns; }
     LineBoxes& lineBoxes() { return m_lineBoxes; }
 
-    void addInlineItem(std::unique_ptr<InlineItem>&& inlineItem) { m_inlineItems.add(WTFMove(inlineItem)); }
+    void addInlineItem(std::unique_ptr<InlineItem>&& inlineItem) { m_inlineItems.append(WTFMove(inlineItem)); }
     void addInlineRun(std::unique_ptr<Display::Run>&& inlineRun) { m_inlineRuns.append(WTFMove(inlineRun)); }
     void addLineBox(LineBox lineBox) { m_lineBoxes.append(lineBox); }
 

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineTextItem.cpp (245811 => 245812)


--- trunk/Source/WebCore/layout/inlineformatting/InlineTextItem.cpp	2019-05-28 14:51:16 UTC (rev 245811)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineTextItem.cpp	2019-05-28 15:36:04 UTC (rev 245812)
@@ -98,7 +98,7 @@
     while (currentPosition < text.length()) {
         // Soft linebreak?
         if (isSoftLineBreak(text[currentPosition], preserveNewline)) {
-            inlineContent.add(std::make_unique<InlineTextItem>(inlineBox, currentPosition, 1, true, false));
+            inlineContent.append(std::make_unique<InlineTextItem>(inlineBox, currentPosition, 1, true, false));
             ++currentPosition;
             continue;
         }
@@ -105,13 +105,13 @@
         if (isWhitespaceCharacter(text[currentPosition], preserveNewline)) {
             auto length = moveToNextNonWhitespacePosition(text, currentPosition, preserveNewline);
             auto isCollapsed = collapseWhiteSpace && length > 1;
-            inlineContent.add(std::make_unique<InlineTextItem>(inlineBox, currentPosition, length, true, isCollapsed));
+            inlineContent.append(std::make_unique<InlineTextItem>(inlineBox, currentPosition, length, true, isCollapsed));
             currentPosition += length;
             continue;
         }
 
         auto length = moveToNextBreakablePosition(currentPosition, lineBreakIterator, style);
-        inlineContent.add(std::make_unique<InlineTextItem>(inlineBox, currentPosition, length, false, false));
+        inlineContent.append(std::make_unique<InlineTextItem>(inlineBox, currentPosition, length, false, false));
         currentPosition += length;
     }
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to