Title: [287922] trunk
Revision
287922
Author
za...@apple.com
Date
2022-01-12 06:37:38 -0800 (Wed, 12 Jan 2022)

Log 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.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (287921 => 287922)


--- trunk/LayoutTests/ChangeLog	2022-01-12 13:05:38 UTC (rev 287921)
+++ trunk/LayoutTests/ChangeLog	2022-01-12 14:37:38 UTC (rev 287922)
@@ -1,3 +1,13 @@
+2022-01-12  Alan Bujtas  <za...@apple.com>
+
+        [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.
+
+        * fast/inline/rtl-negative-margins-expected.html: Added.
+        * fast/inline/rtl-negative-margins.html: Added.
+
 2022-01-11  Said Abou-Hallawa  <s...@apple.com>
 
         [GPU Process] Make SVG resources create remote ImageBuffers for their drawing

Added: trunk/LayoutTests/fast/inline/rtl-negative-margins-expected.html (0 => 287922)


--- trunk/LayoutTests/fast/inline/rtl-negative-margins-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/inline/rtl-negative-margins-expected.html	2022-01-12 14:37:38 UTC (rev 287922)
@@ -0,0 +1,34 @@
+<style>
+.inline-block {
+  display: inline-block;
+  height: 20px;
+  width: 20px;
+  background-color: blue;
+  vertical-align: bottom;
+}
+
+.test {
+  width: 100px;
+  font-family: Ahem;
+  font-size: 20px;
+  color: blue;
+  background-color: green;
+  white-space: pre;
+}
+</style>
+<div class=test><div class=inline-block style="margin-left: 60px;"></div><div class=inline-block></div></div>
+<div class=test><div class=inline-block style="margin-left: 40px; margin-right: 20px;"></div><div class=inline-block></div></div>
+<div class=test><div class=inline-block style="margin-left: 20px;"></div><div class=inline-block></div></div>
+<div class=test><div class=inline-block style="margin-right: 20px;"></div><div class=inline-block></div></div>
+<div class=test><div class=inline-block style="margin-right: 20px;"></div><div class=inline-block></div></div>
+<div class=test><div class=inline-block style="margin-left: 80px;"></div><div class=inline-block></div></div>
+<div class=test><div class=inline-block style="margin-left: 140px;"></div><div class=inline-block></div></div>
+<div class=test><div class=inline-block style="margin-left: 160px;"></div><div class=inline-block></div></div>
+<div class=test><div class=inline-block style="margin-left: 160px;"></div><div class=inline-block></div></div>
+<div class=test><div class=inline-block style="margin-left: 100px; margin-right: 40px;"></div><div class=inline-block></div></div>
+<div class=test><div class=inline-block></div><div class=inline-block></div></div>
+<div class=test><div class=inline-block style="margin-left: 100px; margin-right: 40px;"></div><div class=inline-block></div></div>
+<div class=test><div class=inline-block style="margin-left: 80px;"></div><div class=inline-block></div></div>
+<div class=test><div class=inline-block style="margin-left: 160px; margin-right: 10px;"></div><div class=inline-block></div></div>
+<div class=test><div class=inline-block style="margin-left: 160px;"></div><div class=inline-block></div></div>
+<div class=test><div class=inline-block style="margin-left: 130px; margin-right: 10px;"></div><div class=inline-block></div></div>

Added: trunk/LayoutTests/fast/inline/rtl-negative-margins.html (0 => 287922)


--- trunk/LayoutTests/fast/inline/rtl-negative-margins.html	                        (rev 0)
+++ trunk/LayoutTests/fast/inline/rtl-negative-margins.html	2022-01-12 14:37:38 UTC (rev 287922)
@@ -0,0 +1,37 @@
+<style>
+.inline-block {
+  display: inline-block;
+  height: 20px;
+  width: 20px;
+  background-color: blue;
+  vertical-align: bottom;
+}
+
+.test {
+  direction: rtl;
+  width: 100px;
+  font-family: Ahem;
+  font-size: 20px;
+  color: blue;
+  background-color: green;
+}
+</style>
+<div class=test><span>X</span><div class=inline-block></div></div>
+<div class=test><span style="margin-left: 20px;">X</span><div class=inline-block></div></div>
+<div class=test><span style="margin-right: 40px;">X</span><div class=inline-block></div></div>
+<div class=test><span style="margin-left: 20px; margin-right: 40px;">X</span><div class=inline-block></div></div>
+<div class=test><span style="margin-inline-start: 40px; margin-inline-end: 20px;">X</span><div class=inline-block></div></div>
+
+<div class=test><span style="margin-left: -40px;">X</span><div class=inline-block></div></div>
+<div class=test><span style="margin-right: -80px;">X</span><div class=inline-block></div></div>
+<div class=test><span style="margin-left: -40px; margin-right: -80px;">X</span><div class=inline-block></div></div>
+<div class=test><span style="margin-inline-start: -80px; margin-inline-end: -40px;">X</span><div class=inline-block></div></div>
+
+<div class=test><span style="margin-left: 40px; margin-right: -80px;">X</span><div class=inline-block></div></div>
+<div class=test><span style="margin-left: -40px; margin-right: 80px;">X</span><div class=inline-block></div></div>
+<div class=test><span style="margin-inline-start: -80px; margin-inline-end: 40px;">X</span><div class=inline-block></div></div>
+
+<div class=test><span style="margin-left: -40px;">X</span><div class=inline-block style="margin-left: -50px;"></div></div>
+<div class=test><span style="margin-right: -80px;">X</span><div class=inline-block style="margin-right: -50px;"></div></div>
+<div class=test><span style="margin-left: -40px; margin-right: -80px;">X</span><div class=inline-block style="margin-left: 50px;"></div></div>
+<div class=test><span style="margin-inline-start: -80px; margin-inline-end: -40px;">X</span><div class=inline-block style="margin-right: 50px;"></div></div>

Modified: trunk/Source/WebCore/ChangeLog (287921 => 287922)


--- trunk/Source/WebCore/ChangeLog	2022-01-12 13:05:38 UTC (rev 287921)
+++ trunk/Source/WebCore/ChangeLog	2022-01-12 14:37:38 UTC (rev 287922)
@@ -1,3 +1,31 @@
+2022-01-12  Alan Bujtas  <za...@apple.com>
+
+        [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.
+
+        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):
+
 2022-01-12  Nikolas Zimmermann  <nzimmerm...@igalia.com>
 
         [LBSE] Begin layer-aware RenderSVGContainer implementation

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


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.cpp	2022-01-12 13:05:38 UTC (rev 287921)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.cpp	2022-01-12 14:37:38 UTC (rev 287922)
@@ -228,9 +228,16 @@
     auto logicalLeft = lastRunLogicalRight();
     // Incoming logical width includes the cloned decoration end to be able to do line breaking.
     auto borderAndPaddingEndForDecorationClone = addBorderAndPaddingEndForInlineBoxDecorationClone(inlineItem);
-    m_runs.append({ inlineItem, style, logicalLeft, logicalWidth - borderAndPaddingEndForDecorationClone });
     // Do not let negative margin make the content shorter than it already is.
     m_contentLogicalWidth = std::max(m_contentLogicalWidth, logicalLeft + logicalWidth);
+
+    auto marginStart = formattingContext().geometryForBox(inlineItem.layoutBox()).marginStart();
+    if (marginStart >= 0) {
+        m_runs.append({ inlineItem, style, logicalLeft, logicalWidth - borderAndPaddingEndForDecorationClone });
+        return;
+    }
+    // Negative margin-start pulls the content to the logical left direction.
+    m_runs.append({ inlineItem, style, logicalLeft + marginStart, logicalWidth - marginStart - borderAndPaddingEndForDecorationClone });
 }
 
 void Line::appendInlineBoxEnd(const InlineItem& inlineItem, const RenderStyle& style, InlineLayoutUnit logicalWidth)
