Title: [253938] trunk/Source/WebCore
Revision
253938
Author
[email protected]
Date
2019-12-29 11:33:29 -0800 (Sun, 29 Dec 2019)

Log Message

[LFC][IFC] Implement LineBuilder::revert
https://bugs.webkit.org/show_bug.cgi?id=205629
<rdar://problem/58231425>

Reviewed by Antti Koivisto.

LineBuilder::revert simply removes trailing runs, shrinks the line and rebuilds the collapsible content.

* layout/inlineformatting/InlineLineBuilder.cpp:
(WebCore::Layout::HangingContent::width const):
(WebCore::Layout::HangingContent::isConditional const):
(WebCore::Layout::HangingContent::setIsConditional):
(WebCore::Layout::HangingContent::expand):
(WebCore::Layout::HangingContent::reset):
(WebCore::Layout::LineBuilder::initialize):
(WebCore::Layout::LineBuilder::close):
(WebCore::Layout::LineBuilder::revert):
(WebCore::Layout::LineBuilder::alignHorizontally):
(WebCore::Layout::LineBuilder::collectHangingContent):
* layout/inlineformatting/InlineLineBuilder.h:
(WebCore::Layout::LineBuilder::InlineItemRun::operator== const):
(WebCore::Layout::LineBuilder::InlineItemRun::operator!= const):
(WebCore::Layout::LineBuilder::HangingContent::width const): Deleted. Remove m_hangingContent so that revert does not need to deal with it.
(WebCore::Layout::LineBuilder::HangingContent::isConditional const): Deleted.
(WebCore::Layout::LineBuilder::HangingContent::setIsConditional): Deleted.
(WebCore::Layout::LineBuilder::HangingContent::expand): Deleted.
(WebCore::Layout::LineBuilder::HangingContent::reset): Deleted.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (253937 => 253938)


--- trunk/Source/WebCore/ChangeLog	2019-12-29 18:28:25 UTC (rev 253937)
+++ trunk/Source/WebCore/ChangeLog	2019-12-29 19:33:29 UTC (rev 253938)
@@ -1,5 +1,35 @@
 2019-12-29  Zalan Bujtas  <[email protected]>
 
+        [LFC][IFC] Implement LineBuilder::revert
+        https://bugs.webkit.org/show_bug.cgi?id=205629
+        <rdar://problem/58231425>
+
+        Reviewed by Antti Koivisto.
+
+        LineBuilder::revert simply removes trailing runs, shrinks the line and rebuilds the collapsible content.
+
+        * layout/inlineformatting/InlineLineBuilder.cpp:
+        (WebCore::Layout::HangingContent::width const):
+        (WebCore::Layout::HangingContent::isConditional const):
+        (WebCore::Layout::HangingContent::setIsConditional):
+        (WebCore::Layout::HangingContent::expand):
+        (WebCore::Layout::HangingContent::reset):
+        (WebCore::Layout::LineBuilder::initialize):
+        (WebCore::Layout::LineBuilder::close):
+        (WebCore::Layout::LineBuilder::revert):
+        (WebCore::Layout::LineBuilder::alignHorizontally):
+        (WebCore::Layout::LineBuilder::collectHangingContent):
+        * layout/inlineformatting/InlineLineBuilder.h:
+        (WebCore::Layout::LineBuilder::InlineItemRun::operator== const):
+        (WebCore::Layout::LineBuilder::InlineItemRun::operator!= const):
+        (WebCore::Layout::LineBuilder::HangingContent::width const): Deleted. Remove m_hangingContent so that revert does not need to deal with it.
+        (WebCore::Layout::LineBuilder::HangingContent::isConditional const): Deleted.
+        (WebCore::Layout::LineBuilder::HangingContent::setIsConditional): Deleted.
+        (WebCore::Layout::LineBuilder::HangingContent::expand): Deleted.
+        (WebCore::Layout::LineBuilder::HangingContent::reset): Deleted.
+
+2019-12-29  Zalan Bujtas  <[email protected]>
+
         [LFC][IFC] Add LineBreaker::Result::Revert to indicate an earlier line wrap opportunity
         https://bugs.webkit.org/show_bug.cgi?id=205623
         <rdar://problem/58228339>

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp (253937 => 253938)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp	2019-12-29 18:28:25 UTC (rev 253937)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.cpp	2019-12-29 19:33:29 UTC (rev 253938)
@@ -43,6 +43,27 @@
     return whitespace == WhiteSpace::Pre || whitespace == WhiteSpace::PreWrap || whitespace == WhiteSpace::BreakSpaces;
 }
 
