Title: [287437] trunk/Source/WebCore
Revision
287437
Author
[email protected]
Date
2021-12-25 07:36:13 -0800 (Sat, 25 Dec 2021)

Log Message

[LFC][IFC] InlineContentBreaker should know about the hanging content width
https://bugs.webkit.org/show_bug.cgi?id=234662

Reviewed by Antti Koivisto.

Pass in the trailing hanging content width to InlineContentBreaker as this specific type
of content (e.g. pre-wrap whitespace) should be ignored when checking for content fit.

(Note that we already ignore it through the shouldKeepEndOfLineWhitespace() call in
InlineContentBreaker::processOverflowingContent, but this patch is in preparation for making hanging content logic
more inline with the spec. -and also removing shouldKeepEndOfLineWhitespace needs some more changes.)

* layout/formattingContexts/inline/InlineContentBreaker.cpp:
(WebCore::Layout::InlineContentBreaker::processOverflowingContent const):
* layout/formattingContexts/inline/InlineContentBreaker.h:
* layout/formattingContexts/inline/InlineLine.h:
(WebCore::Layout::Line::hangingTrailingContentWidth const):
(WebCore::Layout::Line::hangingWhitespaceWidth const): Deleted.
* layout/formattingContexts/inline/InlineLineBuilder.cpp:
(WebCore::Layout::LineBuilder::layoutInlineContent):
(WebCore::Layout::LineBuilder::handleInlineContent):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (287436 => 287437)


--- trunk/Source/WebCore/ChangeLog	2021-12-25 10:13:53 UTC (rev 287436)
+++ trunk/Source/WebCore/ChangeLog	2021-12-25 15:36:13 UTC (rev 287437)
@@ -1,3 +1,27 @@
+2021-12-25  Alan Bujtas  <[email protected]>
+
+        [LFC][IFC] InlineContentBreaker should know about the hanging content width
+        https://bugs.webkit.org/show_bug.cgi?id=234662
+
+        Reviewed by Antti Koivisto.
+
+        Pass in the trailing hanging content width to InlineContentBreaker as this specific type
+        of content (e.g. pre-wrap whitespace) should be ignored when checking for content fit.
+
+        (Note that we already ignore it through the shouldKeepEndOfLineWhitespace() call in
+        InlineContentBreaker::processOverflowingContent, but this patch is in preparation for making hanging content logic
+        more inline with the spec. -and also removing shouldKeepEndOfLineWhitespace needs some more changes.)
+
+        * layout/formattingContexts/inline/InlineContentBreaker.cpp:
+        (WebCore::Layout::InlineContentBreaker::processOverflowingContent const):
+        * layout/formattingContexts/inline/InlineContentBreaker.h:
+        * layout/formattingContexts/inline/InlineLine.h:
+        (WebCore::Layout::Line::hangingTrailingContentWidth const):
+        (WebCore::Layout::Line::hangingWhitespaceWidth const): Deleted.
+        * layout/formattingContexts/inline/InlineLineBuilder.cpp:
+        (WebCore::Layout::LineBuilder::layoutInlineContent):
+        (WebCore::Layout::LineBuilder::handleInlineContent):
+
 2021-12-24  Tim Nguyen  <[email protected]>
 
         Unreviewed, remove -webkit-svg-shadow from CSSProperties.json

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


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp	2021-12-25 10:13:53 UTC (rev 287436)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp	2021-12-25 15:36:13 UTC (rev 287437)
@@ -166,29 +166,39 @@
     ASSERT(!continuousContent.runs().isEmpty());
 
     ASSERT(continuousContent.logicalWidth() > lineStatus.availableWidth);
