зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1683424 - Take box sizing into account for replaced elements with aspect-ratio. r=TYLin
If aspect-ratio is '<ratio>', now the aspect-ratio works with box sizing dimensions for replaced elements. Also, ComputeRatioDependentSize() already considers writing-mode so we don't need the conversion like logicalRatio in the old code. For those calculations for intrinsic size contribution, we will fix them in a separate patch. Differential Revision: https://phabricator.services.mozilla.com/D100175
This commit is contained in:
Родитель
361f923f82
Коммит
11ab842010
|
@ -2387,11 +2387,9 @@ bool nsContainerFrame::ResolvedOrientationIsVertical() {
|
|||
|
||||
LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
|
||||
gfxContext* aRenderingContext, WritingMode aWM,
|
||||
const IntrinsicSize& aIntrinsicSize, const AspectRatio& aIntrinsicRatio,
|
||||
const IntrinsicSize& aIntrinsicSize, const AspectRatio& aAspectRatio,
|
||||
const LogicalSize& aCBSize, const LogicalSize& aMargin,
|
||||
const LogicalSize& aBorderPadding, ComputeSizeFlags aFlags) {
|
||||
auto logicalRatio =
|
||||
aWM.IsVertical() ? aIntrinsicRatio.Inverted() : aIntrinsicRatio;
|
||||
const nsStylePosition* stylePos = StylePosition();
|
||||
const auto* inlineStyleCoord = &stylePos->ISize(aWM);
|
||||
const auto* blockStyleCoord = &stylePos->BSize(aWM);
|
||||
|
@ -2641,7 +2639,6 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
|
|||
"Our containing block must not have unconstrained inline-size!");
|
||||
|
||||
// Now calculate the used values for iSize and bSize:
|
||||
|
||||
if (isAutoISize) {
|
||||
if (isAutoBSize) {
|
||||
// 'auto' iSize, 'auto' bSize
|
||||
|
@ -2652,9 +2649,11 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
|
|||
|
||||
if (hasIntrinsicISize) {
|
||||
tentISize = intrinsicISize;
|
||||
} else if (hasIntrinsicBSize && logicalRatio) {
|
||||
tentISize = logicalRatio.ApplyTo(intrinsicBSize);
|
||||
} else if (logicalRatio) {
|
||||
} else if (hasIntrinsicBSize && aAspectRatio) {
|
||||
tentISize = aAspectRatio.ComputeRatioDependentSize(
|
||||
LogicalAxis::eLogicalAxisInline, aWM, intrinsicBSize,
|
||||
boxSizingAdjust);
|
||||
} else if (aAspectRatio) {
|
||||
tentISize =
|
||||
aCBSize.ISize(aWM) - boxSizingToMarginEdgeISize; // XXX scrollbar?
|
||||
if (tentISize < 0) {
|
||||
|
@ -2674,8 +2673,9 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
|
|||
|
||||
if (hasIntrinsicBSize) {
|
||||
tentBSize = intrinsicBSize;
|
||||
} else if (logicalRatio) {
|
||||
tentBSize = logicalRatio.Inverted().ApplyTo(tentISize);
|
||||
} else if (aAspectRatio) {
|
||||
tentBSize = aAspectRatio.ComputeRatioDependentSize(
|
||||
LogicalAxis::eLogicalAxisBlock, aWM, tentISize, boxSizingAdjust);
|
||||
} else {
|
||||
tentBSize = fallbackIntrinsicSize.BSize(aWM);
|
||||
}
|
||||
|
@ -2690,34 +2690,39 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
|
|||
tentISize = iSize; // * / 'stretch'
|
||||
if (stretchB == eStretch) {
|
||||
tentBSize = bSize; // 'stretch' / 'stretch'
|
||||
} else if (stretchB == eStretchPreservingRatio && logicalRatio) {
|
||||
} else if (stretchB == eStretchPreservingRatio && aAspectRatio) {
|
||||
// 'normal' / 'stretch'
|
||||
tentBSize = logicalRatio.Inverted().ApplyTo(iSize);
|
||||
tentBSize = aAspectRatio.ComputeRatioDependentSize(
|
||||
LogicalAxis::eLogicalAxisBlock, aWM, iSize, boxSizingAdjust);
|
||||
}
|
||||
} else if (stretchB == eStretch) {
|
||||
tentBSize = bSize; // 'stretch' / * (except 'stretch')
|
||||
if (stretchI == eStretchPreservingRatio && logicalRatio) {
|
||||
if (stretchI == eStretchPreservingRatio && aAspectRatio) {
|
||||
// 'stretch' / 'normal'
|
||||
tentISize = logicalRatio.ApplyTo(bSize);
|
||||
tentISize = aAspectRatio.ComputeRatioDependentSize(
|
||||
LogicalAxis::eLogicalAxisInline, aWM, bSize, boxSizingAdjust);
|
||||
}
|
||||
} else if (stretchI == eStretchPreservingRatio && logicalRatio) {
|
||||
} else if (stretchI == eStretchPreservingRatio && aAspectRatio) {
|
||||
tentISize = iSize; // * (except 'stretch') / 'normal'
|
||||
tentBSize = logicalRatio.Inverted().ApplyTo(iSize);
|
||||
tentBSize = aAspectRatio.ComputeRatioDependentSize(
|
||||
LogicalAxis::eLogicalAxisBlock, aWM, iSize, boxSizingAdjust);
|
||||
if (stretchB == eStretchPreservingRatio && tentBSize > bSize) {
|
||||
// Stretch within the CB size with preserved intrinsic ratio.
|
||||
tentBSize = bSize; // 'normal' / 'normal'
|
||||
tentISize = logicalRatio.ApplyTo(bSize);
|
||||
tentISize = aAspectRatio.ComputeRatioDependentSize(
|
||||
LogicalAxis::eLogicalAxisInline, aWM, bSize, boxSizingAdjust);
|
||||
}
|
||||
} else if (stretchB == eStretchPreservingRatio && logicalRatio) {
|
||||
} else if (stretchB == eStretchPreservingRatio && aAspectRatio) {
|
||||
tentBSize = bSize; // 'normal' / * (except 'normal' and 'stretch')
|
||||
tentISize = logicalRatio.ApplyTo(bSize);
|
||||
tentISize = aAspectRatio.ComputeRatioDependentSize(
|
||||
LogicalAxis::eLogicalAxisInline, aWM, bSize, boxSizingAdjust);
|
||||
}
|
||||
|
||||
// ComputeAutoSizeWithIntrinsicDimensions preserves the ratio when
|
||||
// applying the min/max-size. We don't want that when we have 'stretch'
|
||||
// in either axis because tentISize/tentBSize is likely not according to
|
||||
// ratio now.
|
||||
if (logicalRatio && stretchI != eStretch && stretchB != eStretch) {
|
||||
if (aAspectRatio && stretchI != eStretch && stretchB != eStretch) {
|
||||
nsSize autoSize = nsLayoutUtils::ComputeAutoSizeWithIntrinsicDimensions(
|
||||
minISize, minBSize, maxISize, maxBSize, tentISize, tentBSize);
|
||||
// The nsSize that ComputeAutoSizeWithIntrinsicDimensions returns will
|
||||
|
@ -2735,8 +2740,9 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
|
|||
// 'auto' iSize, non-'auto' bSize
|
||||
bSize = NS_CSS_MINMAX(bSize, minBSize, maxBSize);
|
||||
if (stretchI != eStretch) {
|
||||
if (logicalRatio) {
|
||||
iSize = logicalRatio.ApplyTo(bSize);
|
||||
if (aAspectRatio) {
|
||||
iSize = aAspectRatio.ComputeRatioDependentSize(
|
||||
LogicalAxis::eLogicalAxisInline, aWM, bSize, boxSizingAdjust);
|
||||
} else if (hasIntrinsicISize) {
|
||||
if (!(aFlags.contains(ComputeSizeFlag::IClampMarginBoxMinSize) &&
|
||||
intrinsicISize > iSize)) {
|
||||
|
@ -2753,8 +2759,9 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions(
|
|||
// non-'auto' iSize, 'auto' bSize
|
||||
iSize = NS_CSS_MINMAX(iSize, minISize, maxISize);
|
||||
if (stretchB != eStretch) {
|
||||
if (logicalRatio) {
|
||||
bSize = logicalRatio.Inverted().ApplyTo(iSize);
|
||||
if (aAspectRatio) {
|
||||
bSize = aAspectRatio.ComputeRatioDependentSize(
|
||||
LogicalAxis::eLogicalAxisBlock, aWM, iSize, boxSizingAdjust);
|
||||
} else if (hasIntrinsicBSize) {
|
||||
if (!(aFlags.contains(ComputeSizeFlag::BClampMarginBoxMinSize) &&
|
||||
intrinsicBSize > bSize)) {
|
||||
|
|
|
@ -864,12 +864,12 @@ class nsContainerFrame : public nsSplittableFrame {
|
|||
* Calculate the used values for 'width' and 'height' for a replaced element.
|
||||
* http://www.w3.org/TR/CSS21/visudet.html#min-max-widths
|
||||
*
|
||||
* @param aIntrinsicRatio the aspect ratio calculated by GetAspectRatio().
|
||||
* @param aAspectRatio the aspect ratio calculated by GetAspectRatio().
|
||||
*/
|
||||
mozilla::LogicalSize ComputeSizeWithIntrinsicDimensions(
|
||||
gfxContext* aRenderingContext, mozilla::WritingMode aWM,
|
||||
const mozilla::IntrinsicSize& aIntrinsicSize,
|
||||
const mozilla::AspectRatio& aIntrinsicRatio,
|
||||
const mozilla::AspectRatio& aAspectRatio,
|
||||
const mozilla::LogicalSize& aCBSize, const mozilla::LogicalSize& aMargin,
|
||||
const mozilla::LogicalSize& aBorderPadding,
|
||||
mozilla::ComputeSizeFlags aFlags);
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSS aspect-ratio: img block size with 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="match" href="../../reference/ref-filled-green-100px-square.xht" />
|
||||
<style>
|
||||
.border1 {
|
||||
border-left: 10px solid green;
|
||||
}
|
||||
.border2 {
|
||||
border-left: 15px solid green;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||
|
||||
<!--
|
||||
1st: A green rect 50x100.
|
||||
border-left is 10x100 and the content box is 40x100.
|
||||
We use 'aspect-ratio: auto && <ratio>', so the aspect-ratio works with
|
||||
content-box dimensions always. The inline size of the content box is
|
||||
(50px - 10px) = 40px, so the block size is 40px * 5/2 = 100px.
|
||||
(note: width here is the inline size of border-box.)
|
||||
|
||||
2st: A green rect 25x100.
|
||||
border-left is 15x100 and the content box is 10x100.
|
||||
(note: width here is the inline size of content-box.)
|
||||
|
||||
3nd: A green rect 25x100.
|
||||
border-left is 15x100 and the content box is 10x100 because we compute
|
||||
the block size by aspect-ratio which works with border-box and so the
|
||||
block size is 25px * 4 = 100.
|
||||
(note: width here is the inline size of border-box.)
|
||||
-->
|
||||
<img class="border1" src="support/20x50-green.png" style="width: 50px; aspect-ratio: auto 1/1; box-sizing: border-box;"
|
||||
><img class="border2" src="support/20x50-green.png" style="width: 10px; aspect-ratio: 1/10; box-sizing: content-box;"
|
||||
><img class="border2" src="support/20x50-green.png" style="width: 25px; aspect-ratio: 1/4; box-sizing: border-box;">
|
|
@ -0,0 +1,34 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSS aspect-ratio: img inline size with 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="match" href="../../reference/ref-filled-green-100px-square.xht" />
|
||||
<style>
|
||||
img {
|
||||
border-top: 40px solid green;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||
|
||||
<!--
|
||||
1st: A green rect 60x100.
|
||||
border-top is 60x40 and the content box is 60x60.
|
||||
We use 'aspect-ratio: auto && <ratio>', so the aspect-ratio works with
|
||||
content-box dimensions always. The block size of the content box is
|
||||
(100px - 40px) = 60px, so the inline size is 60px * 1/1 = 60px.
|
||||
(note: height here is the block size of border-box.)
|
||||
|
||||
2nd: A green rect 20x100.
|
||||
border-top is 20x40 and the content box is 20x60.
|
||||
(note: height here is the block size of content-box.)
|
||||
|
||||
3rd: A green rect 20x100.
|
||||
border-top is 20x40 and the content box is 20x60 because we compute
|
||||
the inline size by aspect-ratio which works with border-box and so the
|
||||
inline size is 100px / 5 = 20px.
|
||||
(note: height here is the block size of border-box.)
|
||||
-->
|
||||
<img src="support/1x1-green.png" style="height: 100px; aspect-ratio: auto 1/10; box-sizing: border-box;"
|
||||
><img src="support/1x1-green.png" style="height: 60px; aspect-ratio: 1/3; box-sizing: content-box;"
|
||||
><img src="support/1x1-green.png" style="height: 100px; aspect-ratio: 1/5; box-sizing: border-box;">
|
Загрузка…
Ссылка в новой задаче