Title: [251329] trunk/Source/WebCore
Revision
251329
Author
za...@apple.com
Date
2019-10-20 07:56:32 -0700 (Sun, 20 Oct 2019)

Log Message

[LFC][IFC] Move the collapsed bit from InlineItems to runs
https://bugs.webkit.org/show_bug.cgi?id=203183

Reviewed by Antti Koivisto.
<rdar://problem/56437181>

Let's not store the collapsed bit on the InlineTextItem. All we need to know is whether the InlineTextItem content is collapsible or not.
Also when only the white-space property changes (going from preserve whitespace to not and vice versa) we don't actually need to rebuild the
InlinItem list since they don't carry any layout dependent information.
This patch also fixes leading/trailing content preservation.

* layout/inlineformatting/InlineLine.cpp:
(WebCore::Layout::Line::Run::canBeExtended const):
(WebCore::Layout::shouldPreserveTrailingContent):
(WebCore::Layout::shouldPreserveLeadingContent):
(WebCore::Layout::Line::appendTextContent):
* layout/inlineformatting/InlineLine.h:
(WebCore::Layout::Line::Run::isCollapsed const):
(WebCore::Layout::Line::Run::setIsCollapsed):
* layout/inlineformatting/InlineLineLayout.cpp:
(WebCore::Layout::inlineItemWidth):
* layout/inlineformatting/InlineTextItem.cpp:
(WebCore::Layout::InlineTextItem::createAndAppendTextItems):
(WebCore::Layout::InlineTextItem::InlineTextItem):
(WebCore::Layout::InlineTextItem::split const):
* layout/inlineformatting/InlineTextItem.h:
(WebCore::Layout::InlineTextItem::isCollapsible const):
(WebCore::Layout::InlineTextItem::isCollapsed const): Deleted.
* layout/inlineformatting/text/TextUtil.cpp:
(WebCore::Layout::TextUtil::isTrimmableContent): Deleted.
* layout/inlineformatting/text/TextUtil.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (251328 => 251329)


--- trunk/Source/WebCore/ChangeLog	2019-10-19 23:50:32 UTC (rev 251328)
+++ trunk/Source/WebCore/ChangeLog	2019-10-20 14:56:32 UTC (rev 251329)
@@ -1,3 +1,37 @@
+2019-10-20  Zalan Bujtas  <za...@apple.com>
+
+        [LFC][IFC] Move the collapsed bit from InlineItems to runs
+        https://bugs.webkit.org/show_bug.cgi?id=203183
+
+        Reviewed by Antti Koivisto.
+        <rdar://problem/56437181>
+
+        Let's not store the collapsed bit on the InlineTextItem. All we need to know is whether the InlineTextItem content is collapsible or not.
+        Also when only the white-space property changes (going from preserve whitespace to not and vice versa) we don't actually need to rebuild the
+        InlinItem list since they don't carry any layout dependent information.
+        This patch also fixes leading/trailing content preservation. 
+
+        * layout/inlineformatting/InlineLine.cpp:
+        (WebCore::Layout::Line::Run::canBeExtended const):
+        (WebCore::Layout::shouldPreserveTrailingContent):
+        (WebCore::Layout::shouldPreserveLeadingContent):
+        (WebCore::Layout::Line::appendTextContent):
+        * layout/inlineformatting/InlineLine.h:
+        (WebCore::Layout::Line::Run::isCollapsed const):
+        (WebCore::Layout::Line::Run::setIsCollapsed):
+        * layout/inlineformatting/InlineLineLayout.cpp:
+        (WebCore::Layout::inlineItemWidth):
+        * layout/inlineformatting/InlineTextItem.cpp:
+        (WebCore::Layout::InlineTextItem::createAndAppendTextItems):
+        (WebCore::Layout::InlineTextItem::InlineTextItem):
+        (WebCore::Layout::InlineTextItem::split const):
+        * layout/inlineformatting/InlineTextItem.h:
+        (WebCore::Layout::InlineTextItem::isCollapsible const):
+        (WebCore::Layout::InlineTextItem::isCollapsed const): Deleted.
+        * layout/inlineformatting/text/TextUtil.cpp:
+        (WebCore::Layout::TextUtil::isTrimmableContent): Deleted.
+        * layout/inlineformatting/text/TextUtil.h:
+
 2019-10-19  Chris Dumez  <cdu...@apple.com>
 
         FileReader should not prevent entering the back/forward cache

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLine.cpp (251328 => 251329)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLine.cpp	2019-10-19 23:50:32 UTC (rev 251328)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLine.cpp	2019-10-20 14:56:32 UTC (rev 251329)
@@ -54,7 +54,10 @@
 {
     if (!isText())
         return false;
-    return !downcast<InlineTextItem>(m_inlineItem).isCollapsed() && !isVisuallyEmpty();
+    // Non-collapsed text runs can be merged into one continuous run.
+    if (isVisuallyEmpty())
+        return false;
+    return !isCollapsed();
 }
 
 Line::Line(const InlineFormattingContext& inlineFormattingContext, const InitialConstraints& initialConstraints, Optional<TextAlignMode> horizontalAlignment, SkipAlignment skipAlignment)
