Title: [287453] trunk
Revision
287453
Author
[email protected]
Date
2021-12-26 22:43:31 -0800 (Sun, 26 Dec 2021)

Log Message

[LFC][IFC] Do not trim the hanging trailing content
https://bugs.webkit.org/show_bug.cgi?id=234679

Reviewed by Antti Koivisto.

Source/WebCore:

This is the final step of making the hanging content handling inline with the spec.
(https://www.w3.org/TR/css-text-3/#hang)
Since we don't (fake)trim such content when closing the line, the content width matches
the actual content on the line which also helps when it is aligned to support RTL ordering.

* layout/formattingContexts/inline/InlineLine.cpp:
(WebCore::Layout::Line::Run::removeTrailingWhitespace):
(WebCore::Layout::Line::visuallyCollapseHangingOverflowingGlyphs): Deleted.
(WebCore::Layout::Line::Run::visuallyCollapseTrailingWhitespace): Deleted.
* layout/formattingContexts/inline/InlineLine.h:
* layout/formattingContexts/inline/InlineLineBoxBuilder.cpp:
(WebCore::Layout::horizontalAlignmentOffset):
* layout/formattingContexts/inline/InlineLineBuilder.cpp:
(WebCore::Layout::LineBuilder::close):

LayoutTests:

* platform/mac/fast/text/whitespace/pre-wrap-overflow-selection-expected.txt: Progression. Matches FF and Chrome selection behavior.

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (287452 => 287453)


--- trunk/LayoutTests/ChangeLog	2021-12-27 00:46:40 UTC (rev 287452)
+++ trunk/LayoutTests/ChangeLog	2021-12-27 06:43:31 UTC (rev 287453)
@@ -1,3 +1,12 @@
+2021-12-26  Alan Bujtas  <[email protected]>
+
+        [LFC][IFC] Do not trim the hanging trailing content
+        https://bugs.webkit.org/show_bug.cgi?id=234679
+
+        Reviewed by Antti Koivisto.
+
+        * platform/mac/fast/text/whitespace/pre-wrap-overflow-selection-expected.txt: Progression. Matches FF and Chrome selection behavior.
+
 2021-12-26  Tim Nguyen  <[email protected]>
 
         Make -webkit-text-combine an inherited property

Modified: trunk/LayoutTests/platform/ios/fast/text/whitespace/pre-wrap-overflow-selection-expected.txt (287452 => 287453)


--- trunk/LayoutTests/platform/ios/fast/text/whitespace/pre-wrap-overflow-selection-expected.txt	2021-12-27 00:46:40 UTC (rev 287452)
+++ trunk/LayoutTests/platform/ios/fast/text/whitespace/pre-wrap-overflow-selection-expected.txt	2021-12-27 06:43:31 UTC (rev 287453)
@@ -21,8 +21,8 @@
       RenderBlock {HR} at (0,92) size 784x2 [border: (1px inset #000000)]
       RenderBlock {HR} at (0,198) size 784x2 [border: (1px inset #000000)]
       RenderBlock {PRE} at (0,213) size 108x78 [border: (4px solid #0000FF)]
-        RenderText {#text} at (4,4) size 100x70
-          text run at (4,4) width 100: "This   text     "
+        RenderText {#text} at (4,4) size 125x70
+          text run at (4,4) width 125: "This   text     "
           text run at (4,18) width 71: "will wrap"
           text run at (74,18) width 1: " "
           text run at (4,32) width 94: "and   fit   "

Modified: trunk/LayoutTests/platform/mac/fast/text/whitespace/pre-wrap-overflow-selection-expected.txt (287452 => 287453)


--- trunk/LayoutTests/platform/mac/fast/text/whitespace/pre-wrap-overflow-selection-expected.txt	2021-12-27 00:46:40 UTC (rev 287452)
+++ trunk/LayoutTests/platform/mac/fast/text/whitespace/pre-wrap-overflow-selection-expected.txt	2021-12-27 06:43:31 UTC (rev 287453)
@@ -21,8 +21,8 @@
       RenderBlock {HR} at (0,86) size 784x2 [border: (1px inset #000000)]
       RenderBlock {HR} at (0,197) size 784x2 [border: (1px inset #000000)]
       RenderBlock {PRE} at (0,212) size 108x83 [border: (4px solid #0000FF)]
-        RenderText {#text} at (4,4) size 100x75
-          text run at (4,4) width 100: "This   text     "
+        RenderText {#text} at (4,4) size 125x75
+          text run at (4,4) width 125: "This   text     "
           text run at (4,19) width 71: "will wrap"
           text run at (74,19) width 1: " "
           text run at (4,34) width 94: "and   fit   "

Modified: trunk/LayoutTests/platform/mac/http/tests/misc/acid3-expected.txt (287452 => 287453)


--- trunk/LayoutTests/platform/mac/http/tests/misc/acid3-expected.txt	2021-12-27 00:46:40 UTC (rev 287452)
+++ trunk/LayoutTests/platform/mac/http/tests/misc/acid3-expected.txt	2021-12-27 06:43:31 UTC (rev 287453)
@@ -54,7 +54,7 @@
                       text run at (0,90) width 8: "Y"
                       text run at (0,105) width 8: "P"
                       text run at (0,120) width 8: "E"
-                      text run at (0,135) width 0: " "
+                      text run at (0,135) width 8: " "
                       text run at (0,150) width 8: "h"
                       text run at (0,165) width 8: "t"
                       text run at (0,180) width 8: "m"

Modified: trunk/Source/WebCore/ChangeLog (287452 => 287453)


--- trunk/Source/WebCore/ChangeLog	2021-12-27 00:46:40 UTC (rev 287452)
+++ trunk/Source/WebCore/ChangeLog	2021-12-27 06:43:31 UTC (rev 287453)
@@ -1,3 +1,25 @@
+2021-12-26  Alan Bujtas  <[email protected]>
+
+        [LFC][IFC] Do not trim the hanging trailing content
+        https://bugs.webkit.org/show_bug.cgi?id=234679
+
+        Reviewed by Antti Koivisto.
+
+        This is the final step of making the hanging content handling inline with the spec.
+        (https://www.w3.org/TR/css-text-3/#hang)
+        Since we don't (fake)trim such content when closing the line, the content width matches
+        the actual content on the line which also helps when it is aligned to support RTL ordering.
+
+        * layout/formattingContexts/inline/InlineLine.cpp:
+        (WebCore::Layout::Line::Run::removeTrailingWhitespace):
+        (WebCore::Layout::Line::visuallyCollapseHangingOverflowingGlyphs): Deleted.
+        (WebCore::Layout::Line::Run::visuallyCollapseTrailingWhitespace): Deleted.
+        * layout/formattingContexts/inline/InlineLine.h:
+        * layout/formattingContexts/inline/InlineLineBoxBuilder.cpp:
+        (WebCore::Layout::horizontalAlignmentOffset):
+        * layout/formattingContexts/inline/InlineLineBuilder.cpp:
+        (WebCore::Layout::LineBuilder::close):
+
 2021-12-26  Tim Nguyen  <[email protected]>
 
         Make -webkit-text-combine an inherited property

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


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.cpp	2021-12-27 00:46:40 UTC (rev 287452)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.cpp	2021-12-27 06:43:31 UTC (rev 287453)
@@ -200,44 +200,6 @@
     m_hangingTrailingContent.reset();
 }
 
-void Line::visuallyCollapseHangingOverflowingGlyphs(InlineLayoutUnit horizontalAvailableSpace)
-{
-    ASSERT(m_trimmableTrailingContent.isEmpty());
-    // If white-space is set to pre-wrap, the UA must
-    // ...
-    // It may also visually collapse the character advance widths of any that would otherwise overflow.
-    auto overflowWidth = contentLogicalWidth() - horizontalAvailableSpace;
-    if (overflowWidth <= 0)
-        return;
-    // Let's just find the trailing pre-wrap whitespace content for now (e.g check if there are multiple trailing runs with
-    // different set of white-space values and decide if the in-between pre-wrap content should be collapsed as well.)
-    auto trimmedContentWidth = InlineLayoutUnit { };
-    for (auto& run : makeReversedRange(m_runs)) {
-        if (!run.shouldTrailingWhitespaceHang())
-            break;
-        auto visuallyCollapsibleInlineItem = run.isLineSpanningInlineBoxStart() || run.isInlineBoxStart() || run.isInlineBoxEnd() || run.hasTrailingWhitespace();
-        if (!visuallyCollapsibleInlineItem)
-            break;
-        ASSERT(!run.hasCollapsibleTrailingWhitespace());
-        auto trimmableWidth = InlineLayoutUnit { };
-        if (run.isText()) {
-            // FIXME: We should always collapse the run at a glyph boundary as the spec indicates: "collapse the character advance widths of any that would otherwise overflow"
-            // and the trimmed width should be capped at std::min(run.trailingWhitespaceWidth(), overflowWidth) for text runs. Both FF and Chrome agree.
-            trimmableWidth = run.visuallyCollapseTrailingWhitespace(overflowWidth);
-        } else {
-            trimmableWidth = run.logicalWidth();
-            run.shrinkHorizontally(trimmableWidth);
-        }
-        trimmedContentWidth += trimmableWidth;
-        overflowWidth -= trimmableWidth;
-        if (overflowWidth <= 0)
-            break;
-    }
-    // FIXME: Add support for incremental reset, where the hanging whitespace partially overflows.
-    m_hangingTrailingContent.reset();
-    m_contentLogicalWidth -= trimmedContentWidth;
-}
-
 void Line::append(const InlineItem& inlineItem, const RenderStyle& style, InlineLayoutUnit logicalWidth)
 {
     if (inlineItem.isText())
@@ -667,24 +629,12 @@
     ASSERT(m_textContent->length);
     constexpr size_t trailingTrimmableContentLength = 1;
     m_textContent->length -= trailingTrimmableContentLength;
-    visuallyCollapseTrailingWhitespace(m_trailingWhitespaceWidth);
+    shrinkHorizontally(m_trailingWhitespaceWidth);
+    m_trailingWhitespaceWidth = { };
+    m_trailingWhitespaceType = TrailingWhitespace::None;
 }
 
-InlineLayoutUnit Line::Run::visuallyCollapseTrailingWhitespace(InlineLayoutUnit tryCollapsingThisMuchSpace)
-{
-    ASSERT(hasTrailingWhitespace());
-    // This is just a visual adjustment, the text length should remain the same.
-    auto trimmedWidth = std::min(tryCollapsingThisMuchSpace, m_trailingWhitespaceWidth);
-    shrinkHorizontally(trimmedWidth);
-    m_trailingWhitespaceWidth -= trimmedWidth;
-    if (!m_trailingWhitespaceWidth) {
-        // We trimmed the trailing whitespace completely.
-        m_trailingWhitespaceType = TrailingWhitespace::None;
-    }
-    return trimmedWidth;
 }
-
 }
-}
 
 #endif

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


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.h	2021-12-27 00:46:40 UTC (rev 287452)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.h	2021-12-27 06:43:31 UTC (rev 287453)
@@ -66,7 +66,6 @@
     enum class ShouldApplyTrailingWhiteSpaceFollowedByBRQuirk { No, Yes };
     void removeTrailingTrimmableContent(ShouldApplyTrailingWhiteSpaceFollowedByBRQuirk);
     void removeHangingGlyphs();
-    void visuallyCollapseHangingOverflowingGlyphs(InlineLayoutUnit horizontalAvailableSpace);
     void applyRunExpansion(InlineLayoutUnit horizontalAvailableSpace);
 
     struct Run {
@@ -140,7 +139,6 @@
         bool hasCollapsedTrailingWhitespace() const { return m_trailingWhitespaceType == TrailingWhitespace::Collapsed; }
         TrailingWhitespace trailingWhitespaceType(const InlineTextItem&) const;
         void removeTrailingWhitespace();
-        InlineLayoutUnit visuallyCollapseTrailingWhitespace(InlineLayoutUnit tryCollapsingThisMuchSpace);
 
         bool hasTrailingLetterSpacing() const;
         InlineLayoutUnit trailingLetterSpacing() const;

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.cpp (287452 => 287453)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.cpp	2021-12-27 00:46:40 UTC (rev 287452)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.cpp	2021-12-27 06:43:31 UTC (rev 287453)
@@ -48,10 +48,10 @@
         // Note that end of last line in a paragraph is considered a forced break.
         auto isConditionalHanging = runs.last().isLineBreak() || lineContent.isLastLineWithInlineContent;
         // In some cases, a glyph at the end of a line can conditionally hang: it hangs only if it does not otherwise fit in the line prior to justification.
-        // FIXME: Only the overflowing glyphs should be considered for hanging.
-        if (isConditionalHanging)
+        if (isConditionalHanging) {
+            // FIXME: Conditional hanging needs partial overflow trimming at glyph boundary, one by one until they fit.
             contentLogicalWidth = std::min(contentLogicalWidth, lineContent.lineLogicalWidth);
-        else
+        } else
             contentLogicalWidth -= lineContent.hangingWhitespaceWidth;
     }
     auto extraHorizontalSpace = lineContent.lineLogicalWidth - contentLogicalWidth;
@@ -107,8 +107,9 @@
 {
     auto& rootStyle = lineIndex ? rootBox().firstLineStyle() : rootBox().style();
     auto rootInlineBoxAlignmentOffset = Layout::horizontalAlignmentOffset(rootStyle.textAlign(), lineContent, rootStyle.isLeftToRightDirection()).value_or(InlineLayoutUnit { });
-    auto lineBox = LineBox { rootBox(), rootInlineBoxAlignmentOffset, lineContent.contentLogicalWidth, lineIndex, lineContent.nonSpanningInlineLevelBoxCount };
-    auto lineBoxLogicalHeight = constructAndAlignInlineLevelBoxes(lineBox, lineContent.runs, lineIndex);
+    // FIXME: The overflowing hanging content should be part of the ink overflow.  
+    auto lineBox = LineBox { rootBox(), rootInlineBoxAlignmentOffset, lineContent.contentLogicalWidth - lineContent.hangingWhitespaceWidth, lineIndex, lineContent.nonSpanningInlineLevelBoxCount };
+    auto lineBoxLogicalHeight = constructAndAlignInlineLevelBoxes(lineBox, lineContent, lineIndex);
     return { lineBox, lineBoxLogicalHeight };
 }
 
@@ -203,7 +204,7 @@
     inlineBox.setLayoutBounds({ floorf(heightAndLayoutBounds.layoutBounds.ascent), ceilf(heightAndLayoutBounds.layoutBounds.descent) });
 }
 
-InlineLayoutUnit LineBoxBuilder::constructAndAlignInlineLevelBoxes(LineBox& lineBox, const Line::RunList& runs, size_t lineIndex)
+InlineLayoutUnit LineBoxBuilder::constructAndAlignInlineLevelBoxes(LineBox& lineBox, const LineBuilder::LineContent& lineContent, size_t lineIndex)
 {
     auto& rootInlineBox = lineBox.rootInlineBox();
     setInitialVerticalGeometryForInlineBox(rootInlineBox);
@@ -222,7 +223,7 @@
     };
 
     auto lineHasContent = false;
-    for (auto& run : runs) {
+    for (auto& run : lineContent.runs) {
         auto& layoutBox = run.layoutBox();
         auto& style = styleToUse(layoutBox);
         auto runHasContent = [&] () -> bool {
@@ -296,7 +297,8 @@
             // Inline box run is based on margin box. Let's convert it to border box.
             auto marginStart = formattingContext().geometryForBox(layoutBox).marginStart();
             auto initialLogicalWidth = rootInlineBox.logicalWidth() - (run.logicalLeft() + marginStart);
-            ASSERT(initialLogicalWidth >= 0);
+            ASSERT(initialLogicalWidth >= 0 || lineContent.hangingWhitespaceWidth);
+            initialLogicalWidth = std::max(initialLogicalWidth, 0.f);
             auto inlineBox = InlineLevelBox::createInlineBox(layoutBox, style, logicalLeft + marginStart, initialLogicalWidth);
             inlineBox.setIsFirstBox();
             setInitialVerticalGeometryForInlineBox(inlineBox);

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.h (287452 => 287453)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.h	2021-12-27 00:46:40 UTC (rev 287452)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.h	2021-12-27 06:43:31 UTC (rev 287453)
@@ -52,7 +52,7 @@
     void setInitialVerticalGeometryForInlineBox(InlineLevelBox&) const;
     void setVerticalGeometryForLineBreakBox(InlineLevelBox& lineBreakBox, const InlineLevelBox& parentInlineBox) const;
     void adjustVerticalGeometryForInlineBoxWithFallbackFonts(InlineLevelBox&, const TextUtil::FallbackFontList&) const;
-    InlineLayoutUnit constructAndAlignInlineLevelBoxes(LineBox&, const Line::RunList&, size_t lineIndex);
+    InlineLayoutUnit constructAndAlignInlineLevelBoxes(LineBox&, const LineBuilder::LineContent&, size_t lineIndex);
 
     const InlineFormattingContext& formattingContext() const { return m_inlineFormattingContext; }
     const Box& rootBox() const { return formattingContext().root(); }

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


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp	2021-12-27 00:46:40 UTC (rev 287452)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp	2021-12-27 06:43:31 UTC (rev 287453)
@@ -520,9 +520,7 @@
             if (!isConditionalHanging)
                 m_line.removeHangingGlyphs();
         }
-    } else
-        m_line.visuallyCollapseHangingOverflowingGlyphs(horizontalAvailableSpace);
-
+    }
     auto horizontalAlignment = root().style().textAlign();
     auto runsExpandHorizontally = horizontalAlignment == TextAlignMode::Justify && !isLastLine;
     if (runsExpandHorizontally)

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayLineBuilder.cpp (287452 => 287453)


--- trunk/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayLineBuilder.cpp	2021-12-27 00:46:40 UTC (rev 287452)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayLineBuilder.cpp	2021-12-27 06:43:31 UTC (rev 287453)
@@ -86,7 +86,7 @@
         : InlineLayoutUnit { rootGeometry.borderEnd() } + rootGeometry.paddingEnd().value_or(0_lu);
     auto contentVisualLeft = isLeftToRightDirection
         ? lineBox.rootInlineBoxAlignmentOffset()
-        : rootGeometry.contentBoxWidth() - lineOffsetFromContentBox -  lineBox.rootInlineBoxAlignmentOffset() - rootInlineBox.logicalWidth();
+        : rootGeometry.contentBoxWidth() - lineOffsetFromContentBox -  lineBox.rootInlineBoxAlignmentOffset() - rootInlineBox.logicalWidth() - lineContent.hangingWhitespaceWidth;
 
     auto lineBoxRect = InlineRect { lineContent.lineLogicalTopLeft.y(), lineBoxVisualLeft, lineContent.lineLogicalWidth, lineBoxLogicalHeight };
     auto enclosingLineGeometry = collectEnclosingLineGeometry(lineBox, lineBoxRect);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to