https://bugs.webkit.org/show_bug.cgi?id=189311
Reviewed by Antti Koivisto.
When the layout logic needs a Display::Box, we must have already created one for the associated Layout::Box.
(It does not necessarily mean that evey Layout::Box has a Display::Box. For example in case of inline formatting context,
we don't create a Display::Box for every inline box, but the formatting logic does not require such pairs.)
* layout/FormattingContext.cpp:
(WebCore::Layout::FormattingContext::computeOutOfFlowHorizontalGeometry const):
(WebCore::Layout::FormattingContext::computeOutOfFlowVerticalGeometry const):
(WebCore::Layout::FormattingContext::computeBorderAndPadding const):
(WebCore::Layout::FormattingContext::mapBoxToAncestor):
(WebCore::Layout::FormattingContext::mapTopLeftToAncestor):
(WebCore::Layout::FormattingContext::mapCoordinateToAncestor):
(WebCore::Layout::FormattingContext::validateGeometryConstraintsAfterLayout const):
* layout/FormattingContextGeometry.cpp:
(WebCore::Layout::contentHeightForFormattingContextRoot):
(WebCore::Layout::staticVerticalPositionForOutOfFlowPositioned):
(WebCore::Layout::staticHorizontalPositionForOutOfFlowPositioned):
(WebCore::Layout::FormattingContext::Geometry::shrinkToFitWidth):
(WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry):
(WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedHorizontalGeometry):
(WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry):
(WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedHorizontalGeometry):
(WebCore::Layout::FormattingContext::Geometry::complicatedCases):
(WebCore::Layout::FormattingContext::Geometry::floatingNonReplacedWidthAndMargin):
(WebCore::Layout::FormattingContext::Geometry::inlineReplacedHeightAndMargin):
(WebCore::Layout::FormattingContext::Geometry::inlineReplacedWidthAndMargin):
(WebCore::Layout::FormattingContext::Geometry::computedPadding):
(WebCore::Layout::FormattingContext::Geometry::computedNonCollapsedHorizontalMarginValue):
(WebCore::Layout::FormattingContext::Geometry::computedNonCollapsedVerticalMarginValue):
* layout/LayoutContext.h:
(WebCore::Layout::LayoutContext::displayBoxForLayoutBox const):
* layout/Verification.cpp:
(WebCore::Layout::outputMismatchingBlockBoxInformationIfNeeded):
* layout/blockformatting/BlockFormattingContext.cpp:
(WebCore::Layout::BlockFormattingContext::computeStaticPosition const):
(WebCore::Layout::BlockFormattingContext::computeEstimatedMarginTop const):
(WebCore::Layout::BlockFormattingContext::computeEstimatedMarginTopForAncestors const):
(WebCore::Layout::BlockFormattingContext::computeFloatingPosition const):
(WebCore::Layout::BlockFormattingContext::computePositionToAvoidFloats const):
(WebCore::Layout::BlockFormattingContext::computeVerticalPositionForFloatClear const):
(WebCore::Layout::BlockFormattingContext::computeInFlowPositionedPosition const):
(WebCore::Layout::BlockFormattingContext::computeWidthAndMargin const):
(WebCore::Layout::BlockFormattingContext::computeHeightAndMargin const):
* layout/blockformatting/BlockFormattingContextGeometry.cpp:
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMargin):
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedWidthAndMargin):
(WebCore::Layout::BlockFormattingContext::Geometry::staticPosition):
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowPositionedPosition):
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowHeightAndMargin):
* layout/blockformatting/BlockMarginCollapse.cpp:
(WebCore::Layout::isMarginTopCollapsedWithParent):
(WebCore::Layout::isMarginBottomCollapsedThrough):
(WebCore::Layout::BlockFormattingContext::Geometry::MarginCollapse::isMarginBottomCollapsedWithParent):
* layout/floats/FloatingContext.cpp:
(WebCore::Layout::FloatingContext::positionForFloat const):
(WebCore::Layout::FloatingContext::verticalPositionWithClearance const):
* layout/floats/FloatingState.cpp:
(WebCore::Layout::FloatingState::append):
* layout/inlineformatting/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::layout const):
* layout/layouttree/LayoutTreeBuilder.cpp:
(WebCore::Layout::outputLayoutTree):
(WebCore::Layout::showLayoutTree):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235681
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
2018-09-05 Zalan Bujtas <zalan@apple.com>
+ [LFC] LayoutContext::displayBoxForLayoutBox() should return a Display::Box&
+ https://bugs.webkit.org/show_bug.cgi?id=189311
+
+ Reviewed by Antti Koivisto.
+
+ When the layout logic needs a Display::Box, we must have already created one for the associated Layout::Box.
+ (It does not necessarily mean that evey Layout::Box has a Display::Box. For example in case of inline formatting context,
+ we don't create a Display::Box for every inline box, but the formatting logic does not require such pairs.)
+
+ * layout/FormattingContext.cpp:
+ (WebCore::Layout::FormattingContext::computeOutOfFlowHorizontalGeometry const):
+ (WebCore::Layout::FormattingContext::computeOutOfFlowVerticalGeometry const):
+ (WebCore::Layout::FormattingContext::computeBorderAndPadding const):
+ (WebCore::Layout::FormattingContext::mapBoxToAncestor):
+ (WebCore::Layout::FormattingContext::mapTopLeftToAncestor):
+ (WebCore::Layout::FormattingContext::mapCoordinateToAncestor):
+ (WebCore::Layout::FormattingContext::validateGeometryConstraintsAfterLayout const):
+ * layout/FormattingContextGeometry.cpp:
+ (WebCore::Layout::contentHeightForFormattingContextRoot):
+ (WebCore::Layout::staticVerticalPositionForOutOfFlowPositioned):
+ (WebCore::Layout::staticHorizontalPositionForOutOfFlowPositioned):
+ (WebCore::Layout::FormattingContext::Geometry::shrinkToFitWidth):
+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry):
+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedHorizontalGeometry):
+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry):
+ (WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedHorizontalGeometry):
+ (WebCore::Layout::FormattingContext::Geometry::complicatedCases):
+ (WebCore::Layout::FormattingContext::Geometry::floatingNonReplacedWidthAndMargin):
+ (WebCore::Layout::FormattingContext::Geometry::inlineReplacedHeightAndMargin):
+ (WebCore::Layout::FormattingContext::Geometry::inlineReplacedWidthAndMargin):
+ (WebCore::Layout::FormattingContext::Geometry::computedPadding):
+ (WebCore::Layout::FormattingContext::Geometry::computedNonCollapsedHorizontalMarginValue):
+ (WebCore::Layout::FormattingContext::Geometry::computedNonCollapsedVerticalMarginValue):
+ * layout/LayoutContext.h:
+ (WebCore::Layout::LayoutContext::displayBoxForLayoutBox const):
+ * layout/Verification.cpp:
+ (WebCore::Layout::outputMismatchingBlockBoxInformationIfNeeded):
+ * layout/blockformatting/BlockFormattingContext.cpp:
+ (WebCore::Layout::BlockFormattingContext::computeStaticPosition const):
+ (WebCore::Layout::BlockFormattingContext::computeEstimatedMarginTop const):
+ (WebCore::Layout::BlockFormattingContext::computeEstimatedMarginTopForAncestors const):
+ (WebCore::Layout::BlockFormattingContext::computeFloatingPosition const):
+ (WebCore::Layout::BlockFormattingContext::computePositionToAvoidFloats const):
+ (WebCore::Layout::BlockFormattingContext::computeVerticalPositionForFloatClear const):
+ (WebCore::Layout::BlockFormattingContext::computeInFlowPositionedPosition const):
+ (WebCore::Layout::BlockFormattingContext::computeWidthAndMargin const):
+ (WebCore::Layout::BlockFormattingContext::computeHeightAndMargin const):
+ * layout/blockformatting/BlockFormattingContextGeometry.cpp:
+ (WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMargin):
+ (WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedWidthAndMargin):
+ (WebCore::Layout::BlockFormattingContext::Geometry::staticPosition):
+ (WebCore::Layout::BlockFormattingContext::Geometry::inFlowPositionedPosition):
+ (WebCore::Layout::BlockFormattingContext::Geometry::inFlowHeightAndMargin):
+ * layout/blockformatting/BlockMarginCollapse.cpp:
+ (WebCore::Layout::isMarginTopCollapsedWithParent):
+ (WebCore::Layout::isMarginBottomCollapsedThrough):
+ (WebCore::Layout::BlockFormattingContext::Geometry::MarginCollapse::isMarginBottomCollapsedWithParent):
+ * layout/floats/FloatingContext.cpp:
+ (WebCore::Layout::FloatingContext::positionForFloat const):
+ (WebCore::Layout::FloatingContext::verticalPositionWithClearance const):
+ * layout/floats/FloatingState.cpp:
+ (WebCore::Layout::FloatingState::append):
+ * layout/inlineformatting/InlineFormattingContext.cpp:
+ (WebCore::Layout::InlineFormattingContext::layout const):
+ * layout/layouttree/LayoutTreeBuilder.cpp:
+ (WebCore::Layout::outputLayoutTree):
+ (WebCore::Layout::showLayoutTree):
+
+2018-09-05 Zalan Bujtas <zalan@apple.com>
+
[LFC] Drop Display:Box from FormattingContext::compute* functions
https://bugs.webkit.org/show_bug.cgi?id=189309
{
auto horizontalGeometry = Geometry::outOfFlowHorizontalGeometry(layoutContext, *this, layoutBox);
- auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+ auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
displayBox.setLeft(horizontalGeometry.left + horizontalGeometry.widthAndMargin.margin.left);
displayBox.setContentBoxWidth(horizontalGeometry.widthAndMargin.width);
displayBox.setHorizontalMargin(horizontalGeometry.widthAndMargin.margin);
{
auto verticalGeometry = Geometry::outOfFlowVerticalGeometry(layoutContext, layoutBox);
- auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+ auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
displayBox.setTop(verticalGeometry.top + verticalGeometry.heightAndMargin.margin.top);
displayBox.setContentBoxHeight(verticalGeometry.heightAndMargin.height);
ASSERT(!verticalGeometry.heightAndMargin.collapsedMargin);
void FormattingContext::computeBorderAndPadding(LayoutContext& layoutContext, const Box& layoutBox) const
{
- auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+ auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
displayBox.setBorder(Geometry::computedBorder(layoutContext, layoutBox));
displayBox.setPadding(Geometry::computedPadding(layoutContext, layoutBox));
}
{
ASSERT(layoutBox.isDescendantOf(ancestor));
- auto* displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
- ASSERT(displayBox);
- auto topLeft = displayBox->topLeft();
+ auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
+ auto topLeft = displayBox.topLeft();
auto* containingBlock = layoutBox.containingBlock();
for (; containingBlock && containingBlock != &ancestor; containingBlock = containingBlock->containingBlock())
- topLeft.moveBy(layoutContext.displayBoxForLayoutBox(*containingBlock)->topLeft());
+ topLeft.moveBy(layoutContext.displayBoxForLayoutBox(*containingBlock).topLeft());
if (!containingBlock) {
ASSERT_NOT_REACHED();
- return Display::Box(*displayBox);
+ return Display::Box(displayBox);
}
- auto mappedDisplayBox = Display::Box(*displayBox);
+ auto mappedDisplayBox = Display::Box(displayBox);
mappedDisplayBox.setTopLeft(topLeft);
return mappedDisplayBox;
}
Position FormattingContext::mapTopLeftToAncestor(const LayoutContext& layoutContext, const Box& layoutBox, const Container& ancestor)
{
ASSERT(layoutBox.isDescendantOf(ancestor));
- return mapCoordinateToAncestor(layoutContext, layoutContext.displayBoxForLayoutBox(layoutBox)->topLeft(), *layoutBox.containingBlock(), ancestor);
+ return mapCoordinateToAncestor(layoutContext, layoutContext.displayBoxForLayoutBox(layoutBox).topLeft(), *layoutBox.containingBlock(), ancestor);
}
Position FormattingContext::mapCoordinateToAncestor(const LayoutContext& layoutContext, Position position, const Container& containingBlock, const Container& ancestor)
auto mappedPosition = position;
auto* container = &containingBlock;
for (; container && container != &ancestor; container = container->containingBlock())
- mappedPosition.moveBy(layoutContext.displayBoxForLayoutBox(*container)->topLeft());
+ mappedPosition.moveBy(layoutContext.displayBoxForLayoutBox(*container).topLeft());
if (!container) {
ASSERT_NOT_REACHED();
for (auto& layoutBox : descendantsOfType<Box>(formattingContextRoot)) {
if (&layoutBox.formattingContextRoot() != &formattingContextRoot)
continue;
- auto& containingBlockDisplayBox = *layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock());
- auto* displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
- ASSERT(displayBox);
+ auto& containingBlockDisplayBox = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock());
+ auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
// 10.3.3 Block-level, non-replaced elements in normal flow
// 10.3.7 Absolutely positioned, non-replaced elements
if ((layoutBox.isBlockLevelBox() || layoutBox.isOutOfFlowPositioned()) && !layoutBox.replaced()) {
// margin-left + border-left-width + padding-left + width + padding-right + border-right-width + margin-right = width of containing block
auto containingBlockWidth = containingBlockDisplayBox.contentBoxWidth();
- ASSERT(displayBox->marginLeft() + displayBox->borderLeft() + displayBox->paddingLeft().value_or(0) + displayBox->contentBoxWidth()
- + displayBox->paddingRight().value_or(0) + displayBox->borderRight() + displayBox->marginRight() == containingBlockWidth);
+ ASSERT(displayBox.marginLeft() + displayBox.borderLeft() + displayBox.paddingLeft().value_or(0) + displayBox.contentBoxWidth()
+ + displayBox.paddingRight().value_or(0) + displayBox.borderRight() + displayBox.marginRight() == containingBlockWidth);
}
// 10.6.4 Absolutely positioned, non-replaced elements
if (layoutBox.isOutOfFlowPositioned() && !layoutBox.replaced()) {
// top + margin-top + border-top-width + padding-top + height + padding-bottom + border-bottom-width + margin-bottom + bottom = height of containing block
auto containingBlockHeight = containingBlockDisplayBox.contentBoxHeight();
- ASSERT(displayBox->top() + displayBox->marginTop() + displayBox->borderTop() + displayBox->paddingTop().value_or(0) + displayBox->contentBoxHeight()
- + displayBox->paddingBottom().value_or(0) + displayBox->borderBottom() + displayBox->marginBottom() == containingBlockHeight);
+ ASSERT(displayBox.top() + displayBox.marginTop() + displayBox.borderTop() + displayBox.paddingTop().value_or(0) + displayBox.contentBoxHeight()
+ + displayBox.paddingBottom().value_or(0) + displayBox.borderBottom() + displayBox.marginBottom() == containingBlockHeight);
}
}
}
if (formattingRootContainer.establishesInlineFormattingContext())
return 0;
- auto* firstDisplayBox = layoutContext.displayBoxForLayoutBox(*formattingRootContainer.firstInFlowChild());
- auto* lastDisplayBox = layoutContext.displayBoxForLayoutBox(*formattingRootContainer.lastInFlowChild());
- auto top = firstDisplayBox->rectWithMargin().top();
- auto bottom = lastDisplayBox->rectWithMargin().bottom();
+ auto& firstDisplayBox = layoutContext.displayBoxForLayoutBox(*formattingRootContainer.firstInFlowChild());
+ auto& lastDisplayBox = layoutContext.displayBoxForLayoutBox(*formattingRootContainer.lastInFlowChild());
+ auto top = firstDisplayBox.rectWithMargin().top();
+ auto bottom = lastDisplayBox.rectWithMargin().bottom();
auto* formattingContextRoot = &layoutBox;
// TODO: The document renderer is not a formatting context root by default at all. Need to find out what it is.
LayoutUnit top;
if (auto* previousInFlowSibling = layoutBox.previousInFlowSibling()) {
// Add sibling offset
- auto& previousInFlowDisplayBox = *layoutContext.displayBoxForLayoutBox(*previousInFlowSibling);
+ auto& previousInFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*previousInFlowSibling);
top += previousInFlowDisplayBox.bottom() + previousInFlowDisplayBox.nonCollapsedMarginBottom();
} else {
ASSERT(layoutBox.parent());
- top = layoutContext.displayBoxForLayoutBox(*layoutBox.parent())->contentBoxTop();
+ top = layoutContext.displayBoxForLayoutBox(*layoutBox.parent()).contentBoxTop();
}
// Resolve top all the way up to the containing block.
auto* containingBlock = layoutBox.containingBlock();
for (auto* container = layoutBox.parent(); container != containingBlock; container = container->containingBlock()) {
- auto& displayBox = *layoutContext.displayBoxForLayoutBox(*container);
+ auto& displayBox = layoutContext.displayBoxForLayoutBox(*container);
// Display::Box::top is the border box top position in its containing block's coordinate system.
top += displayBox.top();
ASSERT(!container->isPositioned());
// Start with this box's border box offset from the parent's border box.
ASSERT(layoutBox.parent());
- auto left = layoutContext.displayBoxForLayoutBox(*layoutBox.parent())->contentBoxLeft();
+ auto left = layoutContext.displayBoxForLayoutBox(*layoutBox.parent()).contentBoxLeft();
// Resolve left all the way up to the containing block.
auto* containingBlock = layoutBox.containingBlock();
for (auto* container = layoutBox.parent(); container != containingBlock; container = container->containingBlock()) {
- auto& displayBox = *layoutContext.displayBoxForLayoutBox(*container);
+ auto& displayBox = layoutContext.displayBoxForLayoutBox(*container);
// Display::Box::left is the border box left position in its containing block's coordinate system.
left += displayBox.left();
ASSERT(!container->isPositioned());
// 'padding-left', 'padding-right', 'border-right-width', 'margin-right', and the widths of any relevant scroll bars.
// Then the shrink-to-fit width is: min(max(preferred minimum width, available width), preferred width).
- auto availableWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->width();
+ auto availableWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock()).width();
auto instrinsicWidthConstraints = formattingContext.instrinsicWidthConstraints(layoutContext, layoutBox);
return std::min(std::max(instrinsicWidthConstraints.minimum, availableWidth), instrinsicWidthConstraints.maximum);
}
// 6. 'bottom' is 'auto', 'top' and 'height' are not 'auto', then set 'auto' values for 'margin-top' and 'margin-bottom' to 0 and solve for 'bottom'
auto& style = layoutBox.style();
- auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
- auto& containingBlockDisplayBox = *layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock());
+ auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
+ auto& containingBlockDisplayBox = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock());
auto containingBlockHeight = containingBlockDisplayBox.height();
auto containingBlockWidth = containingBlockDisplayBox.width();
// 6. 'right' is 'auto', 'left' and 'width' are not 'auto', then solve for 'right'
auto& style = layoutBox.style();
- auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+ auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
auto& containingBlock = *layoutBox.containingBlock();
- auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(containingBlock)->contentBoxWidth();
+ auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(containingBlock).contentBoxWidth();
auto isLeftToRightDirection = containingBlock.style().isLeftToRightDirection();
auto left = computedValueIfNotAuto(style.logicalLeft(), containingBlockWidth);
// 5. If at this point the values are over-constrained, ignore the value for 'bottom' and solve for that value.
auto& style = layoutBox.style();
- auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
- auto& containingBlockDisplayBox = *layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock());
+ auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
+ auto& containingBlockDisplayBox = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock());
auto containingBlockHeight = containingBlockDisplayBox.height();
auto containingBlockWidth = containingBlockDisplayBox.width();
// 'right' (in case 'direction' is 'ltr') and solve for that value.
auto& style = layoutBox.style();
- auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+ auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
auto& containingBlock = *layoutBox.containingBlock();
- auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(containingBlock)->contentBoxWidth();
+ auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(containingBlock).contentBoxWidth();
auto isLeftToRightDirection = containingBlock.style().isLeftToRightDirection();
auto left = computedValueIfNotAuto(style.logicalLeft(), containingBlockWidth);
auto& style = layoutBox.style();
auto& containingBlock = *layoutBox.containingBlock();
- auto& containingBlockDisplayBox = *layoutContext.displayBoxForLayoutBox(containingBlock);
+ auto& containingBlockDisplayBox = layoutContext.displayBoxForLayoutBox(containingBlock);
auto containingBlockWidth = containingBlockDisplayBox.contentBoxWidth();
auto height = fixedValue(style.logicalHeight());
// 2. If 'width' is computed as 'auto', the used value is the "shrink-to-fit" width.
auto& containingBlock = *layoutBox.containingBlock();
- auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(containingBlock)->contentBoxWidth();
+ auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(containingBlock).contentBoxWidth();
// #1
auto margin = computedNonCollapsedHorizontalMarginValue(layoutContext, layoutBox);
auto& style = layoutBox.style();
auto replaced = layoutBox.replaced();
- auto& containingBlockDisplayBox = *layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock());
+ auto& containingBlockDisplayBox = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock());
auto containingBlockWidth = containingBlockDisplayBox.width();
auto height = fixedValue(style.logicalHeight());
// If 300px is too wide to fit the device, UAs should use the width of the largest rectangle that has a 2:1 ratio and fits the device instead.
auto& style = layoutBox.style();
- auto& containingBlockDisplayBox = *layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock());
+ auto& containingBlockDisplayBox = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock());
auto containingBlockWidth = containingBlockDisplayBox.width();
auto computeMarginRight = [&]() {
return std::nullopt;
auto& style = layoutBox.style();
- auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->contentBoxWidth();
+ auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock()).contentBoxWidth();
LOG_WITH_STREAM(FormattingContextLayout, stream << "[Padding] -> layoutBox: " << &layoutBox);
return Edges {
{ valueForLength(style.paddingLeft(), containingBlockWidth), valueForLength(style.paddingRight(), containingBlockWidth) },
HorizontalEdges FormattingContext::Geometry::computedNonCollapsedHorizontalMarginValue(const LayoutContext& layoutContext, const Box& layoutBox)
{
auto& style = layoutBox.style();
- auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->contentBoxWidth();
+ auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock()).contentBoxWidth();
auto marginLeft = computedValueIfNotAuto(style.marginLeft(), containingBlockWidth).value_or(LayoutUnit { 0 });
auto marginRight = computedValueIfNotAuto(style.marginRight(), containingBlockWidth).value_or(LayoutUnit { 0 });
VerticalEdges FormattingContext::Geometry::computedNonCollapsedVerticalMarginValue(const LayoutContext& layoutContext, const Box& layoutBox)
{
auto& style = layoutBox.style();
- auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->contentBoxWidth();
+ auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock()).contentBoxWidth();
auto marginTop = computedValueIfNotAuto(style.marginTop(), containingBlockWidth).value_or(LayoutUnit { 0 });
auto marginBottom = computedValueIfNotAuto(style.marginBottom(), containingBlockWidth).value_or(LayoutUnit { 0 });
FormattingState& establishedFormattingState(const Box& formattingRoot);
Display::Box& createDisplayBox(const Box&);
- Display::Box* displayBoxForLayoutBox(const Box& layoutBox) const { return m_layoutToDisplayBox.get(&layoutBox); }
+ Display::Box& displayBoxForLayoutBox(const Box& layoutBox) const { return *m_layoutToDisplayBox.get(&layoutBox); }
bool inQuirksMode() const { return m_inQuirksMode; }
// For testing purposes only
};
};
- auto* displayBox = context.displayBoxForLayoutBox(layoutBox);
- ASSERT(displayBox);
+ auto& displayBox = context.displayBoxForLayoutBox(layoutBox);
auto frameRect = renderer.frameRect();
// rendering does not offset for relative positioned boxes.
if (renderer.isInFlowPositioned())
frameRect.move(renderer.offsetForInFlowPosition());
- if (frameRect != displayBox->rect()) {
- outputRect("frameBox", renderer.frameRect(), displayBox->rect());
+ if (frameRect != displayBox.rect()) {
+ outputRect("frameBox", renderer.frameRect(), displayBox.rect());
return true;
}
- if (renderer.marginBoxRect() != renderBoxLikeMarginBox(*displayBox)) {
- outputRect("marginBox", renderer.marginBoxRect(), renderBoxLikeMarginBox(*displayBox));
+ if (renderer.marginBoxRect() != renderBoxLikeMarginBox(displayBox)) {
+ outputRect("marginBox", renderer.marginBoxRect(), renderBoxLikeMarginBox(displayBox));
return true;
}
- if (renderer.borderBoxRect() != displayBox->borderBox()) {
- outputRect("borderBox", renderer.borderBoxRect(), displayBox->borderBox());
+ if (renderer.borderBoxRect() != displayBox.borderBox()) {
+ outputRect("borderBox", renderer.borderBoxRect(), displayBox.borderBox());
return true;
}
- if (renderer.paddingBoxRect() != displayBox->paddingBox()) {
- outputRect("paddingBox", renderer.paddingBoxRect(), displayBox->paddingBox());
+ if (renderer.paddingBoxRect() != displayBox.paddingBox()) {
+ outputRect("paddingBox", renderer.paddingBoxRect(), displayBox.paddingBox());
return true;
}
- if (renderer.contentBoxRect() != displayBox->contentBox()) {
- outputRect("contentBox", renderer.contentBoxRect(), displayBox->contentBox());
+ if (renderer.contentBoxRect() != displayBox.contentBox()) {
+ outputRect("contentBox", renderer.contentBoxRect(), displayBox.contentBox());
return true;
}
void BlockFormattingContext::computeStaticPosition(LayoutContext& layoutContext, const Box& layoutBox) const
{
- layoutContext.displayBoxForLayoutBox(layoutBox)->setTopLeft(Geometry::staticPosition(layoutContext, layoutBox));
+ layoutContext.displayBoxForLayoutBox(layoutBox).setTopLeft(Geometry::staticPosition(layoutContext, layoutBox));
}
void BlockFormattingContext::computeEstimatedMarginTop(LayoutContext& layoutContext, const Box& layoutBox) const
{
auto estimatedMarginTop = Geometry::estimatedMarginTop(layoutContext, layoutBox);
- auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+ auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
displayBox.setEstimatedMarginTop(estimatedMarginTop);
displayBox.moveVertically(estimatedMarginTop);
}
// The idea here is that as long as we don't cross the block formatting context boundary, we should be able to pre-compute the final top margin.
for (auto* ancestor = layoutBox.containingBlock(); ancestor && !ancestor->establishesBlockFormattingContext(); ancestor = ancestor->containingBlock()) {
- auto* displayBox = layoutContext.displayBoxForLayoutBox(*ancestor);
- ASSERT(displayBox);
+ auto& displayBox = layoutContext.displayBoxForLayoutBox(*ancestor);
// FIXME: with incremental layout, we might actually have a valid (non-estimated) margin top as well.
- if (displayBox->estimatedMarginTop())
+ if (displayBox.estimatedMarginTop())
return;
computeEstimatedMarginTop(layoutContext, *ancestor);
void BlockFormattingContext::computeFloatingPosition(LayoutContext& layoutContext, FloatingContext& floatingContext, const Box& layoutBox) const
{
ASSERT(layoutBox.isFloatingPositioned());
- auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+ auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
// 8.3.1 Collapsing margins
// In block formatting context margins between a floated box and any other box do not collapse.
// Adjust the static position by using the previous inflow box's non-collapsed margin.
if (auto* previousInFlowBox = layoutBox.previousInFlowSibling()) {
- auto& previousDisplayBox = *layoutContext.displayBoxForLayoutBox(*previousInFlowBox);
+ auto& previousDisplayBox = layoutContext.displayBoxForLayoutBox(*previousInFlowBox);
displayBox.moveVertically(previousDisplayBox.nonCollapsedMarginBottom() - previousDisplayBox.marginBottom());
}
computeEstimatedMarginTopForAncestors(layoutContext, layoutBox);
computeEstimatedMarginTopForAncestors(layoutContext, layoutBox);
if (auto adjustedPosition = floatingContext.positionForFloatAvoiding(layoutBox))
- layoutContext.displayBoxForLayoutBox(layoutBox)->setTopLeft(*adjustedPosition);
+ layoutContext.displayBoxForLayoutBox(layoutBox).setTopLeft(*adjustedPosition);
}
void BlockFormattingContext::computeVerticalPositionForFloatClear(LayoutContext& layoutContext, const FloatingContext& floatingContext, const Box& layoutBox) const
computeEstimatedMarginTopForAncestors(layoutContext, layoutBox);
if (auto verticalPositionWithClearance = floatingContext.verticalPositionWithClearance(layoutBox))
- layoutContext.displayBoxForLayoutBox(layoutBox)->setTop(*verticalPositionWithClearance);
+ layoutContext.displayBoxForLayoutBox(layoutBox).setTop(*verticalPositionWithClearance);
}
void BlockFormattingContext::computeInFlowPositionedPosition(LayoutContext& layoutContext, const Box& layoutBox) const
{
- layoutContext.displayBoxForLayoutBox(layoutBox)->setTopLeft(Geometry::inFlowPositionedPosition(layoutContext, layoutBox));
+ layoutContext.displayBoxForLayoutBox(layoutBox).setTopLeft(Geometry::inFlowPositionedPosition(layoutContext, layoutBox));
}
void BlockFormattingContext::computeWidthAndMargin(LayoutContext& layoutContext, const Box& layoutBox) const
else
ASSERT_NOT_REACHED();
- auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+ auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
displayBox.setContentBoxWidth(widthAndMargin.width);
displayBox.moveHorizontally(widthAndMargin.margin.left);
displayBox.setHorizontalMargin(widthAndMargin.margin);
{
HeightAndMargin heightAndMargin;
std::optional<LayoutUnit> marginTopOffset;
- auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+ auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
if (layoutBox.isInFlow()) {
heightAndMargin = Geometry::inFlowHeightAndMargin(layoutContext, layoutBox);
// and relatively positioned boxes are considered without their offset). Note that the child box may be an anonymous block box.
auto& style = layoutBox.style();
- auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->contentBoxWidth();
- auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+ auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock()).contentBoxWidth();
+ auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
VerticalEdges nonCollapsedMargin = { computedValueIfNotAuto(style.marginTop(), containingBlockWidth).value_or(0),
computedValueIfNotAuto(style.marginBottom(), containingBlockWidth).value_or(0) };
auto* lastInFlowChild = downcast<Container>(layoutBox).lastInFlowChild();
ASSERT(lastInFlowChild);
if (!MarginCollapse::isMarginBottomCollapsedWithParent(layoutContext, *lastInFlowChild)) {
- auto* lastInFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*lastInFlowChild);
- ASSERT(lastInFlowDisplayBox);
- return { lastInFlowDisplayBox->bottom() + lastInFlowDisplayBox->marginBottom() - borderAndPaddingTop, nonCollapsedMargin, collapsedMargin };
+ auto& lastInFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*lastInFlowChild);
+ return { lastInFlowDisplayBox.bottom() + lastInFlowDisplayBox.marginBottom() - borderAndPaddingTop, nonCollapsedMargin, collapsedMargin };
}
// 3. the bottom border edge of the last in-flow child whose top margin doesn't collapse with the element's bottom margin
while (inFlowChild && MarginCollapse::isMarginTopCollapsedWithParentMarginBottom(*inFlowChild))
inFlowChild = inFlowChild->previousInFlowSibling();
if (inFlowChild) {
- auto* inFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*inFlowChild);
- ASSERT(inFlowDisplayBox);
- return { inFlowDisplayBox->top() + inFlowDisplayBox->borderBox().height() - borderAndPaddingTop, nonCollapsedMargin, collapsedMargin };
+ auto& inFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*inFlowChild);
+ return { inFlowDisplayBox.top() + inFlowDisplayBox.borderBox().height() - borderAndPaddingTop, nonCollapsedMargin, collapsedMargin };
}
// 4. zero, otherwise
auto& style = layoutBox.style();
auto* containingBlock = layoutBox.containingBlock();
- auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*containingBlock)->contentBoxWidth();
- auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+ auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*containingBlock).contentBoxWidth();
+ auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
auto width = computedValueIfNotAuto(precomputedWidth ? Length { precomputedWidth.value(), Fixed } : style.logicalWidth(), containingBlockWidth);
auto marginLeft = computedValueIfNotAuto(style.marginLeft(), containingBlockWidth);
return widthAndMargin;
}
- auto initialContainingBlockWidth = layoutContext.displayBoxForLayoutBox(initialContainingBlock(layoutBox))->contentBoxWidth();
+ auto initialContainingBlockWidth = layoutContext.displayBoxForLayoutBox(initialContainingBlock(layoutBox)).contentBoxWidth();
widthAndMargin = stretchWidthToInitialContainingBlock(widthAndMargin, initialContainingBlockWidth);
LOG_WITH_STREAM(FormattingContextLayout, stream << "[Width][Margin] -> inflow non-replaced -> streched to viewport-> width(" << widthAndMargin.width << "px) margin(" << widthAndMargin.margin.left << "px, " << widthAndMargin.margin.right << "px) -> layoutBox(" << &layoutBox << ")");
// In a block formatting context, each box's left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch).
LayoutUnit top;
- auto& containingBlockDisplayBox = *layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock());
+ auto& containingBlockDisplayBox = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock());
if (auto* previousInFlowSibling = layoutBox.previousInFlowSibling()) {
- auto& previousInFlowDisplayBox = *layoutContext.displayBoxForLayoutBox(*previousInFlowSibling);
+ auto& previousInFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*previousInFlowSibling);
top = previousInFlowDisplayBox.bottom() + previousInFlowDisplayBox.marginBottom();
} else
top = containingBlockDisplayBox.contentBoxTop();
// 3. If neither is 'auto', 'bottom' is ignored (i.e., the used value of 'bottom' will be minus the value of 'top').
auto& style = layoutBox.style();
- auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+ auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
auto& containingBlock = *layoutBox.containingBlock();
- auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(containingBlock)->contentBoxWidth();
+ auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(containingBlock).contentBoxWidth();
auto top = computedValueIfNotAuto(style.logicalTop(), containingBlockWidth);
auto bottom = computedValueIfNotAuto(style.logicalBottom(), containingBlockWidth);
if (!isStretchedToInitialContainingBlock(layoutContext, layoutBox))
return heightAndMargin;
- auto initialContainingBlockHeight = layoutContext.displayBoxForLayoutBox(initialContainingBlock(layoutBox))->contentBoxHeight();
+ auto initialContainingBlockHeight = layoutContext.displayBoxForLayoutBox(initialContainingBlock(layoutBox)).contentBoxHeight();
heightAndMargin = stretchHeightToInitialContainingBlock(heightAndMargin, initialContainingBlockHeight);
LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> inflow non-replaced -> streched to viewport -> height(" << heightAndMargin.height << "px) margin(" << heightAndMargin.margin.top << "px, " << heightAndMargin.margin.bottom << "px) -> layoutBox(" << &layoutBox << ")");
if (parent.isDocumentBox() || parent.isInitialContainingBlock())
return false;
- auto& parentDisplayBox = *layoutContext.displayBoxForLayoutBox(parent);
+ auto& parentDisplayBox = layoutContext.displayBoxForLayoutBox(parent);
if (parentDisplayBox.borderTop())
return false;
ASSERT(layoutBox.isBlockLevelBox());
// If the top and bottom margins of a box are adjoining, then it is possible for margins to collapse through it.
- auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+ auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
if (displayBox.borderTop() || displayBox.borderBottom())
return false;
if (parent.isDocumentBox() || parent.isInitialContainingBlock())
return false;
- auto& parentDisplayBox = *layoutContext.displayBoxForLayoutBox(parent);
+ auto& parentDisplayBox = layoutContext.displayBoxForLayoutBox(parent);
if (parentDisplayBox.borderTop())
return false;
ASSERT(layoutBox.isFloatingPositioned());
if (m_floatingState.isEmpty()) {
- auto& displayBox = *layoutContext().displayBoxForLayoutBox(layoutBox);
+ auto& displayBox = layoutContext().displayBoxForLayoutBox(layoutBox);
auto alignWithContainingBlock = [&]() -> PositionInContainingBlock {
// If there is no floating to align with, push the box to the left/right edge of its containing block's content box.
- auto& containingBlockDisplayBox = *layoutContext().displayBoxForLayoutBox(*layoutBox.containingBlock());
+ auto& containingBlockDisplayBox = layoutContext().displayBoxForLayoutBox(*layoutBox.containingBlock());
if (layoutBox.isLeftFloatingPositioned())
return containingBlockDisplayBox.contentBoxLeft() + displayBox.marginLeft();
// 2. The amount necessary to place the top border edge of the block at its hypothetical position.
auto& layoutContext = this->layoutContext();
- auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+ auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
auto rootRelativeTop = FormattingContext::mapTopLeftToAncestor(layoutContext, layoutBox, downcast<Container>(m_floatingState.root())).y;
auto clearance = *floatBottom - rootRelativeTop;
if (clearance <= 0)
// Clearance inhibits margin collapsing. Let's reset the relevant adjoining margins.
if (auto* previousInFlowSibling = layoutBox.previousInFlowSibling()) {
- auto& previousInFlowDisplayBox = *layoutContext.displayBoxForLayoutBox(*previousInFlowSibling);
+ auto& previousInFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*previousInFlowSibling);
// Since the previous inflow sibling has already been laid out, its margin is collapsed by now.
ASSERT(!previousInFlowDisplayBox.marginBottom());
{
ASSERT(is<Container>(*m_formattingContextRoot));
ASSERT(belongsToThisFloatingContext(layoutBox, *m_formattingContextRoot));
-
- // Floating state should hold boxes with computed position/size.
- ASSERT(m_layoutContext.displayBoxForLayoutBox(layoutBox));
ASSERT(is<Container>(*m_formattingContextRoot));
m_floats.append({ layoutBox, *this });
ASSERT(!layoutBox || layoutBox->isDescendantOf(formattingRoot));
}
- auto& formattingRootDisplayBox = *layoutContext.displayBoxForLayoutBox(formattingRoot);
+ auto& formattingRootDisplayBox = layoutContext.displayBoxForLayoutBox(formattingRoot);
auto lineLeft = formattingRootDisplayBox.contentBoxLeft();
auto lineRight = formattingRootDisplayBox.contentBoxRight();
static void outputLayoutTree(const LayoutContext* layoutContext, TextStream& stream, const Container& rootContainer, unsigned depth)
{
for (auto& child : childrenOfType<Box>(rootContainer)) {
- outputLayoutBox(stream, child, layoutContext ? layoutContext->displayBoxForLayoutBox(child) : nullptr, depth);
+ outputLayoutBox(stream, child, layoutContext ? &layoutContext->displayBoxForLayoutBox(child) : nullptr, depth);
if (is<Container>(child))
outputLayoutTree(layoutContext, stream, downcast<Container>(child), depth + 1);
}
TextStream stream(TextStream::LineMode::MultipleLine, TextStream::Formatting::SVGStyleRect);
auto& initialContainingBlock = layoutBox.initialContainingBlock();
- outputLayoutBox(stream, initialContainingBlock, layoutContext ? layoutContext->displayBoxForLayoutBox(initialContainingBlock) : nullptr, 0);
+ outputLayoutBox(stream, initialContainingBlock, layoutContext ? &layoutContext->displayBoxForLayoutBox(initialContainingBlock) : nullptr, 0);
outputLayoutTree(layoutContext, stream, initialContainingBlock, 1);
WTFLogAlways("%s", stream.release().utf8().data());
}