Title: [270163] trunk/Source/WebCore
Revision
270163
Author
[email protected]
Date
2020-11-22 05:52:24 -0800 (Sun, 22 Nov 2020)

Log Message

[LFC][IFC] Only process floats that fit the current line.
https://bugs.webkit.org/show_bug.cgi?id=219239

Reviewed by Antti Koivisto.

Now that we process floats as soft wrap opportunities, all the intrusive logic can be removed.
Any float that we put on the line is considered intrusive and shrinks the available space.

* layout/inlineformatting/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::computeGeometryForLineContent):
* layout/inlineformatting/InlineLineBuilder.cpp:
(WebCore::Layout::LineCandidate::InlineContent::operator() const):
(WebCore::Layout::LineCandidate::reset):
(WebCore::Layout::LineBuilder::placeInlineContent):
(WebCore::Layout::LineBuilder::constraintsForLine):
(WebCore::Layout::LineBuilder::candidateContentForLine):
(WebCore::Layout::LineBuilder::handleFloatOrInlineContent):
(WebCore::Layout::LineBuilder::rebuildLine):
(WebCore::Layout::LineCandidate::InlineContent::continuousContent const): Deleted.
(WebCore::Layout::LineCandidate::FloatContent::list const): Deleted.
(WebCore::Layout::LineCandidate::FloatContent::intrusiveWidth const): Deleted.
(WebCore::Layout::LineCandidate::FloatContent::append): Deleted.
(WebCore::Layout::LineCandidate::FloatContent::reset): Deleted.
(WebCore::Layout::LineBuilder::nextContentForLine): Deleted.
(WebCore::Layout::LineBuilder::commitFloats): Deleted.
(WebCore::Layout::LineBuilder::handleFloatsAndInlineContent): Deleted.
* layout/inlineformatting/InlineLineBuilder.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (270162 => 270163)


--- trunk/Source/WebCore/ChangeLog	2020-11-22 13:11:31 UTC (rev 270162)
+++ trunk/Source/WebCore/ChangeLog	2020-11-22 13:52:24 UTC (rev 270163)
@@ -1,3 +1,33 @@
+2020-11-22  Zalan Bujtas  <[email protected]>
+
+        [LFC][IFC] Only process floats that fit the current line.
+        https://bugs.webkit.org/show_bug.cgi?id=219239
+
+        Reviewed by Antti Koivisto.
+
+        Now that we process floats as soft wrap opportunities, all the intrusive logic can be removed.
+        Any float that we put on the line is considered intrusive and shrinks the available space.
+
+        * layout/inlineformatting/InlineFormattingContext.cpp:
+        (WebCore::Layout::InlineFormattingContext::computeGeometryForLineContent):
+        * layout/inlineformatting/InlineLineBuilder.cpp:
+        (WebCore::Layout::LineCandidate::InlineContent::operator() const):
+        (WebCore::Layout::LineCandidate::reset):
+        (WebCore::Layout::LineBuilder::placeInlineContent):
+        (WebCore::Layout::LineBuilder::constraintsForLine):
+        (WebCore::Layout::LineBuilder::candidateContentForLine):
+        (WebCore::Layout::LineBuilder::handleFloatOrInlineContent):
+        (WebCore::Layout::LineBuilder::rebuildLine):
+        (WebCore::Layout::LineCandidate::InlineContent::continuousContent const): Deleted.
+        (WebCore::Layout::LineCandidate::FloatContent::list const): Deleted.
+        (WebCore::Layout::LineCandidate::FloatContent::intrusiveWidth const): Deleted.
+        (WebCore::Layout::LineCandidate::FloatContent::append): Deleted.
+        (WebCore::Layout::LineCandidate::FloatContent::reset): Deleted.
+        (WebCore::Layout::LineBuilder::nextContentForLine): Deleted.
+        (WebCore::Layout::LineBuilder::commitFloats): Deleted.
+        (WebCore::Layout::LineBuilder::handleFloatsAndInlineContent): Deleted.
+        * layout/inlineformatting/InlineLineBuilder.h:
+
 2020-11-22  Rob Buis  <[email protected]>
 
         Fix getIndexedParameter indexing crash

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp (270162 => 270163)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp	2020-11-22 13:11:31 UTC (rev 270162)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp	2020-11-22 13:52:24 UTC (rev 270163)
@@ -417,15 +417,13 @@
             return;
         auto floatingContext = FloatingContext { *this, formattingState.floatingState() };
         // Move floats to their final position.
