Title: [254837] trunk/Source/WebCore
Revision
254837
Author
[email protected]
Date
2020-01-20 15:32:51 -0800 (Mon, 20 Jan 2020)

Log Message

[LFC][IFC] InlineFormattingContext::lineLayout should take a InlineItem range
https://bugs.webkit.org/show_bug.cgi?id=206507
<rdar://problem/58742468>

Reviewed by Antti Koivisto.

This is in preparation for being able to run inline layout on partial IFC content.

* layout/inlineformatting/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::layoutInFlowContent):
(WebCore::Layout::InlineFormattingContext::lineLayout):
(WebCore::Layout::InlineFormattingContext::computedIntrinsicWidthForConstraint const):
* layout/inlineformatting/InlineFormattingContext.h:
* layout/inlineformatting/LineLayoutContext.cpp:
(WebCore::Layout::nextWrapOpportunity):
(WebCore::Layout::LineLayoutContext::layoutLine):
(WebCore::Layout::LineLayoutContext::close):
(WebCore::Layout::LineLayoutContext::nextContentForLine):
* layout/inlineformatting/LineLayoutContext.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (254836 => 254837)


--- trunk/Source/WebCore/ChangeLog	2020-01-20 21:21:18 UTC (rev 254836)
+++ trunk/Source/WebCore/ChangeLog	2020-01-20 23:32:51 UTC (rev 254837)
@@ -1,3 +1,25 @@
+2020-01-20  Zalan Bujtas  <[email protected]>
+
+        [LFC][IFC] InlineFormattingContext::lineLayout should take a InlineItem range
+        https://bugs.webkit.org/show_bug.cgi?id=206507
+        <rdar://problem/58742468>
+
+        Reviewed by Antti Koivisto.
+
+        This is in preparation for being able to run inline layout on partial IFC content.
+
+        * layout/inlineformatting/InlineFormattingContext.cpp:
+        (WebCore::Layout::InlineFormattingContext::layoutInFlowContent):
+        (WebCore::Layout::InlineFormattingContext::lineLayout):
+        (WebCore::Layout::InlineFormattingContext::computedIntrinsicWidthForConstraint const):
+        * layout/inlineformatting/InlineFormattingContext.h:
+        * layout/inlineformatting/LineLayoutContext.cpp:
+        (WebCore::Layout::nextWrapOpportunity):
+        (WebCore::Layout::LineLayoutContext::layoutLine):
+        (WebCore::Layout::LineLayoutContext::close):
+        (WebCore::Layout::LineLayoutContext::nextContentForLine):
+        * layout/inlineformatting/LineLayoutContext.h:
+
 2020-01-20  David Kilzer  <[email protected]>
 
         Fix missing header guards and clean up empty files in WebCore, WebKitLegacy, WebKit, Tools

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp (254836 => 254837)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp	2020-01-20 21:21:18 UTC (rev 254836)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp	2020-01-20 23:32:51 UTC (rev 254837)
@@ -85,22 +85,22 @@
     }
 
     collectInlineContentIfNeeded();
-    lineLayout(horizontalConstraints, verticalConstraints);
+
+    auto& inlineItems = formattingState().inlineItems();
+    lineLayout(inlineItems, { 0, inlineItems.size() }, horizontalConstraints, verticalConstraints);
     LOG_WITH_STREAM(FormattingContextLayout, stream << "[End] -> inline formatting context -> formatting root(" << &root() << ")");
 }
 
