Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(568)

Unified Diff: Source/core/layout/LayoutGrid.cpp

Issue 1010213002: [CSS Grid Layout] Support marking tracks as infinitely growable (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebased against master. Using new templatized methods. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/core/layout/LayoutGrid.cpp
diff --git a/Source/core/layout/LayoutGrid.cpp b/Source/core/layout/LayoutGrid.cpp
index 534caa132ad032c5ba2569644391082ed977c5c3..2873a97128a4affb64c9f7f046ae8d5714244982 100644
--- a/Source/core/layout/LayoutGrid.cpp
+++ b/Source/core/layout/LayoutGrid.cpp
@@ -43,10 +43,11 @@ class GridItemWithSpan;
class GridTrack {
public:
GridTrack()
- : m_plannedIncrease(0)
- , m_increaseDuringDistribution(0)
- , m_baseSize(0)
+ : m_baseSize(0)
, m_growthLimit(0)
+ , m_plannedSize(0)
+ , m_sizeDuringDistribution(0)
+ , m_infinitelyGrowable(false)
{
}
@@ -74,37 +75,40 @@ public:
ensureGrowthLimitIsBiggerThanBaseSize();
}
- void growBaseSize(LayoutUnit growth)
+ bool growthLimitIsInfinite() const
{
- ASSERT(growth >= 0);
- m_baseSize += growth;
- ensureGrowthLimitIsBiggerThanBaseSize();
+ return m_growthLimit == infinity;
}
- void growGrowthLimit(LayoutUnit growth)
+ bool infiniteGrowthPotential() const
Manuel Rego 2015/06/26 11:09:48 Suggestion: maybe call it isInfiniteGrowthPotentia
svillar 2015/06/29 07:08:27 If you don't mind I'd like to keep the name as it
Manuel Rego 2015/06/29 07:46:42 Ok, fair enough.
{
- ASSERT(growth >= 0);
- if (m_growthLimit == infinity)
- m_growthLimit = m_baseSize + growth;
- else
- m_growthLimit += growth;
+ return growthLimitIsInfinite() || m_infinitelyGrowable;
+ }
+
+ const LayoutUnit& plannedSize() const { return m_plannedSize; }
- ASSERT(m_growthLimit >= m_baseSize);
+ void setPlannedSize(const LayoutUnit& plannedSize)
+ {
+ ASSERT(plannedSize >= 0 || plannedSize == infinity);
+ m_plannedSize = plannedSize;
}
- bool growthLimitIsInfinite() const
+ const LayoutUnit& sizeDuringDistribution() { return m_sizeDuringDistribution; }
+
+ void setSizeDuringDistribution(const LayoutUnit& sizeDuringDistribution)
{
- return m_growthLimit == infinity;
+ ASSERT(sizeDuringDistribution >= 0);
+ m_sizeDuringDistribution = sizeDuringDistribution;
}
- const LayoutUnit& growthLimitIfNotInfinite() const
+ void growSizeDuringDistribution(const LayoutUnit& sizeDuringDistribution)
{
- ASSERT(isGrowthLimitBiggerThanBaseSize());
- return (m_growthLimit == infinity) ? m_baseSize : m_growthLimit;
+ ASSERT(sizeDuringDistribution >= 0);
+ m_sizeDuringDistribution += sizeDuringDistribution;
}
- LayoutUnit m_plannedIncrease;
- LayoutUnit m_increaseDuringDistribution;
+ bool infinitelyGrowable() const { return m_infinitelyGrowable; }
+ void setInfinitelyGrowable(bool infinitelyGrowable) { m_infinitelyGrowable = infinitelyGrowable; }
private:
bool isGrowthLimitBiggerThanBaseSize() const { return growthLimitIsInfinite() || m_growthLimit >= m_baseSize; }
@@ -117,6 +121,9 @@ private:
LayoutUnit m_baseSize;
LayoutUnit m_growthLimit;
+ LayoutUnit m_plannedSize;
+ LayoutUnit m_sizeDuringDistribution;
+ bool m_infinitelyGrowable;
};
struct GridTrackForNormalization {
@@ -417,6 +424,7 @@ void LayoutGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection directi
track.setBaseSize(computeUsedBreadthOfMinLength(direction, minTrackBreadth));
track.setGrowthLimit(computeUsedBreadthOfMaxLength(direction, maxTrackBreadth, track.baseSize()));
+ track.setInfinitelyGrowable(false);
Manuel Rego 2015/06/26 11:09:47 Do we really need this? I thoguht this was false b
svillar 2015/06/29 07:08:27 It's false by default but note that this algorithm
if (trackSize.isContentSized())
sizingData.contentSizedTracksIndex.append(i);
@@ -429,7 +437,7 @@ void LayoutGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection directi
resolveContentBasedTrackSizingFunctions(direction, sizingData);
for (const auto& track: tracks) {
- ASSERT(!track.growthLimitIsInfinite());
+ ASSERT(!track.infiniteGrowthPotential());
freeSpace -= track.baseSize();
}
@@ -450,7 +458,7 @@ void LayoutGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection directi
Vector<GridTrack*> tracksForDistribution(tracksSize);
for (size_t i = 0; i < tracksSize; ++i) {
tracksForDistribution[i] = tracks.data() + i;
- tracksForDistribution[i]->m_plannedIncrease = 0;
+ tracksForDistribution[i]->setPlannedSize(tracksForDistribution[i]->baseSize());
}
Vector<GridTrack*> tracksToStretch(sizingData.contentSizedTracksIndex.size());
@@ -464,7 +472,7 @@ void LayoutGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection directi
distributeSpaceToTracks<MaximizeTracks>(tracksForDistribution, needToStretch ? &tracksToStretch : nullptr, sizingData, freeSpace);
for (auto* track : tracksForDistribution)
- track->growBaseSize(track->m_plannedIncrease);
+ track->setBaseSize(track->plannedSize());
} else {
for (auto& track : tracks)
track.setBaseSize(track.growthLimit());
@@ -798,11 +806,12 @@ static const LayoutUnit& trackSizeForTrackSizeComputationPhase(TrackSizeComputat
case ResolveMaxContentMinimums:
case MaximizeTracks:
return track.baseSize();
- break;
case ResolveIntrinsicMaximums:
case ResolveMaxContentMaximums:
- return restriction == AllowInfinity ? track.growthLimit() : track.growthLimitIfNotInfinite();
- break;
+ const LayoutUnit& growthLimit = track.growthLimit();
+ if (restriction == AllowInfinity)
+ return growthLimit;
+ return growthLimit == infinity ? track.baseSize() : growthLimit;
svillar 2015/06/12 16:07:07 This is not strictly required BTW but the growthLi
}
ASSERT_NOT_REACHED();
@@ -848,16 +857,38 @@ static bool trackShouldGrowBeyondGrowthLimitsForTrackSizeComputationPhase(TrackS
return false;
}
+static void markAsInfinitelyGrowableForTrackSizeComputationPhase(TrackSizeComputationPhase phase, GridTrack& track)
+{
+ switch (phase) {
+ case ResolveIntrinsicMinimums:
+ case ResolveMaxContentMinimums:
+ return;
+ case ResolveIntrinsicMaximums:
+ if (trackSizeForTrackSizeComputationPhase(phase, track, AllowInfinity) == infinity && track.plannedSize() != infinity)
+ track.setInfinitelyGrowable(true);
+ return;
+ case ResolveMaxContentMaximums:
+ if (track.infinitelyGrowable())
+ track.setInfinitelyGrowable(false);
+ return;
+ case MaximizeTracks:
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ ASSERT_NOT_REACHED();
+}
+
svillar 2015/06/12 16:07:07 This is the implementation of step 2.3 from: http:
Manuel Rego 2015/06/26 11:09:47 I think you mean 2.2 here (otherwise I don't get i
svillar 2015/06/29 07:08:27 Sure 2.2 you're right.
static void updateTrackSizeForTrackSizeComputationPhase(TrackSizeComputationPhase phase, GridTrack& track)
{
switch (phase) {
case ResolveIntrinsicMinimums:
case ResolveMaxContentMinimums:
- track.growBaseSize(track.m_plannedIncrease);
+ track.setBaseSize(track.plannedSize());
return;
case ResolveIntrinsicMaximums:
case ResolveMaxContentMaximums:
- track.growGrowthLimit(track.m_plannedIncrease);
+ track.setGrowthLimit(track.plannedSize());
return;
case MaximizeTracks:
ASSERT_NOT_REACHED();
@@ -889,8 +920,10 @@ template <TrackSizeComputationPhase phase>
void LayoutGrid::resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizingDirection direction, GridSizingData& sizingData, const GridItemsSpanGroupRange& gridItemsWithSpan)
{
Vector<GridTrack>& tracks = (direction == ForColumns) ? sizingData.columnTracks : sizingData.rowTracks;
- for (const auto& trackIndex : sizingData.contentSizedTracksIndex)
- tracks[trackIndex].m_plannedIncrease = 0;
+ for (const auto& trackIndex : sizingData.contentSizedTracksIndex) {
+ GridTrack& track = tracks[trackIndex];
+ track.setPlannedSize(trackSizeForTrackSizeComputationPhase(phase, track, AllowInfinity));
+ }
for (auto it = gridItemsWithSpan.rangeStart; it != gridItemsWithSpan.rangeEnd; ++it) {
GridItemWithSpan& gridItemWithSpan = *it;
@@ -917,19 +950,16 @@ void LayoutGrid::resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizing
if (sizingData.filteredTracks.isEmpty())
continue;
- // Specs mandate to floor extraSpace to 0. Instead we directly avoid the function call in those cases as it will be
- // a noop in terms of track sizing.
LayoutUnit extraSpace = currentItemSizeForTrackSizeComputationPhase(phase, gridItemWithSpan.gridItem(), direction, sizingData.columnTracks) - spanningTracksSize;
- if (extraSpace > 0) {
- Vector<GridTrack*>* tracksToGrowBeyondGrowthLimits = sizingData.growBeyondGrowthLimitsTracks.isEmpty() ? &sizingData.filteredTracks : &sizingData.growBeyondGrowthLimitsTracks;
- distributeSpaceToTracks<phase>(sizingData.filteredTracks, tracksToGrowBeyondGrowthLimits, sizingData, extraSpace);
- }
+ extraSpace = std::max<LayoutUnit>(extraSpace, 0);
+ auto& tracksToGrowBeyondGrowthLimits = sizingData.growBeyondGrowthLimitsTracks.isEmpty() ? sizingData.filteredTracks : sizingData.growBeyondGrowthLimitsTracks;
+ distributeSpaceToTracks<phase>(sizingData.filteredTracks, &tracksToGrowBeyondGrowthLimits, sizingData, extraSpace);
}
for (const auto& trackIndex : sizingData.contentSizedTracksIndex) {
GridTrack& track = tracks[trackIndex];
- if (track.m_plannedIncrease)
- updateTrackSizeForTrackSizeComputationPhase(phase, track);
+ markAsInfinitelyGrowableForTrackSizeComputationPhase(phase, track);
+ updateTrackSizeForTrackSizeComputationPhase(phase, track);
}
}
@@ -937,11 +967,11 @@ static bool sortByGridTrackGrowthPotential(const GridTrack* track1, const GridTr
{
// This check ensures that we respect the irreflexivity property of the strict weak ordering required by std::sort
// (forall x: NOT x < x).
- if (track1->growthLimitIsInfinite() && track2->growthLimitIsInfinite())
+ if (track1->infiniteGrowthPotential() && track2->infiniteGrowthPotential())
return false;
- if (track1->growthLimitIsInfinite() || track2->growthLimitIsInfinite())
- return track2->growthLimitIsInfinite();
+ if (track1->infiniteGrowthPotential() || track2->infiniteGrowthPotential())
+ return track2->infiniteGrowthPotential();
return (track1->growthLimit() - track1->baseSize()) < (track2->growthLimit() - track2->baseSize());
}
@@ -949,18 +979,24 @@ static bool sortByGridTrackGrowthPotential(const GridTrack* track1, const GridTr
template <TrackSizeComputationPhase phase>
void LayoutGrid::distributeSpaceToTracks(Vector<GridTrack*>& tracks, const Vector<GridTrack*>* growBeyondGrowthLimitsTracks, GridSizingData& sizingData, LayoutUnit& availableLogicalSpace)
{
- ASSERT(availableLogicalSpace > 0);
- std::sort(tracks.begin(), tracks.end(), sortByGridTrackGrowthPotential);
+ ASSERT(availableLogicalSpace >= 0);
+
+ for (auto* track : tracks)
Manuel Rego 2015/06/26 11:09:48 A pitty that we need an extra loop here. :/
svillar 2015/06/29 07:08:27 Yes, but this is the best place to do it. Otherwis
+ track->setSizeDuringDistribution(trackSizeForTrackSizeComputationPhase(phase, *track, ForbidInfinity));
- size_t tracksSize = tracks.size();
- for (size_t i = 0; i < tracksSize; ++i) {
- GridTrack& track = *tracks[i];
- LayoutUnit availableLogicalSpaceShare = availableLogicalSpace / (tracksSize - i);
- const LayoutUnit& trackBreadth = trackSizeForTrackSizeComputationPhase(phase, track, ForbidInfinity);
- LayoutUnit growthShare = track.growthLimitIsInfinite() ? availableLogicalSpaceShare : std::min(availableLogicalSpaceShare, track.growthLimit() - trackBreadth);
- ASSERT_WITH_MESSAGE(growthShare >= 0, "We must never shrink any grid track or else we can't guarantee we abide by our min-sizing function.");
- track.m_increaseDuringDistribution = growthShare;
- availableLogicalSpace -= growthShare;
+ if (availableLogicalSpace > 0) {
+ std::sort(tracks.begin(), tracks.end(), sortByGridTrackGrowthPotential);
+
+ size_t tracksSize = tracks.size();
+ for (size_t i = 0; i < tracksSize; ++i) {
+ GridTrack& track = *tracks[i];
Manuel Rego 2015/06/26 11:09:48 Couldn't we use a range-based loop here as well?
svillar 2015/06/29 07:08:27 It was considered in previous patches, but note th
Manuel Rego 2015/06/29 07:46:42 Yes, I didn't realize about that.
+ LayoutUnit availableLogicalSpaceShare = availableLogicalSpace / (tracksSize - i);
+ const LayoutUnit& trackBreadth = trackSizeForTrackSizeComputationPhase(phase, track, ForbidInfinity);
+ LayoutUnit growthShare = track.infiniteGrowthPotential() ? availableLogicalSpaceShare : std::min(availableLogicalSpaceShare, track.growthLimit() - trackBreadth);
+ ASSERT_WITH_MESSAGE(growthShare >= 0, "We must never shrink any grid track or else we can't guarantee we abide by our min-sizing function.");
+ track.growSizeDuringDistribution(growthShare);
+ availableLogicalSpace -= growthShare;
+ }
}
if (availableLogicalSpace > 0 && growBeyondGrowthLimitsTracks) {
@@ -968,13 +1004,13 @@ void LayoutGrid::distributeSpaceToTracks(Vector<GridTrack*>& tracks, const Vecto
for (size_t i = 0; i < tracksGrowingAboveMaxBreadthSize; ++i) {
GridTrack* track = growBeyondGrowthLimitsTracks->at(i);
LayoutUnit growthShare = availableLogicalSpace / (tracksGrowingAboveMaxBreadthSize - i);
- track->m_increaseDuringDistribution += growthShare;
+ track->growSizeDuringDistribution(growthShare);
availableLogicalSpace -= growthShare;
}
}
for (auto* track : tracks)
- track->m_plannedIncrease = std::max(track->m_plannedIncrease, track->m_increaseDuringDistribution);
+ track->setPlannedSize(track->plannedSize() == infinity ? track->sizeDuringDistribution() : std::max(track->plannedSize(), track->sizeDuringDistribution()));
}
#if ENABLE(ASSERT)

Powered by Google App Engine
This is Rietveld 408576698