Index: Source/core/layout/LayoutGrid.cpp |
diff --git a/Source/core/layout/LayoutGrid.cpp b/Source/core/layout/LayoutGrid.cpp |
index 56826d06c9350e129bc8fc841290ceabc90320d6..6e72c698118e37b920ba35c27829a59d3bfc4158 100644 |
--- a/Source/core/layout/LayoutGrid.cpp |
+++ b/Source/core/layout/LayoutGrid.cpp |
@@ -142,28 +142,6 @@ public: |
LayoutUnit distributionOffset = -1; |
}; |
-struct GridTrackForNormalization { |
- GridTrackForNormalization(const GridTrack& track, double flex) |
- : m_track(&track) |
- , m_flex(flex) |
- , m_normalizedFlexValue(track.baseSize() / flex) |
- { |
- } |
- |
- // Required by std::sort. |
- GridTrackForNormalization& operator=(const GridTrackForNormalization& o) |
- { |
- m_track = o.m_track; |
- m_flex = o.m_flex; |
- m_normalizedFlexValue = o.m_normalizedFlexValue; |
- return *this; |
- } |
- |
- const GridTrack* m_track; |
- double m_flex; |
- LayoutUnit m_normalizedFlexValue; |
-}; |
- |
enum TrackSizeRestriction { |
AllowInfinity, |
ForbidInfinity, |
@@ -396,6 +374,11 @@ bool LayoutGrid::gridElementIsShrinkToFit() |
return isFloatingOrOutOfFlowPositioned(); |
} |
+static inline double normalizedFlexFraction(const GridTrack& track, double flexFactor) |
+{ |
+ return flexFactor > 1 ? track.baseSize() / flexFactor : track.baseSize().toDouble(); |
+} |
+ |
void LayoutGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection direction, GridSizingData& sizingData, LayoutUnit& freeSpace) |
{ |
const LayoutUnit initialFreeSpace = freeSpace; |
@@ -456,14 +439,12 @@ void LayoutGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection directi |
return; |
// 4. Grow all Grid tracks having a fraction as the MaxTrackSizingFunction. |
- double normalizedFractionBreadth = 0; |
+ double flexFraction = 0; |
if (!hasUndefinedRemainingSpace) { |
- normalizedFractionBreadth = computeNormalizedFractionBreadth(tracks, GridSpan(0, tracks.size() - 1), direction, initialFreeSpace); |
+ flexFraction = findFrUnitSize(tracks, GridSpan(0, tracks.size() - 1), direction, initialFreeSpace); |
} else { |
- for (const auto& trackIndex : flexibleSizedTracksIndex) { |
- GridTrackSize trackSize = gridTrackSize(direction, trackIndex); |
- normalizedFractionBreadth = std::max(normalizedFractionBreadth, tracks[trackIndex].baseSize() / trackSize.maxTrackBreadth().flex()); |
- } |
+ for (const auto& trackIndex : flexibleSizedTracksIndex) |
+ flexFraction = std::max(flexFraction, normalizedFlexFraction(tracks[trackIndex], gridTrackSize(direction, trackIndex).maxTrackBreadth().flex())); |
for (size_t i = 0; i < flexibleSizedTracksIndex.size(); ++i) { |
GridIterator iterator(m_grid, direction, flexibleSizedTracksIndex[i]); |
@@ -475,8 +456,8 @@ void LayoutGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection directi |
if (i > 0 && span.resolvedInitialPosition.toInt() <= flexibleSizedTracksIndex[i - 1]) |
continue; |
- double itemNormalizedFlexBreadth = computeNormalizedFractionBreadth(tracks, span, direction, maxContentForChild(*gridItem, direction, sizingData.columnTracks)); |
- normalizedFractionBreadth = std::max(normalizedFractionBreadth, itemNormalizedFlexBreadth); |
+ double itemFlexFraction = findFrUnitSize(tracks, span, direction, maxContentForChild(*gridItem, direction, sizingData.columnTracks)); |
+ flexFraction = std::max(flexFraction, itemFlexFraction); |
} |
} |
} |
@@ -484,7 +465,7 @@ void LayoutGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection directi |
for (const auto& trackIndex : flexibleSizedTracksIndex) { |
GridTrackSize trackSize = gridTrackSize(direction, trackIndex); |
- LayoutUnit baseSize = std::max<LayoutUnit>(tracks[trackIndex].baseSize(), normalizedFractionBreadth * trackSize.maxTrackBreadth().flex()); |
+ LayoutUnit baseSize = std::max<LayoutUnit>(tracks[trackIndex].baseSize(), flexFraction * trackSize.maxTrackBreadth().flex()); |
tracks[trackIndex].setBaseSize(baseSize); |
freeSpace -= baseSize; |
} |
@@ -528,59 +509,40 @@ LayoutUnit LayoutGrid::computeUsedBreadthOfSpecifiedLength(GridTrackSizingDirect |
return valueForLength(trackLength, direction == ForColumns ? logicalWidth() : std::max(LayoutUnit(), computeContentLogicalHeight(MainOrPreferredSize, style()->logicalHeight(), -1))); |
} |
-static bool sortByGridNormalizedFlexValue(const GridTrackForNormalization& track1, const GridTrackForNormalization& track2) |
+double LayoutGrid::findFrUnitSize(Vector<GridTrack>& tracks, const GridSpan& tracksSpan, GridTrackSizingDirection direction, LayoutUnit spaceToFill, TrackIndexSet tracksToTreatAsInflexible) const |
{ |
- return track1.m_normalizedFlexValue < track2.m_normalizedFlexValue; |
-} |
+ if (spaceToFill <= 0) |
+ return 0; |
-double LayoutGrid::computeNormalizedFractionBreadth(Vector<GridTrack>& tracks, const GridSpan& tracksSpan, GridTrackSizingDirection direction, LayoutUnit spaceToFill) const |
-{ |
- LayoutUnit allocatedSpace; |
- Vector<GridTrackForNormalization> tracksForNormalization; |
+ double flexFactorSum = 0; |
+ LayoutUnit leftOverSpace = spaceToFill; |
+ Vector<size_t> flexibleSizedTracksIndex; |
for (const auto& resolvedPosition : tracksSpan) { |
- GridTrack& track = tracks[resolvedPosition.toInt()]; |
- allocatedSpace += track.baseSize(); |
- |
- GridTrackSize trackSize = gridTrackSize(direction, resolvedPosition.toInt()); |
- if (!trackSize.maxTrackBreadth().isFlex()) |
- continue; |
- |
- tracksForNormalization.append(GridTrackForNormalization(track, trackSize.maxTrackBreadth().flex())); |
- } |
- |
- // The function is not called if we don't have <flex> grid tracks |
- ASSERT(!tracksForNormalization.isEmpty()); |
- |
- std::sort(tracksForNormalization.begin(), tracksForNormalization.end(), sortByGridNormalizedFlexValue); |
- |
- // These values work together: as we walk over our grid tracks, we increase fractionValueBasedOnGridItemsRatio |
- // to match a grid track's usedBreadth to <flex> ratio until the total fractions sized grid tracks wouldn't |
- // fit into availableLogicalSpaceIgnoringFractionTracks. |
- double accumulatedFractions = 0; |
- LayoutUnit fractionValueBasedOnGridItemsRatio = 0; |
- LayoutUnit availableLogicalSpaceIgnoringFractionTracks = spaceToFill - allocatedSpace; |
- |
- for (const auto& track : tracksForNormalization) { |
- if (track.m_normalizedFlexValue > fractionValueBasedOnGridItemsRatio) { |
- // If the normalized flex value (we ordered |tracksForNormalization| by increasing normalized flex value) |
- // will make us overflow our container, then stop. We have the previous step's ratio is the best fit. |
- if (track.m_normalizedFlexValue * accumulatedFractions > availableLogicalSpaceIgnoringFractionTracks) |
- break; |
- |
- fractionValueBasedOnGridItemsRatio = track.m_normalizedFlexValue; |
+ size_t trackIndex = resolvedPosition.toInt(); |
+ GridTrackSize trackSize = gridTrackSize(direction, trackIndex); |
+ if (!trackSize.maxTrackBreadth().isFlex() || tracksToTreatAsInflexible.contains(trackIndex)) { |
+ leftOverSpace -= tracks[trackIndex].baseSize(); |
+ } else { |
+ flexibleSizedTracksIndex.append(trackIndex); |
+ flexFactorSum += trackSize.maxTrackBreadth().flex(); |
} |
- |
- accumulatedFractions += track.m_flex; |
- // This item was processed so we re-add its used breadth to the available space to accurately count the remaining space. |
- availableLogicalSpaceIgnoringFractionTracks += track.m_track->baseSize(); |
} |
// Let flex factor sum be the sum of the flex factors of the flexible tracks. If this value |
// is less than 1, set it to 1 instead. |
- if (accumulatedFractions < 1) |
- return availableLogicalSpaceIgnoringFractionTracks; |
+ double hypotheticalFrSize = flexFactorSum > 1 ? leftOverSpace / flexFactorSum : leftOverSpace.toDouble(); |
+ |
+ // If the product of the hypothetical fr size and a flexible track's flex factor is less |
+ // than the track's base size, restart this algorithm treating all such tracks as inflexible |
+ bool succeed = true; |
+ for (size_t trackIndex : flexibleSizedTracksIndex) { |
+ if (hypotheticalFrSize * gridTrackSize(direction, trackIndex).maxTrackBreadth().flex() < tracks[trackIndex].baseSize().toDouble()) { |
+ tracksToTreatAsInflexible.add(trackIndex); |
+ succeed = false; |
+ } |
+ } |
- return availableLogicalSpaceIgnoringFractionTracks / accumulatedFractions; |
+ return succeed ? hypotheticalFrSize : findFrUnitSize(tracks, tracksSpan, direction, spaceToFill, tracksToTreatAsInflexible); |
esprehn
2015/09/10 01:03:14
This recursion keeps creating more copies of the s
|
} |
bool LayoutGrid::hasDefiniteLogicalSize(GridTrackSizingDirection direction) const |