@@ -79,6 +82,22 @@
     return !(boxGeometry.horizontalBorder() || (boxGeometry.horizontalPadding() && boxGeometry.horizontalPadding().value()));
 }
 
+static bool shouldPreserveTrailingContent(const InlineTextItem& inlineTextItem)
+{
+    if (!inlineTextItem.isWhitespace())
+        return true;
+    auto whitespace = inlineTextItem.style().whiteSpace();
+    return whitespace == WhiteSpace::Pre || whitespace == WhiteSpace::PreWrap;
+}
+
+static bool shouldPreserveLeadingContent(const InlineTextItem& inlineTextItem)
+{
+    if (!inlineTextItem.isWhitespace())
+        return true;
+    auto whitespace = inlineTextItem.style().whiteSpace();
+    return whitespace == WhiteSpace::Pre || whitespace == WhiteSpace::PreWrap || whitespace == WhiteSpace::BreakSpaces;
+}
+
 bool Line::isVisuallyEmpty() const
 {
     // FIXME: This should be cached instead -as the inline items are being added.
@@ -324,7 +343,7 @@
 
 void Line::appendTextContent(const InlineTextItem& inlineItem, LayoutUnit logicalWidth)
 {
-    auto isTrimmable = TextUtil::isTrimmableContent(inlineItem);
+    auto isTrimmable = !shouldPreserveTrailingContent(inlineItem);
     if (!isTrimmable)
         m_trimmableContent.clear();
 
@@ -334,18 +353,22 @@
             ASSERT(!logicalWidth);
             return true;
         }
-        if (!isTrimmable)
-            return false;
         // Leading whitespace.
         if (m_runList.isEmpty())
-            return true;
-        // Check if the last item is trimmable as well.
-        for (int index = m_runList.size() - 1; index >= 0; --index) {
-            auto& run = m_runList[index];
+            return !shouldPreserveLeadingContent(inlineItem);
+
+        if (!inlineItem.isCollapsible())
+            return false;
+        // Check if the last item is collapsed as well.
+        for (auto i = m_runList.size(); i--;) {
+            auto& run = m_runList[i];
             if (run->isBox())
                 return false;
+            // When the previous text run is collapsed, this collapsible run collapses completely.
             if (run->isText())
-                return run->isWhitespace() && run->layoutBox().style().collapseWhiteSpace();
+                return run->isCollapsed();
+            // Collapsing works across inline containers: "<span>  </span> " <- the trailing whitespace collapses completely.
+            // Not that when the inline container has preserve whitespace style, "<span style="white-space: pre">  </span> " <- this whitespace stays around. 
             ASSERT(run->isContainerStart() || run->isContainerEnd());
         }
         return true;
@@ -359,11 +382,15 @@
         logicalRect.setHeight(inlineItemContentHeight(inlineItem));
     }
 
+    auto collapseRun = inlineItem.isCollapsible();
     auto contentStart = inlineItem.start();
-    auto contentLength = inlineItem.isCollapsed() ? 1 : inlineItem.length();
+    auto contentLength =  collapseRun ? 1 : inlineItem.length();
     auto textContent = inlineItem.layoutBox().textContent().substring(contentStart, contentLength);
     auto lineItem = makeUnique<Run>(inlineItem, Display::Run { inlineItem.style(), logicalRect, Display::Run::TextContext { contentStart, contentLength, textContent } });
+
     auto isVisuallyEmpty = willCollapseCompletely();
+    if (collapseRun)
+        lineItem->setIsCollapsed();
     if (isVisuallyEmpty)
         lineItem->setVisuallyIsEmpty();
     else if (isTrimmable)

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLine.h (251328 => 251329)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLine.h	2019-10-19 23:50:32 UTC (rev 251328)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLine.h	2019-10-20 14:56:32 UTC (rev 251329)
@@ -74,6 +74,7 @@
 
         const Display::Rect& logicalRect() const { return m_displayRun.logicalRect(); }
         bool isVisuallyEmpty() const { return m_isVisuallyEmpty; }
+        bool isCollapsed() const { return m_isCollapsed; }
 
         bool isText() const { return m_inlineItem.isText(); }
         bool isBox() const { return m_inlineItem.isBox(); }
@@ -90,6 +91,7 @@
         void expand(const Run&);
 
         void setVisuallyIsEmpty() { m_isVisuallyEmpty = true; }
+        void setIsCollapsed() { m_isCollapsed = true; }
 
         bool isWhitespace() const;
         bool canBeExtended() const;
@@ -96,6 +98,7 @@
 
         const InlineItem& m_inlineItem;
         Display::Run m_displayRun;
+        bool m_isCollapsed { false };
         bool m_isVisuallyEmpty { false };
     };
     using RunList = Vector<std::unique_ptr<Run>>;

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.cpp (251328 => 251329)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.cpp	2019-10-19 23:50:32 UTC (rev 251328)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.cpp	2019-10-20 14:56:32 UTC (rev 251329)
@@ -41,7 +41,7 @@
 
     if (is<InlineTextItem>(inlineItem)) {
         auto& inlineTextItem = downcast<InlineTextItem>(inlineItem);
-        auto end = inlineTextItem.isCollapsed() ? inlineTextItem.start() + 1 : inlineTextItem.end();
+        auto end = inlineTextItem.isCollapsible() ? inlineTextItem.start() + 1 : inlineTextItem.end();
         return TextUtil::width(inlineTextItem.layoutBox(), inlineTextItem.start(), end, contentLogicalLeft);
     }
 

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineTextItem.cpp (251328 => 251329)


