Title: [294828] trunk
Revision
294828
Author
[email protected]
Date
2022-05-25 15:29:46 -0700 (Wed, 25 May 2022)

Log Message

[LFC][IFC] Support each-line keyword in text-indent
https://bugs.webkit.org/show_bug.cgi?id=240731

Patch by Kiet Ho <[email protected]> on 2022-05-25
Reviewed by Alan Bujtas.

Normally, text-indent only affects the first line. When 'each-line' is specified,
subsequent lines where the previous line ends with a hard break are also indented.
This is supported in the legacy layout engine but not in LFC. Adds support for
'each-line' to bring LFC to parity with the legacy engine.

Test: imported/w3c/web-platform-tests/css/css-text/text-indent/text-indent-each-line-hanging.html

* LayoutTests/TestExpectations: Remove ImageOnlyFailure expectation.
* Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp:
(WebCore::Layout::LineBuilder::layoutInlineContent):
(WebCore::Layout::LineBuilder::computedIntrinsicWidth):
(WebCore::Layout::LineBuilder::initialConstraintsForLine const): Add logic to
indent line when 'each-line' is specified, and the previous line ends with a
hard break.
* Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.h:
* Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.h: Modify
initialConstraintsForLine to accept information about the previous line,
not just whether there's one or not.

Canonical link: https://commits.webkit.org/250978@main

Modified Paths

Diff

Modified: trunk/LayoutTests/TestExpectations (294827 => 294828)


--- trunk/LayoutTests/TestExpectations	2022-05-25 22:14:56 UTC (rev 294827)
+++ trunk/LayoutTests/TestExpectations	2022-05-25 22:29:46 UTC (rev 294828)
@@ -2651,7 +2651,6 @@
 webkit.org/b/214290 imported/w3c/web-platform-tests/css/css-text/text-indent/text-indent-tab-positions-001.html [ ImageOnlyFailure ]
 webkit.org/b/240837 imported/w3c/web-platform-tests/css/css-text/text-indent/anonymous-flex-item-001.html [ ImageOnlyFailure ]
 webkit.org/b/240837 imported/w3c/web-platform-tests/css/css-text/text-indent/anonymous-grid-item-001.html [ ImageOnlyFailure ]