+struct HangingContent {
+public:
+    void reset();
+
+    InlineLayoutUnit width() const { return m_width; }
+    bool isConditional() const { return m_isConditional; }
+
+    void setIsConditional() { m_isConditional = true; }
+    void expand(InlineLayoutUnit width) { m_width += width; }
+
+private:
+    bool m_isConditional { false };
+    InlineLayoutUnit m_width { 0 };
+};
+
+void HangingContent::reset()
+{
+    m_isConditional = false;
+    m_width =  0;
+}
+
 struct LineBuilder::ContinousContent {
 public:
     ContinousContent(const InlineItemRun&, bool textIsAlignJustify);
@@ -192,7 +213,6 @@
 
     m_inlineItemRuns.clear();
     m_collapsibleContent.reset();
-    m_hangingContent.reset();
     m_lineIsVisuallyEmptyBeforeCollapsibleContent = { };
 }
 
@@ -210,7 +230,7 @@
     // 2. Join text runs together when possible [foo][ ][bar] -> [foo bar].
     // 3. Align merged runs both vertically and horizontally.
     removeTrailingCollapsibleContent();
-    collectHangingContent(isLastLineWithInlineContent);
+    auto hangingContent = collectHangingContent(isLastLineWithInlineContent);
     RunList runList;
     unsigned runIndex = 0;
     while (runIndex < m_inlineItemRuns.size()) {
@@ -238,11 +258,61 @@
             m_lineBox.resetDescent();
         }
         alignContentVertically(runList);
-        alignHorizontally(runList, isLastLineWithInlineContent);
+        alignHorizontally(runList, hangingContent, isLastLineWithInlineContent);
     }
     return runList;
 }
 
+void LineBuilder::revert(const InlineItem& revertTo)
+{
+    // 1. Remove and shrink the trailing content.
+    // 2. Rebuild collapsible trailing whitespace content.
+    ASSERT(!m_inlineItemRuns.isEmpty());
+    ASSERT(m_inlineItemRuns.last() != revertTo);
+    auto revertedWidth = InlineLayoutUnit { };
+    auto index = m_inlineItemRuns.size() - 1;
+    while (index >= 0 && m_inlineItemRuns[index] != revertTo)
+        revertedWidth += m_inlineItemRuns[index--].logicalWidth();
+    m_lineBox.shrinkHorizontally(revertedWidth);
+    m_inlineItemRuns.shrink(index + 1);
+    // Should never need to clear the line.
+    ASSERT(!m_inlineItemRuns.isEmpty());
+
+    // It's easier just to rebuild trailing collapsible content.
+    m_collapsibleContent.reset();
+    m_lineIsVisuallyEmptyBeforeCollapsibleContent = isVisuallyEmpty();
+    // Find the first collapsible run.
+    Optional<size_t> firstCollapsibleRunIndex;
+    for (auto index = m_inlineItemRuns.size(); index--;) {
+        auto& inlineItemRun = m_inlineItemRuns[index];
+        if (inlineItemRun.isContainerStart() || inlineItemRun.isContainerEnd())
+            continue;
+        auto hasCollapsibleContent = inlineItemRun.isCollapsibleWhitespace() || inlineItemRun.hasTrailingLetterSpacing();
+        if (!hasCollapsibleContent)
+            break;
+        if (inlineItemRun.isCollapsibleWhitespace()) {
+            firstCollapsibleRunIndex = index;
+            continue;
+        }
+        if (inlineItemRun.hasTrailingLetterSpacing()) {
+            // While trailing letter spacing is considered collapsible, it is supposed to be last one in the list.
+            firstCollapsibleRunIndex = index;
+            break;
+        }
+    }
+    // Forward-append runs to m_collapsibleContent. 
+    if (firstCollapsibleRunIndex) {
+        for (auto index = *firstCollapsibleRunIndex; index < m_inlineItemRuns.size(); ++index) {
+            auto& inlineItemRun = m_inlineItemRuns[index];
+            if (inlineItemRun.isContainerStart() || inlineItemRun.isContainerEnd())
+                continue;
+            ASSERT(inlineItemRun.isText());
+            m_collapsibleContent.append(index);
+        }
+    }
+    // Consider alternative solutions if the (edge case)revert gets overly complicated.  
+}
+
 void LineBuilder::alignContentVertically(RunList& runList)
 {
     ASSERT(!m_isIntrinsicSizing);
@@ -330,10 +400,10 @@
     }
 }
 
-void LineBuilder::alignHorizontally(RunList& runList, IsLastLineWithInlineContent lastLine)
+void LineBuilder::alignHorizontally(RunList& runList, const HangingContent& hangingContent, IsLastLineWithInlineContent lastLine)
 {
     ASSERT(!m_isIntrinsicSizing);
-    auto availableWidth = this->availableWidth() + m_hangingContent.width();
+    auto availableWidth = this->availableWidth() + hangingContent.width();
     if (runList.isEmpty() || availableWidth <= 0)
         return;
 
@@ -409,17 +479,18 @@
     m_lineIsVisuallyEmptyBeforeCollapsibleContent = { };
 }
 
