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

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: Created 5 years, 9 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
« no previous file with comments | « Source/core/layout/LayoutGrid.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/layout/LayoutGrid.cpp
diff --git a/Source/core/layout/LayoutGrid.cpp b/Source/core/layout/LayoutGrid.cpp
index 7c0a17bec7fc0ac127904c5dbffef9ea7bf2b4b0..eb0579f1f3250947f9f4633859f81352d8fa791d 100644
--- a/Source/core/layout/LayoutGrid.cpp
+++ b/Source/core/layout/LayoutGrid.cpp
@@ -41,10 +41,11 @@ static const int infinity = -1;
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)
{
}
@@ -72,37 +73,46 @@ 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 growthLimitIsInfiniteOrTrackIsInfinitelyGrowable() const
{
- ASSERT(growth >= 0);
- if (m_growthLimit == infinity)
- m_growthLimit = m_baseSize + growth;
- else
- m_growthLimit += growth;
+ return growthLimitIsInfinite() || m_infinitelyGrowable;
+ }
- ASSERT(m_growthLimit >= m_baseSize);
+ const LayoutUnit& growthLimitIfNotInfinite() const
+ {
+ ASSERT(isGrowthLimitBiggerThanBaseSize());
+ return (m_growthLimit == infinity) ? m_baseSize : m_growthLimit;
}
- bool growthLimitIsInfinite() const
+ const LayoutUnit& plannedSize() const { return m_plannedSize; }
+
+ void setPlannedSize(const LayoutUnit& plannedSize)
{
- return m_growthLimit == infinity;
+ ASSERT(plannedSize >= 0 || plannedSize == infinity);
+ m_plannedSize = plannedSize;
Julien - ping for review 2015/04/08 18:58:56 It seems weird to allow the plannedSize to be infi
svillar 2015/04/10 09:43:09 In theory that's true, although not possible with
}
- const LayoutUnit& growthLimitIfNotInfinite() const
+ const LayoutUnit& sizeDuringDistribution() { return m_sizeDuringDistribution; }
+
+ void setSizeDuringDistribution(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;
+ void growSizeDuringDistribution(const LayoutUnit& sizeDuringDistribution)
+ {
+ ASSERT(sizeDuringDistribution >= 0);
+ m_sizeDuringDistribution += sizeDuringDistribution;
+ }
+
+ bool infinitelyGrowable() const { return m_infinitelyGrowable; }
+ void setInfinitelyGrowable(bool infinitelyGrowable) { m_infinitelyGrowable = infinitelyGrowable; }
private:
bool isGrowthLimitBiggerThanBaseSize() const { return growthLimitIsInfinite() || m_growthLimit >= m_baseSize; }
@@ -115,6 +125,9 @@ private:
LayoutUnit m_baseSize;
LayoutUnit m_growthLimit;
+ LayoutUnit m_plannedSize;
+ LayoutUnit m_sizeDuringDistribution;
+ bool m_infinitelyGrowable;
Julien - ping for review 2015/04/08 18:58:56 We are storing one extra member compared to the sp
svillar 2015/04/10 09:43:09 It does exist in the original algorithm, it's call
};
struct GridTrackForNormalization {
@@ -413,6 +426,7 @@ void LayoutGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection directi
track.setBaseSize(computeUsedBreadthOfMinLength(direction, minTrackBreadth));
track.setGrowthLimit(computeUsedBreadthOfMaxLength(direction, maxTrackBreadth, track.baseSize()));
+ track.setInfinitelyGrowable(false);
if (trackSize.isContentSized())
sizingData.contentSizedTracksIndex.append(i);
@@ -425,7 +439,7 @@ void LayoutGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection directi
resolveContentBasedTrackSizingFunctions(direction, sizingData);
for (const auto& track: tracks) {
- ASSERT(!track.growthLimitIsInfinite());
+ ASSERT(!track.growthLimitIsInfinite() && !track.infinitelyGrowable());
Julien - ping for review 2015/04/08 18:58:56 This should be split in 2. Logical AND in ASSERT m
svillar 2015/04/10 09:43:09 Acknowledged.
freeSpace -= track.baseSize();
}
@@ -440,13 +454,13 @@ 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());
}
distributeSpaceToTracks(tracksForDistribution, nullptr, &GridTrack::baseSize, sizingData, freeSpace);
for (auto* track : tracksForDistribution)
- track->growBaseSize(track->m_plannedIncrease);
+ track->setBaseSize(track->plannedSize());
} else {
for (auto& track : tracks)
track.setBaseSize(track.growthLimit());
@@ -743,10 +757,10 @@ void LayoutGrid::resolveContentBasedTrackSizingFunctions(GridTrackSizingDirectio
auto end = sizingData.itemsSortedByIncreasingSpan.end();
while (it != end) {
GridItemsSpanGroupRange spanGroupRange = { it, std::upper_bound(it, end, *it) };
- resolveContentBasedTrackSizingFunctionsForItems(direction, sizingData, spanGroupRange, &GridTrackSize::hasMinOrMaxContentMinTrackBreadth, &LayoutGrid::minContentForChild, &GridTrack::baseSize, &GridTrack::growBaseSize, &GridTrackSize::hasMinContentMinTrackBreadthAndMinOrMaxContentMaxTrackBreadth);
- resolveContentBasedTrackSizingFunctionsForItems(direction, sizingData, spanGroupRange, &GridTrackSize::hasMaxContentMinTrackBreadth, &LayoutGrid::maxContentForChild, &GridTrack::baseSize, &GridTrack::growBaseSize, &GridTrackSize::hasMaxContentMinTrackBreadthAndMaxContentMaxTrackBreadth);
- resolveContentBasedTrackSizingFunctionsForItems(direction, sizingData, spanGroupRange, &GridTrackSize::hasMinOrMaxContentMaxTrackBreadth, &LayoutGrid::minContentForChild, &GridTrack::growthLimitIfNotInfinite, &GridTrack::growGrowthLimit);
- resolveContentBasedTrackSizingFunctionsForItems(direction, sizingData, spanGroupRange, &GridTrackSize::hasMaxContentMaxTrackBreadth, &LayoutGrid::maxContentForChild, &GridTrack::growthLimitIfNotInfinite, &GridTrack::growGrowthLimit);
+ resolveContentBasedTrackSizingFunctionsForItems(direction, sizingData, spanGroupRange, &GridTrackSize::hasMinOrMaxContentMinTrackBreadth, &LayoutGrid::minContentForChild, &GridTrack::baseSize, &GridTrack::baseSize, &GridTrack::setBaseSize, &GridTrackSize::hasMinContentMinTrackBreadthAndMinOrMaxContentMaxTrackBreadth);
+ resolveContentBasedTrackSizingFunctionsForItems(direction, sizingData, spanGroupRange, &GridTrackSize::hasMaxContentMinTrackBreadth, &LayoutGrid::maxContentForChild, &GridTrack::baseSize, &GridTrack::baseSize, &GridTrack::setBaseSize, &GridTrackSize::hasMaxContentMinTrackBreadthAndMaxContentMaxTrackBreadth);
+ resolveContentBasedTrackSizingFunctionsForItems(direction, sizingData, spanGroupRange, &GridTrackSize::hasMinOrMaxContentMaxTrackBreadth, &LayoutGrid::minContentForChild, &GridTrack::growthLimit, &GridTrack::growthLimitIfNotInfinite, &GridTrack::setGrowthLimit);
+ resolveContentBasedTrackSizingFunctionsForItems(direction, sizingData, spanGroupRange, &GridTrackSize::hasMaxContentMaxTrackBreadth, &LayoutGrid::maxContentForChild, &GridTrack::growthLimit, &GridTrack::growthLimitIfNotInfinite, &GridTrack::setGrowthLimit);
it = spanGroupRange.rangeEnd;
}
@@ -773,11 +787,13 @@ void LayoutGrid::resolveContentBasedTrackSizingFunctionsForNonSpanningItems(Grid
track.setGrowthLimit(std::max(track.growthLimit(), maxContentForChild(gridItem, direction, columnTracks)));
}
-void LayoutGrid::resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizingDirection direction, GridSizingData& sizingData, const GridItemsSpanGroupRange& gridItemsWithSpan, FilterFunction filterFunction, SizingFunction sizingFunction, AccumulatorGetter trackGetter, AccumulatorGrowFunction trackGrowthFunction, FilterFunction growAboveMaxBreadthFilterFunction)
+void LayoutGrid::resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizingDirection direction, GridSizingData& sizingData, const GridItemsSpanGroupRange& gridItemsWithSpan, FilterFunction filterFunction, SizingFunction sizingFunction, AccumulatorGetter trackGetter, AccumulatorGetter trackGetterIfNotInfinite, AccumulatorSetterFunction trackSetterFunction, FilterFunction growAboveMaxBreadthFilterFunction)
{
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((track.*trackGetter)());
+ }
for (auto it = gridItemsWithSpan.rangeStart; it != gridItemsWithSpan.rangeEnd; ++it) {
GridItemWithSpan& gridItemWithSpan = *it;
@@ -791,7 +807,7 @@ void LayoutGrid::resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizing
for (const auto& trackPosition : itemSpan) {
GridTrackSize trackSize = gridTrackSize(direction, trackPosition.toInt());
GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[trackPosition.toInt()] : sizingData.rowTracks[trackPosition.toInt()];
- spanningTracksSize += (track.*trackGetter)();
+ spanningTracksSize += (track.*trackGetterIfNotInfinite)();
if (!(trackSize.*filterFunction)())
continue;
@@ -804,19 +820,19 @@ 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 = (this->*sizingFunction)(gridItemWithSpan.gridItem(), direction, sizingData.columnTracks) - spanningTracksSize;
- if (extraSpace > 0) {
- Vector<GridTrack*>* tracksToGrowBeyondGrowthLimits = sizingData.growBeyondGrowthLimitsTracks.isEmpty() ? &sizingData.filteredTracks : &sizingData.growBeyondGrowthLimitsTracks;
- distributeSpaceToTracks(sizingData.filteredTracks, tracksToGrowBeyondGrowthLimits, trackGetter, sizingData, extraSpace);
- }
+ Vector<GridTrack*>* tracksToGrowBeyondGrowthLimits = sizingData.growBeyondGrowthLimitsTracks.isEmpty() ? &sizingData.filteredTracks : &sizingData.growBeyondGrowthLimitsTracks;
+ extraSpace = std::max<LayoutUnit>(extraSpace, 0);
+ distributeSpaceToTracks(sizingData.filteredTracks, tracksToGrowBeyondGrowthLimits, trackGetterIfNotInfinite, sizingData, extraSpace);
}
for (const auto& trackIndex : sizingData.contentSizedTracksIndex) {
GridTrack& track = tracks[trackIndex];
- if (track.m_plannedIncrease)
- (track.*trackGrowthFunction)(track.m_plannedIncrease);
+ if ((track.*trackGetter)() == infinity && track.plannedSize() != infinity)
+ track.setInfinitelyGrowable(true);
+ else if (track.infinitelyGrowable())
+ track.setInfinitelyGrowable(false);
+ (track.*trackSetterFunction)(track.plannedSize());
}
}
@@ -824,29 +840,34 @@ 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->growthLimitIsInfiniteOrTrackIsInfinitelyGrowable() && track2->growthLimitIsInfiniteOrTrackIsInfinitelyGrowable())
return false;
- if (track1->growthLimitIsInfinite() || track2->growthLimitIsInfinite())
- return track2->growthLimitIsInfinite();
+ if (track1->growthLimitIsInfiniteOrTrackIsInfinitelyGrowable() || track2->growthLimitIsInfiniteOrTrackIsInfinitelyGrowable())
+ return track2->growthLimitIsInfiniteOrTrackIsInfinitelyGrowable();
return (track1->growthLimit() - track1->baseSize()) < (track2->growthLimit() - track2->baseSize());
}
-void LayoutGrid::distributeSpaceToTracks(Vector<GridTrack*>& tracks, const Vector<GridTrack*>* growBeyondGrowthLimitsTracks, AccumulatorGetter trackGetter, GridSizingData& sizingData, LayoutUnit& availableLogicalSpace)
+void LayoutGrid::distributeSpaceToTracks(Vector<GridTrack*>& tracks, const Vector<GridTrack*>* growBeyondGrowthLimitsTracks, AccumulatorGetter trackGetterIfNotInfinite, GridSizingData& sizingData, LayoutUnit& availableLogicalSpace)
{
- ASSERT(availableLogicalSpace > 0);
- std::sort(tracks.begin(), tracks.end(), sortByGridTrackGrowthPotential);
+ ASSERT(availableLogicalSpace >= 0);
+ 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];
- LayoutUnit availableLogicalSpaceShare = availableLogicalSpace / (tracksSize - i);
- const LayoutUnit& trackBreadth = (track.*trackGetter)();
- 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;
+ 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 = (track.*trackGetterIfNotInfinite)();
+ LayoutUnit growthShare = track.growthLimitIsInfiniteOrTrackIsInfinitelyGrowable() ? 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.setSizeDuringDistribution(trackBreadth + growthShare);
+ availableLogicalSpace -= growthShare;
+ }
+ } else {
+ for (auto* track : tracks)
+ track->setSizeDuringDistribution((track->*trackGetterIfNotInfinite)());
}
if (availableLogicalSpace > 0 && growBeyondGrowthLimitsTracks) {
@@ -854,13 +875,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)
« no previous file with comments | « Source/core/layout/LayoutGrid.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698