Title: [283485] trunk/Source/WebCore
Revision
283485
Author
[email protected]
Date
2021-10-03 18:07:25 -0700 (Sun, 03 Oct 2021)

Log Message

[LFC][IFC] HangingTrailingContent should cache width/length
https://bugs.webkit.org/show_bug.cgi?id=231128

Reviewed by Antti Koivisto.

Compute the length of the hanging trailing whitespace sequence.
This is in preparation for fixing imported/w3c/web-platform-tests/css/css-text/white-space/textarea-pre-wrap-014.html

* layout/formattingContexts/inline/InlineLine.cpp:
(WebCore::Layout::Line::Line):
(WebCore::Layout::Line::initialize):
(WebCore::Layout::Line::resetTrailingContent):
(WebCore::Layout::Line::appendTextContent):
(WebCore::Layout::Line::appendNonReplacedInlineLevelBox):
(WebCore::Layout::Line::HangingTrailingContent::add):
(WebCore::Layout::Line::HangingTrailingContent::HangingTrailingContent): Deleted.
(WebCore::Layout::Line::HangingTrailingContent::width const): Deleted.
* layout/formattingContexts/inline/InlineLine.h:
(WebCore::Layout::Line::HangingTrailingContent::length const):
(WebCore::Layout::Line::HangingTrailingContent::width const):
(WebCore::Layout::Line::HangingTrailingContent::reset):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (283484 => 283485)


--- trunk/Source/WebCore/ChangeLog	2021-10-03 23:09:02 UTC (rev 283484)
+++ trunk/Source/WebCore/ChangeLog	2021-10-04 01:07:25 UTC (rev 283485)
@@ -1,3 +1,27 @@
+2021-10-03  Alan Bujtas  <[email protected]>
+
+        [LFC][IFC] HangingTrailingContent should cache width/length
+        https://bugs.webkit.org/show_bug.cgi?id=231128
+
+        Reviewed by Antti Koivisto.
+
+        Compute the length of the hanging trailing whitespace sequence.
+        This is in preparation for fixing imported/w3c/web-platform-tests/css/css-text/white-space/textarea-pre-wrap-014.html
+
+        * layout/formattingContexts/inline/InlineLine.cpp:
+        (WebCore::Layout::Line::Line):
+        (WebCore::Layout::Line::initialize):
+        (WebCore::Layout::Line::resetTrailingContent):
+        (WebCore::Layout::Line::appendTextContent):
+        (WebCore::Layout::Line::appendNonReplacedInlineLevelBox):
+        (WebCore::Layout::Line::HangingTrailingContent::add):
+        (WebCore::Layout::Line::HangingTrailingContent::HangingTrailingContent): Deleted.
+        (WebCore::Layout::Line::HangingTrailingContent::width const): Deleted.
+        * layout/formattingContexts/inline/InlineLine.h:
+        (WebCore::Layout::Line::HangingTrailingContent::length const):
+        (WebCore::Layout::Line::HangingTrailingContent::width const):
+        (WebCore::Layout::Line::HangingTrailingContent::reset):
+
 2021-10-03  Sam Weinig  <[email protected]>
 
         WebXRSession's m_environmentBlendMode and m_interactionMode are never initialized

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.cpp (283484 => 283485)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.cpp	2021-10-03 23:09:02 UTC (rev 283484)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.cpp	2021-10-04 01:07:25 UTC (rev 283485)
@@ -43,7 +43,6 @@
 Line::Line(const InlineFormattingContext& inlineFormattingContext)
     : m_inlineFormattingContext(inlineFormattingContext)
     , m_trimmableTrailingContent(m_runs)
-    , m_hangingTrailingContent(m_runs)
 {
 }
 
@@ -56,8 +55,14 @@
     m_nonSpanningInlineLevelBoxCount = 0;
     m_contentLogicalWidth = { };
     m_runs.clear();
+    resetTrailingContent();
+}
+
+void Line::resetTrailingContent()
+{
+    m_trimmableTrailingContent.reset();
+    m_hangingTrailingContent.reset();
     m_trailingSoftHyphenWidth = { };
-    m_trimmableTrailingContent.reset();
 }
 
 void Line::removeCollapsibleContent(InlineLayoutUnit horizontalAvailableSpace)
@@ -197,6 +202,8 @@
         if (overflowWidth <= 0)
             break;
     }
+    // FIXME: Add support for incremental reset, where the hanging whitespace partially overflows.
+    m_hangingTrailingContent.reset();
     m_contentLogicalWidth -= trimmedContentWidth;
 }
 
@@ -303,22 +310,31 @@
         // Do not let negative letter spacing make the content shorter than it already is.
         m_contentLogicalWidth += std::max(0.0f, logicalWidth);
     }
