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

Side by Side Diff: third_party/WebKit/Source/core/layout/Grid.cpp

Issue 2654533003: [css-grid] Move the track sizing algorithm to its own class (Closed)
Patch Set: Created 3 years, 11 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 unified diff | Download patch
OLDNEW
(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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698