@@ -351,7 +358,8 @@
 void Line::appendNonReplacedInlineLevelBox(const InlineItem& inlineItem, const RenderStyle& style, InlineLayoutUnit marginBoxLogicalWidth)
 {
     resetTrailingContent();
-    m_contentLogicalWidth += marginBoxLogicalWidth;
+    // Do not let negative margin make the content shorter than it already is.
+    m_contentLogicalWidth = std::max(m_contentLogicalWidth, lastRunLogicalRight() + marginBoxLogicalWidth);
     ++m_nonSpanningInlineLevelBoxCount;
     auto marginStart = formattingContext().geometryForBox(inlineItem.layoutBox()).marginStart();
     if (marginStart >= 0) {

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


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.cpp	2022-01-12 13:05:38 UTC (rev 287921)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.cpp	2022-01-12 14:37:38 UTC (rev 287922)
@@ -283,7 +283,7 @@
             if (style.boxDecorationBreak() == BoxDecorationBreak::Clone)
                 marginStart = formattingContext().geometryForBox(layoutBox).marginStart();
 #endif
-            auto adjustedLogicalStart = logicalLeft + marginStart;
+            auto adjustedLogicalStart = logicalLeft + std::max(0.0f, marginStart);
             auto logicalWidth = rootInlineBox.logicalWidth() - adjustedLogicalStart;
             auto inlineBox = InlineLevelBox::createInlineBox(layoutBox, style, adjustedLogicalStart, logicalWidth, InlineLevelBox::LineSpanningInlineBox::Yes);
             setInitialVerticalGeometryForInlineBox(inlineBox);
@@ -296,10 +296,11 @@
             // and adjust it later if we come across an inlineBoxEnd run (see below).
             // 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);
+            logicalLeft += std::max(0_lu, marginStart);
+            auto initialLogicalWidth = rootInlineBox.logicalWidth() - (logicalLeft - rootInlineBox.logicalLeft());
             ASSERT(initialLogicalWidth >= 0 || lineContent.hangingContentWidth);
             initialLogicalWidth = std::max(initialLogicalWidth, 0.f);
-            auto inlineBox = InlineLevelBox::createInlineBox(layoutBox, style, logicalLeft + marginStart, initialLogicalWidth);
+            auto inlineBox = InlineLevelBox::createInlineBox(layoutBox, style, logicalLeft, initialLogicalWidth);
             inlineBox.setIsFirstBox();
             setInitialVerticalGeometryForInlineBox(inlineBox);
             updateCanUseSimplifiedAlignment(inlineBox);

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


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp	2022-01-12 13:05:38 UTC (rev 287921)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp	2022-01-12 14:37:38 UTC (rev 287922)
@@ -353,6 +353,7 @@
         , m_lineLogicalRect.topLeft()
         , m_lineLogicalRect.width()
         , m_line.contentLogicalWidth()
+        , m_line.contentLogicalRight()
         , m_line.hangingTrailingContentWidth()
         , isLastLine
         , m_line.nonSpanningInlineLevelBoxCount()

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


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.h	2022-01-12 13:05:38 UTC (rev 287921)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.h	2022-01-12 14:37:38 UTC (rev 287922)
@@ -61,6 +61,7 @@
         InlineLayoutPoint lineLogicalTopLeft;
         InlineLayoutUnit lineLogicalWidth { 0 };
         InlineLayoutUnit contentLogicalWidth { 0 };
+        InlineLayoutUnit contentLogicalRight { 0 };
         InlineLayoutUnit hangingContentWidth { 0 };
         bool isLastLineWithInlineContent { true };
         size_t nonSpanningInlineLevelBoxCount { 0 };

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


--- trunk/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayLineBuilder.cpp	2022-01-12 13:05:38 UTC (rev 287921)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayLineBuilder.cpp	2022-01-12 14:37:38 UTC (rev 287922)
@@ -89,7 +89,7 @@
         : InlineLayoutUnit { rootGeometry.borderEnd() } + rootGeometry.paddingEnd().value_or(0_lu);
     auto contentVisualLeft = isLeftToRightDirection
         ? lineBox.rootInlineBoxAlignmentOffset()
-        : rootGeometry.contentBoxWidth() - lineOffsetFromContentBox -  lineBox.rootInlineBoxAlignmentOffset() - rootInlineBox.logicalWidth() - lineContent.hangingContentWidth;
+        : rootGeometry.contentBoxWidth() - lineOffsetFromContentBox -  lineBox.rootInlineBoxAlignmentOffset() - lineContent.contentLogicalRight;
 
     auto lineBoxRect = InlineRect { lineContent.lineLogicalTopLeft.y(), lineBoxVisualLeft, lineContent.lineLogicalWidth, lineBoxLogicalHeight };
     auto enclosingLineGeometry = collectEnclosingLineGeometry(lineBox, lineBoxRect);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to