Bug 1665327 - Support transferred {min|max} inline-size by using definite {min|max} block-size and aspect-ratio for non-replaced elements. r=TYLin

This addressed https://github.com/w3c/csswg-drafts/issues/5257.
The min-block-size or max-block-size should affect the inline size computed
through an aspect ratio.

I intentionally don't implement this for transferred {min|max}
block-size because
1. This is useful only if block-size is indefinite.
2. If block-size is indefinite, we may use the inline-size and aspect-ratio to
   get the block-size, which makes block-size definite.
3. This means it is useful when both inline-size and block-size are
   indefinite (e.g. auto).
   In this case, we still resolve a possible inline-size by clamping it
   between specified (and transferred) min and max inline-sizes. Then
   we map this inline-size to block-size through aspect-ratio. This
   transferred block-size should also be between specified (and
   transferred) min and max block-sizes.

Differential Revision: https://phabricator.services.mozilla.com/D94911
This commit is contained in:
Boris Chiou 2020-11-04 23:44:03 +00:00
parent 6098d48cca
commit 2ca58af841
8 changed files with 83 additions and 18 deletions

View File

@ -6036,6 +6036,51 @@ static bool ShouldApplyAutomaticMinimumOnInlineAxis(
return !aDisplay->IsScrollableOverflow() && aPosition->MinISize(aWM).IsAuto();
}
struct MinMaxSize {
nscoord mMinSize = 0;
nscoord mMaxSize = NS_UNCONSTRAINEDSIZE;
nscoord ClampSizeToMinAndMax(nscoord aSize) const {
return NS_CSS_MINMAX(aSize, mMinSize, mMaxSize);
}
};
static MinMaxSize ComputeTransferredMinMaxInlineSize(
WritingMode aWM, const StyleAspectRatio& aAspectRatio,
const MinMaxSize& aMinMaxBSize, const LogicalSize& aBoxSizingAdjustment) {
// Note: the spec mentions that
// 1. This transferred minimum is capped by any definite preferred or maximum
// size in the destination axis.
// 2. This transferred maximum is floored by any definite preferred or minimum
// size in the destination axis
//
// https://drafts.csswg.org/css-sizing-4/#aspect-ratio
//
// The spec requires us to clamp these by the specified size (it calls it the
// preferred size). However, we actually don't need to worry about that,
// because we only use this if the inline size is indefinite.
//
// We do not need to clamp the transferred minimum and maximum as long as we
// always apply the transferred min/max size before the explicit min/max size,
// the result will be identical.
MinMaxSize transferredISize;
if (aMinMaxBSize.mMinSize > 0) {
transferredISize.mMinSize = ComputeInlineSizeFromAspectRatio(
aWM, aAspectRatio, aMinMaxBSize.mMinSize, aBoxSizingAdjustment);
}
if (aMinMaxBSize.mMaxSize != NS_UNCONSTRAINEDSIZE) {
transferredISize.mMaxSize = ComputeInlineSizeFromAspectRatio(
aWM, aAspectRatio, aMinMaxBSize.mMaxSize, aBoxSizingAdjustment);
}
// Minimum size wins over maximum size.
transferredISize.mMaxSize =
std::max(transferredISize.mMinSize, transferredISize.mMaxSize);
return transferredISize;
}
/* virtual */
nsIFrame::SizeComputationResult nsIFrame::ComputeSize(
gfxContext* aRenderingContext, WritingMode aWM, const LogicalSize& aCBSize,
@ -6188,13 +6233,48 @@ nsIFrame::SizeComputationResult nsIFrame::ComputeSize(
}
}
// Calculate and apply min max transferred size contraint.
// https://github.com/w3c/csswg-drafts/issues/5257
// If we have definite preferred size, the transferred minimum and maximum
// are clampled by it. This means transferred minimum and maximum don't have
// effects with definite preferred size.
//
// Note: The axis in which the preferred size calculation depends on this
// aspect ratio is called the ratio-dependent axis, and the resulting size
// is definite if its input sizes are also definite.
const bool isDefiniteISize =
inlineStyleCoord->IsLengthPercentage() ||
aspectRatioUsage == AspectRatioUsage::ToComputeISize;
const bool isFlexItemInlineAxisMainAxis =
isFlexItem && flexMainAxis == eLogicalAxisInline;
if (stylePos->mAspectRatio.HasFiniteRatio() && !isDefiniteISize &&
!isFlexItemInlineAxisMainAxis) {
const auto& minBSizeCoord = stylePos->MinBSize(aWM);
const auto& maxBSizeCoord = stylePos->MaxBSize(aWM);
const MinMaxSize minMaxBSize{
nsLayoutUtils::IsAutoBSize(minBSizeCoord, aCBSize.BSize(aWM))
? 0
: nsLayoutUtils::ComputeBSizeValue(
aCBSize.BSize(aWM), boxSizingAdjust.BSize(aWM),
minBSizeCoord.AsLengthPercentage()),
nsLayoutUtils::IsAutoBSize(maxBSizeCoord, aCBSize.BSize(aWM))
? NS_UNCONSTRAINEDSIZE
: nsLayoutUtils::ComputeBSizeValue(
aCBSize.BSize(aWM), boxSizingAdjust.BSize(aWM),
maxBSizeCoord.AsLengthPercentage())};
MinMaxSize transferredMinMaxISize = ComputeTransferredMinMaxInlineSize(
aWM, stylePos->mAspectRatio, minMaxBSize, boxSizingAdjust);
result.ISize(aWM) =
transferredMinMaxISize.ClampSizeToMinAndMax(result.ISize(aWM));
}
// Flex items ignore their min & max sizing properties in their
// flex container's main-axis. (Those properties get applied later in
// the flexbox algorithm.)
const auto& maxISizeCoord = stylePos->MaxISize(aWM);
nscoord maxISize = NS_UNCONSTRAINEDSIZE;
if (!maxISizeCoord.IsNone() &&
!(isFlexItem && flexMainAxis == eLogicalAxisInline)) {
if (!maxISizeCoord.IsNone() && !isFlexItemInlineAxisMainAxis) {
maxISize = ComputeISizeValue(
aRenderingContext, aCBSize.ISize(aWM), boxSizingAdjust.ISize(aWM),
boxSizingToMarginEdgeISize, maxISizeCoord, aFlags);
@ -6203,8 +6283,7 @@ nsIFrame::SizeComputationResult nsIFrame::ComputeSize(
const auto& minISizeCoord = stylePos->MinISize(aWM);
nscoord minISize;
if (!minISizeCoord.IsAuto() &&
!(isFlexItem && flexMainAxis == eLogicalAxisInline)) {
if (!minISizeCoord.IsAuto() && !isFlexItemInlineAxisMainAxis) {
minISize = ComputeISizeValue(
aRenderingContext, aCBSize.ISize(aWM), boxSizingAdjust.ISize(aWM),
boxSizingToMarginEdgeISize, minISizeCoord, aFlags);

View File

@ -1,2 +0,0 @@
[abspos-008.html]
expected: FAIL

View File

@ -1,2 +0,0 @@
[block-aspect-ratio-020.html]
expected: FAIL

View File

@ -1,2 +0,0 @@
[block-aspect-ratio-021.html]
expected: FAIL

View File

@ -1,2 +0,0 @@
[block-aspect-ratio-023.html]
expected: FAIL

View File

@ -1,2 +0,0 @@
[block-aspect-ratio-025.html]
expected: FAIL

View File

@ -1,2 +0,0 @@
[block-aspect-ratio-026.html]
expected: FAIL

View File

@ -1,2 +0,0 @@
[block-aspect-ratio-027.html]
expected: FAIL