Title: [279568] trunk
Revision
279568
Author
[email protected]
Date
2021-07-05 07:52:21 -0700 (Mon, 05 Jul 2021)

Log Message

[LFC][IFC] Add support for conditionally hanging glyph
https://bugs.webkit.org/show_bug.cgi?id=227676

Reviewed by Antti Koivisto.

Source/WebCore:

When a glyph at the end edge of a line hangs, it is not considered when measuring the line’s contents alignment.
If white-space is set to pre-wrap, the UA must (unconditionally) hang the trailing sequence,
unless the sequence is followed by a forced line break, in which case it must conditionally hang the sequence instead
(hang only if it does not otherwise fit in the line prior to justification).
e.g.
<div style="white-space: pre-wrap; width: 5ch; text-align: center"> 0 </p>
We center the _0_ content as the trailing whitespace does not hang here.

* layout/formattingContexts/inline/InlineFormattingGeometry.cpp:
(WebCore::Layout::hangingGlyphWidth): No need for the struct. We can handle it by returning the hanging content width.
(WebCore::Layout::horizontalAlignmentOffset):
(WebCore::Layout::HangingTrailingWhitespaceContent::width const): Deleted.
(WebCore::Layout::HangingTrailingWhitespaceContent::isConditional const): Deleted.
(WebCore::Layout::HangingTrailingWhitespaceContent::setIsConditional): Deleted.
(WebCore::Layout::HangingTrailingWhitespaceContent::expand): Deleted.
(WebCore::Layout::HangingTrailingWhitespaceContent::reset): Deleted.
(WebCore::Layout::collectHangingTrailingWhitespaceContent): Deleted.

LayoutTests:

* TestExpectations: pre-wrap-12.html is sus. All browsers fail on this one.

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (279567 => 279568)


--- trunk/LayoutTests/ChangeLog	2021-07-05 14:34:20 UTC (rev 279567)
+++ trunk/LayoutTests/ChangeLog	2021-07-05 14:52:21 UTC (rev 279568)
@@ -1,3 +1,12 @@
+2021-07-05  Alan Bujtas  <[email protected]>
+
+        [LFC][IFC] Add support for conditionally hanging glyph
+        https://bugs.webkit.org/show_bug.cgi?id=227676
+
+        Reviewed by Antti Koivisto.
+
+        * TestExpectations: pre-wrap-12.html is sus. All browsers fail on this one.
+
 2021-07-05  Philippe Normand  <[email protected]>
 
         [Media] test-webvtt.m3u8 is invalid

Modified: trunk/LayoutTests/TestExpectations (279567 => 279568)


--- trunk/LayoutTests/TestExpectations	2021-07-05 14:34:20 UTC (rev 279567)
+++ trunk/LayoutTests/TestExpectations	2021-07-05 14:52:21 UTC (rev 279568)
@@ -4347,12 +4347,11 @@
 webkit.org/b/214290 imported/w3c/web-platform-tests/css/css-text/white-space/break-spaces-with-overflow-wrap-008.html [ ImageOnlyFailure ]
 webkit.org/b/214290 imported/w3c/web-platform-tests/css/css-text/white-space/break-spaces-with-overflow-wrap-010.html [ ImageOnlyFailure ]
 webkit.org/b/214290 imported/w3c/web-platform-tests/css/css-text/white-space/eol-spaces-bidi-001.html [ ImageOnlyFailure ]
-webkit.org/b/214290 imported/w3c/web-platform-tests/css/css-text/white-space/pre-wrap-018.html [ ImageOnlyFailure ]
-webkit.org/b/214290 imported/w3c/web-platform-tests/css/css-text/white-space/pre-wrap-019.html [ ImageOnlyFailure ]
 webkit.org/b/214290 imported/w3c/web-platform-tests/css/css-text/white-space/pre-wrap-051.html [ ImageOnlyFailure ]
 webkit.org/b/214290 imported/w3c/web-platform-tests/css/css-text/white-space/pre-wrap-052.html [ ImageOnlyFailure ]
 webkit.org/b/214290 imported/w3c/web-platform-tests/css/css-text/white-space/seg-break-transformation-018.html [ ImageOnlyFailure ]
 webkit.org/b/214290 imported/w3c/web-platform-tests/css/css-text/white-space/seg-break-transformation-019.html [ ImageOnlyFailure ]
+webkit.org/b/214290 imported/w3c/web-platform-tests/css/css-text/white-space/textarea-pre-wrap-012.html [ ImageOnlyFailure ]
 webkit.org/b/214290 imported/w3c/web-platform-tests/css/css-text/white-space/textarea-pre-wrap-014.html [ ImageOnlyFailure ]
 webkit.org/b/214290 imported/w3c/web-platform-tests/css/css-text/white-space/trailing-other-space-separators-001.html [ ImageOnlyFailure ]
 webkit.org/b/214290 imported/w3c/web-platform-tests/css/css-text/white-space/trailing-other-space-separators-002.html [ ImageOnlyFailure ]

Modified: trunk/Source/WebCore/ChangeLog (279567 => 279568)


