Diff
Modified: trunk/Source/WebCore/ChangeLog (272724 => 272725)
--- trunk/Source/WebCore/ChangeLog 2021-02-11 14:46:56 UTC (rev 272724)
+++ trunk/Source/WebCore/ChangeLog 2021-02-11 14:56:18 UTC (rev 272725)
@@ -1,5 +1,29 @@
2021-02-11 Zalan Bujtas <[email protected]>
+ [LFC][IFC] Introduce dedicated logical rect getter for each inline level box type
+ https://bugs.webkit.org/show_bug.cgi?id=221725
+
+ Reviewed by Antti Koivisto.
+
+ This helps when different type of rects (margin vs. border) are returned for different type of boxes.
+
+ * layout/inlineformatting/InlineFormattingContext.cpp:
+ (WebCore::Layout::InlineFormattingContext::computeGeometryForLineContent):
+ * layout/inlineformatting/InlineLineBox.cpp:
+ (WebCore::Layout::LineBox::logicalRectForTextRun const):
+ (WebCore::Layout::LineBox::logicalRectForLineBreakBox const):
+ (WebCore::Layout::LineBox::logicalRectForInlineLevelBox const):
+ (WebCore::Layout::LineBox::logicalMarginRectForAtomicInlineLevelBox const):
+ (WebCore::Layout::LineBox::logicalRectForInlineBox const):
+ (WebCore::Layout::LineBox::logicalMarginRectForInlineLevelBox const): Deleted.
+ * layout/inlineformatting/InlineLineBox.h:
+ * layout/integration/LayoutIntegrationInlineContentBuilder.cpp:
+ (WebCore::LayoutIntegration::InlineContentBuilder::createDisplayNonRootInlineBoxes const):
+ * layout/layouttree/LayoutTreeBuilder.cpp:
+ (WebCore::Layout::showInlineTreeAndRuns):
+
+2021-02-11 Zalan Bujtas <[email protected]>
+
[LFC][IFC] Inline boxes have incorrect content box height/width values
https://bugs.webkit.org/show_bug.cgi?id=221739
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp (272724 => 272725)
--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp 2021-02-11 14:46:56 UTC (rev 272724)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp 2021-02-11 14:56:18 UTC (rev 272725)
@@ -464,7 +464,7 @@
}
for (auto* layoutBox : layoutBoxList) {
auto& boxGeometry = formattingState.boxGeometry(*layoutBox);
- auto inlineBoxLogicalHeight = LayoutUnit::fromFloatCeil(lineBox.logicalMarginRectForInlineLevelBox(*layoutBox, boxGeometry).height());
+ auto inlineBoxLogicalHeight = LayoutUnit::fromFloatCeil(lineBox.logicalRectForInlineBox(*layoutBox, boxGeometry).height());
boxGeometry.setContentBoxHeight(inlineBoxLogicalHeight);
boxGeometry.setContentBoxWidth({ });
boxGeometry.setLogicalTopLeft(toLayoutPoint(lineBoxLogicalRect.topLeft()));
@@ -490,25 +490,26 @@
continue;
}
if (lineRun.isLineBreak()) {
- auto lineBreakBoxRect = lineBox.logicalRectForTextRun(lineRun);
- formattingState.addLineRun({ lineIndex, layoutBox, lineBreakBoxRect, lineRun.expansion(), lineRun.textContent() });
-
if (layoutBox.isLineBreakBox()) {
// Only hard linebreaks have associated layout boxes.
+ auto lineBreakBoxRect = lineBox.logicalRectForLineBreakBox(layoutBox);
+ formattingState.addLineRun({ lineIndex, layoutBox, lineBreakBoxRect, lineRun.expansion(), { } });
+
auto& boxGeometry = formattingState.boxGeometry(layoutBox);
lineBreakBoxRect.moveBy(lineBoxLogicalRect.topLeft());
boxGeometry.setLogicalTopLeft(toLayoutPoint(lineBreakBoxRect.topLeft()));
boxGeometry.setContentBoxHeight(toLayoutUnit(lineBreakBoxRect.height()));
- }
+ } else
+ formattingState.addLineRun({ lineIndex, layoutBox, lineBox.logicalRectForTextRun(lineRun), lineRun.expansion(), lineRun.textContent() });
continue;
}
if (lineRun.isBox()) {
ASSERT(layoutBox.isAtomicInlineLevelBox());
- auto& boxGeometry = formattingState.boxGeometry(layoutBox);
- auto logicalMarginRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, boxGeometry);
+ auto logicalMarginRect = lineBox.logicalMarginRectForAtomicInlineLevelBox(layoutBox);
formattingState.addLineRun({ lineIndex, layoutBox, logicalMarginRect, lineRun.expansion(), { } });
auto borderBoxLogicalTopLeft = logicalMarginRect.topLeft();
+ auto& boxGeometry = formattingState.boxGeometry(layoutBox);
borderBoxLogicalTopLeft.move(std::max(0_lu, boxGeometry.marginStart()), std::max(0_lu, boxGeometry.marginBefore()));
// Note that inline boxes are relative to the line and their top position can be negative.
borderBoxLogicalTopLeft.moveBy(lineBoxLogicalRect.topLeft());
@@ -525,7 +526,7 @@
}
if (lineRun.isInlineBoxStart()) {
auto& boxGeometry = formattingState.boxGeometry(layoutBox);
- auto inlineBoxLogicalRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, boxGeometry);
+ auto inlineBoxLogicalRect = lineBox.logicalRectForInlineBox(layoutBox, boxGeometry);
formattingState.addLineRun({ lineIndex, layoutBox, inlineBoxLogicalRect, lineRun.expansion(), { } });
inlineBoxStartSet.add(&layoutBox);
enclosingTopAndBottom.top = std::min(enclosingTopAndBottom.top, inlineBoxLogicalRect.top());
@@ -533,7 +534,7 @@
}
if (lineRun.isInlineBoxEnd()) {
inlineBoxEndSet.add(&layoutBox);
- auto inlineBoxLogicalRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, formattingState.boxGeometry(layoutBox));
+ auto inlineBoxLogicalRect = lineBox.logicalRectForInlineBox(layoutBox, formattingState.boxGeometry(layoutBox));
enclosingTopAndBottom.bottom = std::max(enclosingTopAndBottom.bottom, inlineBoxLogicalRect.bottom());
continue;
}
@@ -554,7 +555,7 @@
auto& layoutBox = inlineLevelBox->layoutBox();
auto& boxGeometry = formattingState.boxGeometry(layoutBox);
// Inline boxes may or may not be wrapped and have runs on multiple lines (e.g. <span>first line<br>second line<br>third line</span>)
- auto inlineBoxMarginRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, boxGeometry);
+ auto inlineBoxMarginRect = lineBox.logicalRectForInlineBox(layoutBox, boxGeometry);
auto inlineBoxSize = LayoutSize { LayoutUnit::fromFloatCeil(inlineBoxMarginRect.width()), LayoutUnit::fromFloatCeil(inlineBoxMarginRect.height()) };
auto logicalRect = Rect { LayoutPoint { inlineBoxMarginRect.topLeft() }, inlineBoxSize };
logicalRect.moveBy(LayoutPoint { lineBoxLogicalRect.topLeft() });
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp (272724 => 272725)
--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp 2021-02-11 14:46:56 UTC (rev 272724)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp 2021-02-11 14:56:18 UTC (rev 272725)
@@ -106,7 +106,7 @@
InlineRect LineBox::logicalRectForTextRun(const Line::Run& run) const
{
- ASSERT(run.isText() || run.isLineBreak());
+ ASSERT(run.isText() || run.isSoftLineBreak());
auto* parentInlineBox = &inlineLevelBoxForLayoutBox(run.layoutBox().parent());
ASSERT(parentInlineBox->isInlineBox());
auto& fontMetrics = parentInlineBox->style().fontMetrics();
@@ -121,30 +121,46 @@
return { runlogicalTop, m_horizontalAlignmentOffset.valueOr(InlineLayoutUnit { }) + run.logicalLeft(), run.logicalWidth(), logicalHeight };
}
-InlineRect LineBox::logicalMarginRectForInlineLevelBox(const Box& layoutBox, const BoxGeometry& boxGeometry) const
+InlineRect LineBox::logicalRectForLineBreakBox(const Box& layoutBox) const
{
- auto logicalRect = [&] {
- auto* inlineBox = &inlineLevelBoxForLayoutBox(layoutBox);
- auto inlineBoxLogicalRect = inlineBox->logicalRect();
- if (inlineBox->hasLineBoxRelativeAlignment())
- return inlineBoxLogicalRect;
+ ASSERT(layoutBox.isLineBreakBox());
+ return logicalRectForInlineLevelBox(layoutBox);
+}
- if (&layoutBox.parent() == &m_rootInlineBox->layoutBox()) {
- inlineBoxLogicalRect.moveVertically(m_rootInlineBox->logicalTop());
- return inlineBoxLogicalRect;
- }
+InlineRect LineBox::logicalRectForInlineLevelBox(const Box& layoutBox) const
+{
+ ASSERT(layoutBox.isInlineLevelBox() || layoutBox.isLineBreakBox());
+ // Inline level boxes are relative to their parent unless the vertical alignment makes them relative to the line box (e.g. top, bottom).
+ auto* inlineBox = &inlineLevelBoxForLayoutBox(layoutBox);
+ auto inlineBoxLogicalRect = inlineBox->logicalRect();
+ if (inlineBox->hasLineBoxRelativeAlignment())
+ return inlineBoxLogicalRect;
- auto inlineBoxAbsolutelogicalTop = inlineBoxLogicalRect.top();
- while (inlineBox != m_rootInlineBox.get() && !inlineBox->hasLineBoxRelativeAlignment()) {
- inlineBox = &inlineLevelBoxForLayoutBox(inlineBox->layoutBox().parent());
- ASSERT(inlineBox->isInlineBox());
- inlineBoxAbsolutelogicalTop += inlineBox->logicalTop();
- }
- return InlineRect { inlineBoxAbsolutelogicalTop, inlineBoxLogicalRect.left(), inlineBoxLogicalRect.width(), inlineBoxLogicalRect.height() };
- }();
- if (!layoutBox.isInlineBox())
- return logicalRect;
+ // Fast path for inline level boxes on the root inline box (e.g <div><img></div>).
+ if (&layoutBox.parent() == &m_rootInlineBox->layoutBox()) {
+ inlineBoxLogicalRect.moveVertically(m_rootInlineBox->logicalTop());
+ return inlineBoxLogicalRect;
+ }
+ // e.g <div><span><img></span></div>
+ auto inlineBoxAbsolutelogicalTop = inlineBoxLogicalRect.top();
+ while (inlineBox != m_rootInlineBox.get() && !inlineBox->hasLineBoxRelativeAlignment()) {
+ inlineBox = &inlineLevelBoxForLayoutBox(inlineBox->layoutBox().parent());
+ ASSERT(inlineBox->isInlineBox());
+ inlineBoxAbsolutelogicalTop += inlineBox->logicalTop();
+ }
+ return InlineRect { inlineBoxAbsolutelogicalTop, inlineBoxLogicalRect.left(), inlineBoxLogicalRect.width(), inlineBoxLogicalRect.height() };
+}
+
+InlineRect LineBox::logicalMarginRectForAtomicInlineLevelBox(const Box& layoutBox) const
+{
+ ASSERT(layoutBox.isAtomicInlineLevelBox());
+ return logicalRectForInlineLevelBox(layoutBox);
+}
+
+InlineRect LineBox::logicalRectForInlineBox(const Box& layoutBox, const BoxGeometry& boxGeometry) const
+{
+ auto logicalRect = logicalRectForInlineLevelBox(layoutBox);
// This logical rect is as tall as the "text" content is. Let's adjust with vertical border and padding -vertical margin is ignored.
auto verticalBorderAndPadding = boxGeometry.verticalBorder() + boxGeometry.verticalPadding().valueOr(0_lu);
logicalRect.expandVertically(verticalBorderAndPadding);
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.h (272724 => 272725)
--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.h 2021-02-11 14:46:56 UTC (rev 272724)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.h 2021-02-11 14:56:18 UTC (rev 272725)
@@ -150,8 +150,10 @@
const InlineLevelBox& inlineLevelBoxForLayoutBox(const Box& layoutBox) const { return *m_inlineLevelBoxRectMap.get(&layoutBox); }
InlineRect logicalRectForTextRun(const Line::Run&) const;
+ InlineRect logicalRectForLineBreakBox(const Box&) const;
+ InlineRect logicalMarginRectForAtomicInlineLevelBox(const Box&) const;
InlineRect logicalRectForRootInlineBox() const { return m_rootInlineBox->logicalRect(); }
- InlineRect logicalMarginRectForInlineLevelBox(const Box&, const BoxGeometry&) const;
+ InlineRect logicalRectForInlineBox(const Box&, const BoxGeometry&) const;
const InlineLevelBox& rootInlineBox() const { return *m_rootInlineBox; }
using InlineLevelBoxList = Vector<std::unique_ptr<InlineLevelBox>>;
@@ -171,6 +173,7 @@
InlineLevelBox& rootInlineBox() { return *m_rootInlineBox; }
InlineLevelBox& inlineLevelBoxForLayoutBox(const Box& layoutBox) { return *m_inlineLevelBoxRectMap.get(&layoutBox); }
+ InlineRect logicalRectForInlineLevelBox(const Box& layoutBox) const;
void setHasContent(bool hasContent) { m_hasContent = hasContent; }
Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp (272724 => 272725)
--- trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp 2021-02-11 14:46:56 UTC (rev 272724)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp 2021-02-11 14:56:18 UTC (rev 272725)
@@ -341,7 +341,7 @@
continue;
auto& layoutBox = inlineLevelBox->layoutBox();
auto& boxGeometry = m_layoutState.geometryForBox(layoutBox);
- auto inlineBoxRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, boxGeometry);
+ auto inlineBoxRect = lineBox.logicalRectForInlineBox(layoutBox, boxGeometry);
inlineBoxRect.moveBy(lineBoxLogicalRect.topLeft());
inlineContent.nonRootInlineBoxes.append({ lineIndex, layoutBox, inlineBoxRect });
Modified: trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp (272724 => 272725)
--- trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp 2021-02-11 14:46:56 UTC (rev 272724)
+++ trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp 2021-02-11 14:56:18 UTC (rev 272725)
@@ -406,18 +406,22 @@
auto outputInlineLevelBox = [&](const auto& inlineLevelBox) {
addSpacing();
stream << " ";
- if (inlineLevelBox.isRootInlineBox())
+ auto logicalRect = InlineRect { };
+ auto& layoutBox = inlineLevelBox.layoutBox();
+ if (inlineLevelBox.isRootInlineBox()) {
stream << "Root inline box";
- else if (inlineLevelBox.isAtomicInlineLevelBox())
+ logicalRect = lineBox.logicalRectForRootInlineBox();
+ } else if (inlineLevelBox.isAtomicInlineLevelBox()) {
stream << "Atomic inline level box";
- else if (inlineLevelBox.isLineBreakBox())
+ logicalRect = lineBox.logicalMarginRectForAtomicInlineLevelBox(layoutBox);
+ } else if (inlineLevelBox.isLineBreakBox()) {
stream << "Line break box";
- else if (inlineLevelBox.isInlineBox())
- stream << "Generic inline box";
- else
+ logicalRect = lineBox.logicalRectForLineBreakBox(layoutBox);
+ } else if (inlineLevelBox.isInlineBox()) {
+ stream << "Inline box";
+ logicalRect = lineBox.logicalRectForInlineBox(layoutBox, layoutState.geometryForBox(layoutBox));
+ } else
stream << "Generic inline level box";
- auto& layoutBox = inlineLevelBox.layoutBox();
- auto logicalRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, layoutState.geometryForBox(layoutBox));
stream
<< " at (" << logicalRect.left() << "," << logicalRect.top() << ")"
<< " size (" << logicalRect.width() << "x" << logicalRect.height() << ")"