-        for (const auto& floatCandidate : lineContent.floats) {
-            auto& floatBox = floatCandidate.item->layoutBox();
-            auto& boxGeometry = formattingState.boxGeometry(floatBox);
+        for (auto* floatBox : lineContent.floats) {
+            auto& boxGeometry = formattingState.boxGeometry(*floatBox);
             // Set static position first.
-            auto verticalStaticPosition = floatCandidate.isIntrusive ? lineBoxLogicalRect.top() : lineBoxLogicalRect.bottom();
-            boxGeometry.setLogicalTopLeft({ lineBoxLogicalRect.left(), verticalStaticPosition });
+            boxGeometry.setLogicalTopLeft({ lineBoxLogicalRect.left(), lineBoxLogicalRect.top() });
             // Float it.
-            boxGeometry.setLogicalTopLeft(floatingContext.positionForFloat(floatBox, horizontalConstraints));
-            floatingContext.append(floatBox);
+            boxGeometry.setLogicalTopLeft(floatingContext.positionForFloat(*floatBox, horizontalConstraints));
+            floatingContext.append(*floatBox);
         }
     };
     updateFloatGeometry();

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp (270162 => 270163)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp	2020-11-22 13:11:31 UTC (rev 270162)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp	2020-11-22 13:52:24 UTC (rev 270163)
@@ -129,7 +129,7 @@
     struct InlineContent {
         InlineContent(bool ignoreTrailingLetterSpacing);
 
-        const InlineContentBreaker::ContinuousContent& continuousContent() const { return m_continuousContent; }
+        const InlineContentBreaker::ContinuousContent& operator()() const { return m_continuousContent; }
         const InlineItem* trailingLineBreak() const { return m_trailingLineBreak; }
         const InlineItem* trailingWordBreakOpportunity() const { return m_trailingWordBreakOpportunity; }
 
@@ -146,27 +146,9 @@
         const InlineItem* m_trailingWordBreakOpportunity { nullptr };
     };
 
-    struct FloatContent {
-        void append(const InlineItem& floatItem, InlineLayoutUnit logicalWidth, bool isIntrusive);
-
-        struct Float {
-            const InlineItem* item { nullptr };
-            InlineLayoutUnit logicalWidth { 0 };
-            bool isIntrusive { true };
-        };
-        using FloatList = Vector<Float>;
-        const FloatList& list() const { return m_floatList; }
-        InlineLayoutUnit intrusiveWidth() const { return m_intrusiveWidth; }
-
-        void reset();
-
-    private:
-        FloatList m_floatList;
-        InlineLayoutUnit m_intrusiveWidth { 0 };
-    };
-    // Candidate content is a collection of inline items and/or float boxes.
+    // Candidate content is a collection of inline content or a float box.
     InlineContent inlineContent;
-    FloatContent floatContent;
+    const InlineItem* floatItem { nullptr };
 };
 
 LineCandidate::LineCandidate(bool ignoreTrailingLetterSpacing)
@@ -209,22 +191,9 @@
     m_trailingWordBreakOpportunity = { };
 }
 
-inline void LineCandidate::FloatContent::append(const InlineItem& floatItem, InlineLayoutUnit logicalWidth, bool isIntrusive)
-{
-    if (isIntrusive)
-        m_intrusiveWidth += logicalWidth;
-    m_floatList.append({ &floatItem, logicalWidth, isIntrusive });
-}
-
-inline void LineCandidate::FloatContent::reset()
-{
-    m_floatList.clear();
-    m_intrusiveWidth = { };
-}
-
 inline void LineCandidate::reset()
 {
-    floatContent.reset();
+    floatItem = nullptr;
     inlineContent.reset();
 }
 
@@ -319,12 +288,12 @@
         // 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(lineCandidate, currentItemIndex, needsLayoutRange, partialLeadingContentLength, availableWidth() + m_line.trimmableTrailingWidth(), m_line.contentLogicalWidth());
+        candidateContentForLine(lineCandidate, currentItemIndex, needsLayoutRange, partialLeadingContentLength, m_line.contentLogicalWidth());
         // Now check if we can put this content on the current line.
