Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp (282140 => 282141)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp 2021-09-08 12:56:13 UTC (rev 282140)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp 2021-09-08 13:33:30 UTC (rev 282141)
@@ -40,7 +40,6 @@
: m_formattingContextRoot(formattingContextRoot)
, m_formattingState(formattingState)
{
-
}
void InlineDisplayContentBuilder::build(const LineBuilder::LineContent& lineContent, const LineBox& lineBox, const InlineLayoutPoint& lineBoxLogicalTopLeft, const size_t lineIndex)
@@ -52,6 +51,7 @@
formattingState.addRun({ lineIndex, Run::Type::RootInlineBox, root(), rootInlineBoxRect, rootInlineBoxRect, { }, { }, lineBox.rootInlineBox().hasContent()});
createRunsAndUpdateGeometryForLineSpanningInlineBoxes(lineBox, lineBoxLogicalTopLeft, lineIndex);
createRunsAndUpdateGeometryForLineContent(lineContent, lineBox, lineBoxLogicalTopLeft, lineIndex);
+ collectInkOverflowForInlineBoxRuns(lineBox);
}
void InlineDisplayContentBuilder::createRunsAndUpdateGeometryForLineContent(const LineBuilder::LineContent& lineContent, const LineBox& lineBox, const InlineLayoutPoint& lineBoxLogicalTopLeft, const size_t lineIndex)
@@ -132,6 +132,7 @@
auto& boxGeometry = formattingState.boxGeometry(layoutBox);
auto logicalBorderBox = lineBox.logicalBorderBoxForAtomicInlineLevelBox(layoutBox, boxGeometry);
logicalBorderBox.moveBy(lineBoxLogicalTopLeft);
+ // FIXME: Add ink overflow support for atomic inline level boxes (e.g. box shadow).
formattingState.addRun({ lineIndex, Run::Type::AtomicInlineLevelBox, layoutBox, logicalBorderBox, logicalBorderBox, lineRun.expansion(), { } });
auto borderBoxLogicalTopLeft = logicalBorderBox.topLeft();
@@ -139,6 +140,17 @@
// Atomic inline boxes are all set. Their margin/border/content box geometries are already computed. We just have to position them here.
boxGeometry.setLogicalTopLeft(toLayoutPoint(borderBoxLogicalTopLeft));
lineNeedIntegralPosition = false;
+
+ auto adjustParentInlineBoxInkOverflow = [&] {
+ auto& parentInlineBox = layoutBox.parent();
+ if (&parentInlineBox == &root()) {
+ // We don't collect ink overflow for the root inline box run.
+ return;
+ }
+ RELEASE_ASSERT(m_inlineBoxRunIndexMap.contains(&parentInlineBox));
+ formattingState.runs()[m_inlineBoxRunIndexMap.get(&parentInlineBox)].adjustInkOverflow(logicalBorderBox);
+ };
+ adjustParentInlineBoxInkOverflow();
break;
}
case InlineItem::Type::InlineBoxStart: {
@@ -148,6 +160,7 @@
inlineBoxBorderBox.moveBy(lineBoxLogicalTopLeft);
if (lineBox.hasContent()) {
// FIXME: It's expected to not have any runs on empty lines. We should reconsider this.
+ m_inlineBoxRunIndexMap.add(&layoutBox, formattingState.runs().size());
formattingState.addRun({ lineIndex, Run::Type::NonRootInlineBox, layoutBox, inlineBoxBorderBox, inlineBoxBorderBox, { }, { }, lineBox.inlineLevelBoxForLayoutBox(layoutBox).hasContent() });
}
@@ -198,6 +211,7 @@
auto inlineBoxBorderBox = lineBox.logicalBorderBoxForInlineBox(layoutBox, boxGeometry);
inlineBoxBorderBox.moveBy(lineBoxLogicalTopLeft);
+ m_inlineBoxRunIndexMap.add(&layoutBox, formattingState.runs().size());
formattingState.addRun({ lineIndex, Run::Type::NonRootInlineBox, layoutBox, inlineBoxBorderBox, inlineBoxBorderBox, { }, { }, inlineLevelBox.hasContent(), true });
auto inlineBoxSize = LayoutSize { LayoutUnit::fromFloatCeil(inlineBoxBorderBox.width()), LayoutUnit::fromFloatCeil(inlineBoxBorderBox.height()) };
@@ -222,7 +236,32 @@
formattingState.lines().last().setNeedsIntegralPosition(lineNeedIntegralPosition);
}
+void InlineDisplayContentBuilder::collectInkOverflowForInlineBoxRuns(const LineBox& lineBox)
+{
+ if (m_inlineBoxRunIndexMap.isEmpty() || !lineBox.hasContent()) {
+ // This line has no inline box (only root, but we don't collect ink overflow for the root inline box atm)
+ return;
+ }
+
+ auto& formattingState = this->formattingState();
+ auto& nonRootInlineLevelBoxes = lineBox.nonRootInlineLevelBoxes();
+ // Visit the inline boxes and propagate ink overflow to their parents -except to the root inline box.
+ // (e.g. <span style="font-size: 10px;">Small font size<span style="font-size: 300px;">Larger font size. This overflows the top most span.</span></span>).
+ for (size_t index = nonRootInlineLevelBoxes.size(); index--;) {
+ if (!nonRootInlineLevelBoxes[index].isInlineBox())
+ continue;
+ auto& inlineBox = nonRootInlineLevelBoxes[index].layoutBox();
+ auto& parentInlineBox = inlineBox.parent();
+ if (&parentInlineBox == &root())
+ continue;
+ RELEASE_ASSERT(m_inlineBoxRunIndexMap.contains(&inlineBox) && m_inlineBoxRunIndexMap.contains(&parentInlineBox));
+ auto& inkOverflow = formattingState.runs()[m_inlineBoxRunIndexMap.get(&inlineBox)].inkOverflow();
+ auto& parentInlineBoxRun = formattingState.runs()[m_inlineBoxRunIndexMap.get(&parentInlineBox)];
+ parentInlineBoxRun.adjustInkOverflow(inkOverflow);
+ }
}
+
}
+}
#endif
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.h (282140 => 282141)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.h 2021-09-08 12:56:13 UTC (rev 282140)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.h 2021-09-08 13:33:30 UTC (rev 282141)
@@ -46,6 +46,7 @@
private:
void createRunsAndUpdateGeometryForLineContent(const LineBuilder::LineContent&, const LineBox&, const InlineLayoutPoint& lineBoxLogicalTopLeft, const size_t lineIndex);
void createRunsAndUpdateGeometryForLineSpanningInlineBoxes(const LineBox&, const InlineLayoutPoint& lineBoxLogicalTopLeft, const size_t lineIndex);
+ void collectInkOverflowForInlineBoxRuns(const LineBox&);
const ContainerBox& root() const { return m_formattingContextRoot; }
InlineFormattingState& formattingState() const { return m_formattingState; }
@@ -52,6 +53,7 @@
const ContainerBox& m_formattingContextRoot;
InlineFormattingState& m_formattingState;
+ HashMap<const Box*, size_t> m_inlineBoxRunIndexMap;
};
}