--- trunk/Source/WebCore/layout/inlineformatting/InlineTextItem.cpp	2019-10-19 23:50:32 UTC (rev 251328)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineTextItem.cpp	2019-10-20 14:56:32 UTC (rev 251329)
@@ -89,40 +89,37 @@
 {
     auto text = inlineBox.textContent();
     if (!text.length())
-        return inlineContent.append(makeUnique<InlineTextItem>(inlineBox, 0, 0, false, false));
+        return inlineContent.append(makeUnique<InlineTextItem>(inlineBox, 0, 0, false));
 
     auto& style = inlineBox.style();
     auto preserveNewline = style.preserveNewline();
-    auto collapseWhiteSpace = style.collapseWhiteSpace();
     LazyLineBreakIterator lineBreakIterator(text);
     unsigned currentPosition = 0;
     while (currentPosition < text.length()) {
         // Soft linebreak?
         if (isSoftLineBreak(text[currentPosition], preserveNewline)) {
-            inlineContent.append(makeUnique<InlineTextItem>(inlineBox, currentPosition, 1, true, false));
+            inlineContent.append(makeUnique<InlineTextItem>(inlineBox, currentPosition, 1, true));
             ++currentPosition;
             continue;
         }
         if (isWhitespaceCharacter(text[currentPosition], preserveNewline)) {
             auto length = moveToNextNonWhitespacePosition(text, currentPosition, preserveNewline);
-            auto isCollapsed = collapseWhiteSpace && length > 1;
-            inlineContent.append(makeUnique<InlineTextItem>(inlineBox, currentPosition, length, true, isCollapsed));
+            inlineContent.append(makeUnique<InlineTextItem>(inlineBox, currentPosition, length, true));
             currentPosition += length;
             continue;
         }
 
         auto length = moveToNextBreakablePosition(currentPosition, lineBreakIterator, style);
-        inlineContent.append(makeUnique<InlineTextItem>(inlineBox, currentPosition, length, false, false));
+        inlineContent.append(makeUnique<InlineTextItem>(inlineBox, currentPosition, length, false));
         currentPosition += length;
     }
 }
 
