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

Changeset 287922 in webkit


Ignore:
Timestamp:
Jan 12, 2022, 6:37:38 AM (5 years ago)
Author:
Alan Bujtas
Message:

[LFC][IFC] Incorrect negative margin handling (both left/right) with RTL inline base direction
​https://bugs.webkit.org/show_bug.cgi?id=235095

Reviewed by Antti Koivisto.

Source/WebCore:

The simplified negative margin handling on inline boxes does not work well with RTL inline base direction.
With LTR direction, we could just treat the negative left margin value (which pulls content to the left)
as part the "logical width" (may resulting in negative width values) and let this shorter width pull
the the adjoining content.
However this setup produces incorrect box positions when the inline base direction is RTL.
In this patch, we switch over to a more correct inline box positioning where the negative margin
affects the logical left while it does not make the run shorter anymore.

Test: fast/inline/rtl-negative-margins.html

  • layout/formattingContexts/inline/InlineLine.cpp:

(WebCore::Layout::Line::appendInlineBoxStart):
(WebCore::Layout::Line::appendNonReplacedInlineLevelBox):

  • layout/formattingContexts/inline/InlineLineBoxBuilder.cpp:

(WebCore::Layout::LineBoxBuilder::constructAndAlignInlineLevelBoxes):

  • layout/formattingContexts/inline/InlineLineBuilder.cpp:

(WebCore::Layout::LineBuilder::layoutInlineContent):

  • layout/formattingContexts/inline/InlineLineBuilder.h:
  • layout/formattingContexts/inline/display/InlineDisplayLineBuilder.cpp:

(WebCore::Layout::InlineDisplayLineBuilder::build const):

LayoutTests:

  • fast/inline/rtl-negative-margins-expected.html: Added.
  • fast/inline/rtl-negative-margins.html: Added.
