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) |