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 <length-percentage> (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.)
This commit is contained in:
Gaming4JC 2019-09-28 23:36:05 -04:00 committed by Roy Tam
commit e4c397f0d9
16 changed files with 240 additions and 319 deletions

View file

@ -4515,68 +4515,44 @@ nsIFrame::InlinePrefISizeData::ForceBreak()
mSkipWhitespace = true;
}
static void
AddCoord(const nsStyleCoord& aStyle,
nsIFrame* aFrame,
nscoord* aCoord, float* aPercent,
bool aClampNegativeToZero)
static nscoord
ResolveMargin(const nsStyleCoord& aStyle, nscoord aPercentageBasis)
{
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;
}
if (aStyle.GetUnit() == eStyleUnit_Auto) {
return nscoord(0);
}
return nsLayoutUtils::ResolveToLength<false>(aStyle, aPercentageBasis);
}
static nscoord
ResolvePadding(const nsStyleCoord& aStyle, nscoord aPercentageBasis)
{
return nsLayoutUtils::ResolveToLength<true>(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);
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 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);
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