Title: [287442] trunk/Source/WebCore
Revision
287442
Author
[email protected]
Date
2021-12-25 22:16:27 -0800 (Sat, 25 Dec 2021)

Log Message

[LFC][IFC] Turn InlineContentBreaker::ContinuousContent's leading/trailing member variables to std::optional<InlineLayoutUnit>
https://bugs.webkit.org/show_bug.cgi?id=234676

Reviewed by Antti Koivisto.

While an empty (logical width = 0) ContinuousContent takes up no space, it should not be mistaken for collapsed content
(i.e when m_logicalWidth(0) == m_trailingCollapsibleWidth(0), hasCollapsibleContent() should still return false)

* layout/formattingContexts/inline/InlineContentBreaker.cpp:
(WebCore::Layout::InlineContentBreaker::processOverflowingContent const):
(WebCore::Layout::InlineContentBreaker::tryBreakingOverflowingRun const):
(WebCore::Layout::InlineContentBreaker::tryBreakingPreviousNonOverflowingRuns const):
(WebCore::Layout::InlineContentBreaker::ContinuousContent::appendToRunList): Add a dedicated function to deal with append and logicalWidth.
(WebCore::Layout::InlineContentBreaker::ContinuousContent::resetTrailingWhitespace): Turn trailing whitespace into leading if applicable.
(WebCore::Layout::InlineContentBreaker::ContinuousContent::append): Add dedicated functions for each inline item types.
* layout/formattingContexts/inline/InlineContentBreaker.h:
(WebCore::Layout::InlineContentBreaker::ContinuousContent::leadingCollapsibleWidth const):
(WebCore::Layout::InlineContentBreaker::ContinuousContent::trailingCollapsibleWidth const):
(WebCore::Layout::InlineContentBreaker::ContinuousContent::hasCollapsibleContent const):
(WebCore::Layout::InlineContentBreaker::ContinuousContent::isFullyCollapsible const):
* layout/formattingContexts/inline/InlineLineBuilder.cpp:
(WebCore::Layout::LineCandidate::InlineContent::appendInlineItem):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (287441 => 287442)


--- trunk/Source/WebCore/ChangeLog	2021-12-26 06:10:32 UTC (rev 287441)
+++ trunk/Source/WebCore/ChangeLog	2021-12-26 06:16:27 UTC (rev 287442)
@@ -1,5 +1,30 @@
 2021-12-25  Alan Bujtas  <[email protected]>
 
+        [LFC][IFC] Turn InlineContentBreaker::ContinuousContent's leading/trailing member variables to std::optional<InlineLayoutUnit>
+        https://bugs.webkit.org/show_bug.cgi?id=234676
+
+        Reviewed by Antti Koivisto.
+
+        While an empty (logical width = 0) ContinuousContent takes up no space, it should not be mistaken for collapsed content
+        (i.e when m_logicalWidth(0) == m_trailingCollapsibleWidth(0), hasCollapsibleContent() should still return false)
+
+        * layout/formattingContexts/inline/InlineContentBreaker.cpp:
+        (WebCore::Layout::InlineContentBreaker::processOverflowingContent const):
+        (WebCore::Layout::InlineContentBreaker::tryBreakingOverflowingRun const):
+        (WebCore::Layout::InlineContentBreaker::tryBreakingPreviousNonOverflowingRuns const):
+        (WebCore::Layout::InlineContentBreaker::ContinuousContent::appendToRunList): Add a dedicated function to deal with append and logicalWidth.
+        (WebCore::Layout::InlineContentBreaker::ContinuousContent::resetTrailingWhitespace): Turn trailing whitespace into leading if applicable.
+        (WebCore::Layout::InlineContentBreaker::ContinuousContent::append): Add dedicated functions for each inline item types.
+        * layout/formattingContexts/inline/InlineContentBreaker.h:
+        (WebCore::Layout::InlineContentBreaker::ContinuousContent::leadingCollapsibleWidth const):
+        (WebCore::Layout::InlineContentBreaker::ContinuousContent::trailingCollapsibleWidth const):
+        (WebCore::Layout::InlineContentBreaker::ContinuousContent::hasCollapsibleContent const):
+        (WebCore::Layout::InlineContentBreaker::ContinuousContent::isFullyCollapsible const):
+        * layout/formattingContexts/inline/InlineLineBuilder.cpp:
+        (WebCore::Layout::LineCandidate::InlineContent::appendInlineItem):
+
+2021-12-25  Alan Bujtas  <[email protected]>
+
         [LFC][IFC] Remove redundant InlineContentBreaker::shouldKeepEndOfLineWhitespace
         https://bugs.webkit.org/show_bug.cgi?id=234668
 

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp (287441 => 287442)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp	2021-12-26 06:10:32 UTC (rev 287441)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp	2021-12-26 06:16:27 UTC (rev 287442)
@@ -163,9 +163,9 @@
                 // If this new content is fully collapsible, it should surely fit.
                 return InlineContentBreaker::Result { Result::Action::Keep };
             } else {
-                auto spaceRequired = continuousContent.logicalWidth() - continuousContent.trailingCollapsibleWidth();
+                auto spaceRequired = continuousContent.logicalWidth() - continuousContent.trailingCollapsibleWidth().value_or(0.f);
                 if (lineStatus.hasFullyCollapsibleTrailingContent || isVisuallyEmptyWhitespaceContent(continuousContent))
-                    spaceRequired -= continuousContent.leadingCollapsibleWidth();
+                    spaceRequired -= continuousContent.leadingCollapsibleWidth().value_or(0.f);
                 if (spaceRequired <= lineStatus.availableWidth)
                     return InlineContentBreaker::Result { Result::Action::Keep };
             }
