From 8ff295747e7f5e205313e4405d5a63ce23fca993 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sat, 28 Sep 2019 23:36:05 -0400 Subject: Issue #1230 - Part 1: Fix Back-computing percentages for intrinsic sizing in Layout CSS-Grid List of relevant patches applied: 1398537 part 2 - [css-multicol] Implement percentages for 'column-gap' (Gecko part). 1434478 part 1 - [css-grid] Stop back-computing percentage grid gaps when the percentage basis is indefinite. Treat them as zero sized instead. 1434478 part 2 - Stop back-computing percentage padding/margin when the percentage basis is indefinite. Treat them as zero sized instead. 1434478 part 3 - Remove IntrinsicISizeOffsetData::hPctPadding/hPctMargin members since they are now unused. 1434478 part 4 - Factor out constants like NS_UNCONSTRAINEDSIZE so they can be used in headers without needing nsIFrame.h (idempotent patch). 1434478 part 5 - Create nsLayoutUtils::ResolveToLength for resolving CSS (idempotent patch). 1434478 part 6 - Propagate a percentage basis to nsIFrame::IntrinsicISizeOffsets for resolving padding/margin. This is needed only for CSS Grid since in other cases we're only using IntrinsicISizeOffsets in the inline-axis and the percentage basis is always indefinite for *intrinsic sizing*. When calculating the intrinsic size of grid items in the grid container's block axis however, we do have a definite size for the grid area in the inline-axis and it should be used per: https://drafts.csswg.org/css-grid/#algo-overview "2. Next, the track sizing algorithm resolves the sizes of the grid rows, using the grid column sizes calculated in the previous step." (Percentage padding/margin for grid items is always resolved against the grid area's inline-size nowadays.) --- layout/generic/nsFrame.cpp | 93 +++++++++++++++++----------------------------- 1 file changed, 34 insertions(+), 59 deletions(-) (limited to 'layout/generic/nsFrame.cpp') diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index bd96f213b..a531dea07 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -4515,68 +4515,44 @@ nsIFrame::InlinePrefISizeData::ForceBreak() mSkipWhitespace = true; } -static void -AddCoord(const nsStyleCoord& aStyle, - nsIFrame* aFrame, - nscoord* aCoord, float* aPercent, - bool aClampNegativeToZero) -{ - switch (aStyle.GetUnit()) { - case eStyleUnit_Coord: { - NS_ASSERTION(!aClampNegativeToZero || aStyle.GetCoordValue() >= 0, - "unexpected negative value"); - *aCoord += aStyle.GetCoordValue(); - return; - } - case eStyleUnit_Percent: { - NS_ASSERTION(!aClampNegativeToZero || aStyle.GetPercentValue() >= 0.0f, - "unexpected negative value"); - *aPercent += aStyle.GetPercentValue(); - return; - } - case eStyleUnit_Calc: { - const nsStyleCoord::Calc *calc = aStyle.GetCalcValue(); - if (aClampNegativeToZero) { - // This is far from ideal when one is negative and one is positive. - *aCoord += std::max(calc->mLength, 0); - *aPercent += std::max(calc->mPercent, 0.0f); - } else { - *aCoord += calc->mLength; - *aPercent += calc->mPercent; - } - return; - } - default: { - return; - } +static nscoord +ResolveMargin(const nsStyleCoord& aStyle, nscoord aPercentageBasis) +{ + if (aStyle.GetUnit() == eStyleUnit_Auto) { + return nscoord(0); } + return nsLayoutUtils::ResolveToLength(aStyle, aPercentageBasis); +} + +static nscoord +ResolvePadding(const nsStyleCoord& aStyle, nscoord aPercentageBasis) +{ + return nsLayoutUtils::ResolveToLength(aStyle, aPercentageBasis); } static nsIFrame::IntrinsicISizeOffsetData -IntrinsicSizeOffsets(nsIFrame* aFrame, bool aForISize) +IntrinsicSizeOffsets(nsIFrame* aFrame, nscoord aPercentageBasis, bool aForISize) { nsIFrame::IntrinsicISizeOffsetData result; WritingMode wm = aFrame->GetWritingMode(); - const nsStyleMargin* styleMargin = aFrame->StyleMargin(); + const auto& margin = aFrame->StyleMargin()->mMargin; bool verticalAxis = aForISize == wm.IsVertical(); - AddCoord(verticalAxis ? styleMargin->mMargin.GetTop() - : styleMargin->mMargin.GetLeft(), - aFrame, &result.hMargin, &result.hPctMargin, - false); - AddCoord(verticalAxis ? styleMargin->mMargin.GetBottom() - : styleMargin->mMargin.GetRight(), - aFrame, &result.hMargin, &result.hPctMargin, - false); - - const nsStylePadding* stylePadding = aFrame->StylePadding(); - AddCoord(verticalAxis ? stylePadding->mPadding.GetTop() - : stylePadding->mPadding.GetLeft(), - aFrame, &result.hPadding, &result.hPctPadding, - true); - AddCoord(verticalAxis ? stylePadding->mPadding.GetBottom() - : stylePadding->mPadding.GetRight(), - aFrame, &result.hPadding, &result.hPctPadding, - true); + if (verticalAxis) { + result.hMargin += ResolveMargin(margin.GetTop(), aPercentageBasis); + result.hMargin += ResolveMargin(margin.GetBottom(), aPercentageBasis); + } else { + result.hMargin += ResolveMargin(margin.GetLeft(), aPercentageBasis); + result.hMargin += ResolveMargin(margin.GetRight(), aPercentageBasis); + } + + const auto& padding = aFrame->StylePadding()->mPadding; + if (verticalAxis) { + result.hPadding += ResolvePadding(padding.GetTop(), aPercentageBasis); + result.hPadding += ResolvePadding(padding.GetBottom(), aPercentageBasis); + } else { + result.hPadding += ResolvePadding(padding.GetLeft(), aPercentageBasis); + result.hPadding += ResolvePadding(padding.GetRight(), aPercentageBasis); + } const nsStyleBorder* styleBorder = aFrame->StyleBorder(); if (verticalAxis) { @@ -4606,22 +4582,21 @@ IntrinsicSizeOffsets(nsIFrame* aFrame, bool aForISize) result.hPadding = presContext->DevPixelsToAppUnits(verticalAxis ? padding.TopBottom() : padding.LeftRight()); - result.hPctPadding = 0; } } return result; } /* virtual */ nsIFrame::IntrinsicISizeOffsetData -nsFrame::IntrinsicISizeOffsets() +nsFrame::IntrinsicISizeOffsets(nscoord aPercentageBasis) { - return IntrinsicSizeOffsets(this, true); + return IntrinsicSizeOffsets(this, aPercentageBasis, true); } nsIFrame::IntrinsicISizeOffsetData -nsIFrame::IntrinsicBSizeOffsets() +nsIFrame::IntrinsicBSizeOffsets(nscoord aPercentageBasis) { - return IntrinsicSizeOffsets(this, false); + return IntrinsicSizeOffsets(this, aPercentageBasis, false); } /* virtual */ IntrinsicSize -- cgit v1.2.3