-void InlineFormattingContext::lineLayout(const HorizontalConstraints& horizontalConstraints, const VerticalConstraints& verticalConstraints)
+void InlineFormattingContext::lineLayout(InlineItems& inlineItems, LineLayoutContext::InlineItemRange layoutRange, const HorizontalConstraints& horizontalConstraints, const VerticalConstraints& verticalConstraints)
 {
-    auto& inlineItems = formattingState().inlineItems();
     auto lineLogicalTop = verticalConstraints.logicalTop;
-    unsigned leadingInlineItemIndex = 0;
     Optional<unsigned> partialLeadingContentLength;
     auto lineBuilder = LineBuilder { *this, root().style().textAlign(), LineBuilder::IntrinsicSizing::No };
     auto lineLayoutContext = LineLayoutContext { *this, root(), inlineItems };
 
-    while (leadingInlineItemIndex < inlineItems.size()) {
+    while (!layoutRange.isEmpty()) {
         lineBuilder.initialize(constraintsForLine(horizontalConstraints, lineLogicalTop));
-        auto lineContent = lineLayoutContext.layoutLine(lineBuilder, leadingInlineItemIndex, partialLeadingContentLength);
+        auto lineContent = lineLayoutContext.layoutLine(lineBuilder, layoutRange, partialLeadingContentLength);
         setDisplayBoxesForLine(lineContent, horizontalConstraints);
 
         partialLeadingContentLength = { };
@@ -108,12 +108,12 @@
             lineLogicalTop = lineContent.lineBox.logicalBottom();
             // When the trailing content is partial, we need to reuse the last InlinItem.
             if (lineContent.partialContent) {
-                leadingInlineItemIndex = *lineContent.trailingInlineItemIndex;
+                layoutRange.start = *lineContent.trailingInlineItemIndex;
                 // Turn previous line's overflow content length into the next line's leading content partial length.
                 // "sp<->litcontent" -> overflow length: 10 -> leading partial content length: 10. 
                 partialLeadingContentLength = lineContent.partialContent->overflowContentLength;
             } else
-                leadingInlineItemIndex = *lineContent.trailingInlineItemIndex + 1;
+                layoutRange.start = *lineContent.trailingInlineItemIndex + 1;
             continue;
         }
         // Floats prevented us placing any content on the line.
@@ -233,16 +233,16 @@
 InlineLayoutUnit InlineFormattingContext::computedIntrinsicWidthForConstraint(const HorizontalConstraints& horizontalConstraints) const
 {
     auto& inlineItems = formattingState().inlineItems();
-    InlineLayoutUnit maximumLineWidth = 0;
-    unsigned leadingInlineItemIndex = 0;
+    auto maximumLineWidth = InlineLayoutUnit { };
     auto lineBuilder = LineBuilder { *this, root().style().textAlign(), LineBuilder::IntrinsicSizing::Yes };
     auto lineLayoutContext = LineLayoutContext { *this, root(), inlineItems };
-    while (leadingInlineItemIndex < inlineItems.size()) {
+    auto layoutRange = LineLayoutContext::InlineItemRange { 0 , inlineItems.size() };
+    while (!layoutRange.isEmpty()) {
         // Only the horiztonal available width is constrained when computing intrinsic width.
         lineBuilder.initialize(LineBuilder::Constraints { { }, horizontalConstraints.logicalWidth, false, { } });
-        auto lineContent = lineLayoutContext.layoutLine(lineBuilder, leadingInlineItemIndex, { });
+        auto lineContent = lineLayoutContext.layoutLine(lineBuilder, layoutRange , { });
 
-        leadingInlineItemIndex = *lineContent.trailingInlineItemIndex + 1;
+        layoutRange.start = *lineContent.trailingInlineItemIndex + 1;
         InlineLayoutUnit floatsWidth = 0;
         for (auto& floatItem : lineContent.floats)
             floatsWidth += geometryForBox(floatItem->layoutBox()).marginBoxWidth();

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h (254836 => 254837)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h	2020-01-20 21:21:18 UTC (rev 254836)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h	2020-01-20 23:32:51 UTC (rev 254837)
@@ -77,7 +77,7 @@
     };
     InlineFormattingContext::Geometry geometry() const { return Geometry(*this); }
 
-    void lineLayout(const HorizontalConstraints&, const VerticalConstraints&);
+    void lineLayout(InlineItems&, LineLayoutContext::InlineItemRange, const HorizontalConstraints&, const VerticalConstraints&);
     void layoutFormattingContextRoot(const Box&, InvalidationState&, const HorizontalConstraints&, const VerticalConstraints&);
     void computeHorizontalAndVerticalGeometry(const Box&, const HorizontalConstraints&);
 

Modified: trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.cpp (254836 => 254837)


--- trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.cpp	2020-01-20 21:21:18 UTC (rev 254836)
+++ trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.cpp	2020-01-20 23:32:51 UTC (rev 254837)
@@ -105,7 +105,7 @@
     return true;
 }
 
-static inline size_t nextWrapOpportunity(const InlineItems& inlineContent, unsigned startIndex)
+static inline size_t nextWrapOpportunity(const InlineItems& inlineContent, size_t startIndex, const LineLayoutContext::InlineItemRange layoutRange)
 {
     // 1. Find the start candidate by skipping leading non-content items e.g <span><span>start : skip "<span><span>"
     // 2. Find the end candidate by skipping non-content items inbetween e.g. <span><span>start</span>end: skip "</span>"
@@ -115,12 +115,11 @@
     // [ex-][container start][container end][float][ample] (ex-<span></span><div style="float:left"></div>ample) : wrap index is at [ex-].
     // [ex][container start][amp-][container start][le] (ex<span>amp-<span>ample) : wrap index is at [amp-].
     // [ex-][container start][line break][ample] (ex-<span><br>ample) : wrap index is after [br].
-    unsigned inlineItemCount = inlineContent.size();
     auto isAtLineBreak = false;
 
     auto inlineItemIndexWithContent = [&] (auto index) {
         // Break at the first text/box/line break inline item.
-        for (; index < inlineItemCount; ++index) {
+        for (; index < layoutRange.end; ++index) {
             auto& inlineItem = inlineContent[index];
             if (inlineItem.isText() || inlineItem.isBox())
                 return index;
@@ -129,7 +128,7 @@
                 return index;
             }
         }
-        return inlineItemCount;
+        return layoutRange.end;
     };
 
     // Start at the first inline item with content.
@@ -140,11 +139,11 @@
         return startContentIndex + 1;
     }
 
-    while (startContentIndex < inlineItemCount) {
+    while (startContentIndex < layoutRange.end) {
         // 1. Find the next inline item with content.
         // 2. Check if there's a soft wrap opportunity between the start and the next inline item.
         auto nextContentIndex = inlineItemIndexWithContent(startContentIndex + 1);
-        if (nextContentIndex == inlineItemCount)
+        if (nextContentIndex == layoutRange.end)
             return nextContentIndex;
         if (isAtLineBreak) {
             // We always stop at line breaks. The wrap position is after the line break.
@@ -169,7 +168,7 @@
         }
         startContentIndex = nextContentIndex;
     }
-    return inlineItemCount;
+    return layoutRange.end;
 }
 
 struct LineCandidateContent {
@@ -253,7 +252,7 @@
 {
 }
 
-LineLayoutContext::LineContent LineLayoutContext::layoutLine(LineBuilder& line, unsigned leadingInlineItemIndex, Optional<unsigned> partialLeadingContentLength)
+LineLayoutContext::LineContent LineLayoutContext::layoutLine(LineBuilder& line, const InlineItemRange layoutRange, Optional<unsigned> partialLeadingContentLength)
 {
     auto reset = [&] {
         ASSERT(m_floats.isEmpty());
@@ -262,15 +261,15 @@
     };
     reset();
     auto lineBreaker = LineBreaker { };
-    auto currentItemIndex = leadingInlineItemIndex;
+    auto currentItemIndex = layoutRange.start;
     unsigned committedInlineItemCount = 0;
     auto candidateContent = LineCandidateContent { };
-    while (currentItemIndex < m_inlineItems.size()) {
+    while (currentItemIndex < layoutRange.end) {
         // 1. Collect the set of runs that we can commit to the line as one entity e.g. <span>text_and_span_start_span_end</span>.
         // 2. Apply floats and shrink the available horizontal space e.g. <span>intru_<div style="float: left"></div>sive_float</span>.
         // 3. Check if the content fits the line and commit the content accordingly (full, partial or not commit at all).
         // 4. Return if we are at the end of the line either by not being able to fit more content or because of an explicit line break.
-        nextContentForLine(candidateContent, currentItemIndex, partialLeadingContentLength, line.lineBox().logicalWidth());
+        nextContentForLine(candidateContent, currentItemIndex, layoutRange, partialLeadingContentLength, line.lineBox().logicalWidth());
         if (candidateContent.hasIntrusiveFloats()) {
             // Add floats first because they shrink the available horizontal space for the rest of the content.
             auto result = tryAddingFloatItems(line, candidateContent.floats());
@@ -277,7 +276,7 @@
             committedInlineItemCount += result.committedCount;
             if (result.isEndOfLine == LineBreaker::IsEndOfLine::Yes) {
                 // Floats take up all the horizontal space.
-                return close(line, leadingInlineItemIndex, committedInlineItemCount, { });
+                return close(line, layoutRange, committedInlineItemCount, { });
             }
         }
         if (!candidateContent.inlineRuns().isEmpty()) {
@@ -287,25 +286,25 @@
                 ASSERT(!result.committedCount);
                 ASSERT(result.isEndOfLine == LineBreaker::IsEndOfLine::Yes);
                 // An earlier line wrapping opportunity turned out to be the final breaking position.
-                rebuildLineForRevert(line, *result.revertTo, leadingInlineItemIndex);
+                rebuildLineForRevert(line, *result.revertTo, layoutRange);
             }
             committedInlineItemCount += result.committedCount;
             if (result.isEndOfLine == LineBreaker::IsEndOfLine::Yes) {
                 // We can't place any more items on the current line.
-                return close(line, leadingInlineItemIndex, committedInlineItemCount, result.partialContent);
+                return close(line, layoutRange, committedInlineItemCount, result.partialContent);
             }
         } else if (auto* trailingLineBreak = candidateContent.trailingLineBreak()) {
             line.append(*trailingLineBreak, 0);
-            return close(line, leadingInlineItemIndex, ++committedInlineItemCount, { });
+            return close(line, layoutRange, ++committedInlineItemCount, { });
         }
-        currentItemIndex = leadingInlineItemIndex + committedInlineItemCount;
+        currentItemIndex = layoutRange.start + committedInlineItemCount;
         partialLeadingContentLength = { };
     }
     // Looks like we've run out of runs.
-    return close(line, leadingInlineItemIndex, committedInlineItemCount, { });
+    return close(line, layoutRange, committedInlineItemCount, { });
 }
 
-LineLayoutContext::LineContent LineLayoutContext::close(LineBuilder& line, unsigned leadingInlineItemIndex, unsigned committedInlineItemCount, Optional<LineContent::PartialContent> partialContent)
+LineLayoutContext::LineContent LineLayoutContext::close(LineBuilder& line, const InlineItemRange layoutRange, unsigned committedInlineItemCount, Optional<LineContent::PartialContent> partialContent)
 {
     ASSERT(committedInlineItemCount || line.hasIntrusiveFloat());
     if (!committedInlineItemCount)
@@ -317,14 +316,15 @@
     else
         m_successiveHyphenatedLineCount = 0;
 
-    auto trailingInlineItemIndex = leadingInlineItemIndex + committedInlineItemCount - 1;
+    auto trailingInlineItemIndex = layoutRange.start + committedInlineItemCount - 1;
+    ASSERT(trailingInlineItemIndex < layoutRange.end);
     auto isLastLineWithInlineContent = [&] {
-        if (trailingInlineItemIndex == m_inlineItems.size() - 1)
+        if (trailingInlineItemIndex == layoutRange.end - 1)
             return LineBuilder::IsLastLineWithInlineContent::Yes;
         if (partialContent)
             return LineBuilder::IsLastLineWithInlineContent::No;
         // Omit floats to see if this is the last line with inline content.
-        for (auto i = m_inlineItems.size(); i--;) {
+        for (auto i = layoutRange.end; i--;) {
             if (!m_inlineItems[i].isFloat())
                 return i == trailingInlineItemIndex ? LineBuilder::IsLastLineWithInlineContent::Yes : LineBuilder::IsLastLineWithInlineContent::No;
         }
@@ -335,28 +335,28 @@
     return LineContent { trailingInlineItemIndex, partialContent, WTFMove(m_floats), line.close(isLastLineWithInlineContent), line.lineBox() };
 }
 
-void LineLayoutContext::nextContentForLine(LineCandidateContent& candidateContent, unsigned inlineItemIndex, Optional<unsigned> partialLeadingContentLength, InlineLayoutUnit currentLogicalRight)
+void LineLayoutContext::nextContentForLine(LineCandidateContent& candidateContent, unsigned currentInlineItemIndex, const InlineItemRange layoutRange, Optional<unsigned> partialLeadingContentLength, InlineLayoutUnit currentLogicalRight)
 {
-    ASSERT(inlineItemIndex < m_inlineItems.size());
+    ASSERT(currentInlineItemIndex < layoutRange.end);
     candidateContent.reset();
     // 1. Simply add any overflow content from the previous line to the candidate content. It's always a text content.
     // 2. Find the next soft wrap position or explicit line break.
     // 3. Collect floats between the inline content.
-    auto softWrapOpportunityIndex = nextWrapOpportunity(m_inlineItems, inlineItemIndex);
-    // softWrapOpportunityIndex == m_inlineItems.size() means we don't have any wrap opportunity in this content.
-    ASSERT(softWrapOpportunityIndex <= m_inlineItems.size());
+    auto softWrapOpportunityIndex = nextWrapOpportunity(m_inlineItems, currentInlineItemIndex, layoutRange);
+    // softWrapOpportunityIndex == layoutRange.end means we don't have any wrap opportunity in this content.
+    ASSERT(softWrapOpportunityIndex <= layoutRange.end);
 
     if (partialLeadingContentLength) {
         // Handle leading partial content first (split text from the previous line).
         // Construct a partial leading inline item.
-        m_partialLeadingTextItem = downcast<InlineTextItem>(m_inlineItems[inlineItemIndex]).right(*partialLeadingContentLength);
+        m_partialLeadingTextItem = downcast<InlineTextItem>(m_inlineItems[currentInlineItemIndex]).right(*partialLeadingContentLength);
         auto itemWidth = inlineItemWidth(*m_partialLeadingTextItem, currentLogicalRight);
         candidateContent.appendInlineContent(*m_partialLeadingTextItem, itemWidth);
         currentLogicalRight += itemWidth;
-        ++inlineItemIndex;
+        ++currentInlineItemIndex;
     }
 
-    for (auto index = inlineItemIndex; index < softWrapOpportunityIndex; ++index) {
+    for (auto index = currentInlineItemIndex; index < softWrapOpportunityIndex; ++index) {
         auto& inlineItem = m_inlineItems[index];
         if (inlineItem.isText() || inlineItem.isContainerStart() || inlineItem.isContainerEnd()) {
             auto inlineItenmWidth = inlineItemWidth(inlineItem, currentLogicalRight);
@@ -478,11 +478,11 @@
     }
 }
 
-void LineLayoutContext::rebuildLineForRevert(LineBuilder& line, const InlineItem& revertTo, unsigned leadingInlineItemIndex)
+void LineLayoutContext::rebuildLineForRevert(LineBuilder& line, const InlineItem& revertTo, const InlineItemRange layoutRange)
 {
     // This is the rare case when the line needs to be reverted to an earlier position.
     line.resetContent();
-    auto inlineItemIndex = leadingInlineItemIndex;
+    auto inlineItemIndex = layoutRange.start;
     InlineLayoutUnit logicalRight = { };
     if (m_partialLeadingTextItem) {
         auto logicalWidth = inlineItemWidth(*m_partialLeadingTextItem, logicalRight);
@@ -493,7 +493,7 @@
         ++inlineItemIndex;
     }
 
-    for (; inlineItemIndex < m_inlineItems.size(); ++inlineItemIndex) {
+    for (; inlineItemIndex < layoutRange.end; ++inlineItemIndex) {
         auto& inlineItem = m_inlineItems[inlineItemIndex];
         auto logicalWidth = inlineItemWidth(inlineItem, logicalRight);
         line.append(inlineItem, logicalWidth);

Modified: trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.h (254836 => 254837)


--- trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.h	2020-01-20 21:21:18 UTC (rev 254836)
+++ trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.h	2020-01-20 23:32:51 UTC (rev 254837)
@@ -50,11 +50,16 @@
         const LineBuilder::RunList runList;
         const Display::LineBox lineBox;
     };
-    LineContent layoutLine(LineBuilder&, unsigned leadingInlineItemIndex, Optional<unsigned> partialLeadingContentLength);
+    struct InlineItemRange {
+        bool isEmpty() const { return start == end; }
+        size_t start { 0 };
+        size_t end { 0 };
+    };
+    LineContent layoutLine(LineBuilder&, const InlineItemRange, Optional<unsigned> partialLeadingContentLength);
     using FloatList = Vector<const InlineItem*>;
 
 private:
-    void nextContentForLine(LineCandidateContent&, unsigned inlineItemIndex, Optional<unsigned> overflowLength, InlineLayoutUnit currentLogicalRight);
+    void nextContentForLine(LineCandidateContent&, unsigned inlineItemIndex, const InlineItemRange layoutRange, Optional<unsigned> overflowLength, InlineLayoutUnit currentLogicalRight);
     struct Result {
         LineBreaker::IsEndOfLine isEndOfLine { LineBreaker::IsEndOfLine::No };
         size_t committedCount { 0 };
@@ -63,9 +68,9 @@
     };
     Result tryAddingFloatItems(LineBuilder&, const FloatList&);
     Result tryAddingInlineItems(LineBreaker&, LineBuilder&, const LineCandidateContent&);
-    void rebuildLineForRevert(LineBuilder&, const InlineItem& revertTo, unsigned leadingInlineItemIndex);
+    void rebuildLineForRevert(LineBuilder&, const InlineItem& revertTo, const InlineItemRange layoutRange);
     void commitPartialContent(LineBuilder&, const LineBreaker::RunList&, const LineBreaker::Result::PartialTrailingContent&);
-    LineContent close(LineBuilder&, unsigned leadingInlineItemIndex, unsigned committedInlineItemCount, Optional<LineContent::PartialContent>);
+    LineContent close(LineBuilder&, const InlineItemRange layoutRange, unsigned committedInlineItemCount, Optional<LineContent::PartialContent>);
 
     InlineLayoutUnit inlineItemWidth(const InlineItem&, InlineLayoutUnit contentLogicalLeft) const;
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to