| Index: Source/core/rendering/RenderGrid.cpp
|
| diff --git a/Source/core/rendering/RenderGrid.cpp b/Source/core/rendering/RenderGrid.cpp
|
| index 83059ac6bcbe342ba9848fdeb3416ab3463c5ccd..a1de68202177f4dafa8c7e86d0569ead6c56f4df 100644
|
| --- a/Source/core/rendering/RenderGrid.cpp
|
| +++ b/Source/core/rendering/RenderGrid.cpp
|
| @@ -122,16 +122,37 @@ public:
|
| return 0;
|
| }
|
|
|
| - PassOwnPtr<GridCoordinate> nextEmptyGridArea()
|
| + bool checkEmptyCells(size_t rowSpan, size_t columnSpan) const
|
| + {
|
| + // Ignore cells outside current grid as we will grow it later if needed.
|
| + size_t maxRows = std::min(m_rowIndex + rowSpan, m_grid.size());
|
| + size_t maxColumns = std::min(m_columnIndex + columnSpan, m_grid[0].size());
|
| +
|
| + // This adds a O(N^2) behavior that shouldn't be a big deal as we expect spanning areas to be small.
|
| + for (size_t row = m_rowIndex; row < maxRows; ++row) {
|
| + for (size_t column = m_columnIndex; column < maxColumns; ++column) {
|
| + const GridCell& children = m_grid[row][column];
|
| + if (!children.isEmpty())
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + return true;
|
| + }
|
| +
|
| + PassOwnPtr<GridCoordinate> nextEmptyGridArea(size_t fixedTrackSpan, size_t varyingTrackSpan)
|
| {
|
| ASSERT(!m_grid.isEmpty());
|
| + ASSERT(fixedTrackSpan >= 1 && varyingTrackSpan >= 1);
|
| +
|
| + size_t rowSpan = (m_direction == ForColumns) ? varyingTrackSpan : fixedTrackSpan;
|
| + size_t columnSpan = (m_direction == ForColumns) ? fixedTrackSpan : varyingTrackSpan;
|
|
|
| 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)));
|
| + if (checkEmptyCells(rowSpan, columnSpan)) {
|
| + OwnPtr<GridCoordinate> result = adoptPtr(new GridCoordinate(GridSpan(m_rowIndex, m_rowIndex + rowSpan - 1), GridSpan(m_columnIndex, m_columnIndex + columnSpan - 1)));
|
| // Advance the iterator to avoid an infinite loop where we would return the same grid area over and over.
|
| ++varyingTrackIndex;
|
| return result.release();
|
| @@ -846,24 +867,6 @@ void RenderGrid::populateExplicitGridAndOrderIterator()
|
| m_grid[i].grow(maximumColumnIndex);
|
| }
|
|
|
| -bool RenderGrid::checkEmptyCells(const GridCoordinate& coordinate) const
|
| -{
|
| - // Ignore cells outside current grid as we will grow it later if needed.
|
| - size_t maxRows = std::min(coordinate.rows.resolvedFinalPosition.next().toInt(), gridRowCount());
|
| - size_t maxColumns = std::min(coordinate.columns.resolvedFinalPosition.next().toInt(), gridColumnCount());
|
| -
|
| - // This adds a O(N^2) behavior that shouldn't be a big deal as we expect spanning areas to be small.
|
| - for (size_t row = coordinate.rows.resolvedInitialPosition.toInt(); row < maxRows; ++row) {
|
| - for (size_t column = coordinate.columns.resolvedInitialPosition.toInt(); column < maxColumns; ++column) {
|
| - const GridCell& children = m_grid[row][column];
|
| - if (!children.isEmpty())
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| PassOwnPtr<GridCoordinate> RenderGrid::createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(const RenderBox* gridItem, GridTrackSizingDirection specifiedDirection, const GridSpan& specifiedPositions) const
|
| {
|
| GridTrackSizingDirection crossDirection = specifiedDirection == ForColumns ? ForRows : ForColumns;
|
| @@ -872,30 +875,14 @@ PassOwnPtr<GridCoordinate> RenderGrid::createEmptyGridAreaAtSpecifiedPositionsOu
|
| return adoptPtr(new GridCoordinate(specifiedDirection == ForColumns ? crossDirectionPositions : specifiedPositions, specifiedDirection == ForColumns ? specifiedPositions : crossDirectionPositions));
|
| }
|
|
|
| -PassOwnPtr<GridCoordinate> RenderGrid::findEmptyGridAreaAtSpecifiedPositionsInsideGrid(const RenderBox* gridItem, GridTrackSizingDirection specifiedDirection, const GridSpan& specifiedPositions) const
|
| -{
|
| - GridTrackSizingDirection crossDirection = specifiedDirection == ForColumns ? ForRows : ForColumns;
|
| -
|
| - GridIterator iterator(m_grid, specifiedDirection, specifiedPositions.resolvedInitialPosition.toInt());
|
| - OwnPtr<GridCoordinate> emptyGridArea;
|
| - for (emptyGridArea = iterator.nextEmptyGridArea(); emptyGridArea; emptyGridArea = iterator.nextEmptyGridArea()) {
|
| - GridResolvedPosition crossDirectionInitialPositionIndex = crossDirection == ForColumns ? emptyGridArea->columns.resolvedInitialPosition : emptyGridArea->rows.resolvedInitialPosition;
|
| - GridSpan crossDirectionPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(*style(), *gridItem, crossDirection, crossDirectionInitialPositionIndex);
|
| -
|
| - emptyGridArea->rows = specifiedDirection == ForColumns ? crossDirectionPositions : specifiedPositions;
|
| - emptyGridArea->columns = specifiedDirection == ForColumns ? specifiedPositions : crossDirectionPositions;
|
| - if (checkEmptyCells(*emptyGridArea))
|
| - break;
|
| - }
|
| -
|
| - return emptyGridArea.release();
|
| -}
|
| -
|
| void RenderGrid::placeSpecifiedMajorAxisItemsOnGrid(const Vector<RenderBox*>& autoGridItems)
|
| {
|
| for (size_t i = 0; i < autoGridItems.size(); ++i) {
|
| OwnPtr<GridSpan> majorAxisPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *autoGridItems[i], autoPlacementMajorAxisDirection());
|
| - OwnPtr<GridCoordinate> emptyGridArea = findEmptyGridAreaAtSpecifiedPositionsInsideGrid(autoGridItems[i], autoPlacementMajorAxisDirection(), *majorAxisPositions);
|
| + GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(*style(), *autoGridItems[i], autoPlacementMinorAxisDirection(), GridResolvedPosition(0));
|
| +
|
| + GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAxisPositions->resolvedInitialPosition.toInt());
|
| + OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea(majorAxisPositions->integerSpan(), minorAxisPositions.integerSpan());
|
| if (!emptyGridArea)
|
| emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(autoGridItems[i], autoPlacementMajorAxisDirection(), *majorAxisPositions);
|
| insertItemIntoGrid(autoGridItems[i], *emptyGridArea);
|
| @@ -912,18 +899,20 @@ void RenderGrid::placeAutoMajorAxisItemOnGrid(RenderBox* gridItem)
|
| {
|
| OwnPtr<GridSpan> minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *gridItem, autoPlacementMinorAxisDirection());
|
| ASSERT(!GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *gridItem, autoPlacementMajorAxisDirection()));
|
| + GridSpan majorAxisPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(*style(), *gridItem, autoPlacementMajorAxisDirection(), GridResolvedPosition(0));
|
| OwnPtr<GridCoordinate> emptyGridArea;
|
| if (minorAxisPositions) {
|
| - emptyGridArea = findEmptyGridAreaAtSpecifiedPositionsInsideGrid(gridItem, autoPlacementMinorAxisDirection(), *minorAxisPositions);
|
| + GridIterator iterator(m_grid, autoPlacementMinorAxisDirection(), minorAxisPositions->resolvedInitialPosition.toInt());
|
| + emptyGridArea = iterator.nextEmptyGridArea(minorAxisPositions->integerSpan(), majorAxisPositions.integerSpan());
|
| if (!emptyGridArea)
|
| emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(gridItem, autoPlacementMinorAxisDirection(), *minorAxisPositions);
|
| } else {
|
| + GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(*style(), *gridItem, autoPlacementMinorAxisDirection(), GridResolvedPosition(0));
|
| +
|
| const size_t endOfMajorAxis = (autoPlacementMajorAxisDirection() == ForColumns) ? gridColumnCount() : gridRowCount();
|
| for (size_t majorAxisIndex = 0; majorAxisIndex < endOfMajorAxis; ++majorAxisIndex) {
|
| - // We need to resolve the position for every different index as the number of cells might vary depending on it.
|
| - // This will happen when we have "span <custom-indent>", which has a different resolution based on the position.
|
| - GridSpan majorAxisPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(*style(), *gridItem, autoPlacementMajorAxisDirection(), majorAxisIndex);
|
| - emptyGridArea = findEmptyGridAreaAtSpecifiedPositionsInsideGrid(gridItem, autoPlacementMajorAxisDirection(), majorAxisPositions);
|
| + GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAxisIndex);
|
| + emptyGridArea = iterator.nextEmptyGridArea(majorAxisPositions.integerSpan(), minorAxisPositions.integerSpan());
|
|
|
| if (emptyGridArea) {
|
| // Check that it fits in the minor axis direction, as we shouldn't grow in that direction here (it was already managed in populateExplicitGridAndOrderIterator()).
|
| @@ -938,10 +927,8 @@ void RenderGrid::placeAutoMajorAxisItemOnGrid(RenderBox* gridItem)
|
| }
|
| }
|
|
|
| - if (!emptyGridArea) {
|
| - GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(*style(), *gridItem, autoPlacementMinorAxisDirection(), GridResolvedPosition(0));
|
| + if (!emptyGridArea)
|
| emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(gridItem, autoPlacementMinorAxisDirection(), minorAxisPositions);
|
| - }
|
| }
|
|
|
| insertItemIntoGrid(gridItem, *emptyGridArea);
|
|
|