Title: [281271] trunk/Source/WebCore
Revision
281271
Author
[email protected]
Date
2021-08-19 14:59:52 -0700 (Thu, 19 Aug 2021)

Log Message

[LFC][IFC] Add support for negative horizontal margin (inline box)
https://bugs.webkit.org/show_bug.cgi?id=227837

Reviewed by Antti Koivisto.

When building up the line for line breaking, each inline item is placed adjacent with no gaps
in-between the neighboring entries. They are considered atomic with their margins, padding, borders and content width.
Later when we form the inline runs out of these entries, we offset them by their horizontal margin values.

* layout/formattingContexts/inline/InlineLine.cpp:
(WebCore::Layout::Line::appendInlineBoxStart):
* layout/integration/LayoutIntegrationCoverage.cpp:
(WebCore::LayoutIntegration::printReason):
(WebCore::LayoutIntegration::canUseForChild):
* layout/integration/LayoutIntegrationCoverage.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (281270 => 281271)


--- trunk/Source/WebCore/ChangeLog	2021-08-19 21:25:12 UTC (rev 281270)
+++ trunk/Source/WebCore/ChangeLog	2021-08-19 21:59:52 UTC (rev 281271)
@@ -1,5 +1,23 @@
 2021-08-19  Alan Bujtas  <[email protected]>
 
+        [LFC][IFC] Add support for negative horizontal margin (inline box)
+        https://bugs.webkit.org/show_bug.cgi?id=227837
+
+        Reviewed by Antti Koivisto.
+
+        When building up the line for line breaking, each inline item is placed adjacent with no gaps
+        in-between the neighboring entries. They are considered atomic with their margins, padding, borders and content width.
+        Later when we form the inline runs out of these entries, we offset them by their horizontal margin values. 
+
+        * layout/formattingContexts/inline/InlineLine.cpp:
+        (WebCore::Layout::Line::appendInlineBoxStart):
+        * layout/integration/LayoutIntegrationCoverage.cpp:
+        (WebCore::LayoutIntegration::printReason):
+        (WebCore::LayoutIntegration::canUseForChild):
+        * layout/integration/LayoutIntegrationCoverage.h:
+
+2021-08-19  Alan Bujtas  <[email protected]>
+
         [LFC][IFC] Add support for overflow-wrap: anywhere
         https://bugs.webkit.org/show_bug.cgi?id=227695
 

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


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingGeometry.cpp	2021-08-19 21:25:12 UTC (rev 281270)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingGeometry.cpp	2021-08-19 21:59:52 UTC (rev 281271)
@@ -312,13 +312,11 @@
         if (run.isInlineBoxStart()) {
             // At this point we don't know yet how wide this inline box is. Let's assume it's as long as the line is
             // and adjust it later if we come across an inlineBoxEnd run (see below).
-            auto initialLogicalWidth = lineBox.contentLogicalWidth() - run.logicalLeft();
+            // Inline box run is based on margin box. Let's convert it to border box.
+            auto marginStart = formattingContext().geometryForBox(layoutBox).marginStart();
+            auto initialLogicalWidth = lineBox.contentLogicalWidth() - (run.logicalLeft() + marginStart);
             ASSERT(initialLogicalWidth >= 0);
-            // Inline box run is based on margin box. Let's convert it to border box.
-            auto marginStart = std::max(0_lu, formattingContext().geometryForBox(layoutBox).marginStart());
-            logicalLeft += marginStart;
-            initialLogicalWidth -= marginStart;
-            auto inlineBox = InlineLevelBox::createInlineBox(layoutBox, logicalLeft, initialLogicalWidth);
+            auto inlineBox = InlineLevelBox::createInlineBox(layoutBox, logicalLeft + marginStart, initialLogicalWidth);
             setVerticalGeometryForInlineBox(inlineBox);
             simplifiedAlignVerticallyIfApplicable(inlineBox, { });
             lineBox.addInlineLevelBox(WTFMove(inlineBox));
@@ -326,12 +324,17 @@
         }
         if (run.isInlineBoxEnd()) {
             // Adjust the logical width when the inline box closes on this line.
+            // Note that margin end does not affect the logical width (e.g. positive margin right does not make the run wider).
             auto& inlineBox = lineBox.inlineLevelBoxForLayoutBox(layoutBox);
             ASSERT(inlineBox.isInlineBox());
             // Inline box run is based on margin box. Let's convert it to border box.
-            auto marginEnd = std::max(0_lu, formattingContext().geometryForBox(layoutBox).marginEnd());
-            auto inlineBoxLogicalRight = logicalLeft + run.logicalWidth() - marginEnd;
-            inlineBox.setLogicalWidth(inlineBoxLogicalRight - inlineBox.logicalLeft());
+            // Negative margin end makes the run have negative width.
+            auto marginEndAdjustemnt = -formattingContext().geometryForBox(layoutBox).marginEnd();
+            auto logicalWidth = run.logicalWidth() + marginEndAdjustemnt;
+            auto inlineBoxLogicalRight = logicalLeft + logicalWidth;
+            // When the content pulls the </span> to the logical left direction (e.g. negative letter space)
+            // make sure we don't end up with negative logical width on the inline box.
+            inlineBox.setLogicalWidth(std::max(0.f, inlineBoxLogicalRight - inlineBox.logicalLeft()));
             simplifiedAlignVerticallyIfApplicable(inlineBox, { });
             continue;
         }

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


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.cpp	2021-08-19 21:25:12 UTC (rev 281270)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLine.cpp	2021-08-19 21:59:52 UTC (rev 281271)
@@ -194,16 +194,16 @@
 void Line::appendNonBreakableSpace(const InlineItem& inlineItem, InlineLayoutUnit logicalLeft, InlineLayoutUnit logicalWidth)
 {
     m_runs.append({ inlineItem, logicalLeft, logicalWidth });
-    m_contentLogicalWidth += logicalWidth;
+    // Do not let negative margin make the content shorter than it already is.
+    auto runLogicalRight = logicalLeft + logicalWidth;
+    m_contentLogicalWidth = std::max(m_contentLogicalWidth, runLogicalRight);
 }
 
 void Line::appendInlineBoxStart(const InlineItem& inlineItem, InlineLayoutUnit logicalWidth)
 {
     // This is really just a placeholder to mark the start of the inline box <span>.
-    auto& boxGeometry = formattingContext().geometryForBox(inlineItem.layoutBox());
-    auto adjustedRunStart = contentLogicalRight() + std::min(boxGeometry.marginStart(), 0_lu);
     ++m_nonSpanningInlineLevelBoxCount;
-    appendNonBreakableSpace(inlineItem, adjustedRunStart, logicalWidth);
+    appendNonBreakableSpace(inlineItem, contentLogicalRight(), logicalWidth);
 }
 
 void Line::appendInlineBoxEnd(const InlineItem& inlineItem, InlineLayoutUnit logicalWidth)
