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

@ -4671,8 +4671,6 @@ GetDefiniteSize(const nsStyleCoord& aStyle,
nscoord pb = aIsInlineAxis ? aPercentageBasis.value().ISize(wm)
: aPercentageBasis.value().BSize(wm);
if (pb == NS_UNCONSTRAINEDSIZE) {
// XXXmats given that we're calculating an intrinsic size here,
// maybe we should back-compute the calc-size using AddPercents?
return false;
}
*aResult = std::max(0, calc->mLength +
@ -4916,12 +4914,9 @@ AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext,
nscoord result = aContentSize;
nscoord min = aContentMinSize;
nscoord coordOutsideSize = 0;
float pctOutsideSize = 0;
float pctTotal = 0.0f;
if (!(aFlags & nsLayoutUtils::IGNORE_PADDING)) {
coordOutsideSize += aOffsets.hPadding;
pctOutsideSize += aOffsets.hPctPadding;
}
coordOutsideSize += aOffsets.hBorder;
@ -4929,21 +4924,15 @@ AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext,
if (aBoxSizing == StyleBoxSizing::Border) {
min += coordOutsideSize;
result = NSCoordSaturatingAdd(result, coordOutsideSize);
pctTotal += pctOutsideSize;
coordOutsideSize = 0;
pctOutsideSize = 0.0f;
}
coordOutsideSize += aOffsets.hMargin;
pctOutsideSize += aOffsets.hPctMargin;
min += coordOutsideSize;
result = NSCoordSaturatingAdd(result, coordOutsideSize);
pctTotal += pctOutsideSize;
const bool shouldAddPercent = aType == nsLayoutUtils::PREF_ISIZE ||
(aFlags & nsLayoutUtils::ADD_PERCENTS);
nscoord size;
if (aType == nsLayoutUtils::MIN_ISIZE &&
(((aStyleSize.HasPercent() || aStyleMaxSize.HasPercent()) &&
@ -4961,18 +4950,6 @@ AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext,
GetIntrinsicCoord(aStyleSize, aRenderingContext, aFrame,
PROP_WIDTH, size)) {
result = size + coordOutsideSize;
if (shouldAddPercent) {
result = nsLayoutUtils::AddPercents(result, pctOutsideSize);
}
} else {
// NOTE: We could really do a lot better for percents and for some
// cases of calc() containing percent (certainly including any where
// the coefficient on the percent is positive and there are no max()
// expressions). However, doing better for percents wouldn't be
// backwards compatible.
if (shouldAddPercent) {
result = nsLayoutUtils::AddPercents(result, pctTotal);
}
}
nscoord maxSize = aFixedMaxSize ? *aFixedMaxSize : 0;
@ -4980,9 +4957,6 @@ AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext,
GetIntrinsicCoord(aStyleMaxSize, aRenderingContext, aFrame,
PROP_MAX_WIDTH, maxSize)) {
maxSize += coordOutsideSize;
if (shouldAddPercent) {
maxSize = nsLayoutUtils::AddPercents(maxSize, pctOutsideSize);
}
if (result > maxSize) {
result = maxSize;
}
@ -4993,17 +4967,11 @@ AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext,
GetIntrinsicCoord(aStyleMinSize, aRenderingContext, aFrame,
PROP_MIN_WIDTH, minSize)) {
minSize += coordOutsideSize;
if (shouldAddPercent) {
minSize = nsLayoutUtils::AddPercents(minSize, pctOutsideSize);
}
if (result < minSize) {
result = minSize;
}
}
if (shouldAddPercent) {
min = nsLayoutUtils::AddPercents(min, pctTotal);
}
if (result < min) {
result = min;
}
@ -5020,9 +4988,6 @@ AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext,
: devSize.width);
// GetMinimumWidgetSize() returns a border-box width.
themeSize += aOffsets.hMargin;
if (shouldAddPercent) {
themeSize = nsLayoutUtils::AddPercents(themeSize, aOffsets.hPctMargin);
}
if (themeSize > result || !canOverride) {
result = themeSize;
}
@ -5267,9 +5232,19 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis,
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::IntrinsicISizeOffsetData offsets =
MOZ_LIKELY(isInlineAxis) ? aFrame->IntrinsicISizeOffsets()
: aFrame->IntrinsicBSizeOffsets();
MOZ_LIKELY(isInlineAxis) ? aFrame->IntrinsicISizeOffsets(pmPercentageBasis)
: aFrame->IntrinsicBSizeOffsets(pmPercentageBasis);
nscoord contentBoxSize = result;
result = AddIntrinsicSizeOffset(aRenderingContext, aFrame, offsets, aType,
boxSizing, result, min, styleISize,
@ -5310,11 +5285,12 @@ nsLayoutUtils::IntrinsicForContainer(nsRenderingContext* aRenderingContext,
}
/* static */ nscoord
nsLayoutUtils::MinSizeContributionForAxis(PhysicalAxis aAxis,
nsLayoutUtils::MinSizeContributionForAxis(PhysicalAxis aAxis,
nsRenderingContext* aRC,
nsIFrame* aFrame,
IntrinsicISizeType aType,
uint32_t aFlags)
nsIFrame* aFrame,
IntrinsicISizeType aType,
const LogicalSize& aPercentageBasis,
uint32_t aFlags)
{
MOZ_ASSERT(aFrame);
MOZ_ASSERT(aFrame->IsFlexOrGridItem(),
@ -5328,9 +5304,7 @@ nsLayoutUtils::MinSizeContributionForAxis(PhysicalAxis aAxis,
aWM.IsVertical() ? "vertical" : "horizontal");
#endif
// Note: this method is only meant for grid/flex items which always
// include percentages in their intrinsic size.
aFlags |= nsLayoutUtils::ADD_PERCENTS;
// Note: this method is only meant for grid/flex items.
const nsStylePosition* const stylePos = aFrame->StylePosition();
const nsStyleCoord* style = aAxis == eAxisHorizontal ? &stylePos->mMinWidth
: &stylePos->mMinHeight;
@ -5375,11 +5349,17 @@ nsLayoutUtils::MinSizeContributionForAxis(PhysicalAxis aAxis,
// wrapping inside of it should not apply font size inflation.
AutoMaybeDisableFontInflation an(aFrame);
PhysicalAxis ourInlineAxis =
aFrame->GetWritingMode().PhysicalAxis(eLogicalAxisInline);
// The padding/margin percentage basis is the inline-size in the parent's
// writing-mode.
auto childWM = aFrame->GetWritingMode();
nscoord pmPercentageBasis =
aFrame->GetParent()->GetWritingMode().IsOrthogonalTo(childWM) ?
aPercentageBasis.BSize(childWM) :
aPercentageBasis.ISize(childWM);
PhysicalAxis ourInlineAxis = childWM.PhysicalAxis(eLogicalAxisInline);
nsIFrame::IntrinsicISizeOffsetData offsets =
ourInlineAxis == aAxis ? aFrame->IntrinsicISizeOffsets()
: aFrame->IntrinsicBSizeOffsets();
ourInlineAxis == aAxis ? aFrame->IntrinsicISizeOffsets(pmPercentageBasis)
: aFrame->IntrinsicBSizeOffsets(pmPercentageBasis);
nscoord result = 0;
nscoord min = 0;