-void LineBuilder::collectHangingContent(IsLastLineWithInlineContent isLastLineWithInlineContent)
+HangingContent LineBuilder::collectHangingContent(IsLastLineWithInlineContent isLastLineWithInlineContent)
 {
+    auto hangingContent = HangingContent { };
     // Can't setup hanging content with removable trailing whitspaces.
     ASSERT(m_collapsibleContent.isEmpty());
     if (isLastLineWithInlineContent == IsLastLineWithInlineContent::Yes)
-        m_hangingContent.setIsConditional();
+        hangingContent.setIsConditional();
     for (auto& inlineItemRun : WTF::makeReversedRange(m_inlineItemRuns)) {
         if (inlineItemRun.isContainerStart() || inlineItemRun.isContainerEnd())
             continue;
         if (inlineItemRun.isLineBreak()) {
-            m_hangingContent.setIsConditional();
+            hangingContent.setIsConditional();
             continue;
         }
         if (!inlineItemRun.isText() || !inlineItemRun.isWhitespace() || inlineItemRun.isCollapsible())
@@ -428,8 +499,9 @@
         if (inlineItemRun.style().whiteSpace() != WhiteSpace::PreWrap)
             break;
         // This is either a normal or conditionally hanging trailing whitespace.
-        m_hangingContent.expand(inlineItemRun.logicalWidth());
+        hangingContent.expand(inlineItemRun.logicalWidth());
     }
+    return hangingContent;
 }
 
 void LineBuilder::moveLogicalLeft(InlineLayoutUnit delta)

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.h (253937 => 253938)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.h	2019-12-29 18:28:25 UTC (rev 253937)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.h	2019-12-29 19:33:29 UTC (rev 253938)
@@ -35,6 +35,7 @@
 namespace WebCore {
 namespace Layout {
 
+struct HangingContent;
 class InlineFormattingContext;
 
 class LineBuilder {
@@ -114,6 +115,7 @@
     using RunList = Vector<Run, 50>;
     enum class IsLastLineWithInlineContent { No, Yes };
     RunList close(IsLastLineWithInlineContent = IsLastLineWithInlineContent::No);
+    void revert(const InlineItem& revertTo);
 
     static Display::LineBox::Baseline halfLeadingMetrics(const FontMetrics&, InlineLayoutUnit lineLogicalHeight);
 
@@ -140,8 +142,8 @@
     void appendLineBreak(const InlineItem&);
 
     void removeTrailingCollapsibleContent();
-    void collectHangingContent(IsLastLineWithInlineContent);
-    void alignHorizontally(RunList&, IsLastLineWithInlineContent);
+    HangingContent collectHangingContent(IsLastLineWithInlineContent);
+    void alignHorizontally(RunList&, const HangingContent&, IsLastLineWithInlineContent);
     void alignContentVertically(RunList&);
 
     void adjustBaselineAndLineHeight(const Run&);
@@ -192,6 +194,9 @@
 
         bool hasExpansionOpportunity() const { return isWhitespace() && !isCollapsedToZeroAdvanceWidth(); }
 
+        bool operator==(const InlineItem& other) const { return &other == &m_inlineItem; }
+        bool operator!=(const InlineItem& other) const { return !(*this == other); }
+
     private:
         const InlineItem& m_inlineItem;
         InlineLayoutUnit m_logicalLeft { 0 };
@@ -224,25 +229,9 @@
         bool m_lastRunIsFullyCollapsible { false };
     };
 
-    struct HangingContent {
-    public:
-        void reset();
-
-        InlineLayoutUnit width() const { return m_width; }
-        bool isConditional() const { return m_isConditional; }
-
-        void setIsConditional() { m_isConditional = true; }
-        void expand(InlineLayoutUnit width) { m_width += width; }
-
-    private:
-        bool m_isConditional { false };
-        InlineLayoutUnit m_width { 0 };
-    };
-
     const InlineFormattingContext& m_inlineFormattingContext;
     InlineItemRunList m_inlineItemRuns;
     CollapsibleContent m_collapsibleContent;
-    HangingContent m_hangingContent;
     Optional<Display::LineBox::Baseline> m_initialStrut;
     InlineLayoutUnit m_lineLogicalWidth { 0 };
     Optional<TextAlignMode> m_horizontalAlignment;
@@ -259,12 +248,6 @@
     m_lastRunIsFullyCollapsible = false;
 }
 
-inline void LineBuilder::HangingContent::reset()
-{
-    m_isConditional = false;
-    m_width =  0;
 }
-
 }
-}
 #endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to