-        auto result = handleFloatsAndInlineContent(inlineContentBreaker, needsLayoutRange, lineCandidate);
+        auto result = handleFloatOrInlineContent(inlineContentBreaker, needsLayoutRange, lineCandidate);
         committedInlineItemCount = result.committedCount.isRevert ? result.committedCount.value : committedInlineItemCount + result.committedCount.value;
         auto& inlineContent = lineCandidate.inlineContent;
-        auto inlineContentIsFullyCommitted = inlineContent.continuousContent().runs().size() == result.committedCount.value && !result.partialTrailingContentLength;
+        auto inlineContentIsFullyCommitted = inlineContent().runs().size() == result.committedCount.value && !result.partialTrailingContentLength;
         auto isEndOfLine = result.isEndOfLine == InlineContentBreaker::IsEndOfLine::Yes;
 
         if (inlineContentIsFullyCommitted) {
@@ -386,7 +355,7 @@
 
     // Check for intruding floats and adjust logical left/available width for this line accordingly.
     if (!m_floatingContext.isEmpty()) {
-        // FIXME: Add support for variable line height, where the intrusive floats should be probed as the line height grows.
+        // FIXME: Add support for variable line height, where the floats should be probed as the line height grows.
         auto floatConstraints = m_floatingContext.constraints(toLayoutUnit(lineLogicalTop), toLayoutUnit(lineLogicalTop + lineLogicalConstraints.height()));
         // Check if these values actually constrain the line.
         if (floatConstraints.left && floatConstraints.left->x <= lineLogicalLeft)
@@ -451,7 +420,7 @@
     return UsedConstraints { lineLogicalLeft, lineLogicalRight - lineLogicalLeft, lineIsConstrainedByFloat };
 }
 
-void LineBuilder::nextContentForLine(LineCandidate& lineCandidate, size_t currentInlineItemIndex, const InlineItemRange& layoutRange, size_t partialLeadingContentLength, InlineLayoutUnit availableLineWidth, InlineLayoutUnit currentLogicalRight)
+void LineBuilder::candidateContentForLine(LineCandidate& lineCandidate, size_t currentInlineItemIndex, const InlineItemRange& layoutRange, size_t partialLeadingContentLength, InlineLayoutUnit currentLogicalRight)
 {
     ASSERT(currentInlineItemIndex < layoutRange.end);
     lineCandidate.reset();
@@ -472,14 +441,12 @@
         ++currentInlineItemIndex;
     }
 
-    auto accumulatedWidth = InlineLayoutUnit { };
     for (auto index = currentInlineItemIndex; index < softWrapOpportunityIndex; ++index) {
         auto& inlineItem = m_inlineItems[index];
         if (inlineItem.isFloat()) {
-            // Floats are not part of the line context.
-            auto floatWidth = inlineItemWidth(inlineItem, { });
-            lineCandidate.floatContent.append(inlineItem, floatWidth, floatWidth <= (availableLineWidth - accumulatedWidth));
-            accumulatedWidth += floatWidth;
+            lineCandidate.floatItem = &inlineItem;
+            // This is a soft wrap opportunity, must be the only item in the list.
+            ASSERT(currentInlineItemIndex + 1 == softWrapOpportunityIndex);
             continue;
         }
         if (inlineItem.isText() || inlineItem.isInlineBoxStart() || inlineItem.isInlineBoxEnd() || inlineItem.isBox()) {
@@ -486,7 +453,6 @@
             auto logicalWidth = inlineItemWidth(inlineItem, currentLogicalRight);
             lineCandidate.inlineContent.appendInlineItem(inlineItem, logicalWidth);
             currentLogicalRight += logicalWidth;
-            accumulatedWidth += logicalWidth;
             continue;
         }
         if (inlineItem.isWordBreakOpportunity()) {
@@ -557,41 +523,24 @@
     return layoutRange.end;
 }
 
-void LineBuilder::commitFloats(const LineCandidate& lineCandidate, CommitIntrusiveFloatsOnly commitIntrusiveOnly)
+LineBuilder::Result LineBuilder::handleFloatOrInlineContent(InlineContentBreaker& inlineContentBreaker, const InlineItemRange& layoutRange, const LineCandidate& lineCandidate)
 {
-    auto& floatContent = lineCandidate.floatContent;
-    auto leftIntrusiveFloatsWidth = InlineLayoutUnit { };
-    auto rightIntrusiveFloatsWidth = InlineLayoutUnit { };
-
-    for (auto& floatCandidate : floatContent.list()) {
-        if (!floatCandidate.isIntrusive && commitIntrusiveOnly == CommitIntrusiveFloatsOnly::Yes)
-            continue;
-        m_floats.append({ floatCandidate.isIntrusive, floatCandidate.item });
-        if (floatCandidate.isIntrusive) {
-            m_contentIsConstrainedByFloat = true;
-            // This float is intrusive and it shrinks the current line.
-            // Shrink available space for current line.
-            if (floatCandidate.item->layoutBox().isLeftFloatingPositioned())
-                leftIntrusiveFloatsWidth += floatCandidate.logicalWidth;
-            else
-                rightIntrusiveFloatsWidth += floatCandidate.logicalWidth;
-        }
+    if (lineCandidate.inlineContent().runs().isEmpty() && !lineCandidate.floatItem) {
+        auto& inlineContent = lineCandidate.inlineContent;
+        ASSERT(inlineContent.trailingLineBreak() || inlineContent.trailingWordBreakOpportunity());
+        return { inlineContent.trailingLineBreak() ? InlineContentBreaker::IsEndOfLine::Yes : InlineContentBreaker::IsEndOfLine::No };
     }
-    if (leftIntrusiveFloatsWidth || rightIntrusiveFloatsWidth) {
-        if (leftIntrusiveFloatsWidth) {
-            m_line.moveLogicalLeft(leftIntrusiveFloatsWidth);
-            m_horizontalSpaceForLine -= leftIntrusiveFloatsWidth;
-        }
-        if (rightIntrusiveFloatsWidth)
-            m_horizontalSpaceForLine -= rightIntrusiveFloatsWidth;
-    }
-}
-
-LineBuilder::Result LineBuilder::handleFloatsAndInlineContent(InlineContentBreaker& inlineContentBreaker, const InlineItemRange& layoutRange, const LineCandidate& lineCandidate)
-{
-    auto& continuousInlineContent = lineCandidate.inlineContent.continuousContent();
-    if (continuousInlineContent.runs().isEmpty()) {
-        commitFloats(lineCandidate);
+    if (lineCandidate.floatItem) {
+        auto floatBoxWidth = inlineItemWidth(*lineCandidate.floatItem, { });
+        if (floatBoxWidth > availableWidth() && !m_line.isConsideredEmpty())
+            return { InlineContentBreaker::IsEndOfLine::Yes };
+        // This float shrinks the current line.
+        auto& floatBox = lineCandidate.floatItem->layoutBox();
+        m_floats.append(&floatBox);
+        m_contentIsConstrainedByFloat = true;
+        if (floatBox.isLeftFloatingPositioned())
+            m_line.moveLogicalLeft(floatBoxWidth);
+        m_horizontalSpaceForLine -= floatBoxWidth;
         return { InlineContentBreaker::IsEndOfLine::No };
     }
 
@@ -603,20 +552,18 @@
     if (shouldDisableHyphenation())
         inlineContentBreaker.setHyphenationDisabled();
 
-    auto& floatContent = lineCandidate.floatContent;
     // Check if this new content fits.
-    auto availableWidth = this->availableWidth() - floatContent.intrusiveWidth();
+    auto& continuousInlineContent = lineCandidate.inlineContent();
     auto isLineConsideredEmpty = m_line.isConsideredEmpty() && !m_contentIsConstrainedByFloat;
-    auto lineStatus = InlineContentBreaker::LineStatus { m_line.contentLogicalWidth(), availableWidth, m_line.trimmableTrailingWidth(), m_line.trailingSoftHyphenWidth(), m_line.isTrailingRunFullyTrimmable(), isLineConsideredEmpty };
+    auto lineStatus = InlineContentBreaker::LineStatus { m_line.contentLogicalWidth(), availableWidth(), m_line.trimmableTrailingWidth(), m_line.trailingSoftHyphenWidth(), m_line.isTrailingRunFullyTrimmable(), isLineConsideredEmpty };
     auto result = inlineContentBreaker.processInlineContent(continuousInlineContent, lineStatus);
     if (result.lastWrapOpportunityItem)
         m_wrapOpportunityList.append(result.lastWrapOpportunityItem);
     auto& candidateRuns = continuousInlineContent.runs();
     if (result.action == InlineContentBreaker::Result::Action::Keep) {
-        // This continuous content can be fully placed on the current line including non-intrusive floats.
+        // This continuous content can be fully placed on the current line.
         for (auto& run : candidateRuns)
             m_line.append(run.inlineItem, run.logicalWidth);
-        commitFloats(lineCandidate);
         return { result.isEndOfLine, { candidateRuns.size(), false } };
     }
     if (result.action == InlineContentBreaker::Result::Action::Wrap) {
@@ -646,7 +593,6 @@
     if (result.action == InlineContentBreaker::Result::Action::Break) {
         ASSERT(result.isEndOfLine == InlineContentBreaker::IsEndOfLine::Yes);
         // Commit the combination of full and partial content on the current line.
-        commitFloats(lineCandidate, CommitIntrusiveFloatsOnly::Yes);
         ASSERT(result.partialTrailingContent);
         commitPartialContent(candidateRuns, *result.partialTrailingContent);
         // When breaking multiple runs <span style="word-break: break-all">text</span><span>content</span>, we might end up breaking them at run boundary.
@@ -692,7 +638,7 @@
 size_t LineBuilder::rebuildLine(const InlineItemRange& layoutRange, const InlineItem& lastInlineItemToAdd)
 {
     ASSERT(!m_wrapOpportunityList.isEmpty());
-    // We might already have added intrusive floats. They shrink the avilable horizontal space for the line.
+    // We might already have added floats. They shrink the available horizontal space for the line.
     // Let's just reuse what the line has at this point.
     m_line.initialize();
     auto currentItemIndex = layoutRange.start;

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.h (270162 => 270163)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.h	2020-11-22 13:11:31 UTC (rev 270162)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.h	2020-11-22 13:52:24 UTC (rev 270163)
@@ -50,11 +50,7 @@
     struct LineContent {
         InlineItemRange inlineItemRange;
         size_t partialTrailingContentLength { 0 };
-        struct Float {
-            bool isIntrusive { true };
-            const InlineItem* item { nullptr };
-        };
-        using FloatList = Vector<Float>;
+        using FloatList = Vector<const Box*>;
         const FloatList& floats;
         bool hasIntrusiveFloat { false };
         InlineLayoutPoint logicalTopLeft;
@@ -73,7 +69,7 @@
     IntrinsicContent computedIntrinsicWidth(const InlineItemRange&, InlineLayoutUnit availableWidth);
 
 private:
-    void nextContentForLine(LineCandidate&, size_t inlineItemIndex, const InlineItemRange& needsLayoutRange, size_t overflowLength, InlineLayoutUnit availableLineWidth, InlineLayoutUnit currentLogicalRight);
+    void candidateContentForLine(LineCandidate&, size_t inlineItemIndex, const InlineItemRange& needsLayoutRange, size_t overflowLength, InlineLayoutUnit currentLogicalRight);
     size_t nextWrapOpportunity(size_t startIndex, const LineBuilder::InlineItemRange& layoutRange) const;
 
     struct Result {
@@ -85,7 +81,6 @@
         CommittedContentCount committedCount { };
         size_t partialTrailingContentLength { 0 };
     };
-    enum class CommitIntrusiveFloatsOnly { No, Yes };
     struct UsedConstraints {
         InlineLayoutUnit logicalLeft { 0 };
         InlineLayoutUnit logicalWidth { 0 };
@@ -92,8 +87,7 @@
         bool isConstrainedByFloat { false };
     };
     UsedConstraints constraintsForLine(const InlineRect& initialLineConstraints, bool isFirstLine);
-    void commitFloats(const LineCandidate&, CommitIntrusiveFloatsOnly = CommitIntrusiveFloatsOnly::No);
-    Result handleFloatsAndInlineContent(InlineContentBreaker&, const InlineItemRange& needsLayoutRange, const LineCandidate&);
+    Result handleFloatOrInlineContent(InlineContentBreaker&, const InlineItemRange& needsLayoutRange, const LineCandidate&);
     size_t rebuildLine(const InlineItemRange& needsLayoutRange, const InlineItem& lastInlineItemToAdd);
     size_t rebuildLineForTrailingSoftHyphen(const InlineItemRange& layoutRange);
     void commitPartialContent(const InlineContentBreaker::ContinuousContent::RunList&, const InlineContentBreaker::Result::PartialTrailingContent&);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to