@@ -513,8 +513,8 @@
     if (!isWrappableRun(overflowingRun))
         return { };
 
-    auto avilableWidth = std::max(0.0f, lineStatus.availableWidth - nonOverflowingContentWidth);
-    auto partialOverflowingRun = tryBreakingTextRun(runs, { overflowingRunIndex, true, lineStatus.contentLogicalRight + nonOverflowingContentWidth }, avilableWidth, lineStatus.hasWrapOpportunityAtPreviousPosition);
+    auto availableWidth = std::max(0.f, lineStatus.availableWidth - nonOverflowingContentWidth);
+    auto partialOverflowingRun = tryBreakingTextRun(runs, { overflowingRunIndex, true, lineStatus.contentLogicalRight + nonOverflowingContentWidth }, availableWidth, lineStatus.hasWrapOpportunityAtPreviousPosition);
     if (!partialOverflowingRun)
         return { };
     if (partialOverflowingRun->length)
@@ -536,8 +536,8 @@
         if (!isWrappableRun(run))
             continue;
         ASSERT(run.inlineItem.isText());
-        auto avilableWidth = std::max(0.0f, lineStatus.availableWidth - previousContentWidth);
-        if (auto partialRun = tryBreakingTextRun(runs, { index, false, lineStatus.contentLogicalRight + previousContentWidth }, avilableWidth, lineStatus.hasWrapOpportunityAtPreviousPosition)) {
+        auto availableWidth = std::max(0.f, lineStatus.availableWidth - previousContentWidth);
+        if (auto partialRun = tryBreakingTextRun(runs, { index, false, lineStatus.contentLogicalRight + previousContentWidth }, availableWidth, lineStatus.hasWrapOpportunityAtPreviousPosition)) {
             // We know this run fits, so if breaking is allowed on the run, it should return a non-empty left-side
             // since it's either at hyphen position or the entire run is returned.
             ASSERT(partialRun->length);
@@ -679,26 +679,47 @@
     return includeHyphenationIfAllowed({ });
 }
 
-void InlineContentBreaker::ContinuousContent::append(const InlineItem& inlineItem, const RenderStyle& style, InlineLayoutUnit logicalWidth, std::optional<InlineLayoutUnit> collapsibleWidth)
+void InlineContentBreaker::ContinuousContent::appendToRunList(const InlineItem& inlineItem, const RenderStyle& style, InlineLayoutUnit logicalWidth)
 {
-    ASSERT(inlineItem.isText() || inlineItem.isBox() || inlineItem.isInlineBoxStart() || inlineItem.isInlineBoxEnd());
-    auto isLeadingCollapsible = collapsibleWidth && (m_runs.isEmpty() || isFullyCollapsible());
     m_runs.append({ inlineItem, style, logicalWidth });
     m_logicalWidth = clampTo<InlineLayoutUnit>(m_logicalWidth + logicalWidth);
+}
+
+void InlineContentBreaker::ContinuousContent::resetTrailingWhitespace()
+{
+    if (!m_leadingCollapsibleWidth)
+        m_leadingCollapsibleWidth = m_trailingCollapsibleWidth;
+    m_trailingCollapsibleWidth = { };
+}
+
+void InlineContentBreaker::ContinuousContent::append(const InlineItem& inlineItem, const RenderStyle& style, InlineLayoutUnit logicalWidth)
+{
+    ASSERT(inlineItem.isBox() || inlineItem.isInlineBoxStart() || inlineItem.isInlineBoxEnd());
+    appendToRunList(inlineItem, style, logicalWidth);
+    if (inlineItem.isBox()) {
+        // Inline boxes (whitespace-> <span></span>) do not prevent the trailing content from getting collapsed/hung
+        // but atomic inline level boxes do.
+        resetTrailingWhitespace();
+    }
+}
+
+void InlineContentBreaker::ContinuousContent::append(const InlineTextItem& inlineTextItem, const RenderStyle& style, InlineLayoutUnit logicalWidth, std::optional<InlineLayoutUnit> collapsibleWidth)
+{
     if (!collapsibleWidth) {
-        if (inlineItem.isText() || inlineItem.isBox()) {
-            // Inline boxes do not prevent the trailing content from getting collapsed.
-            m_trailingCollapsibleWidth = { };
-        }
+        appendToRunList(inlineTextItem, style, logicalWidth);
+        resetTrailingWhitespace();
         return;
     }
+
     ASSERT(*collapsibleWidth <= logicalWidth);
+    auto isLeadingCollapsible = collapsibleWidth && (!this->logicalWidth() || isFullyCollapsible());
+    appendToRunList(inlineTextItem, style, logicalWidth);
     if (isLeadingCollapsible) {
         ASSERT(!m_trailingCollapsibleWidth);
-        m_leadingCollapsibleWidth += *collapsibleWidth;
+        m_leadingCollapsibleWidth = m_leadingCollapsibleWidth.value_or(0.f) + *collapsibleWidth;
         return;
     }
-    m_trailingCollapsibleWidth = *collapsibleWidth == logicalWidth ? m_trailingCollapsibleWidth + logicalWidth : *collapsibleWidth;
+    m_trailingCollapsibleWidth = *collapsibleWidth == logicalWidth ? m_trailingCollapsibleWidth.value_or(0.f) + logicalWidth : *collapsibleWidth;
 }
 
 void InlineContentBreaker::ContinuousContent::reset()

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.h (287441 => 287442)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.h	2021-12-26 06:10:32 UTC (rev 287441)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.h	2021-12-26 06:16:27 UTC (rev 287442)
@@ -35,6 +35,7 @@
 namespace Layout {
 
 class InlineItem;
+class InlineTextItem;
 struct CandidateTextRunForBreaking;
 
 class InlineContentBreaker {
@@ -80,12 +81,13 @@
     // see https://drafts.csswg.org/css-text-3/#line-break-details
     struct ContinuousContent {
         InlineLayoutUnit logicalWidth() const { return m_logicalWidth; }
-        InlineLayoutUnit leadingCollapsibleWidth() const { return m_leadingCollapsibleWidth; }
-        InlineLayoutUnit trailingCollapsibleWidth() const { return m_trailingCollapsibleWidth; }
-        bool hasCollapsibleContent() const { return trailingCollapsibleWidth() > 0 || leadingCollapsibleWidth() > 0; }
-        bool isFullyCollapsible() const { return logicalWidth() == trailingCollapsibleWidth() + leadingCollapsibleWidth(); }
+        std::optional<InlineLayoutUnit> leadingCollapsibleWidth() const { return m_leadingCollapsibleWidth; }
+        std::optional<InlineLayoutUnit> trailingCollapsibleWidth() const { return m_trailingCollapsibleWidth; }
+        bool hasCollapsibleContent() const { return trailingCollapsibleWidth() || leadingCollapsibleWidth(); }
+        bool isFullyCollapsible() const;
 
-        void append(const InlineItem&, const RenderStyle&, InlineLayoutUnit logicalWidth, std::optional<InlineLayoutUnit> collapsibleWidth = std::nullopt);
+        void append(const InlineItem&, const RenderStyle&, InlineLayoutUnit logicalWidth);
+        void append(const InlineTextItem&, const RenderStyle&, InlineLayoutUnit logicalWidth, std::optional<InlineLayoutUnit> collapsibleWidth);
         void reset();
 
         struct Run {
@@ -101,10 +103,13 @@
         const RunList& runs() const { return m_runs; }
 
     private:
+        void appendToRunList(const InlineItem&, const RenderStyle&, InlineLayoutUnit logicalWidth);
+        void resetTrailingWhitespace();
+
         RunList m_runs;
         InlineLayoutUnit m_logicalWidth { 0 };
-        InlineLayoutUnit m_leadingCollapsibleWidth { 0 };
-        InlineLayoutUnit m_trailingCollapsibleWidth { 0 };
+        std::optional<InlineLayoutUnit> m_leadingCollapsibleWidth { };
+        std::optional<InlineLayoutUnit> m_trailingCollapsibleWidth { };
     };
 
     struct LineStatus {
@@ -171,6 +176,16 @@
 {
 }
 
+inline bool InlineContentBreaker::ContinuousContent::isFullyCollapsible() const
+{
+    auto collapsibleWidth = std::optional<InlineLayoutUnit> { };
+    if (m_leadingCollapsibleWidth)
+        collapsibleWidth = *m_leadingCollapsibleWidth;
+    if (m_trailingCollapsibleWidth)
+        collapsibleWidth = collapsibleWidth.value_or(0.f) + *m_trailingCollapsibleWidth;
+    return collapsibleWidth && *collapsibleWidth == logicalWidth();
 }
+
 }
+}
 #endif

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp (287441 => 287442)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp	2021-12-26 06:10:32 UTC (rev 287441)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp	2021-12-26 06:16:27 UTC (rev 287442)
@@ -193,25 +193,33 @@
 inline void LineCandidate::InlineContent::appendInlineItem(const InlineItem& inlineItem, const RenderStyle& style, InlineLayoutUnit logicalWidth)
 {
     ASSERT(inlineItem.isText() || inlineItem.isBox() || inlineItem.isInlineBoxStart() || inlineItem.isInlineBoxEnd());
-    auto collapsibleWidth = [&]() -> std::optional<InlineLayoutUnit> {
-        if (!inlineItem.isText())
-            return { };
+    m_hasInlineLevelBox = m_hasInlineLevelBox || inlineItem.isBox() || inlineItem.isInlineBoxStart();
+
+    if (inlineItem.isBox() || inlineItem.isInlineBoxStart() || inlineItem.isInlineBoxEnd())
+        return m_continuousContent.append(inlineItem, style, logicalWidth);
+
+    if (inlineItem.isText()) {
         auto& inlineTextItem = downcast<InlineTextItem>(inlineItem);
-        if (inlineTextItem.isWhitespace() && !InlineTextItem::shouldPreserveSpacesAndTabs(inlineTextItem)) {
-            // Fully collapsible trailing content.
-            return logicalWidth;
-        }
-        // Check for partially collapsible content.
-        if (m_ignoreTrailingLetterSpacing)
-            return { };
-        auto letterSpacing = style.letterSpacing();
-        if (letterSpacing <= 0)
-            return { };
-        ASSERT(logicalWidth > letterSpacing);
-        return letterSpacing;
-    };
-    m_continuousContent.append(inlineItem, style, logicalWidth, collapsibleWidth());
-    m_hasInlineLevelBox = m_hasInlineLevelBox || inlineItem.isBox() || inlineItem.isInlineBoxStart();
+        auto isWhitespace = inlineTextItem.isWhitespace();
+
+        auto collapsibleWidth = [&]() -> std::optional<InlineLayoutUnit> {
+            if (isWhitespace && !InlineTextItem::shouldPreserveSpacesAndTabs(inlineTextItem)) {
+                // Fully collapsible trailing content.
+                return logicalWidth;
+            }
+            // Check for partially collapsible content.
+            if (m_ignoreTrailingLetterSpacing)
+                return { };
+            auto letterSpacing = style.letterSpacing();
+            if (letterSpacing <= 0)
+                return { };
+            ASSERT(logicalWidth > letterSpacing);
+            return letterSpacing;
+        };
+        m_continuousContent.append(inlineTextItem, style, logicalWidth, collapsibleWidth());
+        return;
+    }
+    ASSERT_NOT_REACHED();
 }
 
 inline void LineCandidate::InlineContent::reset()
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to