⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 294828 in webkit


Ignore:
Timestamp:
May 25, 2022, 3:29:46 PM (4 years ago)
Author:
commit-queue@webkit.org
Message:

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

Patch by Kiet Ho <Kiet Ho> 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

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/TestExpectations

    r294764 r294828  
    26522652webkit.org/b/240837 imported/w3c/web-platform-tests/css/css-text/text-indent/anonymous-flex-item-001.html [ ImageOnlyFailure ]
    26532653webkit.org/b/240837 imported/w3c/web-platform-tests/css/css-text/text-indent/anonymous-grid-item-001.html [ ImageOnlyFailure ]
    2654 webkit.org/b/240731 imported/w3c/web-platform-tests/css/css-text/text-indent/text-indent-each-line-hanging.html [ ImageOnlyFailure ]
    26552654webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/text-justify/text-justify-001.html [ ImageOnlyFailure ]
    26562655webkit.org/b/214290 imported/w3c/web-platform-tests/css/css-text/text-justify/text-justify-006.html [ ImageOnlyFailure ]
  • trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp

    r294191 r294828  
    322322LineBuilder::LineContent LineBuilder::layoutInlineContent(const InlineItemRange& needsLayoutRange, const InlineRect& lineLogicalRect, const std::optional<PreviousLine>& previousLine)
    323323{
    324     initialize(initialConstraintsForLine(lineLogicalRect, !previousLine), needsLayoutRange.start, previousLine);
     324    initialize(initialConstraintsForLine(lineLogicalRect, previousLine), needsLayoutRange.start, previousLine);
    325325
    326326    auto committedContent = placeInlineContent(needsLayoutRange);
    … …  
    401401    ASSERT(isInIntrinsicWidthMode());
    402402    auto lineLogicalWidth = *intrinsicWidthMode() == IntrinsicWidthMode::Maximum ? maxInlineLayoutUnit() : 0.f;
    403     auto lineConstraints = initialConstraintsForLine({ 0, 0, lineLogicalWidth, 0 }, !previousLine);
     403    auto lineConstraints = initialConstraintsForLine({ 0, 0, lineLogicalWidth, 0 }, previousLine);
    404404    initialize(lineConstraints, needsLayoutRange.start, previousLine);
    405405
    … …  
    628628}
    629629
    630 UsedConstraints LineBuilder::initialConstraintsForLine(const InlineRect& initialLineLogicalRect, bool isFirstLine) const
     630UsedConstraints LineBuilder::initialConstraintsForLine(const InlineRect& initialLineLogicalRect, const std::optional<PreviousLine>& previousLine) const
    631631{
    632632    auto lineLogicalLeft = initialLineLogicalRect.left();
    … …  
    641641
    642642    auto computedTextIndent = [&]() -> InlineLayoutUnit {
     643        auto& root = this->root();
     644
    643645        // text-indent property specifies the indentation applied to lines of inline content in a block.
    644646        // The indent is treated as a margin applied to the start edge of the line box.
    645         // Unless otherwise specified, only lines that are the first formatted line of an element are affected.
    646         // For example, the first line of an anonymous block box is only affected if it is the first child of its parent element.
    647         // FIXME: Add support for each-line.
     647        // The first formatted line of an element is always indented. For example, the first line of an anonymous block box
     648        // is only affected if it is the first child of its parent element.
     649        // If 'each-line' is specified, indentation also applies to all lines where the previous line ends with a hard break.
    648650        // [Integration] root()->parent() would normally produce a valid layout box.
    649         auto& root = this->root();
    650         auto isFormattingContextRootCandidateToTextIndent = !root.isAnonymous();
    651         if (root.isAnonymous()) {
    652             // Unless otherwise specified by the each-line and/or hanging keywords, only lines that are the first formatted line
    653             // of an element are affected.
    654             // For example, the first line of an anonymous block box is only affected if it is the first child of its parent element.
    655             auto isIntegratedRootBoxFirstChild = layoutState().isIntegratedRootBoxFirstChild();
    656             if (isIntegratedRootBoxFirstChild == LayoutState::IsIntegratedRootBoxFirstChild::NotApplicable)
    657                 isFormattingContextRootCandidateToTextIndent = root.parent().firstInFlowChild() == &root;
    658             else
    659                 isFormattingContextRootCandidateToTextIndent = isIntegratedRootBoxFirstChild == LayoutState::IsIntegratedRootBoxFirstChild::Yes;
    660         }
    661         if (!isFormattingContextRootCandidateToTextIndent)
    662             return { };
    663         auto invertLineRange = root.style().textIndentType() == TextIndentType::Hanging;
    664         // text-indent: hanging inverts which lines are affected.
    665         // inverted line range -> all the lines except the first one.
    666         // !inverted line range -> first line gets the indent.
    667         auto shouldIndent = invertLineRange != isFirstLine;
     651        bool shouldIndent = false;
     652        if (!previousLine) {
     653            shouldIndent = !root.isAnonymous();
     654            if (root.isAnonymous()) {
     655                auto isIntegratedRootBoxFirstChild = layoutState().isIntegratedRootBoxFirstChild();
     656                if (isIntegratedRootBoxFirstChild == LayoutState::IsIntegratedRootBoxFirstChild::NotApplicable)
     657                    shouldIndent = root.parent().firstInFlowChild() == &root;
     658                else
     659                    shouldIndent = isIntegratedRootBoxFirstChild == LayoutState::IsIntegratedRootBoxFirstChild::Yes;
     660            }
     661        } else {
     662            shouldIndent = root.style().textIndentLine() == TextIndentLine::EachLine && previousLine->endsWithLineBreak;
     663        }
     664
     665        // Specifying 'hanging' inverts whether the line should be indented or not.
     666        if (root.style().textIndentType() == TextIndentType::Hanging)
     667            shouldIndent = !shouldIndent;
     668
    668669        if (!shouldIndent)
    669670            return { };
  • trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.h

    r293646 r294828  
    108108        std::optional<InlineLayoutUnit> overflowLogicalWidth { };
    109109    };
    110     UsedConstraints initialConstraintsForLine(const InlineRect& initialLineLogicalRect, bool isFirstLine) const;
     110    UsedConstraints initialConstraintsForLine(const InlineRect& initialLineLogicalRect, const std::optional<PreviousLine>&) const;
    111111    std::optional<HorizontalConstraints> floatConstraints(const InlineRect& lineLogicalRect) const;
    112112
Note: See TracChangeset for help on using the changeset viewer.