Index: Source/core/rendering/RenderGrid.cpp |
diff --git a/Source/core/rendering/RenderGrid.cpp b/Source/core/rendering/RenderGrid.cpp |
index 351881084b582f24de06651ade28f7fd5595239d..eb005d41afd62284b8f3777a98a9b9a4c3b17b06 100644 |
--- a/Source/core/rendering/RenderGrid.cpp |
+++ b/Source/core/rendering/RenderGrid.cpp |
@@ -122,21 +122,55 @@ public: |
return 0; |
} |
- PassOwnPtr<GridCoordinate> nextEmptyGridArea() |
+ bool areCellsEmpty(size_t spanningPositions) |
{ |
- ASSERT(!m_grid.isEmpty()); |
+ // This adds a O(N^2) behavior that shouldn't be a big deal as we expect spanning areas to be small. |
+ if (m_direction == ForColumns) { |
+ for (size_t i = m_columnIndex; i < m_columnIndex + spanningPositions; ++i) { |
+ const GridCell& children = m_grid[m_rowIndex][i]; |
+ if (!children.isEmpty()) |
+ return false; |
+ } |
+ } else { |
+ for (size_t i = m_rowIndex; i < m_rowIndex + spanningPositions; ++i) { |
+ const GridCell& children = m_grid[i][m_columnIndex]; |
+ if (!children.isEmpty()) |
+ return false; |
+ } |
+ } |
- size_t& varyingTrackIndex = (m_direction == ForColumns) ? m_rowIndex : m_columnIndex; |
- const size_t endOfVaryingTrackIndex = (m_direction == ForColumns) ? m_grid.size() : m_grid[0].size(); |
- for (; varyingTrackIndex < endOfVaryingTrackIndex; ++varyingTrackIndex) { |
- const GridCell& children = m_grid[m_rowIndex][m_columnIndex]; |
- if (children.isEmpty()) { |
- OwnPtr<GridCoordinate> result = adoptPtr(new GridCoordinate(GridSpan(m_rowIndex, m_rowIndex), GridSpan(m_columnIndex, m_columnIndex))); |
- // Advance the iterator to avoid an infinite loop where we would return the same grid area over and over. |
- ++varyingTrackIndex; |
- return result.release(); |
+ return true; |
+ } |
+ |
+ PassOwnPtr<GridCoordinate> nextEmptyGridArea(size_t spanningPositions) |
Julien - ping for review
2014/04/04 00:10:16
|spanningPositions| confuses me: that's because it
|
+ { |
+ ASSERT(!m_grid.isEmpty()); |
+ ASSERT(spanningPositions >= 1); |
+ |
+ if (m_direction == ForColumns) { |
+ for (; m_rowIndex < m_grid.size(); ++m_rowIndex) { |
+ if (areCellsEmpty(spanningPositions)) { |
+ GridSpan rowSpan = GridSpan(m_rowIndex, m_rowIndex); |
+ GridSpan columnSpan = GridSpan(m_columnIndex, m_columnIndex + spanningPositions - 1); |
+ OwnPtr<GridCoordinate> result = adoptPtr(new GridCoordinate(rowSpan, columnSpan)); |
+ // Advance the iterator to avoid an infinite loop where we would return the same grid area over and over. |
+ ++m_rowIndex; |
+ return result.release(); |
+ } |
+ } |
+ } else { |
+ for (; m_columnIndex < m_grid[0].size(); ++m_columnIndex) { |
+ if (areCellsEmpty(spanningPositions)) { |
+ GridSpan rowSpan = GridSpan(m_rowIndex, m_rowIndex + spanningPositions - 1); |
+ GridSpan columnSpan = GridSpan(m_columnIndex, m_columnIndex); |
+ OwnPtr<GridCoordinate> result = adoptPtr(new GridCoordinate(rowSpan, columnSpan)); |
+ // Advance the iterator to avoid an infinite loop where we would return the same grid area over and over. |
+ ++m_columnIndex; |
+ return result.release(); |
+ } |
} |
} |
+ |
return nullptr; |
} |
@@ -819,15 +853,15 @@ void RenderGrid::placeSpecifiedMajorAxisItemsOnGrid(const Vector<RenderBox*>& au |
for (size_t i = 0; i < autoGridItems.size(); ++i) { |
OwnPtr<GridSpan> majorAxisPositions = resolveGridPositionsFromStyle(autoGridItems[i], autoPlacementMajorAxisDirection()); |
GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAxisPositions->initialPositionIndex); |
- if (OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea()) { |
- insertItemIntoGrid(autoGridItems[i], emptyGridArea->rows.initialPositionIndex, emptyGridArea->columns.initialPositionIndex); |
+ if (OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea(majorAxisPositions->spanningPositions())) { |
+ insertItemIntoGrid(autoGridItems[i], *emptyGridArea); |
continue; |
} |
growGrid(autoPlacementMinorAxisDirection()); |
- OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea(); |
+ OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea(majorAxisPositions->spanningPositions()); |
ASSERT(emptyGridArea); |
- insertItemIntoGrid(autoGridItems[i], emptyGridArea->rows.initialPositionIndex, emptyGridArea->columns.initialPositionIndex); |
+ insertItemIntoGrid(autoGridItems[i], *emptyGridArea); |
} |
} |
@@ -841,19 +875,18 @@ void RenderGrid::placeAutoMajorAxisItemOnGrid(RenderBox* gridItem) |
{ |
OwnPtr<GridSpan> minorAxisPositions = resolveGridPositionsFromStyle(gridItem, autoPlacementMinorAxisDirection()); |
ASSERT(!resolveGridPositionsFromStyle(gridItem, autoPlacementMajorAxisDirection())); |
- size_t minorAxisIndex = 0; |
if (minorAxisPositions) { |
- minorAxisIndex = minorAxisPositions->initialPositionIndex; |
+ size_t minorAxisIndex = minorAxisPositions->initialPositionIndex; |
GridIterator iterator(m_grid, autoPlacementMinorAxisDirection(), minorAxisIndex); |
- if (OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea()) { |
- insertItemIntoGrid(gridItem, emptyGridArea->rows.initialPositionIndex, emptyGridArea->columns.initialPositionIndex); |
+ if (OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea(minorAxisPositions->spanningPositions())) { |
+ insertItemIntoGrid(gridItem, *emptyGridArea); |
return; |
} |
} else { |
const size_t endOfMajorAxis = (autoPlacementMajorAxisDirection() == ForColumns) ? gridColumnCount() : gridRowCount(); |
for (size_t majorAxisIndex = 0; majorAxisIndex < endOfMajorAxis; ++majorAxisIndex) { |
GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAxisIndex); |
- if (OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea()) { |
+ if (OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea(1)) { |
insertItemIntoGrid(gridItem, emptyGridArea->rows.initialPositionIndex, emptyGridArea->columns.initialPositionIndex); |
return; |
} |
@@ -861,10 +894,11 @@ void RenderGrid::placeAutoMajorAxisItemOnGrid(RenderBox* gridItem) |
} |
// We didn't find an empty grid area so we need to create an extra major axis line and insert our gridItem in it. |
- const size_t columnIndex = (autoPlacementMajorAxisDirection() == ForColumns) ? m_grid[0].size() : minorAxisIndex; |
- const size_t rowIndex = (autoPlacementMajorAxisDirection() == ForColumns) ? minorAxisIndex : m_grid.size(); |
+ GridSpan minorAxisSpan = minorAxisPositions ? *minorAxisPositions : GridSpan(0, 0); |
+ GridSpan columnSpan = (autoPlacementMajorAxisDirection() == ForColumns) ? GridSpan(m_grid[0].size(), m_grid[0].size()) : minorAxisSpan; |
+ GridSpan rowSpan = (autoPlacementMajorAxisDirection() == ForColumns) ? minorAxisSpan : GridSpan(m_grid.size(), m_grid.size()); |
growGrid(autoPlacementMajorAxisDirection()); |
- insertItemIntoGrid(gridItem, rowIndex, columnIndex); |
+ insertItemIntoGrid(gridItem, GridCoordinate(rowSpan, columnSpan)); |
} |
GridTrackSizingDirection RenderGrid::autoPlacementMajorAxisDirection() const |