-webkit.org/b/240731 imported/w3c/web-platform-tests/css/css-text/text-indent/text-indent-each-line-hanging.html [ ImageOnlyFailure ]
 webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/text-justify/text-justify-001.html [ ImageOnlyFailure ]
 webkit.org/b/214290 imported/w3c/web-platform-tests/css/css-text/text-justify/text-justify-006.html [ ImageOnlyFailure ]
 webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-capitalize-018.html [ ImageOnlyFailure Pass ]

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


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp	2022-05-25 22:14:56 UTC (rev 294827)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp	2022-05-25 22:29:46 UTC (rev 294828)
@@ -321,7 +321,7 @@
 };
 LineBuilder::LineContent LineBuilder::layoutInlineContent(const InlineItemRange& needsLayoutRange, const InlineRect& lineLogicalRect, const std::optional<PreviousLine>& previousLine)
 {
-    initialize(initialConstraintsForLine(lineLogicalRect, !previousLine), needsLayoutRange.start, previousLine);
+    initialize(initialConstraintsForLine(lineLogicalRect, previousLine), needsLayoutRange.start, previousLine);
 
     auto committedContent = placeInlineContent(needsLayoutRange);
     auto committedRange = close(needsLayoutRange, committedContent);
@@ -400,7 +400,7 @@
 {
     ASSERT(isInIntrinsicWidthMode());
     auto lineLogicalWidth = *intrinsicWidthMode() == IntrinsicWidthMode::Maximum ? maxInlineLayoutUnit() : 0.f;
-    auto lineConstraints = initialConstraintsForLine({ 0, 0, lineLogicalWidth, 0 }, !previousLine);
+    auto lineConstraints = initialConstraintsForLine({ 0, 0, lineLogicalWidth, 0 }, previousLine);
     initialize(lineConstraints, needsLayoutRange.start, previousLine);
 
     auto committedContent = placeInlineContent(needsLayoutRange);
@@ -627,7 +627,7 @@
     return HorizontalConstraints { toLayoutUnit(lineLogicalLeft), toLayoutUnit(lineLogicalRight - lineLogicalLeft) };
 }
 
-UsedConstraints LineBuilder::initialConstraintsForLine(const InlineRect& initialLineLogicalRect, bool isFirstLine) const
+UsedConstraints LineBuilder::initialConstraintsForLine(const InlineRect& initialLineLogicalRect, const std::optional<PreviousLine>& previousLine) const
 {
     auto lineLogicalLeft = initialLineLogicalRect.left();
     auto lineLogicalRight = initialLineLogicalRect.right();
@@ -640,31 +640,32 @@
     }
 
     auto computedTextIndent = [&]() -> InlineLayoutUnit {
+        auto& root = this->root();
+
         // text-indent property specifies the indentation applied to lines of inline content in a block.
         // The indent is treated as a margin applied to the start edge of the line box.
-        // Unless otherwise specified, only lines that are the first formatted line of an element are affected.
-        // For example, the first line of an anonymous block box is only affected if it is the first child of its parent element.
-        // FIXME: Add support for each-line.
+        // The first formatted line of an element is always indented. For example, the first line of an anonymous block box
+        // is only affected if it is the first child of its parent element.
+        // If 'each-line' is specified, indentation also applies to all lines where the previous line ends with a hard break.
         // [Integration] root()->parent() would normally produce a valid layout box.
-        auto& root = this->root();
-        auto isFormattingContextRootCandidateToTextIndent = !root.isAnonymous();
-        if (root.isAnonymous()) {
-            // Unless otherwise specified by the each-line and/or hanging keywords, only lines that are the first formatted line
-            // of an element are affected.
-            // For example, the first line of an anonymous block box is only affected if it is the first child of its parent element.
-            auto isIntegratedRootBoxFirstChild = layoutState().isIntegratedRootBoxFirstChild();
-            if (isIntegratedRootBoxFirstChild == LayoutState::IsIntegratedRootBoxFirstChild::NotApplicable)
-                isFormattingContextRootCandidateToTextIndent = root.parent().firstInFlowChild() == &root;
-            else
-                isFormattingContextRootCandidateToTextIndent = isIntegratedRootBoxFirstChild == LayoutState::IsIntegratedRootBoxFirstChild::Yes;
+        bool shouldIndent = false;
+        if (!previousLine) {
+            shouldIndent = !root.isAnonymous();
+            if (root.isAnonymous()) {
+                auto isIntegratedRootBoxFirstChild = layoutState().isIntegratedRootBoxFirstChild();
+                if (isIntegratedRootBoxFirstChild == LayoutState::IsIntegratedRootBoxFirstChild::NotApplicable)
+                    shouldIndent = root.parent().firstInFlowChild() == &root;
+                else
+                    shouldIndent = isIntegratedRootBoxFirstChild == LayoutState::IsIntegratedRootBoxFirstChild::Yes;
+            }
+        } else {
+            shouldIndent = root.style().textIndentLine() == TextIndentLine::EachLine && previousLine->endsWithLineBreak;
         }
-        if (!isFormattingContextRootCandidateToTextIndent)
-            return { };
-        auto invertLineRange = root.style().textIndentType() == TextIndentType::Hanging;
-        // text-indent: hanging inverts which lines are affected.
-        // inverted line range -> all the lines except the first one.
-        // !inverted line range -> first line gets the indent.
-        auto shouldIndent = invertLineRange != isFirstLine;
+
+        // Specifying 'hanging' inverts whether the line should be indented or not.
+        if (root.style().textIndentType() == TextIndentType::Hanging)
+            shouldIndent = !shouldIndent;
+
         if (!shouldIndent)
             return { };
 

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.h (294827 => 294828)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.h	2022-05-25 22:14:56 UTC (rev 294827)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.h	2022-05-25 22:29:46 UTC (rev 294828)
@@ -107,7 +107,7 @@
         size_t partialTrailingContentLength { 0 };
         std::optional<InlineLayoutUnit> overflowLogicalWidth { };
     };
-    UsedConstraints initialConstraintsForLine(const InlineRect& initialLineLogicalRect, bool isFirstLine) const;
+    UsedConstraints initialConstraintsForLine(const InlineRect& initialLineLogicalRect, const std::optional<PreviousLine>&) const;
     std::optional<HorizontalConstraints> floatConstraints(const InlineRect& lineLogicalRect) const;
 
     void handleFloatContent(const InlineItem&);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to