Bug 1690422 - Take box-sizing into account when computing the intrinsic size with the preferred aspect ratio. r=TYLin,mats

We resolve the auto value in IntrinsicForAxis by the ratio determining size
and the preferred aspect ratio. However, this should take
box-sizing into account when using aspect-ratio property.

Differential Revision: https://phabricator.services.mozilla.com/D104293
This commit is contained in:
Boris Chiou 2021-02-17 02:41:24 +00:00
parent 3c57a55638
commit 181e91cf22
6 changed files with 112 additions and 24 deletions

View File

@ -4734,6 +4734,21 @@ nscoord nsLayoutUtils::IntrinsicForAxis(
haveFixedMinISize = GetAbsoluteCoord(styleMinISize, minISize);
}
auto childWM = aFrame->GetWritingMode();
nscoord pmPercentageBasis = NS_UNCONSTRAINEDSIZE;
if (aPercentageBasis.isSome()) {
// The padding/margin percentage basis is the inline-size in the parent's
// writing-mode.
pmPercentageBasis =
aFrame->GetParent()->GetWritingMode().IsOrthogonalTo(childWM)
? aPercentageBasis->BSize(childWM)
: aPercentageBasis->ISize(childWM);
}
nsIFrame::IntrinsicSizeOffsetData offsets =
MOZ_LIKELY(isInlineAxis)
? aFrame->IntrinsicISizeOffsets(pmPercentageBasis)
: aFrame->IntrinsicBSizeOffsets(pmPercentageBasis);
// If we have a specified width (or a specified 'min-width' greater
// than the specified 'max-width', which works out to the same thing),
// don't even bother getting the frame's intrinsic width, because in
@ -4817,10 +4832,6 @@ nscoord nsLayoutUtils::IntrinsicForAxis(
styleMinBSize.ToLength() == 0)) ||
!styleMaxBSize.IsNone()) {
if (AspectRatio ratio = aFrame->GetAspectRatio()) {
// Convert 'ratio' if necessary, so that it's storing ISize/BSize:
if (!horizontalAxis) {
ratio = ratio.Inverted();
}
AddStateBitToAncestors(
aFrame, NS_FRAME_DESCENDANT_INTRINSIC_ISIZE_DEPENDS_ON_BSIZE);
@ -4828,6 +4839,19 @@ nscoord nsLayoutUtils::IntrinsicForAxis(
(aFlags & IGNORE_PADDING) || aFrame->IsAbsolutelyPositioned();
nscoord bSizeTakenByBoxSizing = GetDefiniteSizeTakenByBoxSizing(
boxSizing, aFrame, !isInlineAxis, ignorePadding, aPercentageBasis);
auto contentBoxSizeToBoxSizingAdjust =
boxSizing == StyleBoxSizing::Border
? LogicalSize(
childWM,
(isInlineAxis
? offsets
: aFrame->IntrinsicISizeOffsets(pmPercentageBasis))
.BorderPadding(),
(!isInlineAxis
? offsets
: aFrame->IntrinsicBSizeOffsets(pmPercentageBasis))
.BorderPadding())
: LogicalSize(childWM);
// NOTE: This is only the minContentSize if we've been passed
// MIN_INTRINSIC_ISIZE (which is fine, because this should only be used
// inside a check for that flag).
@ -4838,7 +4862,11 @@ nscoord nsLayoutUtils::IntrinsicForAxis(
(aPercentageBasis.isNothing() &&
GetPercentBSize(styleBSize, aFrame, horizontalAxis, h))) {
h = std::max(0, h - bSizeTakenByBoxSizing);
result = ratio.ApplyTo(h);
// We are computing the size of |aFrame|, so we use the inline & block
// dimensions of |aFrame|.
result = ratio.ComputeRatioDependentSize(
isInlineAxis ? eLogicalAxisInline : eLogicalAxisBlock, childWM, h,
contentBoxSizeToBoxSizingAdjust);
}
if (GetDefiniteSize(styleMaxBSize, aFrame, !isInlineAxis,
@ -4846,7 +4874,9 @@ nscoord nsLayoutUtils::IntrinsicForAxis(
(aPercentageBasis.isNothing() &&
GetPercentBSize(styleMaxBSize, aFrame, horizontalAxis, h))) {
h = std::max(0, h - bSizeTakenByBoxSizing);
nscoord maxISize = ratio.ApplyTo(h);
nscoord maxISize = ratio.ComputeRatioDependentSize(
isInlineAxis ? eLogicalAxisInline : eLogicalAxisBlock, childWM, h,
contentBoxSizeToBoxSizingAdjust);
if (maxISize < result) {
result = maxISize;
}
@ -4860,7 +4890,9 @@ nscoord nsLayoutUtils::IntrinsicForAxis(
(aPercentageBasis.isNothing() &&
GetPercentBSize(styleMinBSize, aFrame, horizontalAxis, h))) {
h = std::max(0, h - bSizeTakenByBoxSizing);
nscoord minISize = ratio.ApplyTo(h);
nscoord minISize = ratio.ComputeRatioDependentSize(
isInlineAxis ? eLogicalAxisInline : eLogicalAxisBlock, childWM, h,
contentBoxSizeToBoxSizingAdjust);
if (minISize > result) {
result = minISize;
}
@ -4884,20 +4916,6 @@ nscoord nsLayoutUtils::IntrinsicForAxis(
min = aFrame->GetMinISize(aRenderingContext);
}
nscoord pmPercentageBasis = NS_UNCONSTRAINEDSIZE;
if (aPercentageBasis.isSome()) {
// The padding/margin percentage basis is the inline-size in the parent's
// writing-mode.
auto childWM = aFrame->GetWritingMode();
pmPercentageBasis =
aFrame->GetParent()->GetWritingMode().IsOrthogonalTo(childWM)
? aPercentageBasis->BSize(childWM)
: aPercentageBasis->ISize(childWM);
}
nsIFrame::IntrinsicSizeOffsetData offsets =
MOZ_LIKELY(isInlineAxis)
? aFrame->IntrinsicISizeOffsets(pmPercentageBasis)
: aFrame->IntrinsicBSizeOffsets(pmPercentageBasis);
nscoord contentBoxSize = result;
result = AddIntrinsicSizeOffset(
aRenderingContext, aFrame, offsets, aType, boxSizing, result, min,

View File

@ -93,9 +93,10 @@ struct AspectRatio {
*
* @param aRatioDependentAxis The ratio depenedent axis of the box.
* @param aWM The writing mode of the box.
* @param aRatioDetermingSize The size on the ratio determining axis.
* Basically, we use this size and |mRatio| to
* compute the size on the ratio-dependent axis.
* @param aRatioDetermingSize The content-box size on the ratio determining
* axis. Basically, we use this size and |mRatio|
* to compute the size on the ratio-dependent
* axis.
* @param aContentBoxSizeToBoxSizingAdjust The border padding box size
* adjustment. We need this because
* aspect-ratio should take the

View File

@ -2669,6 +2669,7 @@ class nsIFrame : public nsQueryFrame {
nscoord padding = 0;
nscoord border = 0;
nscoord margin = 0;
nscoord BorderPadding() const { return border + padding; };
};
/**

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<title>CSS aspect-ratio: grid track inline size should respect aspect-ratio and box-sizing</title>
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio">
<link rel="help" href="https://drafts.csswg.org/css-grid/#algo-track-sizing">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht" />
<style>
#reference-overlapped-red {
position: absolute;
background-color: red;
width: 100px;
height: 100px;
z-index: -1;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div id="reference-overlapped-red"></div>
<div style="display: grid; grid-template-columns: auto; width: max-content; background: green;">
<div style="height: 100px; aspect-ratio: 1/1; padding-top: 50px; box-sizing: border-box;"></div>
</div>

View File

@ -0,0 +1,23 @@
<!DOCTYPE html>
<title>CSS aspect-ratio: min-content size contribution with border-box</title>
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht" />
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="width: min-content; height: 25px; background: green;">
<div style="height: 25px; aspect-ratio: 4/1; box-sizing: border-box; padding-top: 15px;"></div>
</div>
<div style="width: min-content; height: 25px; background: green;">
<div style="height: 10px; aspect-ratio: 4/1; min-height: 25px; box-sizing: border-box; padding-top: 15px;"></div>
</div>
<div style="width: min-content; height: 25px; background: green;">
<div style="height: 100px; aspect-ratio: 4/1; max-height: 25px; box-sizing: border-box; padding-top: 15px;"></div>
</div>
<div style="width: min-content; height: 25px; background: green;">
<div style="height: 40px; aspect-ratio: auto 4/1; box-sizing: border-box; padding-top: 15px;"></div>
</div>

View File

@ -0,0 +1,23 @@
<!DOCTYPE html>
<title>CSS aspect-ratio: max-content size contribution with border-box</title>
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht" />
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="width: max-content; height: 25px; background: green;">
<div style="height: 25px; aspect-ratio: 4/1; box-sizing: border-box; padding-top: 25px;"></div>
</div>
<div style="width: max-content; height: 25px; background: green;">
<div style="height: 10px; aspect-ratio: 4/1; min-height: 25px; box-sizing: border-box; padding-top: 15px;"></div>
</div>
<div style="width: max-content; height: 25px; background: green;">
<div style="height: 100px; aspect-ratio: 4/1; max-height: 25px; box-sizing: border-box; padding-top: 15px;"></div>
</div>
<div style="width: max-content; height: 25px; background: green;">
<div style="height: 40px; aspect-ratio: auto 4/1; box-sizing: border-box; padding-top: 15px;"></div>
</div>