Modified: trunk/Source/WebCore/ChangeLog (269101 => 269102)
--- trunk/Source/WebCore/ChangeLog 2020-10-28 13:13:34 UTC (rev 269101)
+++ trunk/Source/WebCore/ChangeLog 2020-10-28 13:14:48 UTC (rev 269102)
@@ -1,3 +1,27 @@
+2020-10-28 Zalan Bujtas <[email protected]>
+
+ [LFC][IFC] Add support for case when nested vertical alignment affects the root inlinebox vertical position
+ https://bugs.webkit.org/show_bug.cgi?id=218271
+
+ Reviewed by Antti Koivisto.
+
+ Let's start tracking the nested vertical alignment offsets from the root's baseline.
+ It enables us to find out how much offset the root inlinebox's baseline is required inside the line box.
+ e.g.
+ <div style="font-size: 50px;">
+ root inlinebox text content
+ <span style="font-size: 10px; vertical-align: text-bottom">and some nested text with an image
+ <img src="" style="vertical-align: baseline; height: 100px; width: 100px;">
+ </span>
+ </div>
+ In this case, the nested inline box (<span>) has 'text-bottom' vertical alignment which may stretch the line box and
+ may push the root inlinebox downwards so as the nested <img> (aligned with the <span>'s baseline).
+
+ We simply compute the absolute offset value for each inline level boxes as we walk the "tree" and hold on to the maximum value.
+
+ * layout/inlineformatting/InlineFormattingContextGeometry.cpp:
+ (WebCore::Layout::LineBoxBuilder::alignInlineLevelBoxesVerticallyAndComputeLineBoxHeight):
+
2020-10-28 Philippe Normand <[email protected]>
[GStreamer] Mock video source doesn't set framerate on its caps
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp (269101 => 269102)
--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp 2020-10-28 13:13:34 UTC (rev 269101)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp 2020-10-28 13:14:48 UTC (rev 269102)
@@ -303,15 +303,16 @@
// https://www.w3.org/TR/css-inline-3/#line-layout
auto quirks = formattingContext().quirks();
Vector<LineBox::InlineLevelBox*> lineBoxRelativeInlineLevelBoxes;
- struct AbsoluteTopAndBottom {
+ struct AbsoluteGeometry {
InlineLayoutUnit top { 0 };
InlineLayoutUnit bottom { 0 };
+ InlineLayoutUnit baselineOffsetFromRootInlineBoxBaseline { 0 };
const LineBox::InlineLevelBox* inlineLevelBox { nullptr };
};
- HashMap<LineBox::InlineLevelBox*, AbsoluteTopAndBottom> absoluteLogicalTopAndBottomMap;
+ HashMap<LineBox::InlineLevelBox*, AbsoluteGeometry> inlineLevelBoxAbsoluteGeometryMap;
auto& rootInlineBox = lineBox.rootInlineBox();
- absoluteLogicalTopAndBottomMap.add(&rootInlineBox, AbsoluteTopAndBottom { { }, rootInlineBox.layoutBounds().height(), &rootInlineBox });
- auto maximumOffsetFromRootInlineBoxBaseline = rootInlineBox.isEmpty() ? InlineLayoutUnit() : rootInlineBox.layoutBounds().ascent;
+ inlineLevelBoxAbsoluteGeometryMap.add(&rootInlineBox, AbsoluteGeometry { { }, rootInlineBox.layoutBounds().height(), { }, &rootInlineBox });
+ auto maximumTopOffsetFromRootInlineBoxBaseline = rootInlineBox.isEmpty() ? InlineLayoutUnit() : rootInlineBox.layoutBounds().ascent;
auto alignInlineBoxRelativeInlineLevelBoxes = [&] {
// FIXME: Add proper support for cases when the inline box with line box relative alignment has a child inline box
@@ -324,11 +325,11 @@
}
auto& parentInlineBox = lineBox.inlineLevelBoxForLayoutBox(layoutBox.parent());
auto logicalTop = InlineLayoutUnit { };
- auto offsetFromParentInlineBoxBaseline = InlineLayoutUnit { };
+ auto baselineOffsetFromParentBaseline = InlineLayoutUnit { };
switch (inlineLevelBox->verticalAlign()) {
case VerticalAlign::Baseline:
- offsetFromParentInlineBoxBaseline = inlineLevelBox->layoutBounds().ascent;
- logicalTop = parentInlineBox.baseline() - offsetFromParentInlineBoxBaseline;
+ logicalTop = parentInlineBox.baseline() - inlineLevelBox->layoutBounds().ascent;
+ baselineOffsetFromParentBaseline = { };
break;
case VerticalAlign::TextTop: {
// Note that TextTop aligns with the inline box's font metrics top (ascent) and not the layout bounds top.
@@ -335,7 +336,7 @@
auto parentAscent = parentInlineBox.fontMetrics().ascent();
auto parentInlineBoxLogicalTop = parentInlineBox.layoutBounds().ascent - parentAscent;
logicalTop = parentInlineBoxLogicalTop;
- offsetFromParentInlineBoxBaseline = parentAscent;
+ baselineOffsetFromParentBaseline = parentAscent - inlineLevelBox->layoutBounds().ascent;
break;
}
case VerticalAlign::TextBottom: {
@@ -343,22 +344,28 @@
auto& parentFontMetrics = parentInlineBox.fontMetrics();
auto parentInlineBoxLayoutBounds = parentInlineBox.layoutBounds();
auto parentInlineBoxLogicalBottom = parentInlineBoxLayoutBounds.height() - parentInlineBoxLayoutBounds.descent + parentFontMetrics.descent();
- logicalTop = parentInlineBoxLogicalBottom - inlineLevelBox->logicalHeight();
- offsetFromParentInlineBoxBaseline = inlineLevelBox->logicalHeight() - parentFontMetrics.descent();
+ auto layoutBounds = inlineLevelBox->layoutBounds();
+ logicalTop = parentInlineBoxLogicalBottom - layoutBounds.height();
+ baselineOffsetFromParentBaseline = layoutBounds.descent - parentFontMetrics.descent();
break;
}
- case VerticalAlign::Middle:
- offsetFromParentInlineBoxBaseline = (inlineLevelBox->layoutBounds().height() / 2 + parentInlineBox.fontMetrics().xHeight() / 2);
- logicalTop = parentInlineBox.baseline() - offsetFromParentInlineBoxBaseline;
+ case VerticalAlign::Middle: {
+ auto logicalTopOffsetFromParentBaseline = inlineLevelBox->layoutBounds().height() / 2 + parentInlineBox.fontMetrics().xHeight() / 2;
+ logicalTop = parentInlineBox.baseline() - logicalTopOffsetFromParentBaseline;
+ baselineOffsetFromParentBaseline = logicalTopOffsetFromParentBaseline - inlineLevelBox->layoutBounds().ascent;
break;
- case VerticalAlign::BaselineMiddle:
- offsetFromParentInlineBoxBaseline = inlineLevelBox->layoutBounds().height() / 2;
- logicalTop = parentInlineBox.baseline() - offsetFromParentInlineBoxBaseline;
+ }
+ case VerticalAlign::BaselineMiddle: {
+ auto logicalTopOffsetFromParentBaseline = inlineLevelBox->layoutBounds().height() / 2;
+ logicalTop = parentInlineBox.baseline() - logicalTopOffsetFromParentBaseline;
+ baselineOffsetFromParentBaseline = logicalTopOffsetFromParentBaseline - inlineLevelBox->layoutBounds().ascent;
break;
+ }
case VerticalAlign::Length: {
auto& style = layoutBox.style();
- offsetFromParentInlineBoxBaseline = floatValueForLength(style.verticalAlignLength(), style.computedLineHeight());
- logicalTop = parentInlineBox.baseline() - offsetFromParentInlineBoxBaseline - inlineLevelBox->logicalHeight();
+ auto logicalTopOffsetFromParentBaseline = floatValueForLength(style.verticalAlignLength(), style.computedLineHeight()) + inlineLevelBox->layoutBounds().height();
+ logicalTop = parentInlineBox.baseline() - logicalTopOffsetFromParentBaseline;
+ baselineOffsetFromParentBaseline = logicalTopOffsetFromParentBaseline - inlineLevelBox->layoutBounds().ascent;
break;
}
default:
@@ -366,13 +373,15 @@
break;
}
inlineLevelBox->setLogicalTop(logicalTop);
- auto parentAbsoluteLogicalTop = absoluteLogicalTopAndBottomMap.get(&parentInlineBox).top;
- auto absoluteLogicalTop = parentAbsoluteLogicalTop + logicalTop;
- absoluteLogicalTopAndBottomMap.add(inlineLevelBox.get(), AbsoluteTopAndBottom { absoluteLogicalTop, absoluteLogicalTop + inlineLevelBox->layoutBounds().height(), inlineLevelBox.get() });
+ auto parentInlineBoxAbsoluteGeometry = inlineLevelBoxAbsoluteGeometryMap.get(&parentInlineBox);
+ auto absoluteLogicalTop = parentInlineBoxAbsoluteGeometry.top + logicalTop;
+ auto absoluteLogicalBottom = absoluteLogicalTop + inlineLevelBox->layoutBounds().height();
+ auto absoluteBaselineOffsetFromRootInlineBoxBaseline = parentInlineBoxAbsoluteGeometry.baselineOffsetFromRootInlineBoxBaseline + baselineOffsetFromParentBaseline;
+ inlineLevelBoxAbsoluteGeometryMap.add(inlineLevelBox.get(), AbsoluteGeometry { absoluteLogicalTop, absoluteLogicalBottom, absoluteBaselineOffsetFromRootInlineBoxBaseline, inlineLevelBox.get() });
- auto affectsRootInlineBoxVerticalPostion = isRootInlineBox(parentInlineBox) && quirks.shouldInlineLevelBoxStretchLineBox(lineBox, *inlineLevelBox);
- if (affectsRootInlineBoxVerticalPostion)
- maximumOffsetFromRootInlineBoxBaseline = std::max(maximumOffsetFromRootInlineBoxBaseline, offsetFromParentInlineBoxBaseline);
+ auto affectsRootInlineBoxVerticalPosition = quirks.shouldInlineLevelBoxStretchLineBox(lineBox, *inlineLevelBox);
+ if (affectsRootInlineBoxVerticalPosition)
+ maximumTopOffsetFromRootInlineBoxBaseline = std::max(maximumTopOffsetFromRootInlineBoxBaseline, absoluteBaselineOffsetFromRootInlineBoxBaseline + inlineLevelBox->layoutBounds().ascent);
}
};
alignInlineBoxRelativeInlineLevelBoxes();
@@ -383,12 +392,12 @@
// FIXME: Add support for layout bounds based line box height.
auto minimumLogicalTop = Optional<InlineLayoutUnit> { };
auto maximumLogicalBottom = Optional<InlineLayoutUnit> { };
- for (auto absoluteLogicalTopAndBottom : absoluteLogicalTopAndBottomMap.values()) {
- auto& inlineLevelBox = *absoluteLogicalTopAndBottom.inlineLevelBox;
+ for (auto absoluteGeometry : inlineLevelBoxAbsoluteGeometryMap.values()) {
+ auto& inlineLevelBox = *absoluteGeometry.inlineLevelBox;
if (!quirks.shouldInlineLevelBoxStretchLineBox(lineBox, inlineLevelBox))
continue;
- minimumLogicalTop = std::min(minimumLogicalTop.valueOr(absoluteLogicalTopAndBottom.top), absoluteLogicalTopAndBottom.top);
- maximumLogicalBottom = std::max(maximumLogicalBottom.valueOr(absoluteLogicalTopAndBottom.bottom), absoluteLogicalTopAndBottom.bottom);
+ minimumLogicalTop = std::min(minimumLogicalTop.valueOr(absoluteGeometry.top), absoluteGeometry.top);
+ maximumLogicalBottom = std::max(maximumLogicalBottom.valueOr(absoluteGeometry.bottom), absoluteGeometry.bottom);
}
inlineBoxRelativeLogicalHeight = maximumLogicalBottom.valueOr(InlineLayoutUnit()) - minimumLogicalTop.valueOr(InlineLayoutUnit());
lineBoxLogicalHeight = inlineBoxRelativeLogicalHeight;
@@ -403,7 +412,7 @@
auto adjustRootInlineBoxVerticalPosition = [&] {
// FIXME: Add support for cases when the stretching inline boxes are not baseline aligned.
- auto rootInlineBoxLogicalTop = maximumOffsetFromRootInlineBoxBaseline - rootInlineBox.layoutBounds().ascent;
+ auto rootInlineBoxLogicalTop = maximumTopOffsetFromRootInlineBoxBaseline - rootInlineBox.layoutBounds().ascent;
rootInlineBox.setLogicalTop(rootInlineBoxLogicalTop);
};
adjustRootInlineBoxVerticalPosition();