- 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&);