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

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

Issue 2080643002: [css-grid] Implement repeat(auto-fit) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Collapse empty tracks (do not drop them) Created 4 years, 5 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
Index: third_party/WebKit/Source/core/layout/LayoutGrid.cpp
diff --git a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
index 6d8864e4a0d6d97a786ebe9bb66b5cfebf6bd4b9..02cef0508f2d9b4696980bb36e078437ba16dce3 100644
--- a/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutGrid.cpp
@@ -387,7 +387,7 @@ LayoutUnit LayoutGrid::computeTrackBasedLogicalHeight(const GridSizingData& sizi
for (const auto& row : sizingData.rowTracks)
logicalHeight += row.baseSize();
- logicalHeight += guttersSize(ForRows, sizingData.rowTracks.size());
+ logicalHeight += guttersSize(ForRows, 0, sizingData.rowTracks.size());
return logicalHeight;
}
@@ -395,7 +395,7 @@ LayoutUnit LayoutGrid::computeTrackBasedLogicalHeight(const GridSizingData& sizi
void LayoutGrid::computeTrackSizesForDirection(GridTrackSizingDirection direction, GridSizingData& sizingData, LayoutUnit freeSpace)
{
DCHECK(sizingData.isValidTransitionForDirection(direction));
- sizingData.freeSpaceForDirection(direction) = freeSpace - guttersSize(direction, direction == ForRows ? gridRowCount() : gridColumnCount());
+ sizingData.freeSpaceForDirection(direction) = freeSpace - guttersSize(direction, 0, direction == ForRows ? gridRowCount() : gridColumnCount());
sizingData.sizingOperation = TrackSizing;
LayoutUnit baseSizes, growthLimits;
@@ -500,13 +500,65 @@ void LayoutGrid::layoutBlock(bool relayoutChildren)
clearNeedsLayout();
}
-LayoutUnit LayoutGrid::guttersSize(GridTrackSizingDirection direction, size_t span) const
+bool LayoutGrid::isEmptyAutoRepeatTrack(GridTrackSizingDirection direction, size_t lineNumber) const
Manuel Rego 2016/07/08 11:12:34 We usually use just "line" to refer to the other l
svillar 2016/07/11 12:46:19 Acknowledged.
+{
+ return direction == ForColumns ? m_autoRepeatEmptyColumns->contains(lineNumber) : m_autoRepeatEmptyRows->contains(lineNumber);
+}
+
+LayoutUnit LayoutGrid::gridGapForDirection(GridTrackSizingDirection direction) const
+{
+ return valueForLength(direction == ForColumns ? styleRef().gridColumnGap() : styleRef().gridRowGap(), LayoutUnit());
+}
+
+LayoutUnit LayoutGrid::guttersSize(GridTrackSizingDirection direction, size_t startLine, size_t span) const
Manuel Rego 2016/07/08 11:12:35 In most of the cases startLine is simply 0. I'd mo
svillar 2016/07/11 12:46:19 That's correct, but I did it like this for API coh
{
if (span <= 1)
return LayoutUnit();
- const Length& trackGap = direction == ForColumns ? styleRef().gridColumnGap() : styleRef().gridRowGap();
- return valueForLength(trackGap, LayoutUnit()) * (span - 1);
+ bool isRowAxis = direction == ForColumns;
+ LayoutUnit gap = gridGapForDirection(direction);
+
+ // Fast path, no collapsing tracks.
+ if (isRowAxis ? !m_autoRepeatEmptyColumns : !m_autoRepeatEmptyRows)
+ return gap * (span - 1);
+
+ // If there are collapsing tracks we need to be sure that gutters are properly collapsed. Apart
+ // from that, if we have a collapsed track in the edges of the span we're considering, we need
+ // to move forward (or backwards) in order to know whether the collapsed tracks reach the end of
+ // the grid (so the gap becomes 0) or there is a non empty track before that.
+
+ LayoutUnit gutterAccumulator;
Manuel Rego 2016/07/08 11:12:34 Nit: You call this gapAccumulator in a different m
svillar 2016/07/11 12:46:19 Acknowledged.
+ size_t endLine = startLine + span;
+
+ for (size_t line = startLine; line < endLine - 1; ++line) {
+ if (!isEmptyAutoRepeatTrack(direction, line))
+ gutterAccumulator += gap;
+ }
+
+ // If the startLine is the start line of a collapsed track we need to go backwards till we reach
+ // a non collapsed track. Should we find a non collapsed track we need to add that gap.
Manuel Rego 2016/07/08 11:12:34 Nit: s/Should/If/ (it's clearer to me).
svillar 2016/07/11 12:46:18 Acknowledged.
Manuel Rego 2016/07/14 09:10:51 Ping ;)
+ if (startLine && isEmptyAutoRepeatTrack(direction, startLine)) {
+ size_t nonEmptyTracksBeforeStartLine = startLine;
+ auto begin = isRowAxis ? m_autoRepeatEmptyColumns->begin() : m_autoRepeatEmptyRows->begin();
+ for (auto it = begin; *it != startLine; ++it)
+ --nonEmptyTracksBeforeStartLine;
+ if (nonEmptyTracksBeforeStartLine)
+ gutterAccumulator += gap;
+ }
+
+ // If the endLine is the end line of a collapsed track we need to go forward till we reach a non
+ // collapsed track. Should we find a non collapsed track we need to add that gap.
Manuel Rego 2016/07/08 11:12:35 Ditto.
svillar 2016/07/11 12:46:19 Acknowledged.
+ if (isEmptyAutoRepeatTrack(direction, endLine - 1)) {
+ size_t nonEmptyTracksAfterEndLine = (isRowAxis ? gridColumnCount() : gridRowCount()) - endLine;
+ auto currentEmptyLine = isRowAxis ? m_autoRepeatEmptyColumns->find(endLine - 1) : m_autoRepeatEmptyRows->find(endLine - 1);
+ auto endEmptyLine = isRowAxis ? m_autoRepeatEmptyColumns->end() : m_autoRepeatEmptyRows->end();
+ for (auto it = currentEmptyLine; it != endEmptyLine; ++it)
+ --nonEmptyTracksAfterEndLine;
+ if (nonEmptyTracksAfterEndLine)
+ gutterAccumulator += gap;
+ }
+
+ return gutterAccumulator;
}
void LayoutGrid::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
@@ -518,7 +570,7 @@ void LayoutGrid::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, Layo
sizingData.sizingOperation = IntrinsicSizeComputation;
const_cast<LayoutGrid*>(this)->computeUsedBreadthOfGridTracks(ForColumns, sizingData, minLogicalWidth, maxLogicalWidth);
- LayoutUnit totalGuttersSize = guttersSize(ForColumns, sizingData.columnTracks.size());
+ LayoutUnit totalGuttersSize = guttersSize(ForColumns, 0, sizingData.columnTracks.size());
minLogicalWidth += totalGuttersSize;
maxLogicalWidth += totalGuttersSize;
@@ -534,7 +586,7 @@ void LayoutGrid::computeIntrinsicLogicalHeight(GridSizingData& sizingData)
sizingData.sizingOperation = IntrinsicSizeComputation;
computeUsedBreadthOfGridTracks(ForRows, sizingData, m_minContentHeight, m_maxContentHeight);
- LayoutUnit totalGuttersSize = guttersSize(ForRows, gridRowCount());
+ LayoutUnit totalGuttersSize = guttersSize(ForRows, 0, gridRowCount());
m_minContentHeight += totalGuttersSize;
m_maxContentHeight += totalGuttersSize;
@@ -579,7 +631,7 @@ void LayoutGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection directi
// Grid gutters were removed from freeSpace by the caller, but we must use them to compute relative (i.e. percentages) sizes.
bool hasDefiniteFreeSpace = sizingData.sizingOperation == TrackSizing;
if (hasDefiniteFreeSpace)
- maxSize += guttersSize(direction, direction == ForRows ? gridRowCount() : gridColumnCount());
+ maxSize += guttersSize(direction, 0, direction == ForRows ? gridRowCount() : gridColumnCount());
// 1. Initialize per Grid track variables.
for (size_t i = 0; i < tracks.size(); ++i) {
@@ -809,6 +861,11 @@ const GridTrackSize& LayoutGrid::rawGridTrackSize(GridTrackSizingDirection direc
GridTrackSize LayoutGrid::gridTrackSize(GridTrackSizingDirection direction, size_t translatedIndex, SizingOperation sizingOperation) const
{
+ // Collapse empty auto repeat tracks if auto-fit
Manuel Rego 2016/07/08 11:12:34 Nit: Missing dot at the end.
svillar 2016/07/11 12:46:19 Acknowledged.
+ if ((direction == ForColumns && m_autoRepeatEmptyColumns && m_autoRepeatEmptyColumns->contains(translatedIndex))
+ || (direction == ForRows && m_autoRepeatEmptyRows && m_autoRepeatEmptyRows->contains(translatedIndex)))
Manuel Rego 2016/07/08 11:12:34 Cannot we use isEmptyAutoRepeatTrack() here?
svillar 2016/07/11 12:46:19 Totally, but I still need the null check here (won
+ return GridTrackSize(Length(Fixed), Length(Fixed));
+
const GridTrackSize& trackSize = rawGridTrackSize(direction, translatedIndex);
GridLength minTrackBreadth = trackSize.minTrackBreadth();
@@ -1203,7 +1260,8 @@ void LayoutGrid::resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizing
if (sizingData.filteredTracks.isEmpty())
continue;
- spanningTracksSize += guttersSize(direction, itemSpan.integerSpan());
+ DCHECK(itemSpan.isTranslatedDefinite());
Manuel Rego 2016/07/08 11:12:35 I don't believe we need this here. We've an ASSER
svillar 2016/07/11 12:46:19 Acknowledged.
+ spanningTracksSize += guttersSize(direction, itemSpan.startLine(), itemSpan.integerSpan());
LayoutUnit extraSpace = currentItemSizeForTrackSizeComputationPhase(phase, gridItemWithSpan.gridItem(), direction, sizingData) - spanningTracksSize;
extraSpace = extraSpace.clampNegativeToZero();
@@ -1366,7 +1424,7 @@ size_t LayoutGrid::computeAutoRepeatTracksCount(GridTrackSizingDirection directi
// Add gutters as if there where only 1 auto repeat track. Gaps between auto repeat tracks will be added later when
// computing the repetitions.
- LayoutUnit gapSize = guttersSize(direction, 2);
+ LayoutUnit gapSize = gridGapForDirection(direction);
tracksSize += gapSize * trackSizes.size();
LayoutUnit freeSpace = availableSize - tracksSize;
@@ -1384,6 +1442,37 @@ size_t LayoutGrid::computeAutoRepeatTracksCount(GridTrackSizingDirection directi
return repetitions;
}
+
+std::unique_ptr<LayoutGrid::TrackIndexSet> LayoutGrid::computeEmptyTracksForAutoRepeat(GridTrackSizingDirection direction) const
+{
+ bool isRowAxis = direction == ForColumns;
+ if ((isRowAxis && styleRef().gridAutoRepeatColumnsType() != AutoFit)
+ || (!isRowAxis && styleRef().gridAutoRepeatRowsType() != AutoFit))
+ return nullptr;
+
+ std::unique_ptr<TrackIndexSet> emptyTrackIndexes;
Manuel Rego 2016/07/08 11:12:34 I guess you can initialize it here already so you
svillar 2016/07/11 12:46:19 What if there is no empty track? I'd need to creat
Manuel Rego 2016/07/14 09:10:50 True, I didn't realize before.
+ size_t insertionPoint = isRowAxis ? styleRef().gridAutoRepeatColumnsInsertionPoint() : styleRef().gridAutoRepeatRowsInsertionPoint();
+ size_t repetitions = autoRepeatCountForDirection(direction);
+ size_t firstAutoRepeatTrack = insertionPoint + std::abs(isRowAxis ? m_smallestColumnStart : m_smallestRowStart);
+ size_t lastAutoRepeatTrack = firstAutoRepeatTrack + repetitions;
+
+ if (m_gridItemArea.isEmpty()) {
+ emptyTrackIndexes = wrapUnique(new TrackIndexSet);
+ for (size_t trackIndex = firstAutoRepeatTrack; trackIndex < lastAutoRepeatTrack; ++trackIndex)
+ emptyTrackIndexes->add(trackIndex);
+ } else {
+ for (size_t trackIndex = firstAutoRepeatTrack; trackIndex < lastAutoRepeatTrack; ++trackIndex) {
Manuel Rego 2016/07/08 11:12:35 The for is the same, maybe you can move the outer
svillar 2016/07/11 12:46:18 If I do that I'd evaluate the if() condition for e
+ GridIterator iterator(m_grid, direction, trackIndex);
+ if (!iterator.nextGridItem()) {
+ if (!emptyTrackIndexes)
+ emptyTrackIndexes = wrapUnique(new TrackIndexSet);
+ emptyTrackIndexes->add(trackIndex);
+ }
+ }
+ }
+ return emptyTrackIndexes;
+}
+
void LayoutGrid::placeItemsOnGrid()
{
if (!m_gridIsDirty)
@@ -1434,6 +1523,10 @@ void LayoutGrid::placeItemsOnGrid()
m_grid.shrinkToFit();
+ // Compute collapsable tracks for auto-fit
Manuel Rego 2016/07/08 11:12:34 Nit: Missing dot at the end.
+ m_autoRepeatEmptyColumns = computeEmptyTracksForAutoRepeat(ForColumns);
+ m_autoRepeatEmptyRows = computeEmptyTracksForAutoRepeat(ForRows);
+
#if ENABLE(ASSERT)
for (LayoutBox* child = m_orderIterator.first(); child; child = m_orderIterator.next()) {
if (child->isOutOfFlowPositioned())
@@ -1632,6 +1725,47 @@ void LayoutGrid::dirtyGrid()
m_gridItemsOverflowingGridArea.resize(0);
m_gridItemsIndexesMap.clear();
m_gridIsDirty = true;
+ m_autoRepeatEmptyColumns = nullptr;
+ m_autoRepeatEmptyRows = nullptr;
+}
+
+Vector<LayoutUnit> LayoutGrid::trackSizesForComputedStyle(GridTrackSizingDirection direction) const
Manuel Rego 2016/07/08 11:12:35 We've been computing almost the same information i
svillar 2016/07/11 12:46:19 In one method we're computing the line positions w
Manuel Rego 2016/07/14 09:10:51 Yeah I agree. My concern was that there're some du
+{
+ bool isRowAxis = direction == ForColumns;
+ auto& positions = isRowAxis ? m_columnPositions : m_rowPositions;
+ size_t numPositions = positions.size();
Manuel Rego 2016/07/08 11:12:34 Maybe we can rename numPositions to numTracks: n
svillar 2016/07/11 12:46:19 Hmm not sure what we would win with that, we still
+ LayoutUnit offsetBetweenTracks = isRowAxis ? m_offsetBetweenColumns : m_offsetBetweenRows;
+
+ Vector<LayoutUnit> tracks;
+ if (numPositions < 2)
+ return tracks;
+
+ bool hasCollapsedTracks = isRowAxis ? !!m_autoRepeatEmptyColumns : !!m_autoRepeatEmptyRows;
+ LayoutUnit gap = !hasCollapsedTracks ? gridGapForDirection(direction) : LayoutUnit();
+ tracks.reserveCapacity(numPositions - 1);
+ for (size_t i = 0; i < numPositions - 2; ++i)
+ tracks.append(positions[i + 1] - positions[i] - offsetBetweenTracks - gap);
+ tracks.append(positions[numPositions - 1] - positions[numPositions - 2]);
+
+ if (!hasCollapsedTracks)
+ return tracks;
+
+ size_t remainingEmptyTracks = isRowAxis ? m_autoRepeatEmptyColumns->size() : m_autoRepeatEmptyRows->size();
+ size_t lastLine = tracks.size();
Manuel Rego 2016/07/08 11:12:35 E.g. Here we'd already have the numTracks stored.
+ gap = gridGapForDirection(direction);
+ for (size_t i = 1; i < lastLine; ++i) {
+ if (isEmptyAutoRepeatTrack(direction, i - 1)) {
+ --remainingEmptyTracks;
+ } else {
+ // Remove the gap between consecutive non empty tracks. Remove it also just once for an
+ // arbitrary number of empty tracks between two non empty ones.
+ bool allRemainingTracksAreEmpty = remainingEmptyTracks == (lastLine - i);
+ if (!allRemainingTracksAreEmpty || !isEmptyAutoRepeatTrack(direction, i))
+ tracks[i - 1] -= gap;
+ }
Manuel Rego 2016/07/08 11:12:35 Could we early return if (remainingEmptyTracks ==
svillar 2016/07/11 12:46:19 Totally the opposite :). If none of the remaining
+ }
+
+ return tracks;
}
static const StyleContentAlignmentData& normalValueBehavior()
@@ -1820,9 +1954,11 @@ void LayoutGrid::offsetAndBreadthForPositionedChild(const LayoutBox& child, Grid
end = m_rowPositions[endLine] - borderBefore();
}
- // These vectors store line positions including gaps, but we shouldn't consider them for the edges of the grid.
- if (endLine > 0 && endLine < lastLine) {
- end -= guttersSize(direction, 2);
+ // These vectors store line positions including gaps, but we shouldn't consider them for the
+ // edges of the grid (note that a collapsed track at the end of the grid has its end line
+ // overlapping the grid'd edge).
Manuel Rego 2016/07/08 11:12:35 Apart from the typo "grid'd" I don't get the part
Manuel Rego 2016/07/14 09:10:51 Ping. I don't understand the part between parenthe
+ if (endLine && (endLine < lastLine)) {
Manuel Rego 2016/07/08 11:12:35 Why you removed "> 0" for endLine? endLine is an i
svillar 2016/07/11 12:46:19 Oh my mistake, I did it due to the coding style
+ end -= guttersSize(direction, endLine - 1, 2);
Manuel Rego 2016/07/08 11:12:34 Cannot we use gridGapForDirection(direction) like
svillar 2016/07/11 12:46:19 No we cannot. gridGapForDirection just returns the
end -= isForColumns ? m_offsetBetweenColumns : m_offsetBetweenRows;
}
}
@@ -1839,7 +1975,7 @@ void LayoutGrid::offsetAndBreadthForPositionedChild(const LayoutBox& child, Grid
offset = translateRTLCoordinate(m_columnPositions[endLine]) - borderLogicalLeft();
if (endLine > 0 && endLine < lastLine) {
- offset += guttersSize(direction, 2);
+ offset += gridGapForDirection(direction);
offset += isForColumns ? m_offsetBetweenColumns : m_offsetBetweenRows;
}
}
@@ -1874,7 +2010,7 @@ LayoutUnit LayoutGrid::assumedRowsSizeForOrthogonalChild(const LayoutBox& child,
gridAreaSize += valueForLength(maxTrackSize.length(), containingBlockAvailableSize);
}
- gridAreaSize += guttersSize(ForRows, span.integerSpan());
+ gridAreaSize += guttersSize(ForRows, span.startLine(), span.integerSpan());
return gridAreaIsIndefinite ? std::max(child.maxPreferredLogicalWidth(), gridAreaSize) : gridAreaSize;
}
@@ -1893,7 +2029,8 @@ LayoutUnit LayoutGrid::gridAreaBreadthForChild(const LayoutBox& child, GridTrack
for (const auto& trackPosition : span)
gridAreaBreadth += tracks[trackPosition].baseSize();
- gridAreaBreadth += guttersSize(direction, span.integerSpan());
+ DCHECK(span.isTranslatedDefinite());
Manuel Rego 2016/07/08 11:12:34 Ditto.
+ gridAreaBreadth += guttersSize(direction, span.startLine(), span.integerSpan());
return gridAreaBreadth;
}
@@ -1926,16 +2063,40 @@ void LayoutGrid::populateGridPositionsForDirection(GridSizingData& sizingData, G
size_t numberOfLines = numberOfTracks + 1;
size_t lastLine = numberOfLines - 1;
ContentAlignmentData offset = computeContentPositionAndDistributionOffset(direction, sizingData.freeSpaceForDirection(direction), numberOfTracks);
- LayoutUnit trackGap = guttersSize(direction, 2);
auto& positions = isRowAxis ? m_columnPositions : m_rowPositions;
positions.resize(numberOfLines);
auto borderAndPadding = isRowAxis ? borderAndPaddingLogicalLeft() : borderAndPaddingBefore();
positions[0] = borderAndPadding + offset.positionOffset;
if (numberOfLines > 1) {
+ // If we have collapsed tracks we just ignore gaps here and add them later as we might not
+ // compute the gap between two consecutive tracks without examining the surrounding ones.
+ bool hasEmptyLinesForDirection = isRowAxis ? !!m_autoRepeatEmptyColumns : !!m_autoRepeatEmptyRows;
Manuel Rego 2016/07/08 11:12:35 s/hasEmptyLinesForDirection/hasEmptyTracksForDirec
svillar 2016/07/11 12:46:19 Oh yeah, empty lines makes no sense indeed.
+ LayoutUnit gap = !hasEmptyLinesForDirection ? gridGapForDirection(direction) : LayoutUnit();
size_t nextToLastLine = numberOfLines - 2;
for (size_t i = 0; i < nextToLastLine; ++i)
- positions[i + 1] = positions[i] + offset.distributionOffset + tracks[i].baseSize() + trackGap;
+ positions[i + 1] = positions[i] + offset.distributionOffset + tracks[i].baseSize() + gap;
positions[lastLine] = positions[nextToLastLine] + tracks[nextToLastLine].baseSize();
+
+ // Adjust collapsed gaps. Collapsed tracks cause the surrounding gutters to collapse (they
+ // coincide exactly) except on the edges of the grid where they become 0.
+ if (hasEmptyLinesForDirection) {
+ gap = gridGapForDirection(direction);
+ size_t remainingEmptyTracks = isRowAxis ? m_autoRepeatEmptyColumns->size() : m_autoRepeatEmptyRows->size();
+ LayoutUnit gapAccumulator;
+ for (size_t i = 1; i < lastLine; ++i) {
+ if (isEmptyAutoRepeatTrack(direction, i - 1)) {
+ --remainingEmptyTracks;
+ } else {
+ // Add gap between consecutive non empty tracks. Add it also just once for an
+ // arbitrary number of empty tracks between two non empty ones.
+ bool allRemainingTracksAreEmpty = remainingEmptyTracks == (lastLine - i);
+ if (!allRemainingTracksAreEmpty || !isEmptyAutoRepeatTrack(direction, i))
+ gapAccumulator += gap;
+ }
+ positions[i] += gapAccumulator;
+ }
+ positions[lastLine] += gapAccumulator;
+ }
}
auto& offsetBetweenTracks = isRowAxis ? m_offsetBetweenColumns : m_offsetBetweenRows;
offsetBetweenTracks = offset.distributionOffset;
@@ -2186,7 +2347,7 @@ LayoutUnit LayoutGrid::columnAxisOffsetForChild(const LayoutBox& child, GridSizi
// m_rowPositions include distribution offset (because of content alignment) and gutters
// so we need to subtract them to get the actual end position for a given row
// (this does not have to be done for the last track as there are no more m_columnPositions after it).
- LayoutUnit trackGap = guttersSize(ForRows, 2);
+ LayoutUnit trackGap = gridGapForDirection(ForRows);
if (childEndLine < m_rowPositions.size() - 1) {
endOfRow -= trackGap;
endOfRow -= m_offsetBetweenRows;
@@ -2221,7 +2382,7 @@ LayoutUnit LayoutGrid::rowAxisOffsetForChild(const LayoutBox& child, GridSizingD
// m_columnPositions include distribution offset (because of content alignment) and gutters
// so we need to subtract them to get the actual end position for a given column
// (this does not have to be done for the last track as there are no more m_columnPositions after it).
- LayoutUnit trackGap = guttersSize(ForColumns, 2);
+ LayoutUnit trackGap = gridGapForDirection(ForColumns);
if (childEndLine < m_columnPositions.size() - 1) {
endOfColumn -= trackGap;
endOfColumn -= m_offsetBetweenColumns;

Powered by Google App Engine
This is Rietveld 408576698