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

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

Issue 1323053004: [CSS Grid Layout] Flex tracks sizing alg must handle 0fr values (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Applied suggested changes. Created 5 years, 3 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
« Source/core/layout/LayoutGrid.h ('K') | « 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 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
« Source/core/layout/LayoutGrid.h ('K') | « Source/core/layout/LayoutGrid.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698