Location:
trunk
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r287911 r287922  
     12022-01-12  Alan Bujtas  <zalan@apple.com>
     2
     3        [LFC][IFC] Incorrect negative margin handling (both left/right) with RTL inline base direction
     4        https://bugs.webkit.org/show_bug.cgi?id=235095
     5
     6        Reviewed by Antti Koivisto.
     7
     8        * fast/inline/rtl-negative-margins-expected.html: Added.
     9        * fast/inline/rtl-negative-margins.html: Added.
     10
    1112022-01-11  Said Abou-Hallawa  <said@apple.com>
    212
  • trunk/Source/WebCore/ChangeLog

    r287921 r287922  
     12022-01-12  Alan Bujtas  <zalan@apple.com>
     2
     3        [LFC][IFC] Incorrect negative margin handling (both left/right) with RTL inline base direction
     4        https://bugs.webkit.org/show_bug.cgi?id=235095
     5
     6        Reviewed by Antti Koivisto.
     7
     8        The simplified negative margin handling on inline boxes does not work well with RTL inline base direction.
     9        With LTR direction, we could just treat the negative left margin value (which pulls content to the left)
     10        as part the "logical width" (may resulting in negative width values) and let this shorter width pull
     11        the the adjoining content.
     12        However this setup produces incorrect box positions when the inline base direction is RTL.
     13        In this patch, we switch over to a more correct inline box positioning where the negative margin
     14        affects the logical left while it does not make the run shorter anymore.
     15
     16        Test: fast/inline/rtl-negative-margins.html
     17
     18        * layout/formattingContexts/inline/InlineLine.cpp:
     19        (WebCore::Layout::Line::appendInlineBoxStart):
     20        (WebCore::Layout::Line::appendNonReplacedInlineLevelBox):
     21        * layout/formattingContexts/inline/InlineLineBoxBuilder.cpp:
     22        (WebCore::Layout::LineBoxBuilder::constructAndAlignInlineLevelBoxes):
     23        * layout/formattingContexts/inline/InlineLineBuilder.cpp:
     24        (WebCore::Layout::LineBuilder::layoutInlineContent):
     25        * layout/formattingContexts/inline/InlineLineBuilder.h:
     26        * layout/formattingContexts/inline/display/InlineDisplayLineBuilder.cpp:
     27        (WebCore::Layout::InlineDisplayLineBuilder::build const):
     28
    1292022-01-12  Nikolas Zimmermann  <nzimmermann@igalia.com>
    230
  • trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.cpp

    r287824 r287922  
    229229    // Incoming logical width includes the cloned decoration end to be able to do line breaking.
    230230    auto borderAndPaddingEndForDecorationClone = addBorderAndPaddingEndForInlineBoxDecorationClone(inlineItem);
    231     m_runs.append({ inlineItem, style, logicalLeft, logicalWidth - borderAndPaddingEndForDecorationClone });
    232231    // Do not let negative margin make the content shorter than it already is.
    233232    m_contentLogicalWidth = std::max(m_contentLogicalWidth, logicalLeft + logicalWidth);
     233
     234    auto marginStart = formattingContext().geometryForBox(inlineItem.layoutBox()).marginStart();
     235    if (marginStart >= 0) {
     236        m_runs.append({ inlineItem, style, logicalLeft, logicalWidth - borderAndPaddingEndForDecorationClone });
     237        return;
     238    }
     239    // Negative margin-start pulls the content to the logical left direction.
     240    m_runs.append({ inlineItem, style, logicalLeft + marginStart, logicalWidth - marginStart - borderAndPaddingEndForDecorationClone });
    234241}
    235242
    … …  
    352359{
    353360    resetTrailingContent();
    354     m_contentLogicalWidth += marginBoxLogicalWidth;
     361    // Do not let negative margin make the content shorter than it already is.
     362    m_contentLogicalWidth = std::max(m_contentLogicalWidth, lastRunLogicalRight() + marginBoxLogicalWidth);
    355363    ++m_nonSpanningInlineLevelBoxCount;
    356364    auto marginStart = formattingContext().geometryForBox(inlineItem.layoutBox()).marginStart();
  • trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.cpp

    r287731 r287922  
    284284                marginStart = formattingContext().geometryForBox(layoutBox).marginStart();
    285285#endif
    286             auto adjustedLogicalStart = logicalLeft + marginStart;
     286            auto adjustedLogicalStart = logicalLeft + std::max(0.0f, marginStart);
    287287            auto logicalWidth = rootInlineBox.logicalWidth() - adjustedLogicalStart;
    288288            auto inlineBox = InlineLevelBox::createInlineBox(layoutBox, style, adjustedLogicalStart, logicalWidth, InlineLevelBox::LineSpanningInlineBox::Yes);
    … …  
    297297            // Inline box run is based on margin box. Let's convert it to border box.
    298298            auto marginStart = formattingContext().geometryForBox(layoutBox).marginStart();
    299             auto initialLogicalWidth = rootInlineBox.logicalWidth() - (run.logicalLeft() + marginStart);
     299            logicalLeft += std::max(0_lu, marginStart);
     300            auto initialLogicalWidth = rootInlineBox.logicalWidth() - (logicalLeft - rootInlineBox.logicalLeft());
    300301            ASSERT(initialLogicalWidth >= 0 || lineContent.hangingContentWidth);
    301302            initialLogicalWidth = std::max(initialLogicalWidth, 0.f);
    302             auto inlineBox = InlineLevelBox::createInlineBox(layoutBox, style, logicalLeft + marginStart, initialLogicalWidth);
     303            auto inlineBox = InlineLevelBox::createInlineBox(layoutBox, style, logicalLeft, initialLogicalWidth);
    303304            inlineBox.setIsFirstBox();
    304305            setInitialVerticalGeometryForInlineBox(inlineBox);
  • trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp

    r287482 r287922  
    354354        , m_lineLogicalRect.width()
    355355        , m_line.contentLogicalWidth()
     356        , m_line.contentLogicalRight()
    356357        , m_line.hangingTrailingContentWidth()
    357358        , isLastLine
  • trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.h

    r287471 r287922  
    6262        InlineLayoutUnit lineLogicalWidth { 0 };
    6363        InlineLayoutUnit contentLogicalWidth { 0 };
     64        InlineLayoutUnit contentLogicalRight { 0 };
    6465        InlineLayoutUnit hangingContentWidth { 0 };
    6566        bool isLastLineWithInlineContent { true };
  • trunk/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayLineBuilder.cpp

    r287486 r287922  
    9090    auto contentVisualLeft = isLeftToRightDirection
    9191        ? lineBox.rootInlineBoxAlignmentOffset()
    92         : rootGeometry.contentBoxWidth() - lineOffsetFromContentBox -  lineBox.rootInlineBoxAlignmentOffset() - rootInlineBox.logicalWidth() - lineContent.hangingContentWidth;
     92        : rootGeometry.contentBoxWidth() - lineOffsetFromContentBox -  lineBox.rootInlineBoxAlignmentOffset() - lineContent.contentLogicalRight;
    9393
    9494    auto lineBoxRect = InlineRect { lineContent.lineLogicalTopLeft.y(), lineBoxVisualLeft, lineContent.lineLogicalWidth, lineBoxLogicalHeight };
Note: See TracChangeset for help on using the changeset viewer.