-    // Set the trailing trimmable content.
-    if (inlineTextItem.isWhitespace() && !InlineTextItem::shouldPreserveSpacesAndTabs(inlineTextItem)) {
-        m_trimmableTrailingContent.addFullyTrimmableContent(m_runs.size() - 1, contentLogicalWidth() - oldContentLogicalWidth);
-        return;
+
+    // Handle trailing content, specifically whitespace and letter spacing.
+    auto lastRunIndex = m_runs.size() - 1;
+    if (inlineTextItem.isWhitespace()) {
+        if (InlineTextItem::shouldPreserveSpacesAndTabs(inlineTextItem)) {
+            m_trimmableTrailingContent.reset();
+            if (m_runs[lastRunIndex].shouldTrailingWhitespaceHang())
+                m_hangingTrailingContent.add(inlineTextItem, logicalWidth);
+        } else  {
+            m_hangingTrailingContent.reset();
+            m_trimmableTrailingContent.addFullyTrimmableContent(lastRunIndex, contentLogicalWidth() - oldContentLogicalWidth);
+        }
+        m_trailingSoftHyphenWidth = { };
+    } else {
+        resetTrailingContent();
+        if (style.letterSpacing() > 0 && !formattingContext().layoutState().shouldIgnoreTrailingLetterSpacing())
+            m_trimmableTrailingContent.addPartiallyTrimmableContent(lastRunIndex, style.letterSpacing());
+        if (inlineTextItem.hasTrailingSoftHyphen())
+            m_trailingSoftHyphenWidth = style.fontCascade().width(TextRun { StringView { style.hyphenString() } });
     }
-    // Any non-whitespace, no-trimmable content resets the existing trimmable.
-    m_trimmableTrailingContent.reset();
-    if (!formattingContext().layoutState().shouldIgnoreTrailingLetterSpacing() && !inlineTextItem.isWhitespace() && style.letterSpacing() > 0)
-        m_trimmableTrailingContent.addPartiallyTrimmableContent(m_runs.size() - 1, style.letterSpacing());
-    m_trailingSoftHyphenWidth = inlineTextItem.hasTrailingSoftHyphen() ? std::make_optional(style.fontCascade().width(TextRun { StringView { style.hyphenString() } })) : std::nullopt;
 }
 
 void Line::appendNonReplacedInlineLevelBox(const InlineItem& inlineItem, const RenderStyle& style, InlineLayoutUnit marginBoxLogicalWidth)
 {
-    m_trimmableTrailingContent.reset();
-    m_trailingSoftHyphenWidth = { };
+    resetTrailingContent();
     m_contentLogicalWidth += marginBoxLogicalWidth;
     ++m_nonSpanningInlineLevelBoxCount;
     auto marginStart = formattingContext().geometryForBox(inlineItem.layoutBox()).marginStart();
@@ -443,27 +459,14 @@
     return remove();
 }
 
-Line::HangingTrailingContent::HangingTrailingContent(const RunList& runs)
-    : m_runs(runs)
+void Line::HangingTrailingContent::add(const InlineTextItem& trailingWhitespace, InlineLayoutUnit logicalWidth)
 {
-}
-
-InlineLayoutUnit Line::HangingTrailingContent::width() const
-{
     // When a glyph at the start or end edge of a line hangs, it is not considered when measuring the line’s contents for fit, alignment, or justification.
     // Depending on the line’s alignment/justification, this can result in the mark being placed outside the line box.
     // https://drafts.csswg.org/css-text-3/#hanging
-    auto hangingWidth = InlineLayoutUnit { };
-    for (auto& run : WTF::makeReversedRange(m_runs)) {
-        if (run.isBox() || run.isLineBreak())
-            break;
-        if (run.isInlineBoxStart() || run.isInlineBoxEnd())
-            continue;
-        if (!run.hasTrailingWhitespace() || !run.shouldTrailingWhitespaceHang())
-            break;
-        hangingWidth += run.trailingWhitespaceWidth();
-    }
-    return hangingWidth;
+    ASSERT(trailingWhitespace.isWhitespace());
+    m_width += logicalWidth;
+    m_length += trailingWhitespace.length();
 }
 
 Line::Run::Run(const InlineItem& inlineItem, const RenderStyle& style, InlineLayoutUnit logicalLeft, InlineLayoutUnit logicalWidth)

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.h (283484 => 283485)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.h	2021-10-03 23:09:02 UTC (rev 283484)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.h	2021-10-04 01:07:25 UTC (rev 283485)
@@ -156,6 +156,8 @@
     void removeTrailingTrimmableContent();
     void visuallyCollapseHangingOverflow(InlineLayoutUnit horizontalAvailableSpace);
 
+    void resetTrailingContent();
+
     const InlineFormattingContext& formattingContext() const;
 
     struct TrimmableTrailingContent {
@@ -182,12 +184,15 @@
     };
 
     struct HangingTrailingContent {
-        HangingTrailingContent(const RunList&);
+        void add(const InlineTextItem& trailingWhitespace, InlineLayoutUnit logicalWidth);
+        void reset();
 
-        InlineLayoutUnit width() const;
+        size_t length() const { return m_length; }
+        InlineLayoutUnit width() const { return m_width; }
 
     private:
-        const RunList& m_runs;
+        size_t m_length { 0 };
+        InlineLayoutUnit m_width { 0 };
     };
 
     const InlineFormattingContext& m_inlineFormattingContext;
@@ -207,6 +212,12 @@
     m_partiallyTrimmableWidth = { };
 }
 
+inline void Line::HangingTrailingContent::reset()
+{
+    m_width = { };
+    m_length = { };
+}
+
 inline Line::Run::TrailingWhitespace Line::Run::trailingWhitespaceType(const InlineTextItem& inlineTextItem) const
 {
     if (!inlineTextItem.isWhitespace())
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to