Bug 1271392 part 1 - [css-grid] Make grid item 'stretch' not require an extra reflow. r=dholbert

This part removes the 'stretch' logic in AlignJustifySelf and implements
it in nsLayoutUtils::ComputeSizeWithIntrinsicDimensions /
nsFrame::ComputeSize instead.
This commit is contained in:
Mats Palmgren 2016-05-18 13:49:33 +02:00
Родитель b4594808f5
Коммит 6dca609754
5 изменённых файлов: 77 добавлений и 16 удалений

Просмотреть файл

@ -5349,7 +5349,12 @@ nsLayoutUtils::ComputeSizeWithIntrinsicDimensions(WritingMode aWM,
const nsStyleCoord* inlineStyleCoord = &stylePos->ISize(aWM);
const nsStyleCoord* blockStyleCoord = &stylePos->BSize(aWM);
bool isFlexItem = aFrame->IsFlexItem();
nsIAtom* parentFrameType =
aFrame->GetParent() ? aFrame->GetParent()->GetType() : nullptr;
const bool isGridItem = (parentFrameType == nsGkAtoms::gridContainerFrame &&
!(aFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW));
const bool isFlexItem = (parentFrameType == nsGkAtoms::flexContainerFrame &&
!(aFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW));
bool isInlineFlexItem = false;
Maybe<nsStyleCoord> imposedMainSizeStyleCoord;
@ -5418,7 +5423,7 @@ nsLayoutUtils::ComputeSizeWithIntrinsicDimensions(WritingMode aWM,
// or (a * b) / c (which are equivalent).
const bool isAutoISize = inlineStyleCoord->GetUnit() == eStyleUnit_Auto;
const bool isAutoBSize = IsAutoBSize(*blockStyleCoord, aCBSize.BSize(aWM));
bool isAutoBSize = IsAutoBSize(*blockStyleCoord, aCBSize.BSize(aWM));
LogicalSize boxSizingAdjust(aWM);
switch (stylePos->mBoxSizing) {
@ -5479,6 +5484,25 @@ nsLayoutUtils::ComputeSizeWithIntrinsicDimensions(WritingMode aWM,
bSize = nsLayoutUtils::ComputeBSizeValue(aCBSize.BSize(aWM),
boxSizingAdjust.BSize(aWM),
*blockStyleCoord);
} else if (MOZ_UNLIKELY(isGridItem)) {
MOZ_ASSERT(!IS_TRUE_OVERFLOW_CONTAINER(aFrame));
// 'auto' block-size for grid-level box - apply 'stretch' as needed:
auto cbSize = aCBSize.BSize(aWM);
if (cbSize != NS_AUTOHEIGHT &&
!aFrame->StyleMargin()->HasBlockAxisAuto(aWM)) {
auto blockAxisAlignment =
!aWM.IsOrthogonalTo(aFrame->GetParent()->GetWritingMode()) ?
stylePos->ComputedAlignSelf(aFrame->StyleContext()->GetParent()) :
stylePos->ComputedJustifySelf(aFrame->StyleContext()->GetParent());
if (blockAxisAlignment == NS_STYLE_ALIGN_NORMAL ||
blockAxisAlignment == NS_STYLE_ALIGN_STRETCH) {
bSize = std::max(nscoord(0), cbSize -
aPadding.BSize(aWM) -
aBorder.BSize(aWM) -
aMargin.BSize(aWM));
isAutoBSize = false;
}
}
}
const nsStyleCoord& maxBSizeCoord = stylePos->MaxBSize(aWM);

Просмотреть файл

@ -4729,12 +4729,32 @@ nsFrame::ComputeSize(nsRenderingContext *aRenderingContext,
// (but not if we're auto-height or if we recieved the "eUseAutoHeight"
// flag -- then, we'll just stick with the height that we already calculated
// in the initial ComputeAutoSize() call.)
if (!nsLayoutUtils::IsAutoBSize(*blockStyleCoord, aCBSize.BSize(aWM)) &&
!(aFlags & nsIFrame::eUseAutoHeight)) {
if (!(aFlags & nsIFrame::eUseAutoHeight)) {
if (!nsLayoutUtils::IsAutoBSize(*blockStyleCoord, aCBSize.BSize(aWM))) {
result.BSize(aWM) =
nsLayoutUtils::ComputeBSizeValue(aCBSize.BSize(aWM),
boxSizingAdjust.BSize(aWM),
*blockStyleCoord);
} else if (MOZ_UNLIKELY(isGridItem) &&
blockStyleCoord->GetUnit() == eStyleUnit_Auto &&
!IS_TRUE_OVERFLOW_CONTAINER(this)) {
// 'auto' block-size for grid-level box - apply 'stretch' as needed:
auto cbSize = aCBSize.BSize(aWM);
if (cbSize != NS_AUTOHEIGHT &&
!StyleMargin()->HasBlockAxisAuto(aWM)) {
auto blockAxisAlignment =
!aWM.IsOrthogonalTo(GetParent()->GetWritingMode()) ?
StylePosition()->ComputedAlignSelf(StyleContext()->GetParent()) :
StylePosition()->ComputedJustifySelf(StyleContext()->GetParent());
if (blockAxisAlignment == NS_STYLE_ALIGN_NORMAL ||
blockAxisAlignment == NS_STYLE_ALIGN_STRETCH) {
result.BSize(aWM) = std::max(nscoord(0), cbSize -
aPadding.BSize(aWM) -
aBorder.BSize(aWM) -
aMargin.BSize(aWM));
}
}
}
}
const nsStyleCoord& maxBSizeCoord = stylePos->MaxBSize(aWM);

Просмотреть файл

@ -2185,6 +2185,8 @@ AlignJustifySelf(uint8_t aAlignment, bool aOverflowSafe, LogicalAxis aAxis,
case NS_STYLE_ALIGN_LAST_BASELINE:
NS_WARNING("NYI: baseline/last-baseline for grid (bug 1151204)"); // XXX
MOZ_FALLTHROUGH;
case NS_STYLE_ALIGN_STRETCH:
MOZ_FALLTHROUGH; // ComputeSize() deals with it
case NS_STYLE_ALIGN_START:
offset = marginStart;
break;
@ -2200,6 +2202,7 @@ AlignJustifySelf(uint8_t aAlignment, bool aOverflowSafe, LogicalAxis aAxis,
offset = (aCBSize - size + marginStart - marginEnd) / 2;
break;
}
#if 0
case NS_STYLE_ALIGN_STRETCH: {
MOZ_ASSERT(!hasAutoMarginStart && !hasAutoMarginEnd);
offset = marginStart;
@ -2242,6 +2245,7 @@ AlignJustifySelf(uint8_t aAlignment, bool aOverflowSafe, LogicalAxis aAxis,
}
break;
}
#endif
default:
MOZ_ASSERT_UNREACHABLE("unknown align-/justify-self value");
}
@ -3268,7 +3272,8 @@ ContentContribution(nsIFrame* aChild,
// XXX this will give mostly correct results for now (until bug 1174569).
LogicalSize availableSize(wm, INFINITE_ISIZE_COORD, NS_UNCONSTRAINEDSIZE);
nsHTMLReflowState childRS(pc, *rs, aChild, availableSize, nullptr,
nsHTMLReflowState::COMPUTE_SIZE_SHRINK_WRAP);
nsHTMLReflowState::COMPUTE_SIZE_SHRINK_WRAP |
nsHTMLReflowState::COMPUTE_SIZE_USE_AUTO_BSIZE);
nsHTMLReflowMetrics childSize(childRS);
nsReflowStatus childStatus;
const uint32_t flags = NS_FRAME_NO_MOVE_FRAME | NS_FRAME_NO_SIZE_VIEW;
@ -4149,12 +4154,7 @@ nsGridContainerFrame::ReflowInFlowChild(nsIFrame* aChild,
cb = aState.ContainingBlockFor(area);
isConstrainedBSize = aFragmentainer && !wm.IsOrthogonalTo(childWM);
if (isConstrainedBSize) {
nscoord fragCBOffset = cb.BStart(wm) - aState.mFragBStart;
if (fragCBOffset < 0) {
// Subtract the "consumed" part of the grid area.
cb.BSize(wm) = std::max(fragCBOffset + cb.BSize(wm), 0);
}
cb.BStart(wm) = std::max(fragCBOffset, 0);
cb.BStart(wm) = std::max(0, cb.BStart(wm) - aState.mFragBStart);
toFragmentainerEnd = aFragmentainer->mToFragmentainerEnd -
aState.mFragBStart - cb.BStart(wm);
toFragmentainerEnd = std::max(toFragmentainerEnd, 0);

Просмотреть файл

@ -82,6 +82,9 @@ nsHTMLReflowState::nsHTMLReflowState(nsPresContext* aPresContext,
if (aFlags & COMPUTE_SIZE_SHRINK_WRAP) {
mFlags.mShrinkWrap = true;
}
if (aFlags & COMPUTE_SIZE_USE_AUTO_BSIZE) {
mFlags.mUseAutoBSize = true;
}
if (aFlags & STATIC_POS_IS_CB_ORIGIN) {
mFlags.mStaticPosIsCBOrigin = true;
}
@ -226,6 +229,7 @@ nsHTMLReflowState::nsHTMLReflowState(
mFlags.mIsFlexContainerMeasuringHeight = false;
mFlags.mDummyParentReflowState = false;
mFlags.mShrinkWrap = !!(aFlags & COMPUTE_SIZE_SHRINK_WRAP);
mFlags.mUseAutoBSize = !!(aFlags & COMPUTE_SIZE_USE_AUTO_BSIZE);
mFlags.mStaticPosIsCBOrigin = !!(aFlags & STATIC_POS_IS_CB_ORIGIN);
mDiscoveredClearance = nullptr;
@ -1618,6 +1622,10 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsPresContext* aPresContext,
computeSizeFlags =
ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eShrinkWrap);
}
if (mFlags.mUseAutoBSize) {
computeSizeFlags =
ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eUseAutoHeight);
}
if (wm.IsOrthogonalTo(cbwm)) {
if (bStartIsAuto || bEndIsAuto) {
computeSizeFlags =
@ -2319,6 +2327,10 @@ nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext,
computeSizeFlags =
ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eShrinkWrap);
}
if (mFlags.mUseAutoBSize) {
computeSizeFlags =
ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eUseAutoHeight);
}
nsIFrame* parent = frame->GetParent();
nsIAtom* parentFrameType = parent ? parent->GetType() : nullptr;

Просмотреть файл

@ -584,6 +584,7 @@ public:
// (e.g. columns), it should always
// reflow its placeholder children.
uint16_t mShrinkWrap:1; // stores the COMPUTE_SIZE_SHRINK_WRAP ctor flag
uint16_t mUseAutoBSize:1; // stores the COMPUTE_SIZE_USE_AUTO_BSIZE ctor flag
uint16_t mStaticPosIsCBOrigin:1; // the STATIC_POS_IS_CB_ORIGIN ctor flag
} mFlags;
@ -681,9 +682,13 @@ public:
// will be passed to ComputeSize()).
COMPUTE_SIZE_SHRINK_WRAP = (1<<2),
// The caller wants height:auto behavior (ComputeSizeFlags::eUseAutoHeight
// will be be passed to ComputeSize()).
COMPUTE_SIZE_USE_AUTO_BSIZE = (1<<3),
// The caller wants the abs.pos. static-position resolved at the origin
// of the containing block, i.e. at LogicalPoint(0, 0).
STATIC_POS_IS_CB_ORIGIN = (1<<3),
STATIC_POS_IS_CB_ORIGIN = (1<<4),
};
// This method initializes various data members. It is automatically