-    if (continuousContent.hasCollapsibleContent()) {
-        if (lineStatus.hasFullyCollapsibleTrailingContent && continuousContent.isFullyCollapsible()) {
-            // If this new content is fully collapsible, it should surely fit.
-            return { Result::Action::Keep, IsEndOfLine::No };
+    auto checkForTrailingContentFit = [&]() -> std::optional<InlineContentBreaker::Result> {
+        if (continuousContent.hasCollapsibleContent()) {
+            // Check if the content fits if we collapsed it.
+            if (continuousContent.isFullyCollapsible()) {
+                if (lineStatus.hasFullyCollapsibleTrailingContent || lineStatus.availableWidth >= 0) {
+                    // If this new content is fully collapsible, it should surely fit.
+                    return InlineContentBreaker::Result { Result::Action::Keep, IsEndOfLine::No };
+                }
+            }
+            auto spaceRequired = continuousContent.logicalWidth() - continuousContent.trailingCollapsibleWidth();
+            if (lineStatus.hasFullyCollapsibleTrailingContent)
+                spaceRequired -= continuousContent.leadingCollapsibleWidth();
+            if (spaceRequired <= lineStatus.availableWidth)
+                return InlineContentBreaker::Result { Result::Action::Keep, IsEndOfLine::No };
         }
-        // Check if the content fits if we collapsed it.
-        auto spaceRequired = continuousContent.logicalWidth() - continuousContent.trailingCollapsibleWidth();
-        if (lineStatus.hasFullyCollapsibleTrailingContent)
-            spaceRequired -= continuousContent.leadingCollapsibleWidth();
-        if (spaceRequired <= lineStatus.availableWidth)
-            return { Result::Action::Keep, IsEndOfLine::No };
-    } else if (lineStatus.collapsibleWidth && isNonContentRunsOnly(continuousContent)) {
-        // Let's see if the non-content runs fit when the line has trailing collapsible content.
-        // "text content <span style="padding: 1px"></span>" <- the <span></span> runs could fit after collapsing the trailing whitespace.
-        if (continuousContent.logicalWidth() <= lineStatus.availableWidth + lineStatus.collapsibleWidth)
-            return { Result::Action::Keep };
-    }
-    if (isVisuallyEmptyWhitespaceContent(continuousContent) && shouldKeepEndOfLineWhitespace(continuousContent)) {
-        // This overflowing content apparently falls into the remove/hang end-of-line-spaces category.
-        // see https://www.w3.org/TR/css-text-3/#white-space-property matrix
-        return { Result::Action::Keep };
-    }
 
+        auto canIgnoreNonContentTrailingRuns = lineStatus.collapsibleOrHangingWidth && isNonContentRunsOnly(continuousContent);
+        if (canIgnoreNonContentTrailingRuns) {
+            // Let's see if the non-content runs fit when the line has trailing collapsible/hanging content.
+            // "text content <span style="padding: 1px"></span>" <- the <span></span> runs could fit after collapsing the trailing whitespace.
+            if (continuousContent.logicalWidth() <= lineStatus.availableWidth + lineStatus.collapsibleOrHangingWidth)
+                return InlineContentBreaker::Result { Result::Action::Keep };
+        }
+        if (isVisuallyEmptyWhitespaceContent(continuousContent) && shouldKeepEndOfLineWhitespace(continuousContent)) {
+            // This overflowing content apparently falls into the remove/hang end-of-line-spaces category.
+            // see https://www.w3.org/TR/css-text-3/#white-space-property matrix
+            return InlineContentBreaker::Result { Result::Action::Keep };
+        }
+        return { };
+    };
+    if (auto result = checkForTrailingContentFit())
+        return *result;
+
     size_t overflowingRunIndex = 0;
     if (hasTextRun(continuousContent)) {
         auto tryBreakingContentWithText = [&]() -> std::optional<Result> {

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


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.h	2021-12-25 10:13:53 UTC (rev 287436)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.h	2021-12-25 15:36:13 UTC (rev 287437)
@@ -110,7 +110,8 @@
     struct LineStatus {
         InlineLayoutUnit contentLogicalRight { 0 };
         InlineLayoutUnit availableWidth { 0 };
-        InlineLayoutUnit collapsibleWidth { 0 };
+        // Both of these types of trailing content may be ignored when checking for content fit.
+        InlineLayoutUnit collapsibleOrHangingWidth { 0 };
         std::optional<InlineLayoutUnit> trailingSoftHyphenWidth;
         bool hasFullyCollapsibleTrailingContent { false };
         bool hasContent { false };

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


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.h	2021-12-25 10:13:53 UTC (rev 287436)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.h	2021-12-25 15:36:13 UTC (rev 287437)
@@ -58,7 +58,7 @@
     InlineLayoutUnit trimmableTrailingWidth() const { return m_trimmableTrailingContent.width(); }
     bool isTrailingRunFullyTrimmable() const { return m_trimmableTrailingContent.isTrailingRunFullyTrimmable(); }
 
-    InlineLayoutUnit hangingWhitespaceWidth() const { return m_hangingTrailingContent.width(); }
+    InlineLayoutUnit hangingTrailingContentWidth() const { return m_hangingTrailingContent.width(); }
 
     std::optional<InlineLayoutUnit> trailingSoftHyphenWidth() const { return m_trailingSoftHyphenWidth; }
     void addTrailingHyphen(InlineLayoutUnit hyphenLogicalWidth);

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


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp	2021-12-25 10:13:53 UTC (rev 287436)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp	2021-12-25 15:36:13 UTC (rev 287437)
@@ -341,7 +341,7 @@
         , m_lineLogicalRect.topLeft()
         , m_lineLogicalRect.width()
         , m_line.contentLogicalWidth()
-        , m_line.hangingWhitespaceWidth()
+        , m_line.hangingTrailingContentWidth()
         , isLastLine
         , m_line.nonSpanningInlineLevelBoxCount()
         , computedVisualOrder()
@@ -860,7 +860,21 @@
     // While the floats are not considered to be on the line, they make the line contentful for line breaking.
     auto availableWidthForNewContent = availableWidth(inlineContent, m_line, lineLogicalRectForCandidateContent.width());
     auto lineHasContent = m_line.hasContent() || m_contentIsConstrainedByFloat;
-    auto lineStatus = InlineContentBreaker::LineStatus { m_line.contentLogicalRight(), availableWidthForNewContent, m_line.trimmableTrailingWidth(), m_line.trailingSoftHyphenWidth(), m_line.isTrailingRunFullyTrimmable(), lineHasContent, !m_wrapOpportunityList.isEmpty() };
+    auto trailingContentWidthToIgnore = [&] {
+        if (auto trimmableWidth = m_line.trimmableTrailingWidth()) {
+            ASSERT(!m_line.hangingTrailingContentWidth());
+            return trimmableWidth;
+        }
+        return m_line.hangingTrailingContentWidth();
+    };
+    auto lineStatus = InlineContentBreaker::LineStatus { m_line.contentLogicalRight()
+        , availableWidthForNewContent
+        , trailingContentWidthToIgnore()
+        , m_line.trailingSoftHyphenWidth()
+        , m_line.isTrailingRunFullyTrimmable()
+        , lineHasContent
+        , !m_wrapOpportunityList.isEmpty()
+    };
     auto result = inlineContentBreaker.processInlineContent(continuousInlineContent, lineStatus);
     auto& candidateRuns = continuousInlineContent.runs();
     if (result.action == InlineContentBreaker::Result::Action::Keep) {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to