# HG changeset patch # User Mats Palmgren # Date 1521150084 -3600 # Thu Mar 15 22:41:24 2018 +0100 # Node ID d94a08198cc99a918faac31eeb261ecf6dd5ab04 # Parent 03fbcda33f105d9dcf491714447cef9c298d54f5 Bug 1425599 part 6 - [css-grid] Make the size distribution methods templated with the intent of merging them in a later patch (idempotent change). r=dholbert This patch also introduces an eInfinitelyGrowable bit to help get rid of the 'limits' temporary track sizes in the next patch. diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -203,16 +203,17 @@ struct nsGridContainerFrame::TrackSize eIntrinsicMaxSizing = eAutoOrMaxContentMaxSizing | eMinContentMaxSizing, eFlexMaxSizing = 0x80, eFrozen = 0x100, eSkipGrowUnlimited1 = 0x200, eSkipGrowUnlimited2 = 0x400, eSkipGrowUnlimited = eSkipGrowUnlimited1 | eSkipGrowUnlimited2, eBreakBefore = 0x800, eFitContent = 0x1000, + eInfinitelyGrowable = 0x2000, }; StateBits Initialize(nscoord aPercentageBasis, const nsStyleCoord& aMinCoord, const nsStyleCoord& aMaxCoord); bool IsFrozen() const { return mState & eFrozen; } #ifdef DEBUG void Dump() const; @@ -1265,25 +1266,27 @@ struct nsGridContainerFrame::Tracks } if (sz.mState & aSelector) { aGrowableTracks.AppendElement(i); } } return aGrowableTracks.IsEmpty() ? 0 : space; } - void SetupGrowthPlan(nsTArray& aItemPlan, - const nsTArray& aSizes, - const nsTArray& aTracks) const + template + void InitializeItemPlan(nsTArray& aItemPlan, + const nsTArray& aTracks) const { for (uint32_t track : aTracks) { - auto& sz = aItemPlan[track]; - sz.mBase = aSizes[track].mBase; - sz.mLimit = aSizes[track].mLimit; - sz.mState = aSizes[track].mState; + auto& plan = aItemPlan[track]; + const TrackSize& sz = mSizes[track]; + plan.mBase = StartSizeInDistribution(sz); + bool unlimited = sz.mState & TrackSize::eInfinitelyGrowable; + plan.mLimit = unlimited ? NS_UNCONSTRAINEDSIZE : sz.mLimit; + plan.mState = sz.mState; } } template void InitializePlan(nsTArray& aPlan) const { for (size_t i = 0, len = aPlan.Length(); i < len; ++i) { auto& plan = aPlan[i]; @@ -1299,18 +1302,20 @@ struct nsGridContainerFrame::Tracks mSizes[i].mBase = aPlan[i].mBase; } } void CopyPlanToLimit(const nsTArray& aPlan) { for (size_t i = 0, len = mSizes.Length(); i < len; ++i) { MOZ_ASSERT(aPlan[i].mBase >= 0); + auto& sz = mSizes[i]; + sz.mState &= ~TrackSize::eInfinitelyGrowable; if (aPlan[i].mState & TrackSize::eModified) { - mSizes[i].mLimit = aPlan[i].mBase; + sz.mLimit = aPlan[i].mBase; } } } using FitContentClamper = std::function; /** * Grow the planned size for tracks in aGrowableTracks up to their limit @@ -1470,39 +1475,41 @@ struct nsGridContainerFrame::Tracks MOZ_ASSERT(didClamp, "we don't exit the loop above except by return, " "unless we clamped some track's size"); } /** * Distribute aAvailableSpace to the planned base size for aGrowableTracks * up to their limits, then distribute the remaining space beyond the limits. */ + template void DistributeToTrackBases(nscoord aAvailableSpace, nsTArray& aPlan, nsTArray& aItemPlan, nsTArray& aGrowableTracks, TrackSize::StateBits aSelector) { - SetupGrowthPlan(aItemPlan, mSizes, aGrowableTracks); + InitializeItemPlan(aItemPlan, aGrowableTracks); nscoord space = GrowTracksToLimit(aAvailableSpace, aItemPlan, aGrowableTracks, nullptr); if (space > 0) { GrowSelectedTracksUnlimited(space, aItemPlan, aGrowableTracks, aSelector, nullptr); } for (uint32_t track : aGrowableTracks) { nscoord& plannedSize = aPlan[track].mBase; nscoord itemIncurredSize = aItemPlan[track].mBase; if (plannedSize < itemIncurredSize) { plannedSize = itemIncurredSize; } } } /** * Distribute aAvailableSpace to the planned limits for aGrowableTracks. */ + template void DistributeToTrackLimits(nscoord aAvailableSpace, const nsTArray& aSizes, nsTArray& aPlan, nsTArray& aItemPlan, nsTArray& aGrowableTracks, const TrackSizingFunctions& aFunctions, nscoord aPercentageBasis) { @@ -1512,17 +1519,17 @@ struct nsGridContainerFrame::Tracks nscoord fitContentLimit = ::ResolveToDefiniteSize(aFunctions.MaxSizingFor(aTrack), aPercentageBasis); if (*aSize > fitContentLimit) { *aSize = std::max(aMinSize, fitContentLimit); return true; } return false; }; - SetupGrowthPlan(aItemPlan, aSizes, aGrowableTracks); + InitializeItemPlan(aItemPlan, aGrowableTracks); nscoord space = GrowTracksToLimit(aAvailableSpace, aItemPlan, aGrowableTracks, fitContentClamper); if (space > 0) { GrowSelectedTracksUnlimited(space, aItemPlan, aGrowableTracks, TrackSize::StateBits(0), fitContentClamper); } for (uint32_t track : aGrowableTracks) { nscoord& plannedSize = aPlan[track].mBase; @@ -4264,17 +4271,17 @@ nsGridContainerFrame::Tracks::GrowBaseFo nscoord space = item.SizeContributionForPhase(phase); if (space <= 0) { continue; } aTracks.ClearAndRetainStorage(); space = CollectGrowable(space, item.mLineRange, aSelector, aTracks); if (space > 0) { - DistributeToTrackBases(space, aPlan, aItemPlan, aTracks, aSelector); + DistributeToTrackBases(space, aPlan, aItemPlan, aTracks, aSelector); updatedBase = true; } } if (updatedBase) { CopyPlanToBase(aPlan); } return updatedBase; } @@ -4303,18 +4310,18 @@ nsGridContainerFrame::Tracks::GrowLimitF aPlan[j].mState |= TrackSize::eModified; } nscoord space = item.SizeContributionForPhase(phase); if (space > 0) { aTracks.ClearAndRetainStorage(); space = CollectGrowable(space, item.mLineRange, aSelector, aTracks); if (space > 0) { - DistributeToTrackLimits(space, aSizes, aPlan, aItemPlan, aTracks, - aFunctions, aPercentageBasis); + DistributeToTrackLimits(space, aSizes, aPlan, aItemPlan, aTracks, + aFunctions, aPercentageBasis); } } } return true; } void nsGridContainerFrame::Tracks::ResolveIntrinsicSize( @@ -4508,18 +4515,21 @@ nsGridContainerFrame::Tracks::ResolveInt GrowLimitForSpanningItems( step2Items, tracks, limits, plan, itemPlan, TrackSize::eIntrinsicMaxSizing, aFunctions, aPercentageBasis, spanGroupStartIndex, spanGroupEndIndex); for (size_t j = 0, len = mSizes.Length(); j < len; ++j) { TrackSize& sz = itemPlan[j]; sz.mState &= ~(TrackSize::eFrozen | TrackSize::eSkipGrowUnlimited); if (plan[j].mState & TrackSize::eModified) { + if (mSizes[j].mLimit == NS_UNCONSTRAINEDSIZE) { + mSizes[j].mState |= TrackSize::eInfinitelyGrowable; + } + mSizes[j].mLimit = plan[j].mBase; limits[j].mBase = plan[j].mBase; - mSizes[j].mLimit = plan[j].mBase; if (limits[j].mLimit != NS_UNCONSTRAINEDSIZE) { limits[j].mLimit = limits[j].mBase; } } plan[j].mState &= ~(TrackSize::eModified); } if (stateBitsPerSpan[span] & TrackSize::eAutoOrMaxContentMaxSizing) {