-InlineTextItem::InlineTextItem(const Box& inlineBox, unsigned start, unsigned length, bool isWhitespace, bool isCollapsed)
+InlineTextItem::InlineTextItem(const Box& inlineBox, unsigned start, unsigned length, bool isWhitespace)
     : InlineItem(inlineBox, Type::Text)
     , m_start(start)
     , m_length(length)
     , m_isWhitespace(isWhitespace)
-    , m_isCollapsed(isCollapsed)
 {
 }
 
@@ -130,7 +127,7 @@
 {
     RELEASE_ASSERT(splitPosition >= this->start());
     RELEASE_ASSERT(splitPosition + length <= end());
-    return makeUnique<InlineTextItem>(layoutBox(), splitPosition, length, isWhitespace(), isCollapsed());
+    return makeUnique<InlineTextItem>(layoutBox(), splitPosition, length, isWhitespace());
 }
 
 }

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineTextItem.h (251328 => 251329)


--- trunk/Source/WebCore/layout/inlineformatting/InlineTextItem.h	2019-10-19 23:50:32 UTC (rev 251328)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineTextItem.h	2019-10-20 14:56:32 UTC (rev 251329)
@@ -37,7 +37,7 @@
 public:
     static void createAndAppendTextItems(InlineItems&, const Box&);
 
-    InlineTextItem(const Box&, unsigned start, unsigned length, bool isWhitespace, bool isCollapsed);
+    InlineTextItem(const Box&, unsigned start, unsigned length, bool isWhitespace);
 
     unsigned start() const { return m_start; }
     unsigned end() const { return start() + length(); }
@@ -44,7 +44,7 @@
     unsigned length() const { return m_length; }
 
     bool isWhitespace() const { return m_isWhitespace; }
-    bool isCollapsed() const { return m_isCollapsed; }
+    bool isCollapsible() const { return isWhitespace() && style().collapseWhiteSpace(); }
 
     std::unique_ptr<InlineTextItem> split(unsigned splitPosition, unsigned length) const;
 
@@ -52,7 +52,6 @@
     unsigned m_start { 0 };
     unsigned m_length { 0 };
     bool m_isWhitespace { false };
-    bool m_isCollapsed { false };
 };
 
 }

Modified: trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.cpp (251328 => 251329)


--- trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.cpp	2019-10-19 23:50:32 UTC (rev 251328)
+++ trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.cpp	2019-10-20 14:56:32 UTC (rev 251329)
@@ -89,14 +89,6 @@
     return width;
 }
 
-bool TextUtil::isTrimmableContent(const InlineItem& inlineItem)
-{
-    if (!is<InlineTextItem>(inlineItem))
-        return false;
-    auto& inlineTextItem = downcast<InlineTextItem>(inlineItem);
-    return inlineTextItem.isWhitespace() && inlineTextItem.style().collapseWhiteSpace();
-}
-
 TextUtil::SplitData TextUtil::split(const Box& inlineBox, unsigned startPosition, unsigned length, LayoutUnit textWidth, LayoutUnit availableWidth, LayoutUnit contentLogicalLeft)
 {
     // FIXME This should take hypens into account.

Modified: trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.h (251328 => 251329)


--- trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.h	2019-10-19 23:50:32 UTC (rev 251328)
+++ trunk/Source/WebCore/layout/inlineformatting/text/TextUtil.h	2019-10-20 14:56:32 UTC (rev 251329)
@@ -36,7 +36,6 @@
 public:
     static LayoutUnit width(const Box&, unsigned from, unsigned to, LayoutUnit contentLogicalLeft);
     static Optional<unsigned> hyphenPositionBefore(const InlineItem&, unsigned from, unsigned length);
-    static bool isTrimmableContent(const InlineItem&);
     struct SplitData {
         unsigned start { 0 };
         unsigned length { 0 };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to