@@ -217,7 +217,7 @@
     // Prevent trailing letter-spacing from spilling out of the inline box.
     // https://drafts.csswg.org/css-text-3/#letter-spacing-property See example 21.
     removeTrailingLetterSpacing();
-    appendNonBreakableSpace(inlineItem, contentLogicalWidth(), logicalWidth);
+    appendNonBreakableSpace(inlineItem, contentLogicalRight(), logicalWidth);
 }
 
 void Line::appendTextContent(const InlineTextItem& inlineTextItem, InlineLayoutUnit logicalWidth)

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationCoverage.cpp (281270 => 281271)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationCoverage.cpp	2021-08-19 21:25:12 UTC (rev 281270)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationCoverage.cpp	2021-08-19 21:59:52 UTC (rev 281271)
@@ -270,9 +270,6 @@
     case AvoidanceReason::InlineBoxHasBackground:
         stream << "inline box has background";
         break;
-    case AvoidanceReason::InlineBoxHasNegativeMargin:
-        stream << "inline box has negative margin";
-        break;
     default:
         break;
     }
@@ -708,8 +705,6 @@
             SET_REASON_AND_RETURN_IF_NEEDED(InlineBoxHasBackground, reasons, includeReasons);
         if (style.hasOutline())
             SET_REASON_AND_RETURN_IF_NEEDED(ContentHasOutline, reasons, includeReasons);
-        if (renderInline.marginLeft() < 0 || renderInline.marginRight() < 0 || renderInline.marginTop() < 0 || renderInline.marginBottom() < 0)
-            SET_REASON_AND_RETURN_IF_NEEDED(InlineBoxHasNegativeMargin, reasons, includeReasons);
         if (renderInline.isInFlowPositioned())
             SET_REASON_AND_RETURN_IF_NEEDED(ChildBoxIsFloatingOrPositioned, reasons, includeReasons);
         if (renderInline.containingBlock()->style().lineBoxContain() != RenderStyle::initialLineBoxContain())

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationCoverage.h (281270 => 281271)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationCoverage.h	2021-08-19 21:25:12 UTC (rev 281270)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationCoverage.h	2021-08-19 21:59:52 UTC (rev 281271)
@@ -99,8 +99,7 @@
     InlineBoxNeedsLayer                          = 1LLU  << 59,
     InlineBoxHasBorderOrBorderImage              = 1LLU  << 60,
     InlineBoxHasBackground                       = 1LLU  << 61,
-    InlineBoxHasNegativeMargin                   = 1LLU  << 62,
-    EndOfReasons                                 = 1LLU  << 63
+    EndOfReasons                                 = 1LLU  << 62
 };
 
 bool canUseForLineLayout(const RenderBlockFlow&);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to