Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #include "core/layout/Grid.h" | |
| 2 | |
| 3 #include "core/layout/LayoutGrid.h" | |
| 4 | |
| 5 namespace blink { | |
| 6 | |
| 7 Grid::Grid(const LayoutGrid* grid) : m_orderIterator(grid) {} | |
| 8 | |
| 9 size_t Grid::numTracks(GridTrackSizingDirection direction) const { | |
| 10 if (direction == ForRows) | |
| 11 return m_grid.size(); | |
| 12 return m_grid.size() ? m_grid[0].size() : 0; | |
| 13 } | |
| 14 | |
| 15 void Grid::ensureGridSize(size_t maximumRowSize, size_t maximumColumnSize) { | |
| 16 const size_t oldRowSize = numTracks(ForRows); | |
| 17 if (maximumRowSize > oldRowSize) { | |
| 18 m_grid.grow(maximumRowSize); | |
| 19 for (size_t row = oldRowSize; row < numTracks(ForRows); ++row) | |
| 20 m_grid[row].grow(numTracks(ForColumns)); | |
| 21 } | |
| 22 | |
| 23 if (maximumColumnSize > numTracks(ForColumns)) { | |
| 24 for (size_t row = 0; row < numTracks(ForRows); ++row) | |
| 25 m_grid[row].grow(maximumColumnSize); | |
| 26 } | |
| 27 } | |
| 28 | |
| 29 void Grid::insert(LayoutBox& child, const GridArea& area) { | |
| 30 DCHECK(area.rows.isTranslatedDefinite() && | |
| 31 area.columns.isTranslatedDefinite()); | |
| 32 ensureGridSize(area.rows.endLine(), area.columns.endLine()); | |
| 33 | |
| 34 for (const auto& row : area.rows) { | |
| 35 for (const auto& column : area.columns) | |
| 36 m_grid[row][column].append(&child); | |
| 37 } | |
| 38 | |
| 39 setGridItemArea(child, area); | |
| 40 } | |
| 41 | |
| 42 void Grid::setSmallestTracksStart(int rowStart, int columnStart) { | |
| 43 m_smallestRowStart = rowStart; | |
| 44 m_smallestColumnStart = columnStart; | |
| 45 } | |
| 46 | |
| 47 int Grid::smallestTrackStart(GridTrackSizingDirection direction) const { | |
| 48 return direction == ForRows ? m_smallestRowStart : m_smallestColumnStart; | |
| 49 } | |
| 50 | |
| 51 GridArea Grid::gridItemArea(const LayoutBox& item) const { | |
| 52 DCHECK(m_gridItemArea.contains(&item)); | |
| 53 return m_gridItemArea.get(&item); | |
| 54 } | |
| 55 | |
| 56 void Grid::setGridItemArea(const LayoutBox& item, GridArea area) { | |
| 57 m_gridItemArea.set(&item, area); | |
| 58 } | |
| 59 | |
| 60 size_t Grid::gridItemPaintOrder(const LayoutBox& item) const { | |
| 61 return m_gridItemsIndexesMap.get(&item); | |
|
Manuel Rego
2017/01/30 11:00:45
Some of these oneliner methods are implemented on
svillar
2017/01/30 11:28:28
I think I'm being consistent, this is not a one-li
| |
| 62 } | |
| 63 | |
| 64 void Grid::setGridItemPaintOrder(const LayoutBox& item, size_t order) { | |
| 65 m_gridItemsIndexesMap.set(&item, order); | |
| 66 } | |
| 67 | |
| 68 #if DCHECK_IS_ON() | |
| 69 bool Grid::hasAnyGridItemPaintOrder() const { | |
| 70 return !m_gridItemsIndexesMap.isEmpty(); | |
| 71 } | |
| 72 #endif | |
| 73 | |
| 74 void Grid::setAutoRepeatTracks(size_t autoRepeatRows, | |
| 75 size_t autoRepeatColumns) { | |
| 76 m_autoRepeatRows = autoRepeatRows; | |
| 77 m_autoRepeatColumns = autoRepeatColumns; | |
| 78 } | |
| 79 | |
| 80 size_t Grid::autoRepeatTracks(GridTrackSizingDirection direction) const { | |
| 81 return direction == ForRows ? m_autoRepeatRows : m_autoRepeatColumns; | |
| 82 } | |
| 83 | |
| 84 void Grid::setAutoRepeatEmptyColumns( | |
| 85 std::unique_ptr<OrderedTrackIndexSet> autoRepeatEmptyColumns) { | |
| 86 m_autoRepeatEmptyColumns = std::move(autoRepeatEmptyColumns); | |
| 87 } | |
| 88 | |
| 89 void Grid::setAutoRepeatEmptyRows( | |
| 90 std::unique_ptr<OrderedTrackIndexSet> autoRepeatEmptyRows) { | |
| 91 m_autoRepeatEmptyRows = std::move(autoRepeatEmptyRows); | |
| 92 } | |
| 93 | |
| 94 bool Grid::hasAutoRepeatEmptyTracks(GridTrackSizingDirection direction) const { | |
| 95 return direction == ForColumns ? !!m_autoRepeatEmptyColumns | |
| 96 : !!m_autoRepeatEmptyRows; | |
| 97 } | |
| 98 | |
| 99 bool Grid::isEmptyAutoRepeatTrack(GridTrackSizingDirection direction, | |
| 100 size_t line) const { | |
| 101 DCHECK(hasAutoRepeatEmptyTracks(direction)); | |
| 102 return autoRepeatEmptyTracks(direction)->contains(line); | |
| 103 } | |
| 104 | |
| 105 OrderedTrackIndexSet* Grid::autoRepeatEmptyTracks( | |
| 106 GridTrackSizingDirection direction) const { | |
| 107 DCHECK(hasAutoRepeatEmptyTracks(direction)); | |
| 108 return direction == ForColumns ? m_autoRepeatEmptyColumns.get() | |
| 109 : m_autoRepeatEmptyRows.get(); | |
| 110 } | |
| 111 | |
| 112 GridSpan Grid::gridItemSpan(const LayoutBox& gridItem, | |
| 113 GridTrackSizingDirection direction) const { | |
| 114 GridArea area = gridItemArea(gridItem); | |
| 115 return direction == ForColumns ? area.columns : area.rows; | |
| 116 } | |
| 117 | |
| 118 void Grid::setHasAnyOrthogonalGridItem(bool hasAnyOrthogonalGridItem) { | |
| 119 m_hasAnyOrthogonalGridItem = hasAnyOrthogonalGridItem; | |
| 120 } | |
| 121 | |
| 122 void Grid::setNeedsItemsPlacement(bool needsItemsPlacement) { | |
| 123 m_needsItemsPlacement = needsItemsPlacement; | |
| 124 | |
| 125 if (!needsItemsPlacement) { | |
| 126 m_grid.shrinkToFit(); | |
| 127 return; | |
| 128 } | |
| 129 | |
| 130 m_grid.resize(0); | |
| 131 m_gridItemArea.clear(); | |
| 132 m_gridItemsIndexesMap.clear(); | |
| 133 m_hasAnyOrthogonalGridItem = false; | |
| 134 m_smallestRowStart = 0; | |
| 135 m_smallestColumnStart = 0; | |
| 136 m_autoRepeatColumns = 0; | |
| 137 m_autoRepeatRows = 0; | |
| 138 m_autoRepeatEmptyColumns = nullptr; | |
| 139 m_autoRepeatEmptyRows = nullptr; | |
| 140 } | |
| 141 | |
| 142 GridIterator::GridIterator(const Grid& grid, | |
| 143 GridTrackSizingDirection direction, | |
| 144 size_t fixedTrackIndex, | |
| 145 size_t varyingTrackIndex) | |
| 146 : m_grid(grid.m_grid), | |
| 147 m_direction(direction), | |
| 148 m_rowIndex((direction == ForColumns) ? varyingTrackIndex | |
| 149 : fixedTrackIndex), | |
| 150 m_columnIndex((direction == ForColumns) ? fixedTrackIndex | |
| 151 : varyingTrackIndex), | |
| 152 m_childIndex(0) { | |
| 153 DCHECK(!m_grid.isEmpty()); | |
| 154 DCHECK(!m_grid[0].isEmpty()); | |
| 155 DCHECK(m_rowIndex < m_grid.size()); | |
| 156 DCHECK(m_columnIndex < m_grid[0].size()); | |
| 157 } | |
| 158 | |
| 159 LayoutBox* GridIterator::nextGridItem() { | |
| 160 DCHECK(!m_grid.isEmpty()); | |
| 161 DCHECK(!m_grid[0].isEmpty()); | |
| 162 | |
| 163 size_t& varyingTrackIndex = | |
| 164 (m_direction == ForColumns) ? m_rowIndex : m_columnIndex; | |
| 165 const size_t endOfVaryingTrackIndex = | |
| 166 (m_direction == ForColumns) ? m_grid.size() : m_grid[0].size(); | |
| 167 for (; varyingTrackIndex < endOfVaryingTrackIndex; ++varyingTrackIndex) { | |
| 168 const GridCell& children = m_grid[m_rowIndex][m_columnIndex]; | |
| 169 if (m_childIndex < children.size()) | |
| 170 return children[m_childIndex++]; | |
| 171 | |
| 172 m_childIndex = 0; | |
| 173 } | |
| 174 return nullptr; | |
| 175 } | |
| 176 | |
| 177 bool GridIterator::checkEmptyCells(size_t rowSpan, size_t columnSpan) const { | |
| 178 DCHECK(!m_grid.isEmpty()); | |
| 179 DCHECK(!m_grid[0].isEmpty()); | |
| 180 | |
| 181 // Ignore cells outside current grid as we will grow it later if needed. | |
| 182 size_t maxRows = std::min(m_rowIndex + rowSpan, m_grid.size()); | |
| 183 size_t maxColumns = std::min(m_columnIndex + columnSpan, m_grid[0].size()); | |
| 184 | |
| 185 // This adds a O(N^2) behavior that shouldn't be a big deal as we expect | |
| 186 // spanning areas to be small. | |
| 187 for (size_t row = m_rowIndex; row < maxRows; ++row) { | |
| 188 for (size_t column = m_columnIndex; column < maxColumns; ++column) { | |
| 189 const GridCell& children = m_grid[row][column]; | |
| 190 if (!children.isEmpty()) | |
| 191 return false; | |
| 192 } | |
| 193 } | |
| 194 | |
| 195 return true; | |
| 196 } | |
| 197 | |
| 198 std::unique_ptr<GridArea> GridIterator::nextEmptyGridArea( | |
| 199 size_t fixedTrackSpan, | |
| 200 size_t varyingTrackSpan) { | |
| 201 DCHECK(!m_grid.isEmpty()); | |
| 202 DCHECK(!m_grid[0].isEmpty()); | |
| 203 DCHECK(fixedTrackSpan >= 1 && varyingTrackSpan >= 1); | |
| 204 | |
| 205 size_t rowSpan = | |
| 206 (m_direction == ForColumns) ? varyingTrackSpan : fixedTrackSpan; | |
| 207 size_t columnSpan = | |
| 208 (m_direction == ForColumns) ? fixedTrackSpan : varyingTrackSpan; | |
| 209 | |
| 210 size_t& varyingTrackIndex = | |
| 211 (m_direction == ForColumns) ? m_rowIndex : m_columnIndex; | |
| 212 const size_t endOfVaryingTrackIndex = | |
| 213 (m_direction == ForColumns) ? m_grid.size() : m_grid[0].size(); | |
| 214 for (; varyingTrackIndex < endOfVaryingTrackIndex; ++varyingTrackIndex) { | |
| 215 if (checkEmptyCells(rowSpan, columnSpan)) { | |
| 216 std::unique_ptr<GridArea> result = WTF::wrapUnique( | |
| 217 new GridArea(GridSpan::translatedDefiniteGridSpan( | |
| 218 m_rowIndex, m_rowIndex + rowSpan), | |
| 219 GridSpan::translatedDefiniteGridSpan( | |
| 220 m_columnIndex, m_columnIndex + columnSpan))); | |
| 221 // Advance the iterator to avoid an infinite loop where we would return | |
| 222 // the same grid area over and over. | |
| 223 ++varyingTrackIndex; | |
| 224 return result; | |
| 225 } | |
| 226 } | |
| 227 return nullptr; | |
| 228 } | |
| 229 | |
| 230 } // namespace blink | |
| OLD | NEW |