--- trunk/Source/WebCore/ChangeLog	2021-07-05 14:34:20 UTC (rev 279567)
+++ trunk/Source/WebCore/ChangeLog	2021-07-05 14:52:21 UTC (rev 279568)
@@ -1,3 +1,28 @@
+2021-07-05  Alan Bujtas  <[email protected]>
+
+        [LFC][IFC] Add support for conditionally hanging glyph
+        https://bugs.webkit.org/show_bug.cgi?id=227676
+
+        Reviewed by Antti Koivisto.
+
+        When a glyph at the end edge of a line hangs, it is not considered when measuring the line’s contents alignment.
+        If white-space is set to pre-wrap, the UA must (unconditionally) hang the trailing sequence,
+        unless the sequence is followed by a forced line break, in which case it must conditionally hang the sequence instead
+        (hang only if it does not otherwise fit in the line prior to justification).
+        e.g.
+        <div style="white-space: pre-wrap; width: 5ch; text-align: center"> 0 </p>
+        We center the _0_ content as the trailing whitespace does not hang here. 
+
+        * layout/formattingContexts/inline/InlineFormattingGeometry.cpp:
+        (WebCore::Layout::hangingGlyphWidth): No need for the struct. We can handle it by returning the hanging content width.
+        (WebCore::Layout::horizontalAlignmentOffset):
+        (WebCore::Layout::HangingTrailingWhitespaceContent::width const): Deleted.
+        (WebCore::Layout::HangingTrailingWhitespaceContent::isConditional const): Deleted.
+        (WebCore::Layout::HangingTrailingWhitespaceContent::setIsConditional): Deleted.
+        (WebCore::Layout::HangingTrailingWhitespaceContent::expand): Deleted.
+        (WebCore::Layout::HangingTrailingWhitespaceContent::reset): Deleted.
+        (WebCore::Layout::collectHangingTrailingWhitespaceContent): Deleted.
+
 2021-07-05  Alexey Shvayka  <[email protected]>
 
         Use AbortSignal's [PrivateIdentifier] whenSignalAborted() static method

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingGeometry.cpp (279567 => 279568)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingGeometry.cpp	2021-07-05 14:34:20 UTC (rev 279567)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingGeometry.cpp	2021-07-05 14:52:21 UTC (rev 279568)
@@ -83,37 +83,18 @@
     const InlineFormattingContext& m_inlineFormattingContext;
 };
 
-struct HangingTrailingWhitespaceContent {
-public:
-    void reset();
-
-    InlineLayoutUnit width() const { return m_width; }
-    bool isConditional() const { return m_isConditional; }
-
-    void setIsConditional() { m_isConditional = true; }
-    void expand(InlineLayoutUnit width) { m_width += width; }
-
-private:
-    bool m_isConditional { false };
-    InlineLayoutUnit m_width { 0 };
-};
-
-void HangingTrailingWhitespaceContent::reset()
+static InlineLayoutUnit hangingGlyphWidth(InlineLayoutUnit extraHorizontalSpace, const Line::RunList& runs, bool isLastLineWithInlineContent)
 {
-    m_isConditional = false;
-    m_width =  0;
-}
-
-static HangingTrailingWhitespaceContent collectHangingTrailingWhitespaceContent(const Line::RunList& runs, bool isLastLineWithInlineContent)
-{
-    auto hangingContent = HangingTrailingWhitespaceContent { };
-    if (isLastLineWithInlineContent)
-        hangingContent.setIsConditional();
+    // 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 isConditional = isLastLineWithInlineContent;
+    auto hangingWidth = InlineLayoutUnit { };
     for (auto& run : WTF::makeReversedRange(runs)) {
         if (run.isInlineBoxStart() || run.isInlineBoxEnd())
             continue;
         if (run.isLineBreak()) {
-            hangingContent.setIsConditional();
+            isConditional = true;
             continue;
         }
         if (!run.hasTrailingWhitespace())
@@ -122,17 +103,18 @@
         if (run.style().whiteSpace() != WhiteSpace::PreWrap)
             break;
         // This is either a normal or conditionally hanging trailing whitespace.
-        hangingContent.expand(run.trailingWhitespaceWidth());
+        hangingWidth += run.trailingWhitespaceWidth();
     }
-    return hangingContent;
+    // 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.
+    return !isConditional || extraHorizontalSpace < 0 ? hangingWidth : InlineLayoutUnit { };
 }
 
 static std::optional<InlineLayoutUnit> horizontalAlignmentOffset(const Line::RunList& runs, TextAlignMode textAlign, InlineLayoutUnit lineLogicalWidth, InlineLayoutUnit contentLogicalWidth, bool isLastLine)
 {
-    auto availableWidth = lineLogicalWidth - contentLogicalWidth;
-    auto hangingTrailingWhitespaceContent = collectHangingTrailingWhitespaceContent(runs, isLastLine);
-    availableWidth += hangingTrailingWhitespaceContent.width();
-    if (availableWidth <= 0)
+    auto extraHorizontalSpace = lineLogicalWidth - contentLogicalWidth;
+    // Depending on the line’s alignment/justification, the hanging glyph can be placed outside the line box.
+    extraHorizontalSpace += hangingGlyphWidth(extraHorizontalSpace, runs, isLastLine);
+    if (extraHorizontalSpace <= 0)
         return { };
 
     auto computedHorizontalAlignment = [&] {
@@ -154,10 +136,10 @@
     case TextAlignMode::Right:
     case TextAlignMode::WebKitRight:
     case TextAlignMode::End:
-        return availableWidth;
+        return extraHorizontalSpace;
     case TextAlignMode::Center:
     case TextAlignMode::WebKitCenter:
-        return availableWidth / 2;
+        return extraHorizontalSpace / 2;
     case TextAlignMode::Justify:
         // TextAlignMode::Justify is a run alignment (and we only do inline box alignment here)
         return { };
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to