Chromium Code Reviews| 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 |