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

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

Issue 2654533003: [css-grid] Move the track sizing algorithm to its own class (Closed)
Patch Set: Win build fix Created 3 years, 10 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
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutGrid.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Apple Inc. All rights reserved. 2 * Copyright (C) 2011 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 21 matching lines...) Expand all
32 #include "core/paint/PaintLayer.h" 32 #include "core/paint/PaintLayer.h"
33 #include "core/style/ComputedStyle.h" 33 #include "core/style/ComputedStyle.h"
34 #include "core/style/GridArea.h" 34 #include "core/style/GridArea.h"
35 #include "platform/LengthFunctions.h" 35 #include "platform/LengthFunctions.h"
36 #include "wtf/PtrUtil.h" 36 #include "wtf/PtrUtil.h"
37 #include <algorithm> 37 #include <algorithm>
38 #include <memory> 38 #include <memory>
39 39
40 namespace blink { 40 namespace blink {
41 41
42 static const int infinity = -1;
43
44 class GridItemWithSpan;
45
46 size_t LayoutGrid::Grid::numTracks(GridTrackSizingDirection direction) const {
47 if (direction == ForRows)
48 return m_grid.size();
49 return m_grid.size() ? m_grid[0].size() : 0;
50 }
51
52 void LayoutGrid::Grid::ensureGridSize(size_t maximumRowSize,
53 size_t maximumColumnSize) {
54 DCHECK(maximumRowSize <= kGridMaxTracks * 2);
55 DCHECK(maximumColumnSize <= kGridMaxTracks * 2);
56 const size_t oldRowSize = numTracks(ForRows);
57 if (maximumRowSize > oldRowSize) {
58 m_grid.grow(maximumRowSize);
59 for (size_t row = oldRowSize; row < numTracks(ForRows); ++row)
60 m_grid[row].grow(numTracks(ForColumns));
61 }
62
63 if (maximumColumnSize > numTracks(ForColumns)) {
64 for (size_t row = 0; row < numTracks(ForRows); ++row)
65 m_grid[row].grow(maximumColumnSize);
66 }
67 }
68
69 void LayoutGrid::Grid::insert(LayoutBox& child, const GridArea& area) {
70 DCHECK(area.rows.isTranslatedDefinite() &&
71 area.columns.isTranslatedDefinite());
72 ensureGridSize(area.rows.endLine(), area.columns.endLine());
73
74 for (const auto& row : area.rows) {
75 for (const auto& column : area.columns)
76 m_grid[row][column].push_back(&child);
77 }
78
79 setGridItemArea(child, area);
80 }
81
82 void LayoutGrid::Grid::setSmallestTracksStart(int rowStart, int columnStart) {
83 m_smallestRowStart = rowStart;
84 m_smallestColumnStart = columnStart;
85 }
86
87 int LayoutGrid::Grid::smallestTrackStart(
88 GridTrackSizingDirection direction) const {
89 return direction == ForRows ? m_smallestRowStart : m_smallestColumnStart;
90 }
91
92 GridArea LayoutGrid::Grid::gridItemArea(const LayoutBox& item) const {
93 DCHECK(m_gridItemArea.contains(&item));
94 return m_gridItemArea.get(&item);
95 }
96
97 void LayoutGrid::Grid::setGridItemArea(const LayoutBox& item, GridArea area) {
98 m_gridItemArea.set(&item, area);
99 }
100
101 size_t LayoutGrid::Grid::gridItemPaintOrder(const LayoutBox& item) const {
102 return m_gridItemsIndexesMap.get(&item);
103 }
104
105 void LayoutGrid::Grid::setGridItemPaintOrder(const LayoutBox& item,
106 size_t order) {
107 m_gridItemsIndexesMap.set(&item, order);
108 }
109
110 #if DCHECK_IS_ON()
111 bool LayoutGrid::Grid::hasAnyGridItemPaintOrder() const {
112 return !m_gridItemsIndexesMap.isEmpty();
113 }
114 #endif
115
116 void LayoutGrid::Grid::setAutoRepeatTracks(size_t autoRepeatRows,
117 size_t autoRepeatColumns) {
118 m_autoRepeatRows = autoRepeatRows;
119 m_autoRepeatColumns = autoRepeatColumns;
120 }
121
122 size_t LayoutGrid::Grid::autoRepeatTracks(
123 GridTrackSizingDirection direction) const {
124 return direction == ForRows ? m_autoRepeatRows : m_autoRepeatColumns;
125 }
126
127 void LayoutGrid::Grid::setAutoRepeatEmptyColumns(
128 std::unique_ptr<OrderedTrackIndexSet> autoRepeatEmptyColumns) {
129 m_autoRepeatEmptyColumns = std::move(autoRepeatEmptyColumns);
130 }
131
132 void LayoutGrid::Grid::setAutoRepeatEmptyRows(
133 std::unique_ptr<OrderedTrackIndexSet> autoRepeatEmptyRows) {
134 m_autoRepeatEmptyRows = std::move(autoRepeatEmptyRows);
135 }
136
137 bool LayoutGrid::Grid::hasAutoRepeatEmptyTracks(
138 GridTrackSizingDirection direction) const {
139 return direction == ForColumns ? !!m_autoRepeatEmptyColumns
140 : !!m_autoRepeatEmptyRows;
141 }
142
143 bool LayoutGrid::Grid::isEmptyAutoRepeatTrack(
144 GridTrackSizingDirection direction,
145 size_t line) const {
146 DCHECK(hasAutoRepeatEmptyTracks(direction));
147 return autoRepeatEmptyTracks(direction)->contains(line);
148 }
149
150 LayoutGrid::OrderedTrackIndexSet* LayoutGrid::Grid::autoRepeatEmptyTracks(
151 GridTrackSizingDirection direction) const {
152 DCHECK(hasAutoRepeatEmptyTracks(direction));
153 return direction == ForColumns ? m_autoRepeatEmptyColumns.get()
154 : m_autoRepeatEmptyRows.get();
155 }
156
157 GridSpan LayoutGrid::Grid::gridItemSpan(
158 const LayoutBox& gridItem,
159 GridTrackSizingDirection direction) const {
160 GridArea area = gridItemArea(gridItem);
161 return direction == ForColumns ? area.columns : area.rows;
162 }
163
164 void LayoutGrid::Grid::setHasAnyOrthogonalGridItem(
165 bool hasAnyOrthogonalGridItem) {
166 m_hasAnyOrthogonalGridItem = hasAnyOrthogonalGridItem;
167 }
168
169 void LayoutGrid::Grid::setNeedsItemsPlacement(bool needsItemsPlacement) {
170 m_needsItemsPlacement = needsItemsPlacement;
171
172 if (!needsItemsPlacement) {
173 m_grid.shrinkToFit();
174 return;
175 }
176
177 m_grid.resize(0);
178 m_gridItemArea.clear();
179 m_gridItemsIndexesMap.clear();
180 m_hasAnyOrthogonalGridItem = false;
181 m_smallestRowStart = 0;
182 m_smallestColumnStart = 0;
183 m_autoRepeatColumns = 0;
184 m_autoRepeatRows = 0;
185 m_autoRepeatEmptyColumns = nullptr;
186 m_autoRepeatEmptyRows = nullptr;
187 }
188
189 class GridTrack {
190 public:
191 GridTrack() : m_infinitelyGrowable(false) {}
192
193 LayoutUnit baseSize() const {
194 DCHECK(isGrowthLimitBiggerThanBaseSize());
195 return m_baseSize;
196 }
197
198 LayoutUnit growthLimit() const {
199 DCHECK(isGrowthLimitBiggerThanBaseSize());
200 DCHECK(!m_growthLimitCap || m_growthLimitCap.value() >= m_growthLimit ||
201 m_baseSize >= m_growthLimitCap.value());
202 return m_growthLimit;
203 }
204
205 void setBaseSize(LayoutUnit baseSize) {
206 m_baseSize = baseSize;
207 ensureGrowthLimitIsBiggerThanBaseSize();
208 }
209
210 void setGrowthLimit(LayoutUnit growthLimit) {
211 m_growthLimit =
212 growthLimit == infinity
213 ? growthLimit
214 : std::min(growthLimit, m_growthLimitCap.value_or(growthLimit));
215 ensureGrowthLimitIsBiggerThanBaseSize();
216 }
217
218 bool infiniteGrowthPotential() const {
219 return growthLimitIsInfinite() || m_infinitelyGrowable;
220 }
221
222 LayoutUnit plannedSize() const { return m_plannedSize; }
223
224 void setPlannedSize(const LayoutUnit& plannedSize) {
225 ASSERT(plannedSize >= 0 || plannedSize == infinity);
226 m_plannedSize = plannedSize;
227 }
228
229 LayoutUnit sizeDuringDistribution() const { return m_sizeDuringDistribution; }
230
231 void setSizeDuringDistribution(const LayoutUnit& sizeDuringDistribution) {
232 DCHECK_GE(sizeDuringDistribution, 0);
233 DCHECK(growthLimitIsInfinite() || growthLimit() >= sizeDuringDistribution);
234 m_sizeDuringDistribution = sizeDuringDistribution;
235 }
236
237 void growSizeDuringDistribution(const LayoutUnit& sizeDuringDistribution) {
238 DCHECK_GE(sizeDuringDistribution, 0);
239 m_sizeDuringDistribution += sizeDuringDistribution;
240 }
241
242 bool infinitelyGrowable() const { return m_infinitelyGrowable; }
243 void setInfinitelyGrowable(bool infinitelyGrowable) {
244 m_infinitelyGrowable = infinitelyGrowable;
245 }
246
247 void setGrowthLimitCap(Optional<LayoutUnit> growthLimitCap) {
248 DCHECK(!growthLimitCap || *growthLimitCap >= 0);
249 m_growthLimitCap = growthLimitCap;
250 }
251
252 Optional<LayoutUnit> growthLimitCap() const { return m_growthLimitCap; }
253
254 private:
255 bool growthLimitIsInfinite() const { return m_growthLimit == infinity; }
256 bool isGrowthLimitBiggerThanBaseSize() const {
257 return growthLimitIsInfinite() || m_growthLimit >= m_baseSize;
258 }
259
260 void ensureGrowthLimitIsBiggerThanBaseSize() {
261 if (m_growthLimit != infinity && m_growthLimit < m_baseSize)
262 m_growthLimit = m_baseSize;
263 }
264
265 LayoutUnit m_baseSize;
266 LayoutUnit m_growthLimit;
267 LayoutUnit m_plannedSize;
268 LayoutUnit m_sizeDuringDistribution;
269 Optional<LayoutUnit> m_growthLimitCap;
270 bool m_infinitelyGrowable;
271 };
272
273 struct ContentAlignmentData { 42 struct ContentAlignmentData {
274 STACK_ALLOCATED(); 43 STACK_ALLOCATED();
275 44
276 public: 45 public:
277 ContentAlignmentData(){}; 46 ContentAlignmentData(){};
278 ContentAlignmentData(LayoutUnit position, LayoutUnit distribution) 47 ContentAlignmentData(LayoutUnit position, LayoutUnit distribution)
279 : positionOffset(position), distributionOffset(distribution) {} 48 : positionOffset(position), distributionOffset(distribution) {}
280 49
281 bool isValid() { return positionOffset >= 0 && distributionOffset >= 0; } 50 bool isValid() { return positionOffset >= 0 && distributionOffset >= 0; }
282 51
283 LayoutUnit positionOffset = LayoutUnit(-1); 52 LayoutUnit positionOffset = LayoutUnit(-1);
284 LayoutUnit distributionOffset = LayoutUnit(-1); 53 LayoutUnit distributionOffset = LayoutUnit(-1);
285 }; 54 };
286 55
287 enum TrackSizeRestriction { 56 enum TrackSizeRestriction {
288 AllowInfinity, 57 AllowInfinity,
289 ForbidInfinity, 58 ForbidInfinity,
290 }; 59 };
291 60
292 class LayoutGrid::GridIterator { 61 LayoutGrid::LayoutGrid(Element* element)
293 WTF_MAKE_NONCOPYABLE(GridIterator); 62 : LayoutBlock(element), m_grid(this), m_trackSizingAlgorithm(this, m_grid) {
294
295 public:
296 // |direction| is the direction that is fixed to |fixedTrackIndex| so e.g
297 // GridIterator(m_grid, ForColumns, 1) will walk over the rows of the 2nd
298 // column.
299 GridIterator(const Grid& grid,
300 GridTrackSizingDirection direction,
301 size_t fixedTrackIndex,
302 size_t varyingTrackIndex = 0)
303 : m_grid(grid.m_grid),
304 m_direction(direction),
305 m_rowIndex((direction == ForColumns) ? varyingTrackIndex
306 : fixedTrackIndex),
307 m_columnIndex((direction == ForColumns) ? fixedTrackIndex
308 : varyingTrackIndex),
309 m_childIndex(0) {
310 DCHECK(!m_grid.isEmpty());
311 DCHECK(!m_grid[0].isEmpty());
312 DCHECK(m_rowIndex < m_grid.size());
313 DCHECK(m_columnIndex < m_grid[0].size());
314 }
315
316 LayoutBox* nextGridItem() {
317 DCHECK(!m_grid.isEmpty());
318 DCHECK(!m_grid[0].isEmpty());
319
320 size_t& varyingTrackIndex =
321 (m_direction == ForColumns) ? m_rowIndex : m_columnIndex;
322 const size_t endOfVaryingTrackIndex =
323 (m_direction == ForColumns) ? m_grid.size() : m_grid[0].size();
324 for (; varyingTrackIndex < endOfVaryingTrackIndex; ++varyingTrackIndex) {
325 const GridCell& children = m_grid[m_rowIndex][m_columnIndex];
326 if (m_childIndex < children.size())
327 return children[m_childIndex++];
328
329 m_childIndex = 0;
330 }
331 return nullptr;
332 }
333
334 bool checkEmptyCells(size_t rowSpan, size_t columnSpan) const {
335 DCHECK(!m_grid.isEmpty());
336 DCHECK(!m_grid[0].isEmpty());
337
338 // Ignore cells outside current grid as we will grow it later if needed.
339 size_t maxRows = std::min(m_rowIndex + rowSpan, m_grid.size());
340 size_t maxColumns = std::min(m_columnIndex + columnSpan, m_grid[0].size());
341
342 // This adds a O(N^2) behavior that shouldn't be a big deal as we expect
343 // spanning areas to be small.
344 for (size_t row = m_rowIndex; row < maxRows; ++row) {
345 for (size_t column = m_columnIndex; column < maxColumns; ++column) {
346 const GridCell& children = m_grid[row][column];
347 if (!children.isEmpty())
348 return false;
349 }
350 }
351
352 return true;
353 }
354
355 std::unique_ptr<GridArea> nextEmptyGridArea(size_t fixedTrackSpan,
356 size_t varyingTrackSpan) {
357 DCHECK(!m_grid.isEmpty());
358 DCHECK(!m_grid[0].isEmpty());
359 ASSERT(fixedTrackSpan >= 1 && varyingTrackSpan >= 1);
360
361 size_t rowSpan =
362 (m_direction == ForColumns) ? varyingTrackSpan : fixedTrackSpan;
363 size_t columnSpan =
364 (m_direction == ForColumns) ? fixedTrackSpan : varyingTrackSpan;
365
366 size_t& varyingTrackIndex =
367 (m_direction == ForColumns) ? m_rowIndex : m_columnIndex;
368 const size_t endOfVaryingTrackIndex =
369 (m_direction == ForColumns) ? m_grid.size() : m_grid[0].size();
370 for (; varyingTrackIndex < endOfVaryingTrackIndex; ++varyingTrackIndex) {
371 if (checkEmptyCells(rowSpan, columnSpan)) {
372 std::unique_ptr<GridArea> result = WTF::wrapUnique(
373 new GridArea(GridSpan::translatedDefiniteGridSpan(
374 m_rowIndex, m_rowIndex + rowSpan),
375 GridSpan::translatedDefiniteGridSpan(
376 m_columnIndex, m_columnIndex + columnSpan)));
377 // Advance the iterator to avoid an infinite loop where we would return
378 // the same grid area over and over.
379 ++varyingTrackIndex;
380 return result;
381 }
382 }
383 return nullptr;
384 }
385
386 private:
387 const GridAsMatrix& m_grid;
388 GridTrackSizingDirection m_direction;
389 size_t m_rowIndex;
390 size_t m_columnIndex;
391 size_t m_childIndex;
392 };
393
394 struct LayoutGrid::GridSizingData {
395 WTF_MAKE_NONCOPYABLE(GridSizingData);
396 STACK_ALLOCATED();
397
398 public:
399 GridSizingData(size_t gridColumnCount, size_t gridRowCount, Grid& grid)
400 : columnTracks(gridColumnCount), rowTracks(gridRowCount), m_grid(grid) {}
401
402 Vector<GridTrack> columnTracks;
403 Vector<GridTrack> rowTracks;
404 Vector<size_t> contentSizedTracksIndex;
405
406 // Performance optimization: hold onto these Vectors until the end of Layout
407 // to avoid repeated malloc / free.
408 Vector<GridTrack*> filteredTracks;
409 Vector<GridItemWithSpan> itemsSortedByIncreasingSpan;
410 Vector<GridTrack*> growBeyondGrowthLimitsTracks;
411
412 LayoutUnit& freeSpace(GridTrackSizingDirection direction) {
413 return direction == ForColumns ? freeSpaceForColumns : freeSpaceForRows;
414 }
415
416 LayoutUnit availableSpace() const { return m_availableSpace; }
417 void setAvailableSpace(LayoutUnit availableSpace) {
418 m_availableSpace = availableSpace;
419 }
420
421 SizingOperation sizingOperation{TrackSizing};
422 enum SizingState {
423 ColumnSizingFirstIteration,
424 RowSizingFirstIteration,
425 ColumnSizingSecondIteration,
426 RowSizingSecondIteration
427 };
428 SizingState sizingState{ColumnSizingFirstIteration};
429 void nextState() {
430 switch (sizingState) {
431 case ColumnSizingFirstIteration:
432 sizingState = RowSizingFirstIteration;
433 return;
434 case RowSizingFirstIteration:
435 sizingState = ColumnSizingSecondIteration;
436 return;
437 case ColumnSizingSecondIteration:
438 sizingState = RowSizingSecondIteration;
439 return;
440 case RowSizingSecondIteration:
441 sizingState = ColumnSizingFirstIteration;
442 return;
443 }
444 NOTREACHED();
445 sizingState = ColumnSizingFirstIteration;
446 }
447 bool isValidTransition(GridTrackSizingDirection direction) const {
448 switch (sizingState) {
449 case ColumnSizingFirstIteration:
450 case ColumnSizingSecondIteration:
451 return direction == ForColumns;
452 case RowSizingFirstIteration:
453 case RowSizingSecondIteration:
454 return direction == ForRows;
455 }
456 NOTREACHED();
457 return false;
458 }
459
460 Grid& grid() const { return m_grid; }
461
462 private:
463 LayoutUnit freeSpaceForColumns{};
464 LayoutUnit freeSpaceForRows{};
465 // No need to store one per direction as it will be only used for computations
466 // during each axis track sizing. It's cached here because we need it to
467 // compute relative sizes.
468 LayoutUnit m_availableSpace;
469
470 Grid& m_grid;
471 };
472
473 struct GridItemsSpanGroupRange {
474 Vector<GridItemWithSpan>::iterator rangeStart;
475 Vector<GridItemWithSpan>::iterator rangeEnd;
476 };
477
478 LayoutGrid::LayoutGrid(Element* element) : LayoutBlock(element), m_grid(this) {
479 ASSERT(!childrenInline()); 63 ASSERT(!childrenInline());
480 if (!isAnonymous()) 64 if (!isAnonymous())
481 UseCounter::count(document(), UseCounter::CSSGridLayout); 65 UseCounter::count(document(), UseCounter::CSSGridLayout);
482 } 66 }
483 67
484 LayoutGrid::~LayoutGrid() {} 68 LayoutGrid::~LayoutGrid() {}
485 69
486 LayoutGrid* LayoutGrid::createAnonymous(Document* document) { 70 LayoutGrid* LayoutGrid::createAnonymous(Document* document) {
487 LayoutGrid* layoutGrid = new LayoutGrid(nullptr); 71 LayoutGrid* layoutGrid = new LayoutGrid(nullptr);
488 layoutGrid->setDocumentForAnonymous(document); 72 layoutGrid->setDocumentForAnonymous(document);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 oldStyle.gridAutoRepeatRows().size() != 124 oldStyle.gridAutoRepeatRows().size() !=
541 styleRef().gridAutoRepeatRows().size(); 125 styleRef().gridAutoRepeatRows().size();
542 } 126 }
543 127
544 bool LayoutGrid::namedGridLinesDefinitionDidChange( 128 bool LayoutGrid::namedGridLinesDefinitionDidChange(
545 const ComputedStyle& oldStyle) const { 129 const ComputedStyle& oldStyle) const {
546 return oldStyle.namedGridRowLines() != styleRef().namedGridRowLines() || 130 return oldStyle.namedGridRowLines() != styleRef().namedGridRowLines() ||
547 oldStyle.namedGridColumnLines() != styleRef().namedGridColumnLines(); 131 oldStyle.namedGridColumnLines() != styleRef().namedGridColumnLines();
548 } 132 }
549 133
550 LayoutUnit LayoutGrid::computeTrackBasedLogicalHeight( 134 LayoutUnit LayoutGrid::computeTrackBasedLogicalHeight() const {
551 const GridSizingData& sizingData) const {
552 LayoutUnit logicalHeight; 135 LayoutUnit logicalHeight;
553 136
554 for (const auto& row : sizingData.rowTracks) 137 const Vector<GridTrack>& allRows = m_trackSizingAlgorithm.tracks(ForRows);
138 for (const auto& row : allRows)
555 logicalHeight += row.baseSize(); 139 logicalHeight += row.baseSize();
556 140
557 logicalHeight += 141 logicalHeight += guttersSize(m_grid, ForRows, 0, allRows.size(), TrackSizing);
558 guttersSize(sizingData.grid(), ForRows, 0, sizingData.rowTracks.size(),
559 sizingData.sizingOperation);
560 142
561 return logicalHeight; 143 return logicalHeight;
562 } 144 }
563 145
564 void LayoutGrid::computeTrackSizesForDefiniteSize( 146 void LayoutGrid::computeTrackSizesForDefiniteSize(
565 GridTrackSizingDirection direction, 147 GridTrackSizingDirection direction,
566 GridSizingData& sizingData, 148 LayoutUnit availableSpace) {
567 LayoutUnit availableSpace) const { 149 LayoutUnit freeSpace =
568 DCHECK(sizingData.isValidTransition(direction)); 150 availableSpace - guttersSize(m_grid, direction, 0,
569 sizingData.setAvailableSpace(availableSpace); 151 m_grid.numTracks(direction), TrackSizing);
570 sizingData.freeSpace(direction) = 152 m_trackSizingAlgorithm.setup(direction, numTracks(direction, m_grid),
571 availableSpace - guttersSize(sizingData.grid(), direction, 0, 153 TrackSizing, availableSpace, freeSpace);
572 sizingData.grid().numTracks(direction), 154 m_trackSizingAlgorithm.run();
573 sizingData.sizingOperation);
574 sizingData.sizingOperation = TrackSizing;
575 155
576 LayoutUnit baseSizes, growthLimits; 156 #if DCHECK_IS_ON()
577 computeUsedBreadthOfGridTracks(direction, sizingData, baseSizes, 157 DCHECK(m_trackSizingAlgorithm.tracksAreWiderThanMinTrackBreadth());
578 growthLimits); 158 #endif
579 ASSERT(tracksAreWiderThanMinTrackBreadth(direction, sizingData));
580 sizingData.nextState();
581 } 159 }
582 160
583 void LayoutGrid::repeatTracksSizingIfNeeded(GridSizingData& sizingData, 161 void LayoutGrid::repeatTracksSizingIfNeeded(LayoutUnit availableSpaceForColumns,
584 LayoutUnit availableSpaceForColumns,
585 LayoutUnit availableSpaceForRows) { 162 LayoutUnit availableSpaceForRows) {
586 DCHECK(sizingData.sizingState > GridSizingData::RowSizingFirstIteration);
587
588 // In orthogonal flow cases column track's size is determined by using the 163 // In orthogonal flow cases column track's size is determined by using the
589 // computed row track's size, which it was estimated during the first cycle of 164 // computed row track's size, which it was estimated during the first cycle of
590 // the sizing algorithm. 165 // the sizing algorithm.
591 // Hence we need to repeat computeUsedBreadthOfGridTracks for both, columns 166 // Hence we need to repeat computeUsedBreadthOfGridTracks for both, columns
592 // and rows, to determine the final values. 167 // and rows, to determine the final values.
593 // TODO (lajava): orthogonal flows is just one of the cases which may require 168 // TODO (lajava): orthogonal flows is just one of the cases which may require
594 // a new cycle of the sizing algorithm; there may be more. In addition, not 169 // a new cycle of the sizing algorithm; there may be more. In addition, not
595 // all the cases with orthogonal flows require this extra cycle; we need a 170 // all the cases with orthogonal flows require this extra cycle; we need a
596 // more specific condition to detect whether child's min-content contribution 171 // more specific condition to detect whether child's min-content contribution
597 // has changed or not. 172 // has changed or not.
598 if (sizingData.grid().hasAnyOrthogonalGridItem()) { 173 if (m_grid.hasAnyOrthogonalGridItem()) {
599 computeTrackSizesForDefiniteSize(ForColumns, sizingData, 174 computeTrackSizesForDefiniteSize(ForColumns, availableSpaceForColumns);
600 availableSpaceForColumns); 175 computeTrackSizesForDefiniteSize(ForRows, availableSpaceForRows);
601 computeTrackSizesForDefiniteSize(ForRows, sizingData,
602 availableSpaceForRows);
603 } 176 }
604 } 177 }
605 178
606 void LayoutGrid::layoutBlock(bool relayoutChildren) { 179 void LayoutGrid::layoutBlock(bool relayoutChildren) {
607 ASSERT(needsLayout()); 180 ASSERT(needsLayout());
608 181
609 // We cannot perform a simplifiedLayout() on a dirty grid that 182 // We cannot perform a simplifiedLayout() on a dirty grid that
610 // has positioned items to be laid out. 183 // has positioned items to be laid out.
611 if (!relayoutChildren && 184 if (!relayoutChildren &&
612 (!m_grid.needsItemsPlacement() || !posChildNeedsLayout()) && 185 (!m_grid.needsItemsPlacement() || !posChildNeedsLayout()) &&
(...skipping 24 matching lines...) Expand all
637 } 210 }
638 } 211 }
639 212
640 updateLogicalWidth(); 213 updateLogicalWidth();
641 m_hasDefiniteLogicalHeight = hasDefiniteLogicalHeight(); 214 m_hasDefiniteLogicalHeight = hasDefiniteLogicalHeight();
642 215
643 TextAutosizer::LayoutScope textAutosizerLayoutScope(this, &layoutScope); 216 TextAutosizer::LayoutScope textAutosizerLayoutScope(this, &layoutScope);
644 217
645 placeItemsOnGrid(m_grid, TrackSizing); 218 placeItemsOnGrid(m_grid, TrackSizing);
646 219
647 GridSizingData sizingData(numTracks(ForColumns, m_grid),
648 numTracks(ForRows, m_grid), m_grid);
649
650 // 1- First, the track sizing algorithm is used to resolve the sizes of the 220 // 1- First, the track sizing algorithm is used to resolve the sizes of the
651 // grid columns. 221 // grid columns.
652 // At this point the logical width is always definite as the above call to 222 // At this point the logical width is always definite as the above call to
653 // updateLogicalWidth() properly resolves intrinsic sizes. We cannot do the 223 // updateLogicalWidth() properly resolves intrinsic sizes. We cannot do the
654 // same for heights though because many code paths inside 224 // same for heights though because many code paths inside
655 // updateLogicalHeight() require a previous call to setLogicalHeight() to 225 // updateLogicalHeight() require a previous call to setLogicalHeight() to
656 // resolve heights properly (like for positioned items for example). 226 // resolve heights properly (like for positioned items for example).
657 LayoutUnit availableSpaceForColumns = availableLogicalWidth(); 227 LayoutUnit availableSpaceForColumns = availableLogicalWidth();
658 computeTrackSizesForDefiniteSize(ForColumns, sizingData, 228 computeTrackSizesForDefiniteSize(ForColumns, availableSpaceForColumns);
659 availableSpaceForColumns);
660 229
661 // 2- Next, the track sizing algorithm resolves the sizes of the grid rows, 230 // 2- Next, the track sizing algorithm resolves the sizes of the grid rows,
662 // using the grid column sizes calculated in the previous step. 231 // using the grid column sizes calculated in the previous step.
663 if (cachedHasDefiniteLogicalHeight()) { 232 if (cachedHasDefiniteLogicalHeight()) {
664 computeTrackSizesForDefiniteSize( 233 computeTrackSizesForDefiniteSize(
665 ForRows, sizingData, 234 ForRows, availableLogicalHeight(ExcludeMarginBorderPadding));
666 availableLogicalHeight(ExcludeMarginBorderPadding));
667 } else { 235 } else {
668 computeTrackSizesForIndefiniteSize( 236 computeTrackSizesForIndefiniteSize(m_trackSizingAlgorithm, ForRows,
669 ForRows, sizingData, m_minContentHeight, m_maxContentHeight); 237 m_grid, m_minContentHeight,
670 sizingData.nextState(); 238 m_maxContentHeight);
671 sizingData.sizingOperation = TrackSizing;
672 } 239 }
673 LayoutUnit trackBasedLogicalHeight = 240 LayoutUnit trackBasedLogicalHeight = computeTrackBasedLogicalHeight() +
674 computeTrackBasedLogicalHeight(sizingData) + 241 borderAndPaddingLogicalHeight() +
675 borderAndPaddingLogicalHeight() + scrollbarLogicalHeight(); 242 scrollbarLogicalHeight();
676 setLogicalHeight(trackBasedLogicalHeight); 243 setLogicalHeight(trackBasedLogicalHeight);
677 244
678 LayoutUnit oldClientAfterEdge = clientLogicalBottom(); 245 LayoutUnit oldClientAfterEdge = clientLogicalBottom();
679 updateLogicalHeight(); 246 updateLogicalHeight();
680 247
681 // Once grid's indefinite height is resolved, we can compute the 248 // Once grid's indefinite height is resolved, we can compute the
682 // available free space for Content Alignment. 249 // available free space for Content Alignment.
683 if (!cachedHasDefiniteLogicalHeight()) 250 if (!cachedHasDefiniteLogicalHeight()) {
684 sizingData.freeSpace(ForRows) = logicalHeight() - trackBasedLogicalHeight; 251 m_trackSizingAlgorithm.freeSpace(ForRows) =
252 logicalHeight() - trackBasedLogicalHeight;
253 }
685 254
686 // 3- If the min-content contribution of any grid items have changed based 255 // 3- If the min-content contribution of any grid items have changed based
687 // on the row sizes calculated in step 2, steps 1 and 2 are repeated with 256 // on the row sizes calculated in step 2, steps 1 and 2 are repeated with
688 // the new min-content contribution (once only). 257 // the new min-content contribution (once only).
689 repeatTracksSizingIfNeeded(sizingData, availableSpaceForColumns, 258 repeatTracksSizingIfNeeded(availableSpaceForColumns,
690 contentLogicalHeight()); 259 contentLogicalHeight());
691 260
692 // Grid container should have the minimum height of a line if it's editable. 261 // Grid container should have the minimum height of a line if it's editable.
693 // That doesn't affect track sizing though. 262 // That doesn't affect track sizing though.
694 if (hasLineIfEmpty()) 263 if (hasLineIfEmpty())
695 setLogicalHeight( 264 setLogicalHeight(
696 std::max(logicalHeight(), minimumLogicalHeightForEmptyLine())); 265 std::max(logicalHeight(), minimumLogicalHeightForEmptyLine()));
697 266
698 applyStretchAlignmentToTracksIfNeeded(ForColumns, sizingData); 267 applyStretchAlignmentToTracksIfNeeded(ForColumns);
699 applyStretchAlignmentToTracksIfNeeded(ForRows, sizingData); 268 applyStretchAlignmentToTracksIfNeeded(ForRows);
700 269
701 layoutGridItems(sizingData); 270 layoutGridItems();
271 m_trackSizingAlgorithm.reset();
702 272
703 if (size() != previousSize) 273 if (size() != previousSize)
704 relayoutChildren = true; 274 relayoutChildren = true;
705 275
706 layoutPositionedObjects(relayoutChildren || isDocumentElement()); 276 layoutPositionedObjects(relayoutChildren || isDocumentElement());
707 277
708 computeOverflow(oldClientAfterEdge); 278 computeOverflow(oldClientAfterEdge);
709 } 279 }
710 280
711 updateLayerTransformAfterLayout(); 281 updateLayerTransformAfterLayout();
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 368
799 return gapAccumulator; 369 return gapAccumulator;
800 } 370 }
801 371
802 void LayoutGrid::computeIntrinsicLogicalWidths( 372 void LayoutGrid::computeIntrinsicLogicalWidths(
803 LayoutUnit& minLogicalWidth, 373 LayoutUnit& minLogicalWidth,
804 LayoutUnit& maxLogicalWidth) const { 374 LayoutUnit& maxLogicalWidth) const {
805 Grid grid(this); 375 Grid grid(this);
806 placeItemsOnGrid(grid, IntrinsicSizeComputation); 376 placeItemsOnGrid(grid, IntrinsicSizeComputation);
807 377
808 GridSizingData sizingData(numTracks(ForColumns, grid), 378 GridTrackSizingAlgorithm algorithm(this, grid);
809 numTracks(ForRows, grid), grid); 379 computeTrackSizesForIndefiniteSize(algorithm, ForColumns, grid,
810 380 minLogicalWidth, maxLogicalWidth);
811 computeTrackSizesForIndefiniteSize(ForColumns, sizingData, minLogicalWidth,
812 maxLogicalWidth);
813 381
814 LayoutUnit scrollbarWidth = LayoutUnit(scrollbarLogicalWidth()); 382 LayoutUnit scrollbarWidth = LayoutUnit(scrollbarLogicalWidth());
815 minLogicalWidth += scrollbarWidth; 383 minLogicalWidth += scrollbarWidth;
816 maxLogicalWidth += scrollbarWidth; 384 maxLogicalWidth += scrollbarWidth;
817 } 385 }
818 386
819 void LayoutGrid::computeTrackSizesForIndefiniteSize( 387 void LayoutGrid::computeTrackSizesForIndefiniteSize(
388 GridTrackSizingAlgorithm& algo,
820 GridTrackSizingDirection direction, 389 GridTrackSizingDirection direction,
821 GridSizingData& sizingData, 390 Grid& grid,
822 LayoutUnit& minIntrinsicSize, 391 LayoutUnit& minIntrinsicSize,
823 LayoutUnit& maxIntrinsicSize) const { 392 LayoutUnit& maxIntrinsicSize) const {
824 DCHECK(sizingData.isValidTransition(direction)); 393 algo.setup(direction, numTracks(direction, grid), IntrinsicSizeComputation,
825 sizingData.setAvailableSpace(LayoutUnit()); 394 LayoutUnit(), LayoutUnit());
826 sizingData.freeSpace(direction) = LayoutUnit(); 395 algo.run();
827 sizingData.sizingOperation = IntrinsicSizeComputation;
828 396
829 computeUsedBreadthOfGridTracks(direction, sizingData, minIntrinsicSize, 397 minIntrinsicSize = algo.minContentSize();
830 maxIntrinsicSize); 398 maxIntrinsicSize = algo.maxContentSize();
831 399
832 size_t numberOfTracks = direction == ForColumns 400 size_t numberOfTracks = algo.tracks(direction).size();
833 ? sizingData.columnTracks.size()
834 : sizingData.rowTracks.size();
835 LayoutUnit totalGuttersSize = 401 LayoutUnit totalGuttersSize =
836 guttersSize(sizingData.grid(), direction, 0, numberOfTracks, 402 guttersSize(grid, direction, 0, numberOfTracks, IntrinsicSizeComputation);
837 sizingData.sizingOperation);
838 minIntrinsicSize += totalGuttersSize; 403 minIntrinsicSize += totalGuttersSize;
839 maxIntrinsicSize += totalGuttersSize; 404 maxIntrinsicSize += totalGuttersSize;
840 405
841 #if DCHECK_IS_ON() 406 #if DCHECK_IS_ON()
842 DCHECK(tracksAreWiderThanMinTrackBreadth(direction, sizingData)); 407 DCHECK(algo.tracksAreWiderThanMinTrackBreadth());
843 #endif 408 #endif
844 } 409 }
845 410
846 LayoutUnit LayoutGrid::computeIntrinsicLogicalContentHeightUsing( 411 LayoutUnit LayoutGrid::computeIntrinsicLogicalContentHeightUsing(
847 const Length& logicalHeightLength, 412 const Length& logicalHeightLength,
848 LayoutUnit intrinsicContentHeight, 413 LayoutUnit intrinsicContentHeight,
849 LayoutUnit borderAndPadding) const { 414 LayoutUnit borderAndPadding) const {
850 if (logicalHeightLength.isMinContent()) 415 if (logicalHeightLength.isMinContent())
851 return m_minContentHeight; 416 return m_minContentHeight;
852 417
(...skipping 10 matching lines...) Expand all
863 } 428 }
864 429
865 if (logicalHeightLength.isFillAvailable()) 430 if (logicalHeightLength.isFillAvailable())
866 return containingBlock()->availableLogicalHeight( 431 return containingBlock()->availableLogicalHeight(
867 ExcludeMarginBorderPadding) - 432 ExcludeMarginBorderPadding) -
868 borderAndPadding; 433 borderAndPadding;
869 ASSERT_NOT_REACHED(); 434 ASSERT_NOT_REACHED();
870 return LayoutUnit(); 435 return LayoutUnit();
871 } 436 }
872 437
873 static inline double normalizedFlexFraction(const GridTrack& track,
874 double flexFactor) {
875 return track.baseSize() / std::max<double>(1, flexFactor);
876 }
877
878 void LayoutGrid::computeUsedBreadthOfGridTracks(
879 GridTrackSizingDirection direction,
880 GridSizingData& sizingData,
881 LayoutUnit& baseSizesWithoutMaximization,
882 LayoutUnit& growthLimitsWithoutMaximization) const {
883 LayoutUnit& freeSpace = sizingData.freeSpace(direction);
884 const LayoutUnit initialFreeSpace = freeSpace;
885 Vector<GridTrack>& tracks = (direction == ForColumns)
886 ? sizingData.columnTracks
887 : sizingData.rowTracks;
888 Vector<size_t> flexibleSizedTracksIndex;
889 sizingData.contentSizedTracksIndex.shrink(0);
890
891 // Grid gutters were removed from freeSpace by the caller, but we must use
892 // them to compute relative (i.e. percentages) sizes.
893 LayoutUnit maxSize = sizingData.availableSpace().clampNegativeToZero();
894 bool hasDefiniteFreeSpace = sizingData.sizingOperation == TrackSizing;
895
896 // 1. Initialize per Grid track variables.
897 for (size_t i = 0; i < tracks.size(); ++i) {
898 GridTrack& track = tracks[i];
899 GridTrackSize trackSize = gridTrackSize(direction, i, sizingData);
900
901 track.setBaseSize(computeUsedBreadthOfMinLength(trackSize, maxSize));
902 track.setGrowthLimit(
903 computeUsedBreadthOfMaxLength(trackSize, track.baseSize(), maxSize));
904 track.setInfinitelyGrowable(false);
905
906 if (trackSize.isFitContent()) {
907 GridLength gridLength = trackSize.fitContentTrackBreadth();
908 if (!gridLength.hasPercentage() || hasDefiniteFreeSpace)
909 track.setGrowthLimitCap(valueForLength(gridLength.length(), maxSize));
910 }
911
912 if (trackSize.isContentSized())
913 sizingData.contentSizedTracksIndex.push_back(i);
914 if (trackSize.maxTrackBreadth().isFlex())
915 flexibleSizedTracksIndex.push_back(i);
916 }
917
918 // 2. Resolve content-based TrackSizingFunctions.
919 if (!sizingData.contentSizedTracksIndex.isEmpty())
920 resolveContentBasedTrackSizingFunctions(direction, sizingData);
921
922 baseSizesWithoutMaximization = growthLimitsWithoutMaximization = LayoutUnit();
923
924 for (auto& track : tracks) {
925 ASSERT(!track.infiniteGrowthPotential());
926 baseSizesWithoutMaximization += track.baseSize();
927 growthLimitsWithoutMaximization += track.growthLimit();
928 // The growth limit caps must be cleared now in order to properly sort
929 // tracks by growth potential on an eventual "Maximize Tracks".
930 track.setGrowthLimitCap(WTF::nullopt);
931 }
932 freeSpace = initialFreeSpace - baseSizesWithoutMaximization;
933
934 if (hasDefiniteFreeSpace && freeSpace <= 0)
935 return;
936
937 // 3. Grow all Grid tracks in GridTracks from their baseSize up to their
938 // growthLimit value until freeSpace is exhausted.
939 const size_t tracksSize = tracks.size();
940 if (hasDefiniteFreeSpace) {
941 Vector<GridTrack*> tracksForDistribution(tracksSize);
942 for (size_t i = 0; i < tracksSize; ++i) {
943 tracksForDistribution[i] = tracks.data() + i;
944 tracksForDistribution[i]->setPlannedSize(
945 tracksForDistribution[i]->baseSize());
946 }
947
948 distributeSpaceToTracks<MaximizeTracks>(tracksForDistribution, nullptr,
949 sizingData, freeSpace);
950
951 for (auto* track : tracksForDistribution)
952 track->setBaseSize(track->plannedSize());
953 } else {
954 for (auto& track : tracks)
955 track.setBaseSize(track.growthLimit());
956 }
957
958 if (flexibleSizedTracksIndex.isEmpty())
959 return;
960
961 // 4. Grow all Grid tracks having a fraction as the MaxTrackSizingFunction.
962 double flexFraction = 0;
963 if (hasDefiniteFreeSpace) {
964 flexFraction = findFlexFactorUnitSize(
965 tracks, GridSpan::translatedDefiniteGridSpan(0, tracks.size()),
966 direction, initialFreeSpace, sizingData);
967 } else {
968 for (const auto& trackIndex : flexibleSizedTracksIndex) {
969 flexFraction = std::max(
970 flexFraction, normalizedFlexFraction(
971 tracks[trackIndex],
972 gridTrackSize(direction, trackIndex, sizingData)
973 .maxTrackBreadth()
974 .flex()));
975 }
976
977 const Grid& grid = sizingData.grid();
978 if (grid.hasGridItems()) {
979 for (size_t i = 0; i < flexibleSizedTracksIndex.size(); ++i) {
980 GridIterator iterator(grid, direction, flexibleSizedTracksIndex[i]);
981 while (LayoutBox* gridItem = iterator.nextGridItem()) {
982 const GridSpan& span = grid.gridItemSpan(*gridItem, direction);
983
984 // Do not include already processed items.
985 if (i > 0 && span.startLine() <= flexibleSizedTracksIndex[i - 1])
986 continue;
987
988 flexFraction =
989 std::max(flexFraction,
990 findFlexFactorUnitSize(
991 tracks, span, direction,
992 maxContentForChild(*gridItem, direction, sizingData),
993 sizingData));
994 }
995 }
996 }
997 }
998
999 LayoutUnit totalGrowth;
1000 Vector<LayoutUnit> increments;
1001 increments.grow(flexibleSizedTracksIndex.size());
1002 computeFlexSizedTracksGrowth(direction, tracks, flexibleSizedTracksIndex,
1003 flexFraction, increments, totalGrowth,
1004 sizingData);
1005
1006 // We only need to redo the flex fraction computation for indefinite heights
1007 // (definite sizes are already constrained by min/max sizes). Regarding
1008 // widths, they are always definite at layout time so we shouldn't ever have
1009 // to do this.
1010 if (!hasDefiniteFreeSpace && direction == ForRows) {
1011 auto minSize = computeContentLogicalHeight(
1012 MinSize, styleRef().logicalMinHeight(), LayoutUnit(-1));
1013 auto maxSize = computeContentLogicalHeight(
1014 MaxSize, styleRef().logicalMaxHeight(), LayoutUnit(-1));
1015
1016 // Redo the flex fraction computation using min|max-height as definite
1017 // available space in case the total height is smaller than min-height or
1018 // larger than max-height.
1019 LayoutUnit rowsSize =
1020 totalGrowth + computeTrackBasedLogicalHeight(sizingData);
1021 bool checkMinSize = minSize && rowsSize < minSize;
1022 bool checkMaxSize = maxSize != -1 && rowsSize > maxSize;
1023 if (checkMinSize || checkMaxSize) {
1024 LayoutUnit freeSpace = checkMaxSize ? maxSize : LayoutUnit(-1);
1025 freeSpace = std::max(freeSpace, minSize) -
1026 guttersSize(sizingData.grid(), ForRows, 0,
1027 sizingData.grid().numTracks(ForRows),
1028 sizingData.sizingOperation);
1029
1030 flexFraction = findFlexFactorUnitSize(
1031 tracks, GridSpan::translatedDefiniteGridSpan(0, tracks.size()),
1032 ForRows, freeSpace, sizingData);
1033
1034 totalGrowth = LayoutUnit(0);
1035 computeFlexSizedTracksGrowth(ForRows, tracks, flexibleSizedTracksIndex,
1036 flexFraction, increments, totalGrowth,
1037 sizingData);
1038 }
1039 }
1040
1041 size_t i = 0;
1042 for (auto trackIndex : flexibleSizedTracksIndex) {
1043 auto& track = tracks[trackIndex];
1044 if (LayoutUnit increment = increments[i++])
1045 track.setBaseSize(track.baseSize() + increment);
1046 }
1047 freeSpace -= totalGrowth;
1048 growthLimitsWithoutMaximization += totalGrowth;
1049 }
1050
1051 void LayoutGrid::computeFlexSizedTracksGrowth(
1052 GridTrackSizingDirection direction,
1053 Vector<GridTrack>& tracks,
1054 const Vector<size_t>& flexibleSizedTracksIndex,
1055 double flexFraction,
1056 Vector<LayoutUnit>& increments,
1057 LayoutUnit& totalGrowth,
1058 const GridSizingData& sizingData) const {
1059 size_t numFlexTracks = flexibleSizedTracksIndex.size();
1060 DCHECK_EQ(increments.size(), numFlexTracks);
1061 for (size_t i = 0; i < numFlexTracks; ++i) {
1062 size_t trackIndex = flexibleSizedTracksIndex[i];
1063 auto trackSize = gridTrackSize(direction, trackIndex, sizingData);
1064 DCHECK(trackSize.maxTrackBreadth().isFlex());
1065 LayoutUnit oldBaseSize = tracks[trackIndex].baseSize();
1066 LayoutUnit newBaseSize =
1067 std::max(oldBaseSize,
1068 LayoutUnit(flexFraction * trackSize.maxTrackBreadth().flex()));
1069 increments[i] = newBaseSize - oldBaseSize;
1070 totalGrowth += increments[i];
1071 }
1072 }
1073
1074 LayoutUnit LayoutGrid::computeUsedBreadthOfMinLength(
1075 const GridTrackSize& trackSize,
1076 LayoutUnit maxSize) const {
1077 const GridLength& gridLength = trackSize.minTrackBreadth();
1078 if (gridLength.isFlex())
1079 return LayoutUnit();
1080
1081 const Length& trackLength = gridLength.length();
1082 if (trackLength.isSpecified())
1083 return valueForLength(trackLength, maxSize);
1084
1085 ASSERT(trackLength.isMinContent() || trackLength.isAuto() ||
1086 trackLength.isMaxContent());
1087 return LayoutUnit();
1088 }
1089
1090 LayoutUnit LayoutGrid::computeUsedBreadthOfMaxLength(
1091 const GridTrackSize& trackSize,
1092 LayoutUnit usedBreadth,
1093 LayoutUnit maxSize) const {
1094 const GridLength& gridLength = trackSize.maxTrackBreadth();
1095 if (gridLength.isFlex())
1096 return usedBreadth;
1097
1098 const Length& trackLength = gridLength.length();
1099 if (trackLength.isSpecified())
1100 return valueForLength(trackLength, maxSize);
1101
1102 ASSERT(trackLength.isMinContent() || trackLength.isAuto() ||
1103 trackLength.isMaxContent());
1104 return LayoutUnit(infinity);
1105 }
1106
1107 double LayoutGrid::computeFlexFactorUnitSize(
1108 const Vector<GridTrack>& tracks,
1109 GridTrackSizingDirection direction,
1110 double flexFactorSum,
1111 LayoutUnit& leftOverSpace,
1112 const Vector<size_t, 8>& flexibleTracksIndexes,
1113 const GridSizingData& sizingData,
1114 std::unique_ptr<TrackIndexSet> tracksToTreatAsInflexible) const {
1115 // We want to avoid the effect of flex factors sum below 1 making the factor
1116 // unit size to grow exponentially.
1117 double hypotheticalFactorUnitSize =
1118 leftOverSpace / std::max<double>(1, flexFactorSum);
1119
1120 // product of the hypothetical "flex factor unit" and any flexible track's
1121 // "flex factor" must be grater than such track's "base size".
1122 std::unique_ptr<TrackIndexSet> additionalTracksToTreatAsInflexible =
1123 std::move(tracksToTreatAsInflexible);
1124 bool validFlexFactorUnit = true;
1125 for (auto index : flexibleTracksIndexes) {
1126 if (additionalTracksToTreatAsInflexible &&
1127 additionalTracksToTreatAsInflexible->contains(index))
1128 continue;
1129 LayoutUnit baseSize = tracks[index].baseSize();
1130 double flexFactor =
1131 gridTrackSize(direction, index, sizingData).maxTrackBreadth().flex();
1132 // treating all such tracks as inflexible.
1133 if (baseSize > hypotheticalFactorUnitSize * flexFactor) {
1134 leftOverSpace -= baseSize;
1135 flexFactorSum -= flexFactor;
1136 if (!additionalTracksToTreatAsInflexible)
1137 additionalTracksToTreatAsInflexible = WTF::makeUnique<TrackIndexSet>();
1138 additionalTracksToTreatAsInflexible->insert(index);
1139 validFlexFactorUnit = false;
1140 }
1141 }
1142 if (!validFlexFactorUnit) {
1143 return computeFlexFactorUnitSize(
1144 tracks, direction, flexFactorSum, leftOverSpace, flexibleTracksIndexes,
1145 sizingData, std::move(additionalTracksToTreatAsInflexible));
1146 }
1147 return hypotheticalFactorUnitSize;
1148 }
1149
1150 double LayoutGrid::findFlexFactorUnitSize(
1151 const Vector<GridTrack>& tracks,
1152 const GridSpan& tracksSpan,
1153 GridTrackSizingDirection direction,
1154 LayoutUnit leftOverSpace,
1155 const GridSizingData& sizingData) const {
1156 if (leftOverSpace <= 0)
1157 return 0;
1158
1159 double flexFactorSum = 0;
1160 Vector<size_t, 8> flexibleTracksIndexes;
1161 for (const auto& trackIndex : tracksSpan) {
1162 GridTrackSize trackSize = gridTrackSize(direction, trackIndex, sizingData);
1163 if (!trackSize.maxTrackBreadth().isFlex()) {
1164 leftOverSpace -= tracks[trackIndex].baseSize();
1165 } else {
1166 flexibleTracksIndexes.push_back(trackIndex);
1167 flexFactorSum += trackSize.maxTrackBreadth().flex();
1168 }
1169 }
1170
1171 // The function is not called if we don't have <flex> grid tracks
1172 ASSERT(!flexibleTracksIndexes.isEmpty());
1173
1174 return computeFlexFactorUnitSize(tracks, direction, flexFactorSum,
1175 leftOverSpace, flexibleTracksIndexes,
1176 sizingData);
1177 }
1178
1179 static bool hasOverrideContainingBlockContentSizeForChild(
1180 const LayoutBox& child,
1181 GridTrackSizingDirection direction) {
1182 return direction == ForColumns
1183 ? child.hasOverrideContainingBlockLogicalWidth()
1184 : child.hasOverrideContainingBlockLogicalHeight();
1185 }
1186
1187 static LayoutUnit overrideContainingBlockContentSizeForChild( 438 static LayoutUnit overrideContainingBlockContentSizeForChild(
1188 const LayoutBox& child, 439 const LayoutBox& child,
1189 GridTrackSizingDirection direction) { 440 GridTrackSizingDirection direction) {
1190 return direction == ForColumns 441 return direction == ForColumns
1191 ? child.overrideContainingBlockContentLogicalWidth() 442 ? child.overrideContainingBlockContentLogicalWidth()
1192 : child.overrideContainingBlockContentLogicalHeight(); 443 : child.overrideContainingBlockContentLogicalHeight();
1193 } 444 }
1194 445
1195 static void setOverrideContainingBlockContentSizeForChild(
1196 LayoutBox& child,
1197 GridTrackSizingDirection direction,
1198 LayoutUnit size) {
1199 if (direction == ForColumns)
1200 child.setOverrideContainingBlockContentLogicalWidth(size);
1201 else
1202 child.setOverrideContainingBlockContentLogicalHeight(size);
1203 }
1204
1205 static bool shouldClearOverrideContainingBlockContentSizeForChild(
1206 const LayoutBox& child,
1207 GridTrackSizingDirection direction) {
1208 if (direction == ForColumns)
1209 return child.hasRelativeLogicalWidth() ||
1210 child.styleRef().logicalWidth().isIntrinsicOrAuto();
1211 return child.hasRelativeLogicalHeight() ||
1212 child.styleRef().logicalHeight().isIntrinsicOrAuto();
1213 }
1214
1215 const GridTrackSize& LayoutGrid::rawGridTrackSize(
1216 GridTrackSizingDirection direction,
1217 size_t translatedIndex,
1218 const GridSizingData& sizingData) const {
1219 bool isRowAxis = direction == ForColumns;
1220 const Vector<GridTrackSize>& trackStyles =
1221 isRowAxis ? styleRef().gridTemplateColumns()
1222 : styleRef().gridTemplateRows();
1223 const Vector<GridTrackSize>& autoRepeatTrackStyles =
1224 isRowAxis ? styleRef().gridAutoRepeatColumns()
1225 : styleRef().gridAutoRepeatRows();
1226 const Vector<GridTrackSize>& autoTrackStyles =
1227 isRowAxis ? styleRef().gridAutoColumns() : styleRef().gridAutoRows();
1228 size_t insertionPoint = isRowAxis
1229 ? styleRef().gridAutoRepeatColumnsInsertionPoint()
1230 : styleRef().gridAutoRepeatRowsInsertionPoint();
1231 size_t autoRepeatTracksCount = sizingData.grid().autoRepeatTracks(direction);
1232
1233 // We should not use GridPositionsResolver::explicitGridXXXCount() for this
1234 // because the explicit grid might be larger than the number of tracks in
1235 // grid-template-rows|columns (if grid-template-areas is specified for
1236 // example).
1237 size_t explicitTracksCount = trackStyles.size() + autoRepeatTracksCount;
1238
1239 int untranslatedIndexAsInt =
1240 translatedIndex + sizingData.grid().smallestTrackStart(direction);
1241 size_t autoTrackStylesSize = autoTrackStyles.size();
1242 if (untranslatedIndexAsInt < 0) {
1243 int index = untranslatedIndexAsInt % static_cast<int>(autoTrackStylesSize);
1244 // We need to traspose the index because the first negative implicit line
1245 // will get the last defined auto track and so on.
1246 index += index ? autoTrackStylesSize : 0;
1247 return autoTrackStyles[index];
1248 }
1249
1250 size_t untranslatedIndex = static_cast<size_t>(untranslatedIndexAsInt);
1251 if (untranslatedIndex >= explicitTracksCount)
1252 return autoTrackStyles[(untranslatedIndex - explicitTracksCount) %
1253 autoTrackStylesSize];
1254
1255 if (LIKELY(!autoRepeatTracksCount) || untranslatedIndex < insertionPoint)
1256 return trackStyles[untranslatedIndex];
1257
1258 if (untranslatedIndex < (insertionPoint + autoRepeatTracksCount)) {
1259 size_t autoRepeatLocalIndex = untranslatedIndexAsInt - insertionPoint;
1260 return autoRepeatTrackStyles[autoRepeatLocalIndex %
1261 autoRepeatTrackStyles.size()];
1262 }
1263
1264 return trackStyles[untranslatedIndex - autoRepeatTracksCount];
1265 }
1266
1267 GridTrackSize LayoutGrid::gridTrackSize(
1268 GridTrackSizingDirection direction,
1269 size_t translatedIndex,
1270 const GridSizingData& sizingData) const {
1271 // Collapse empty auto repeat tracks if auto-fit.
1272 if (sizingData.grid().hasAutoRepeatEmptyTracks(direction) &&
1273 sizingData.grid().isEmptyAutoRepeatTrack(direction, translatedIndex))
1274 return {Length(Fixed), LengthTrackSizing};
1275
1276 const GridTrackSize& trackSize =
1277 rawGridTrackSize(direction, translatedIndex, sizingData);
1278 if (trackSize.isFitContent())
1279 return trackSize;
1280
1281 GridLength minTrackBreadth = trackSize.minTrackBreadth();
1282 GridLength maxTrackBreadth = trackSize.maxTrackBreadth();
1283 // If the logical width/height of the grid container is indefinite, percentage
1284 // values are treated as <auto>.
1285 if (minTrackBreadth.hasPercentage() || maxTrackBreadth.hasPercentage()) {
1286 // For the inline axis this only happens when we're computing the intrinsic
1287 // sizes (AvailableSpaceIndefinite).
1288 if ((sizingData.sizingOperation == IntrinsicSizeComputation) ||
1289 (direction == ForRows && !cachedHasDefiniteLogicalHeight())) {
1290 if (minTrackBreadth.hasPercentage())
1291 minTrackBreadth = Length(Auto);
1292 if (maxTrackBreadth.hasPercentage())
1293 maxTrackBreadth = Length(Auto);
1294 }
1295 }
1296
1297 // Flex sizes are invalid as a min sizing function. However we still can have
1298 // a flexible |minTrackBreadth| if the track had a flex size directly (e.g.
1299 // "1fr"), the spec says that in this case it implies an automatic minimum.
1300 if (minTrackBreadth.isFlex())
1301 minTrackBreadth = Length(Auto);
1302
1303 return GridTrackSize(minTrackBreadth, maxTrackBreadth);
1304 }
1305
1306 bool LayoutGrid::isOrthogonalChild(const LayoutBox& child) const { 446 bool LayoutGrid::isOrthogonalChild(const LayoutBox& child) const {
1307 return child.isHorizontalWritingMode() != isHorizontalWritingMode(); 447 return child.isHorizontalWritingMode() != isHorizontalWritingMode();
1308 } 448 }
1309 449
1310 LayoutUnit LayoutGrid::logicalHeightForChild(LayoutBox& child,
1311 GridSizingData& sizingData) const {
1312 GridTrackSizingDirection childBlockDirection =
1313 flowAwareDirectionForChild(child, ForRows);
1314 // If |child| has a relative logical height, we shouldn't let it override its
1315 // intrinsic height, which is what we are interested in here. Thus we need to
1316 // set the block-axis override size to -1 (no possible resolution).
1317 if (shouldClearOverrideContainingBlockContentSizeForChild(child, ForRows)) {
1318 setOverrideContainingBlockContentSizeForChild(child, childBlockDirection,
1319 LayoutUnit(-1));
1320 child.setNeedsLayout(LayoutInvalidationReason::GridChanged);
1321 }
1322
1323 // We need to clear the stretched height to properly compute logical height
1324 // during layout.
1325 if (child.needsLayout())
1326 child.clearOverrideLogicalContentHeight();
1327
1328 child.layoutIfNeeded();
1329 return child.logicalHeight() + child.marginLogicalHeight();
1330 }
1331
1332 GridTrackSizingDirection LayoutGrid::flowAwareDirectionForChild(
1333 const LayoutBox& child,
1334 GridTrackSizingDirection direction) const {
1335 return !isOrthogonalChild(child)
1336 ? direction
1337 : (direction == ForColumns ? ForRows : ForColumns);
1338 }
1339
1340 LayoutUnit LayoutGrid::minSizeForChild(LayoutBox& child,
1341 GridTrackSizingDirection direction,
1342 GridSizingData& sizingData) const {
1343 GridTrackSizingDirection childInlineDirection =
1344 flowAwareDirectionForChild(child, ForColumns);
1345 bool isRowAxis = direction == childInlineDirection;
1346 const Length& childSize = isRowAxis ? child.styleRef().logicalWidth()
1347 : child.styleRef().logicalHeight();
1348 const Length& childMinSize = isRowAxis ? child.styleRef().logicalMinWidth()
1349 : child.styleRef().logicalMinHeight();
1350 bool overflowIsVisible =
1351 isRowAxis
1352 ? child.styleRef().overflowInlineDirection() == EOverflow::Visible
1353 : child.styleRef().overflowBlockDirection() == EOverflow::Visible;
1354 if (!childSize.isAuto() || (childMinSize.isAuto() && overflowIsVisible))
1355 return minContentForChild(child, direction, sizingData);
1356
1357 bool overrideSizeHasChanged =
1358 updateOverrideContainingBlockContentSizeForChild(
1359 child, childInlineDirection, sizingData);
1360 if (isRowAxis) {
1361 LayoutUnit marginLogicalWidth =
1362 sizingData.sizingOperation == TrackSizing
1363 ? computeMarginLogicalSizeForChild(InlineDirection, child)
1364 : marginIntrinsicLogicalWidthForChild(child);
1365 return child.computeLogicalWidthUsing(
1366 MinSize, childMinSize,
1367 overrideContainingBlockContentSizeForChild(child,
1368 childInlineDirection),
1369 this) +
1370 marginLogicalWidth;
1371 }
1372
1373 if (overrideSizeHasChanged &&
1374 (direction != ForColumns ||
1375 sizingData.sizingOperation != IntrinsicSizeComputation))
1376 child.setNeedsLayout(LayoutInvalidationReason::GridChanged);
1377 child.layoutIfNeeded();
1378 return child.computeLogicalHeightUsing(MinSize, childMinSize,
1379 child.intrinsicLogicalHeight()) +
1380 child.marginLogicalHeight() + child.scrollbarLogicalHeight();
1381 }
1382
1383 bool LayoutGrid::updateOverrideContainingBlockContentSizeForChild(
1384 LayoutBox& child,
1385 GridTrackSizingDirection direction,
1386 GridSizingData& sizingData) const {
1387 LayoutUnit overrideSize =
1388 gridAreaBreadthForChild(child, direction, sizingData);
1389 if (hasOverrideContainingBlockContentSizeForChild(child, direction) &&
1390 overrideContainingBlockContentSizeForChild(child, direction) ==
1391 overrideSize)
1392 return false;
1393
1394 setOverrideContainingBlockContentSizeForChild(child, direction, overrideSize);
1395 return true;
1396 }
1397
1398 DISABLE_CFI_PERF
1399 LayoutUnit LayoutGrid::minContentForChild(LayoutBox& child,
1400 GridTrackSizingDirection direction,
1401 GridSizingData& sizingData) const {
1402 GridTrackSizingDirection childInlineDirection =
1403 flowAwareDirectionForChild(child, ForColumns);
1404 if (direction == childInlineDirection) {
1405 // If |child| has a relative logical width, we shouldn't let it override its
1406 // intrinsic width, which is what we are interested in here. Thus we need to
1407 // set the inline-axis override size to -1 (no possible resolution).
1408 if (shouldClearOverrideContainingBlockContentSizeForChild(child,
1409 ForColumns))
1410 setOverrideContainingBlockContentSizeForChild(child, childInlineDirection,
1411 LayoutUnit(-1));
1412
1413 // FIXME: It's unclear if we should return the intrinsic width or the
1414 // preferred width.
1415 // See http://lists.w3.org/Archives/Public/www-style/2013Jan/0245.html
1416 LayoutUnit marginLogicalWidth =
1417 child.needsLayout()
1418 ? computeMarginLogicalSizeForChild(InlineDirection, child)
1419 : child.marginLogicalWidth();
1420 return child.minPreferredLogicalWidth() + marginLogicalWidth;
1421 }
1422
1423 // All orthogonal flow boxes were already laid out during an early layout
1424 // phase performed in FrameView::performLayout.
1425 // It's true that grid track sizing was not completed at that time and it may
1426 // afffect the final height of a grid item, but since it's forbidden to
1427 // perform a layout during intrinsic width computation, we have to use that
1428 // computed height for now.
1429 if (direction == ForColumns &&
1430 sizingData.sizingOperation == IntrinsicSizeComputation) {
1431 DCHECK(isOrthogonalChild(child));
1432 return child.logicalHeight() + child.marginLogicalHeight();
1433 }
1434
1435 if (updateOverrideContainingBlockContentSizeForChild(
1436 child, childInlineDirection, sizingData))
1437 child.setNeedsLayout(LayoutInvalidationReason::GridChanged);
1438 return logicalHeightForChild(child, sizingData);
1439 }
1440
1441 DISABLE_CFI_PERF
1442 LayoutUnit LayoutGrid::maxContentForChild(LayoutBox& child,
1443 GridTrackSizingDirection direction,
1444 GridSizingData& sizingData) const {
1445 GridTrackSizingDirection childInlineDirection =
1446 flowAwareDirectionForChild(child, ForColumns);
1447 if (direction == childInlineDirection) {
1448 // If |child| has a relative logical width, we shouldn't let it override its
1449 // intrinsic width, which is what we are interested in here. Thus we need to
1450 // set the inline-axis override size to -1 (no possible resolution).
1451 if (shouldClearOverrideContainingBlockContentSizeForChild(child,
1452 ForColumns))
1453 setOverrideContainingBlockContentSizeForChild(child, childInlineDirection,
1454 LayoutUnit(-1));
1455
1456 // FIXME: It's unclear if we should return the intrinsic width or the
1457 // preferred width.
1458 // See http://lists.w3.org/Archives/Public/www-style/2013Jan/0245.html
1459 LayoutUnit marginLogicalWidth =
1460 child.needsLayout()
1461 ? computeMarginLogicalSizeForChild(InlineDirection, child)
1462 : child.marginLogicalWidth();
1463 return child.maxPreferredLogicalWidth() + marginLogicalWidth;
1464 }
1465
1466 // All orthogonal flow boxes were already laid out during an early layout
1467 // phase performed in FrameView::performLayout.
1468 // It's true that grid track sizing was not completed at that time and it may
1469 // afffect the final height of a grid item, but since it's forbidden to
1470 // perform a layout during intrinsic width computation, we have to use that
1471 // computed height for now.
1472 if (direction == ForColumns &&
1473 sizingData.sizingOperation == IntrinsicSizeComputation) {
1474 DCHECK(isOrthogonalChild(child));
1475 return child.logicalHeight() + child.marginLogicalHeight();
1476 }
1477
1478 if (updateOverrideContainingBlockContentSizeForChild(
1479 child, childInlineDirection, sizingData))
1480 child.setNeedsLayout(LayoutInvalidationReason::GridChanged);
1481 return logicalHeightForChild(child, sizingData);
1482 }
1483
1484 // We're basically using a class instead of a std::pair because of accessing
1485 // gridItem() or getGridSpan() is much more self-explanatory that using .first
1486 // or .second members in the pair. Having a std::pair<LayoutBox*, size_t>
1487 // does not work either because we still need the GridSpan so we'd have to add
1488 // an extra hash lookup for each item at the beginning of
1489 // LayoutGrid::resolveContentBasedTrackSizingFunctionsForItems().
1490 class GridItemWithSpan {
1491 public:
1492 GridItemWithSpan(LayoutBox& gridItem, const GridSpan& gridSpan)
1493 : m_gridItem(&gridItem), m_gridSpan(gridSpan) {}
1494
1495 LayoutBox& gridItem() const { return *m_gridItem; }
1496 GridSpan getGridSpan() const { return m_gridSpan; }
1497
1498 bool operator<(const GridItemWithSpan other) const {
1499 return m_gridSpan.integerSpan() < other.m_gridSpan.integerSpan();
1500 }
1501
1502 private:
1503 LayoutBox* m_gridItem;
1504 GridSpan m_gridSpan;
1505 };
1506
1507 bool LayoutGrid::spanningItemCrossesFlexibleSizedTracks(
1508 const GridSpan& span,
1509 GridTrackSizingDirection direction,
1510 const GridSizingData& sizingData) const {
1511 for (const auto& trackPosition : span) {
1512 const GridTrackSize& trackSize =
1513 gridTrackSize(direction, trackPosition, sizingData);
1514 if (trackSize.minTrackBreadth().isFlex() ||
1515 trackSize.maxTrackBreadth().isFlex())
1516 return true;
1517 }
1518
1519 return false;
1520 }
1521
1522 void LayoutGrid::resolveContentBasedTrackSizingFunctions(
1523 GridTrackSizingDirection direction,
1524 GridSizingData& sizingData) const {
1525 sizingData.itemsSortedByIncreasingSpan.shrink(0);
1526 const Grid& grid = sizingData.grid();
1527 if (grid.hasGridItems()) {
1528 HashSet<LayoutBox*> itemsSet;
1529 for (const auto& trackIndex : sizingData.contentSizedTracksIndex) {
1530 GridIterator iterator(grid, direction, trackIndex);
1531 GridTrack& track = (direction == ForColumns)
1532 ? sizingData.columnTracks[trackIndex]
1533 : sizingData.rowTracks[trackIndex];
1534 while (LayoutBox* gridItem = iterator.nextGridItem()) {
1535 if (itemsSet.insert(gridItem).isNewEntry) {
1536 const GridSpan& span = grid.gridItemSpan(*gridItem, direction);
1537 if (span.integerSpan() == 1) {
1538 resolveContentBasedTrackSizingFunctionsForNonSpanningItems(
1539 direction, span, *gridItem, track, sizingData);
1540 } else if (!spanningItemCrossesFlexibleSizedTracks(span, direction,
1541 sizingData)) {
1542 sizingData.itemsSortedByIncreasingSpan.push_back(
1543 GridItemWithSpan(*gridItem, span));
1544 }
1545 }
1546 }
1547 }
1548 std::sort(sizingData.itemsSortedByIncreasingSpan.begin(),
1549 sizingData.itemsSortedByIncreasingSpan.end());
1550 }
1551
1552 auto it = sizingData.itemsSortedByIncreasingSpan.begin();
1553 auto end = sizingData.itemsSortedByIncreasingSpan.end();
1554 while (it != end) {
1555 GridItemsSpanGroupRange spanGroupRange = {it,
1556 std::upper_bound(it, end, *it)};
1557 resolveContentBasedTrackSizingFunctionsForItems<ResolveIntrinsicMinimums>(
1558 direction, sizingData, spanGroupRange);
1559 resolveContentBasedTrackSizingFunctionsForItems<
1560 ResolveContentBasedMinimums>(direction, sizingData, spanGroupRange);
1561 resolveContentBasedTrackSizingFunctionsForItems<ResolveMaxContentMinimums>(
1562 direction, sizingData, spanGroupRange);
1563 resolveContentBasedTrackSizingFunctionsForItems<ResolveIntrinsicMaximums>(
1564 direction, sizingData, spanGroupRange);
1565 resolveContentBasedTrackSizingFunctionsForItems<ResolveMaxContentMaximums>(
1566 direction, sizingData, spanGroupRange);
1567 it = spanGroupRange.rangeEnd;
1568 }
1569
1570 for (const auto& trackIndex : sizingData.contentSizedTracksIndex) {
1571 GridTrack& track = (direction == ForColumns)
1572 ? sizingData.columnTracks[trackIndex]
1573 : sizingData.rowTracks[trackIndex];
1574 if (track.growthLimit() == infinity)
1575 track.setGrowthLimit(track.baseSize());
1576 }
1577 }
1578
1579 void LayoutGrid::resolveContentBasedTrackSizingFunctionsForNonSpanningItems(
1580 GridTrackSizingDirection direction,
1581 const GridSpan& span,
1582 LayoutBox& gridItem,
1583 GridTrack& track,
1584 GridSizingData& sizingData) const {
1585 const size_t trackPosition = span.startLine();
1586 GridTrackSize trackSize = gridTrackSize(direction, trackPosition, sizingData);
1587
1588 if (trackSize.hasMinContentMinTrackBreadth())
1589 track.setBaseSize(std::max(
1590 track.baseSize(), minContentForChild(gridItem, direction, sizingData)));
1591 else if (trackSize.hasMaxContentMinTrackBreadth())
1592 track.setBaseSize(std::max(
1593 track.baseSize(), maxContentForChild(gridItem, direction, sizingData)));
1594 else if (trackSize.hasAutoMinTrackBreadth())
1595 track.setBaseSize(std::max(
1596 track.baseSize(), minSizeForChild(gridItem, direction, sizingData)));
1597
1598 if (trackSize.hasMinContentMaxTrackBreadth()) {
1599 track.setGrowthLimit(
1600 std::max(track.growthLimit(),
1601 minContentForChild(gridItem, direction, sizingData)));
1602 } else if (trackSize.hasMaxContentOrAutoMaxTrackBreadth()) {
1603 LayoutUnit growthLimit =
1604 maxContentForChild(gridItem, direction, sizingData);
1605 if (trackSize.isFitContent())
1606 growthLimit =
1607 std::min(growthLimit,
1608 valueForLength(trackSize.fitContentTrackBreadth().length(),
1609 sizingData.availableSpace()));
1610 track.setGrowthLimit(std::max(track.growthLimit(), growthLimit));
1611 }
1612 }
1613
1614 static LayoutUnit trackSizeForTrackSizeComputationPhase(
1615 TrackSizeComputationPhase phase,
1616 const GridTrack& track,
1617 TrackSizeRestriction restriction) {
1618 switch (phase) {
1619 case ResolveIntrinsicMinimums:
1620 case ResolveContentBasedMinimums:
1621 case ResolveMaxContentMinimums:
1622 case MaximizeTracks:
1623 return track.baseSize();
1624 case ResolveIntrinsicMaximums:
1625 case ResolveMaxContentMaximums:
1626 const LayoutUnit& growthLimit = track.growthLimit();
1627 if (restriction == AllowInfinity)
1628 return growthLimit;
1629 return growthLimit == infinity ? track.baseSize() : growthLimit;
1630 }
1631
1632 ASSERT_NOT_REACHED();
1633 return track.baseSize();
1634 }
1635
1636 static bool shouldProcessTrackForTrackSizeComputationPhase(
1637 TrackSizeComputationPhase phase,
1638 const GridTrackSize& trackSize) {
1639 switch (phase) {
1640 case ResolveIntrinsicMinimums:
1641 return trackSize.hasIntrinsicMinTrackBreadth();
1642 case ResolveContentBasedMinimums:
1643 return trackSize.hasMinOrMaxContentMinTrackBreadth();
1644 case ResolveMaxContentMinimums:
1645 return trackSize.hasMaxContentMinTrackBreadth();
1646 case ResolveIntrinsicMaximums:
1647 return trackSize.hasIntrinsicMaxTrackBreadth();
1648 case ResolveMaxContentMaximums:
1649 return trackSize.hasMaxContentOrAutoMaxTrackBreadth();
1650 case MaximizeTracks:
1651 ASSERT_NOT_REACHED();
1652 return false;
1653 }
1654
1655 ASSERT_NOT_REACHED();
1656 return false;
1657 }
1658
1659 static bool trackShouldGrowBeyondGrowthLimitsForTrackSizeComputationPhase(
1660 TrackSizeComputationPhase phase,
1661 const GridTrackSize& trackSize) {
1662 switch (phase) {
1663 case ResolveIntrinsicMinimums:
1664 case ResolveContentBasedMinimums:
1665 return trackSize
1666 .hasAutoOrMinContentMinTrackBreadthAndIntrinsicMaxTrackBreadth();
1667 case ResolveMaxContentMinimums:
1668 return trackSize
1669 .hasMaxContentMinTrackBreadthAndMaxContentMaxTrackBreadth();
1670 case ResolveIntrinsicMaximums:
1671 case ResolveMaxContentMaximums:
1672 return true;
1673 case MaximizeTracks:
1674 ASSERT_NOT_REACHED();
1675 return false;
1676 }
1677
1678 ASSERT_NOT_REACHED();
1679 return false;
1680 }
1681
1682 static void markAsInfinitelyGrowableForTrackSizeComputationPhase(
1683 TrackSizeComputationPhase phase,
1684 GridTrack& track) {
1685 switch (phase) {
1686 case ResolveIntrinsicMinimums:
1687 case ResolveContentBasedMinimums:
1688 case ResolveMaxContentMinimums:
1689 return;
1690 case ResolveIntrinsicMaximums:
1691 if (trackSizeForTrackSizeComputationPhase(phase, track, AllowInfinity) ==
1692 infinity &&
1693 track.plannedSize() != infinity)
1694 track.setInfinitelyGrowable(true);
1695 return;
1696 case ResolveMaxContentMaximums:
1697 if (track.infinitelyGrowable())
1698 track.setInfinitelyGrowable(false);
1699 return;
1700 case MaximizeTracks:
1701 ASSERT_NOT_REACHED();
1702 return;
1703 }
1704
1705 ASSERT_NOT_REACHED();
1706 }
1707
1708 static void updateTrackSizeForTrackSizeComputationPhase(
1709 TrackSizeComputationPhase phase,
1710 GridTrack& track) {
1711 switch (phase) {
1712 case ResolveIntrinsicMinimums:
1713 case ResolveContentBasedMinimums:
1714 case ResolveMaxContentMinimums:
1715 track.setBaseSize(track.plannedSize());
1716 return;
1717 case ResolveIntrinsicMaximums:
1718 case ResolveMaxContentMaximums:
1719 track.setGrowthLimit(track.plannedSize());
1720 return;
1721 case MaximizeTracks:
1722 ASSERT_NOT_REACHED();
1723 return;
1724 }
1725
1726 ASSERT_NOT_REACHED();
1727 }
1728
1729 LayoutUnit LayoutGrid::currentItemSizeForTrackSizeComputationPhase(
1730 TrackSizeComputationPhase phase,
1731 LayoutBox& gridItem,
1732 GridTrackSizingDirection direction,
1733 GridSizingData& sizingData) const {
1734 switch (phase) {
1735 case ResolveIntrinsicMinimums:
1736 case ResolveIntrinsicMaximums:
1737 return minSizeForChild(gridItem, direction, sizingData);
1738 case ResolveContentBasedMinimums:
1739 return minContentForChild(gridItem, direction, sizingData);
1740 case ResolveMaxContentMinimums:
1741 case ResolveMaxContentMaximums:
1742 return maxContentForChild(gridItem, direction, sizingData);
1743 case MaximizeTracks:
1744 ASSERT_NOT_REACHED();
1745 return LayoutUnit();
1746 }
1747
1748 ASSERT_NOT_REACHED();
1749 return LayoutUnit();
1750 }
1751
1752 template <TrackSizeComputationPhase phase>
1753 void LayoutGrid::resolveContentBasedTrackSizingFunctionsForItems(
1754 GridTrackSizingDirection direction,
1755 GridSizingData& sizingData,
1756 const GridItemsSpanGroupRange& gridItemsWithSpan) const {
1757 Vector<GridTrack>& tracks = (direction == ForColumns)
1758 ? sizingData.columnTracks
1759 : sizingData.rowTracks;
1760 for (const auto& trackIndex : sizingData.contentSizedTracksIndex) {
1761 GridTrack& track = tracks[trackIndex];
1762 track.setPlannedSize(
1763 trackSizeForTrackSizeComputationPhase(phase, track, AllowInfinity));
1764 }
1765
1766 for (auto it = gridItemsWithSpan.rangeStart; it != gridItemsWithSpan.rangeEnd;
1767 ++it) {
1768 GridItemWithSpan& gridItemWithSpan = *it;
1769 ASSERT(gridItemWithSpan.getGridSpan().integerSpan() > 1);
1770 const GridSpan& itemSpan = gridItemWithSpan.getGridSpan();
1771
1772 sizingData.growBeyondGrowthLimitsTracks.shrink(0);
1773 sizingData.filteredTracks.shrink(0);
1774 LayoutUnit spanningTracksSize;
1775 for (const auto& trackPosition : itemSpan) {
1776 GridTrackSize trackSize =
1777 gridTrackSize(direction, trackPosition, sizingData);
1778 GridTrack& track = (direction == ForColumns)
1779 ? sizingData.columnTracks[trackPosition]
1780 : sizingData.rowTracks[trackPosition];
1781 spanningTracksSize +=
1782 trackSizeForTrackSizeComputationPhase(phase, track, ForbidInfinity);
1783 if (!shouldProcessTrackForTrackSizeComputationPhase(phase, trackSize))
1784 continue;
1785
1786 sizingData.filteredTracks.push_back(&track);
1787
1788 if (trackShouldGrowBeyondGrowthLimitsForTrackSizeComputationPhase(
1789 phase, trackSize))
1790 sizingData.growBeyondGrowthLimitsTracks.push_back(&track);
1791 }
1792
1793 if (sizingData.filteredTracks.isEmpty())
1794 continue;
1795
1796 spanningTracksSize +=
1797 guttersSize(sizingData.grid(), direction, itemSpan.startLine(),
1798 itemSpan.integerSpan(), sizingData.sizingOperation);
1799
1800 LayoutUnit extraSpace =
1801 currentItemSizeForTrackSizeComputationPhase(
1802 phase, gridItemWithSpan.gridItem(), direction, sizingData) -
1803 spanningTracksSize;
1804 extraSpace = extraSpace.clampNegativeToZero();
1805 auto& tracksToGrowBeyondGrowthLimits =
1806 sizingData.growBeyondGrowthLimitsTracks.isEmpty()
1807 ? sizingData.filteredTracks
1808 : sizingData.growBeyondGrowthLimitsTracks;
1809 distributeSpaceToTracks<phase>(sizingData.filteredTracks,
1810 &tracksToGrowBeyondGrowthLimits, sizingData,
1811 extraSpace);
1812 }
1813
1814 for (const auto& trackIndex : sizingData.contentSizedTracksIndex) {
1815 GridTrack& track = tracks[trackIndex];
1816 markAsInfinitelyGrowableForTrackSizeComputationPhase(phase, track);
1817 updateTrackSizeForTrackSizeComputationPhase(phase, track);
1818 }
1819 }
1820
1821 static bool sortByGridTrackGrowthPotential(const GridTrack* track1,
1822 const GridTrack* track2) {
1823 // This check ensures that we respect the irreflexivity property of the strict
1824 // weak ordering required by std::sort(forall x: NOT x < x).
1825 bool track1HasInfiniteGrowthPotentialWithoutCap =
1826 track1->infiniteGrowthPotential() && !track1->growthLimitCap();
1827 bool track2HasInfiniteGrowthPotentialWithoutCap =
1828 track2->infiniteGrowthPotential() && !track2->growthLimitCap();
1829
1830 if (track1HasInfiniteGrowthPotentialWithoutCap &&
1831 track2HasInfiniteGrowthPotentialWithoutCap)
1832 return false;
1833
1834 if (track1HasInfiniteGrowthPotentialWithoutCap ||
1835 track2HasInfiniteGrowthPotentialWithoutCap)
1836 return track2HasInfiniteGrowthPotentialWithoutCap;
1837
1838 LayoutUnit track1Limit =
1839 track1->growthLimitCap().value_or(track1->growthLimit());
1840 LayoutUnit track2Limit =
1841 track2->growthLimitCap().value_or(track2->growthLimit());
1842 return (track1Limit - track1->baseSize()) <
1843 (track2Limit - track2->baseSize());
1844 }
1845
1846 static void clampGrowthShareIfNeeded(TrackSizeComputationPhase phase,
1847 const GridTrack& track,
1848 LayoutUnit& growthShare) {
1849 if (phase != ResolveMaxContentMaximums || !track.growthLimitCap())
1850 return;
1851
1852 LayoutUnit distanceToCap =
1853 track.growthLimitCap().value() - track.sizeDuringDistribution();
1854 if (distanceToCap <= 0)
1855 return;
1856
1857 growthShare = std::min(growthShare, distanceToCap);
1858 }
1859
1860 template <TrackSizeComputationPhase phase>
1861 void LayoutGrid::distributeSpaceToTracks(
1862 Vector<GridTrack*>& tracks,
1863 Vector<GridTrack*>* growBeyondGrowthLimitsTracks,
1864 GridSizingData& sizingData,
1865 LayoutUnit& availableLogicalSpace) const {
1866 ASSERT(availableLogicalSpace >= 0);
1867
1868 for (auto* track : tracks)
1869 track->setSizeDuringDistribution(
1870 trackSizeForTrackSizeComputationPhase(phase, *track, ForbidInfinity));
1871
1872 if (availableLogicalSpace > 0) {
1873 std::sort(tracks.begin(), tracks.end(), sortByGridTrackGrowthPotential);
1874
1875 size_t tracksSize = tracks.size();
1876 for (size_t i = 0; i < tracksSize; ++i) {
1877 GridTrack& track = *tracks[i];
1878 LayoutUnit availableLogicalSpaceShare =
1879 availableLogicalSpace / (tracksSize - i);
1880 const LayoutUnit& trackBreadth =
1881 trackSizeForTrackSizeComputationPhase(phase, track, ForbidInfinity);
1882 LayoutUnit growthShare =
1883 track.infiniteGrowthPotential()
1884 ? availableLogicalSpaceShare
1885 : std::min(availableLogicalSpaceShare,
1886 track.growthLimit() - trackBreadth);
1887 clampGrowthShareIfNeeded(phase, track, growthShare);
1888 DCHECK_GE(growthShare, 0) << "We must never shrink any grid track or "
1889 "else we can't guarantee we abide by our "
1890 "min-sizing function.";
1891 track.growSizeDuringDistribution(growthShare);
1892 availableLogicalSpace -= growthShare;
1893 }
1894 }
1895
1896 if (availableLogicalSpace > 0 && growBeyondGrowthLimitsTracks) {
1897 // We need to sort them because there might be tracks with growth limit caps
1898 // (like the ones with fit-content()) which cannot indefinitely grow over
1899 // the limits.
1900 if (phase == ResolveMaxContentMaximums)
1901 std::sort(growBeyondGrowthLimitsTracks->begin(),
1902 growBeyondGrowthLimitsTracks->end(),
1903 sortByGridTrackGrowthPotential);
1904
1905 size_t tracksGrowingAboveMaxBreadthSize =
1906 growBeyondGrowthLimitsTracks->size();
1907 for (size_t i = 0; i < tracksGrowingAboveMaxBreadthSize; ++i) {
1908 GridTrack* track = growBeyondGrowthLimitsTracks->at(i);
1909 LayoutUnit growthShare =
1910 availableLogicalSpace / (tracksGrowingAboveMaxBreadthSize - i);
1911 clampGrowthShareIfNeeded(phase, *track, growthShare);
1912 DCHECK_GE(growthShare, 0) << "We must never shrink any grid track or "
1913 "else we can't guarantee we abide by our "
1914 "min-sizing function.";
1915 track->growSizeDuringDistribution(growthShare);
1916 availableLogicalSpace -= growthShare;
1917 }
1918 }
1919
1920 for (auto* track : tracks)
1921 track->setPlannedSize(
1922 track->plannedSize() == infinity
1923 ? track->sizeDuringDistribution()
1924 : std::max(track->plannedSize(), track->sizeDuringDistribution()));
1925 }
1926
1927 #if DCHECK_IS_ON()
1928 bool LayoutGrid::tracksAreWiderThanMinTrackBreadth(
1929 GridTrackSizingDirection direction,
1930 GridSizingData& sizingData) const {
1931 const Vector<GridTrack>& tracks = (direction == ForColumns)
1932 ? sizingData.columnTracks
1933 : sizingData.rowTracks;
1934 LayoutUnit maxSize = sizingData.availableSpace().clampNegativeToZero();
1935 for (size_t i = 0; i < tracks.size(); ++i) {
1936 GridTrackSize trackSize = gridTrackSize(direction, i, sizingData);
1937 if (computeUsedBreadthOfMinLength(trackSize, maxSize) >
1938 tracks[i].baseSize())
1939 return false;
1940 }
1941 return true;
1942 }
1943 #endif
1944
1945 size_t LayoutGrid::computeAutoRepeatTracksCount( 450 size_t LayoutGrid::computeAutoRepeatTracksCount(
1946 GridTrackSizingDirection direction, 451 GridTrackSizingDirection direction,
1947 SizingOperation sizingOperation) const { 452 SizingOperation sizingOperation) const {
1948 bool isRowAxis = direction == ForColumns; 453 bool isRowAxis = direction == ForColumns;
1949 const auto& autoRepeatTracks = isRowAxis ? styleRef().gridAutoRepeatColumns() 454 const auto& autoRepeatTracks = isRowAxis ? styleRef().gridAutoRepeatColumns()
1950 : styleRef().gridAutoRepeatRows(); 455 : styleRef().gridAutoRepeatRows();
1951 size_t autoRepeatTrackListLength = autoRepeatTracks.size(); 456 size_t autoRepeatTrackListLength = autoRepeatTracks.size();
1952 457
1953 if (!autoRepeatTrackListLength) 458 if (!autoRepeatTrackListLength)
1954 return 0; 459 return 0;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
2045 // Clamp the number of repetitions so we don't end up with too many tracks. 550 // Clamp the number of repetitions so we don't end up with too many tracks.
2046 if (repetitions > kGridMaxTracks) { 551 if (repetitions > kGridMaxTracks) {
2047 DCHECK_GT(autoRepeatTrackListLength, 0u); 552 DCHECK_GT(autoRepeatTrackListLength, 0u);
2048 repetitions = 553 repetitions =
2049 (kGridMaxTracks - trackSizes.size()) / autoRepeatTrackListLength; 554 (kGridMaxTracks - trackSizes.size()) / autoRepeatTrackListLength;
2050 } 555 }
2051 556
2052 return repetitions * autoRepeatTrackListLength; 557 return repetitions * autoRepeatTrackListLength;
2053 } 558 }
2054 559
2055 std::unique_ptr<LayoutGrid::OrderedTrackIndexSet> 560 std::unique_ptr<OrderedTrackIndexSet>
2056 LayoutGrid::computeEmptyTracksForAutoRepeat( 561 LayoutGrid::computeEmptyTracksForAutoRepeat(
2057 Grid& grid, 562 Grid& grid,
2058 GridTrackSizingDirection direction) const { 563 GridTrackSizingDirection direction) const {
2059 bool isRowAxis = direction == ForColumns; 564 bool isRowAxis = direction == ForColumns;
2060 if ((isRowAxis && styleRef().gridAutoRepeatColumnsType() != AutoFit) || 565 if ((isRowAxis && styleRef().gridAutoRepeatColumnsType() != AutoFit) ||
2061 (!isRowAxis && styleRef().gridAutoRepeatRowsType() != AutoFit)) 566 (!isRowAxis && styleRef().gridAutoRepeatRowsType() != AutoFit))
2062 return nullptr; 567 return nullptr;
2063 568
2064 std::unique_ptr<OrderedTrackIndexSet> emptyTrackIndexes; 569 std::unique_ptr<OrderedTrackIndexSet> emptyTrackIndexes;
2065 size_t insertionPoint = isRowAxis 570 size_t insertionPoint = isRowAxis
(...skipping 16 matching lines...) Expand all
2082 if (!iterator.nextGridItem()) { 587 if (!iterator.nextGridItem()) {
2083 if (!emptyTrackIndexes) 588 if (!emptyTrackIndexes)
2084 emptyTrackIndexes = WTF::wrapUnique(new OrderedTrackIndexSet); 589 emptyTrackIndexes = WTF::wrapUnique(new OrderedTrackIndexSet);
2085 emptyTrackIndexes->add(trackIndex); 590 emptyTrackIndexes->add(trackIndex);
2086 } 591 }
2087 } 592 }
2088 } 593 }
2089 return emptyTrackIndexes; 594 return emptyTrackIndexes;
2090 } 595 }
2091 596
2092 void LayoutGrid::placeItemsOnGrid(LayoutGrid::Grid& grid, 597 void LayoutGrid::placeItemsOnGrid(Grid& grid,
2093 SizingOperation sizingOperation) const { 598 SizingOperation sizingOperation) const {
2094 size_t autoRepeatRows = 599 size_t autoRepeatRows =
2095 computeAutoRepeatTracksCount(ForRows, sizingOperation); 600 computeAutoRepeatTracksCount(ForRows, sizingOperation);
2096 size_t autoRepeatColumns = 601 size_t autoRepeatColumns =
2097 computeAutoRepeatTracksCount(ForColumns, sizingOperation); 602 computeAutoRepeatTracksCount(ForColumns, sizingOperation);
2098 if (autoRepeatRows != grid.autoRepeatTracks(ForRows) || 603 if (autoRepeatRows != grid.autoRepeatTracks(ForRows) ||
2099 autoRepeatColumns != grid.autoRepeatTracks(ForColumns)) { 604 autoRepeatColumns != grid.autoRepeatTracks(ForColumns)) {
2100 grid.setNeedsItemsPlacement(true); 605 grid.setNeedsItemsPlacement(true);
2101 grid.setAutoRepeatTracks(autoRepeatRows, autoRepeatColumns); 606 grid.setAutoRepeatTracks(autoRepeatRows, autoRepeatColumns);
2102 } 607 }
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
2472 return tracks; 977 return tracks;
2473 } 978 }
2474 979
2475 static const StyleContentAlignmentData& contentAlignmentNormalBehavior() { 980 static const StyleContentAlignmentData& contentAlignmentNormalBehavior() {
2476 static const StyleContentAlignmentData normalBehavior = { 981 static const StyleContentAlignmentData normalBehavior = {
2477 ContentPositionNormal, ContentDistributionStretch}; 982 ContentPositionNormal, ContentDistributionStretch};
2478 return normalBehavior; 983 return normalBehavior;
2479 } 984 }
2480 985
2481 void LayoutGrid::applyStretchAlignmentToTracksIfNeeded( 986 void LayoutGrid::applyStretchAlignmentToTracksIfNeeded(
2482 GridTrackSizingDirection direction, 987 GridTrackSizingDirection direction) {
2483 GridSizingData& sizingData) { 988 LayoutUnit& availableSpace = m_trackSizingAlgorithm.freeSpace(direction);
2484 LayoutUnit& availableSpace = sizingData.freeSpace(direction);
2485 if (availableSpace <= 0 || 989 if (availableSpace <= 0 ||
2486 (direction == ForColumns && 990 (direction == ForColumns &&
2487 styleRef().resolvedJustifyContentDistribution( 991 styleRef().resolvedJustifyContentDistribution(
2488 contentAlignmentNormalBehavior()) != ContentDistributionStretch) || 992 contentAlignmentNormalBehavior()) != ContentDistributionStretch) ||
2489 (direction == ForRows && 993 (direction == ForRows &&
2490 styleRef().resolvedAlignContentDistribution( 994 styleRef().resolvedAlignContentDistribution(
2491 contentAlignmentNormalBehavior()) != ContentDistributionStretch)) 995 contentAlignmentNormalBehavior()) != ContentDistributionStretch))
2492 return; 996 return;
2493 997
2494 // Spec defines auto-sized tracks as the ones with an 'auto' max-sizing 998 // Spec defines auto-sized tracks as the ones with an 'auto' max-sizing
2495 // function. 999 // function.
2496 Vector<GridTrack>& tracks = (direction == ForColumns) 1000 Vector<GridTrack>& allTracks = m_trackSizingAlgorithm.tracks(direction);
2497 ? sizingData.columnTracks
2498 : sizingData.rowTracks;
2499 Vector<unsigned> autoSizedTracksIndex; 1001 Vector<unsigned> autoSizedTracksIndex;
2500 for (unsigned i = 0; i < tracks.size(); ++i) { 1002 for (unsigned i = 0; i < allTracks.size(); ++i) {
2501 const GridTrackSize& trackSize = gridTrackSize(direction, i, sizingData); 1003 const GridTrackSize& trackSize =
1004 m_trackSizingAlgorithm.gridTrackSize(direction, i, TrackSizing);
2502 if (trackSize.hasAutoMaxTrackBreadth()) 1005 if (trackSize.hasAutoMaxTrackBreadth())
2503 autoSizedTracksIndex.push_back(i); 1006 autoSizedTracksIndex.push_back(i);
2504 } 1007 }
2505 1008
2506 unsigned numberOfAutoSizedTracks = autoSizedTracksIndex.size(); 1009 unsigned numberOfAutoSizedTracks = autoSizedTracksIndex.size();
2507 if (numberOfAutoSizedTracks < 1) 1010 if (numberOfAutoSizedTracks < 1)
2508 return; 1011 return;
2509 1012
2510 LayoutUnit sizeToIncrease = availableSpace / numberOfAutoSizedTracks; 1013 LayoutUnit sizeToIncrease = availableSpace / numberOfAutoSizedTracks;
2511 for (const auto& trackIndex : autoSizedTracksIndex) { 1014 for (const auto& trackIndex : autoSizedTracksIndex) {
2512 GridTrack* track = tracks.data() + trackIndex; 1015 GridTrack* track = allTracks.data() + trackIndex;
2513 LayoutUnit baseSize = track->baseSize() + sizeToIncrease; 1016 LayoutUnit baseSize = track->baseSize() + sizeToIncrease;
2514 track->setBaseSize(baseSize); 1017 track->setBaseSize(baseSize);
2515 } 1018 }
1019
2516 availableSpace = LayoutUnit(); 1020 availableSpace = LayoutUnit();
2517 } 1021 }
2518 1022
2519 void LayoutGrid::layoutGridItems(GridSizingData& sizingData) { 1023 void LayoutGrid::layoutGridItems() {
2520 DCHECK_EQ(sizingData.sizingOperation, TrackSizing); 1024 populateGridPositionsForDirection(ForColumns);
2521 populateGridPositionsForDirection(sizingData, ForColumns); 1025 populateGridPositionsForDirection(ForRows);
2522 populateGridPositionsForDirection(sizingData, ForRows);
2523 m_gridItemsOverflowingGridArea.resize(0); 1026 m_gridItemsOverflowingGridArea.resize(0);
2524 1027
2525 for (LayoutBox* child = firstChildBox(); child; 1028 for (LayoutBox* child = firstChildBox(); child;
2526 child = child->nextSiblingBox()) { 1029 child = child->nextSiblingBox()) {
2527 if (child->isOutOfFlowPositioned()) { 1030 if (child->isOutOfFlowPositioned()) {
2528 prepareChildForPositionedLayout(*child); 1031 prepareChildForPositionedLayout(*child);
2529 continue; 1032 continue;
2530 } 1033 }
2531 1034
2532 // Because the grid area cannot be styled, we don't need to adjust 1035 // Because the grid area cannot be styled, we don't need to adjust
2533 // the grid breadth to account for 'box-sizing'. 1036 // the grid breadth to account for 'box-sizing'.
2534 LayoutUnit oldOverrideContainingBlockContentLogicalWidth = 1037 LayoutUnit oldOverrideContainingBlockContentLogicalWidth =
2535 child->hasOverrideContainingBlockLogicalWidth() 1038 child->hasOverrideContainingBlockLogicalWidth()
2536 ? child->overrideContainingBlockContentLogicalWidth() 1039 ? child->overrideContainingBlockContentLogicalWidth()
2537 : LayoutUnit(); 1040 : LayoutUnit();
2538 LayoutUnit oldOverrideContainingBlockContentLogicalHeight = 1041 LayoutUnit oldOverrideContainingBlockContentLogicalHeight =
2539 child->hasOverrideContainingBlockLogicalHeight() 1042 child->hasOverrideContainingBlockLogicalHeight()
2540 ? child->overrideContainingBlockContentLogicalHeight() 1043 ? child->overrideContainingBlockContentLogicalHeight()
2541 : LayoutUnit(); 1044 : LayoutUnit();
2542 1045
2543 LayoutUnit overrideContainingBlockContentLogicalWidth = 1046 LayoutUnit overrideContainingBlockContentLogicalWidth =
2544 gridAreaBreadthForChildIncludingAlignmentOffsets(*child, ForColumns, 1047 gridAreaBreadthForChildIncludingAlignmentOffsets(*child, ForColumns);
2545 sizingData);
2546 LayoutUnit overrideContainingBlockContentLogicalHeight = 1048 LayoutUnit overrideContainingBlockContentLogicalHeight =
2547 gridAreaBreadthForChildIncludingAlignmentOffsets(*child, ForRows, 1049 gridAreaBreadthForChildIncludingAlignmentOffsets(*child, ForRows);
2548 sizingData);
2549 1050
2550 if (oldOverrideContainingBlockContentLogicalWidth != 1051 if (oldOverrideContainingBlockContentLogicalWidth !=
2551 overrideContainingBlockContentLogicalWidth || 1052 overrideContainingBlockContentLogicalWidth ||
2552 (oldOverrideContainingBlockContentLogicalHeight != 1053 (oldOverrideContainingBlockContentLogicalHeight !=
2553 overrideContainingBlockContentLogicalHeight && 1054 overrideContainingBlockContentLogicalHeight &&
2554 child->hasRelativeLogicalHeight())) 1055 child->hasRelativeLogicalHeight()))
2555 child->setNeedsLayout(LayoutInvalidationReason::GridChanged); 1056 child->setNeedsLayout(LayoutInvalidationReason::GridChanged);
2556 1057
2557 child->setOverrideContainingBlockContentLogicalWidth( 1058 child->setOverrideContainingBlockContentLogicalWidth(
2558 overrideContainingBlockContentLogicalWidth); 1059 overrideContainingBlockContentLogicalWidth);
2559 child->setOverrideContainingBlockContentLogicalHeight( 1060 child->setOverrideContainingBlockContentLogicalHeight(
2560 overrideContainingBlockContentLogicalHeight); 1061 overrideContainingBlockContentLogicalHeight);
2561 1062
2562 // Stretching logic might force a child layout, so we need to run it before 1063 // Stretching logic might force a child layout, so we need to run it before
2563 // the layoutIfNeeded call to avoid unnecessary relayouts. This might imply 1064 // the layoutIfNeeded call to avoid unnecessary relayouts. This might imply
2564 // that child margins, needed to correctly determine the available space 1065 // that child margins, needed to correctly determine the available space
2565 // before stretching, are not set yet. 1066 // before stretching, are not set yet.
2566 applyStretchAlignmentToChildIfNeeded(*child); 1067 applyStretchAlignmentToChildIfNeeded(*child);
2567 1068
2568 child->layoutIfNeeded(); 1069 child->layoutIfNeeded();
2569 1070
2570 // We need pending layouts to be done in order to compute auto-margins 1071 // We need pending layouts to be done in order to compute auto-margins
2571 // properly. 1072 // properly.
2572 updateAutoMarginsInColumnAxisIfNeeded(*child); 1073 updateAutoMarginsInColumnAxisIfNeeded(*child);
2573 updateAutoMarginsInRowAxisIfNeeded(*child); 1074 updateAutoMarginsInRowAxisIfNeeded(*child);
2574 1075
2575 const GridArea& area = sizingData.grid().gridItemArea(*child); 1076 const GridArea& area = m_grid.gridItemArea(*child);
2576 #if DCHECK_IS_ON() 1077 #if DCHECK_IS_ON()
2577 ASSERT(area.columns.startLine() < sizingData.columnTracks.size()); 1078 DCHECK(area.columns.startLine() <
2578 ASSERT(area.rows.startLine() < sizingData.rowTracks.size()); 1079 m_trackSizingAlgorithm.tracks(ForColumns).size());
1080 DCHECK(area.rows.startLine() <
1081 m_trackSizingAlgorithm.tracks(ForRows).size());
2579 #endif 1082 #endif
2580 child->setLogicalLocation(findChildLogicalPosition(*child, sizingData)); 1083 child->setLogicalLocation(findChildLogicalPosition(*child));
2581 1084
2582 // Keep track of children overflowing their grid area as we might need to 1085 // Keep track of children overflowing their grid area as we might need to
2583 // paint them even if the grid-area is not visible. Using physical 1086 // paint them even if the grid-area is not visible. Using physical
2584 // dimensions for simplicity, so we can forget about orthogonalty. 1087 // dimensions for simplicity, so we can forget about orthogonalty.
2585 LayoutUnit childGridAreaHeight = 1088 LayoutUnit childGridAreaHeight =
2586 isHorizontalWritingMode() ? overrideContainingBlockContentLogicalHeight 1089 isHorizontalWritingMode() ? overrideContainingBlockContentLogicalHeight
2587 : overrideContainingBlockContentLogicalWidth; 1090 : overrideContainingBlockContentLogicalWidth;
2588 LayoutUnit childGridAreaWidth = 1091 LayoutUnit childGridAreaWidth =
2589 isHorizontalWritingMode() ? overrideContainingBlockContentLogicalWidth 1092 isHorizontalWritingMode() ? overrideContainingBlockContentLogicalWidth
2590 : overrideContainingBlockContentLogicalHeight; 1093 : overrideContainingBlockContentLogicalHeight;
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
2737 1240
2738 if (endLine > 0 && endLine < lastLine) { 1241 if (endLine > 0 && endLine < lastLine) {
2739 DCHECK(!m_grid.needsItemsPlacement()); 1242 DCHECK(!m_grid.needsItemsPlacement());
2740 offset += guttersSize(m_grid, direction, endLine - 1, 2, TrackSizing); 1243 offset += guttersSize(m_grid, direction, endLine - 1, 2, TrackSizing);
2741 offset += isForColumns ? m_offsetBetweenColumns : m_offsetBetweenRows; 1244 offset += isForColumns ? m_offsetBetweenColumns : m_offsetBetweenRows;
2742 } 1245 }
2743 } 1246 }
2744 } 1247 }
2745 } 1248 }
2746 1249
2747 LayoutUnit LayoutGrid::assumedRowsSizeForOrthogonalChild(
2748 const LayoutBox& child,
2749 const GridSizingData& sizingData) const {
2750 DCHECK(isOrthogonalChild(child));
2751 const Grid& grid = sizingData.grid();
2752 const GridSpan& span = grid.gridItemSpan(child, ForRows);
2753 LayoutUnit gridAreaSize;
2754 bool gridAreaIsIndefinite = false;
2755 LayoutUnit containingBlockAvailableSize =
2756 containingBlockLogicalHeightForContent(ExcludeMarginBorderPadding);
2757 for (auto trackPosition : span) {
2758 GridLength maxTrackSize =
2759 gridTrackSize(ForRows, trackPosition, sizingData).maxTrackBreadth();
2760 if (maxTrackSize.isContentSized() || maxTrackSize.isFlex())
2761 gridAreaIsIndefinite = true;
2762 else
2763 gridAreaSize +=
2764 valueForLength(maxTrackSize.length(), containingBlockAvailableSize);
2765 }
2766
2767 gridAreaSize += guttersSize(grid, ForRows, span.startLine(),
2768 span.integerSpan(), sizingData.sizingOperation);
2769
2770 return gridAreaIsIndefinite
2771 ? std::max(child.maxPreferredLogicalWidth(), gridAreaSize)
2772 : gridAreaSize;
2773 }
2774
2775 LayoutUnit LayoutGrid::gridAreaBreadthForChild(
2776 const LayoutBox& child,
2777 GridTrackSizingDirection direction,
2778 const GridSizingData& sizingData) const {
2779 // To determine the column track's size based on an orthogonal grid item we
2780 // need it's logical height, which may depend on the row track's size. It's
2781 // possible that the row tracks sizing logic has not been performed yet, so we
2782 // will need to do an estimation.
2783 if (direction == ForRows &&
2784 sizingData.sizingState == GridSizingData::ColumnSizingFirstIteration)
2785 return assumedRowsSizeForOrthogonalChild(child, sizingData);
2786
2787 const Vector<GridTrack>& tracks =
2788 direction == ForColumns ? sizingData.columnTracks : sizingData.rowTracks;
2789 const GridSpan& span = sizingData.grid().gridItemSpan(child, direction);
2790 LayoutUnit gridAreaBreadth;
2791 for (const auto& trackPosition : span)
2792 gridAreaBreadth += tracks[trackPosition].baseSize();
2793
2794 gridAreaBreadth +=
2795 guttersSize(sizingData.grid(), direction, span.startLine(),
2796 span.integerSpan(), sizingData.sizingOperation);
2797
2798 return gridAreaBreadth;
2799 }
2800
2801 LayoutUnit LayoutGrid::gridAreaBreadthForChildIncludingAlignmentOffsets( 1250 LayoutUnit LayoutGrid::gridAreaBreadthForChildIncludingAlignmentOffsets(
2802 const LayoutBox& child, 1251 const LayoutBox& child,
2803 GridTrackSizingDirection direction, 1252 GridTrackSizingDirection direction) const {
2804 const GridSizingData& sizingData) const {
2805 // We need the cached value when available because Content Distribution 1253 // We need the cached value when available because Content Distribution
2806 // alignment properties may have some influence in the final grid area 1254 // alignment properties may have some influence in the final grid area
2807 // breadth. 1255 // breadth.
2808 const Vector<GridTrack>& tracks = (direction == ForColumns) 1256 const Vector<GridTrack>& tracks = m_trackSizingAlgorithm.tracks(direction);
2809 ? sizingData.columnTracks 1257 const GridSpan& span =
2810 : sizingData.rowTracks; 1258 m_trackSizingAlgorithm.grid().gridItemSpan(child, direction);
2811 const GridSpan& span = sizingData.grid().gridItemSpan(child, direction);
2812 const Vector<LayoutUnit>& linePositions = 1259 const Vector<LayoutUnit>& linePositions =
2813 (direction == ForColumns) ? m_columnPositions : m_rowPositions; 1260 (direction == ForColumns) ? m_columnPositions : m_rowPositions;
2814 LayoutUnit initialTrackPosition = linePositions[span.startLine()]; 1261 LayoutUnit initialTrackPosition = linePositions[span.startLine()];
2815 LayoutUnit finalTrackPosition = linePositions[span.endLine() - 1]; 1262 LayoutUnit finalTrackPosition = linePositions[span.endLine() - 1];
2816 // Track Positions vector stores the 'start' grid line of each track, so we 1263 // Track Positions vector stores the 'start' grid line of each track, so we
2817 // have to add last track's baseSize. 1264 // have to add last track's baseSize.
2818 return finalTrackPosition - initialTrackPosition + 1265 return finalTrackPosition - initialTrackPosition +
2819 tracks[span.endLine() - 1].baseSize(); 1266 tracks[span.endLine() - 1].baseSize();
2820 } 1267 }
2821 1268
2822 void LayoutGrid::populateGridPositionsForDirection( 1269 void LayoutGrid::populateGridPositionsForDirection(
2823 GridSizingData& sizingData,
2824 GridTrackSizingDirection direction) { 1270 GridTrackSizingDirection direction) {
2825 // Since we add alignment offsets and track gutters, grid lines are not always 1271 // Since we add alignment offsets and track gutters, grid lines are not always
2826 // adjacent. Hence we will have to assume from now on that we just store 1272 // adjacent. Hence we will have to assume from now on that we just store
2827 // positions of the initial grid lines of each track, except the last one, 1273 // positions of the initial grid lines of each track, except the last one,
2828 // which is the only one considered as a final grid line of a track. 1274 // which is the only one considered as a final grid line of a track.
2829 1275
2830 // The grid container's frame elements (border, padding and <content-position> 1276 // The grid container's frame elements (border, padding and <content-position>
2831 // offset) are sensible to the inline-axis flow direction. However, column 1277 // offset) are sensible to the inline-axis flow direction. However, column
2832 // lines positions are 'direction' unaware. This simplification allows us to 1278 // lines positions are 'direction' unaware. This simplification allows us to
2833 // use the same indexes to identify the columns independently on the 1279 // use the same indexes to identify the columns independently on the
2834 // inline-axis direction. 1280 // inline-axis direction.
2835 bool isRowAxis = direction == ForColumns; 1281 bool isRowAxis = direction == ForColumns;
2836 auto& tracks = isRowAxis ? sizingData.columnTracks : sizingData.rowTracks; 1282 auto& tracks = m_trackSizingAlgorithm.tracks(direction);
2837 size_t numberOfTracks = tracks.size(); 1283 size_t numberOfTracks = tracks.size();
2838 size_t numberOfLines = numberOfTracks + 1; 1284 size_t numberOfLines = numberOfTracks + 1;
2839 size_t lastLine = numberOfLines - 1; 1285 size_t lastLine = numberOfLines - 1;
2840 ContentAlignmentData offset = computeContentPositionAndDistributionOffset( 1286 ContentAlignmentData offset = computeContentPositionAndDistributionOffset(
2841 direction, sizingData.freeSpace(direction), numberOfTracks); 1287 direction, m_trackSizingAlgorithm.freeSpace(direction), numberOfTracks);
2842 auto& positions = isRowAxis ? m_columnPositions : m_rowPositions; 1288 auto& positions = isRowAxis ? m_columnPositions : m_rowPositions;
2843 positions.resize(numberOfLines); 1289 positions.resize(numberOfLines);
2844 auto borderAndPadding = 1290 auto borderAndPadding =
2845 isRowAxis ? borderAndPaddingLogicalLeft() : borderAndPaddingBefore(); 1291 isRowAxis ? borderAndPaddingLogicalLeft() : borderAndPaddingBefore();
2846 positions[0] = borderAndPadding + offset.positionOffset; 1292 positions[0] = borderAndPadding + offset.positionOffset;
2847 const Grid& grid = sizingData.grid(); 1293 const Grid& grid = m_trackSizingAlgorithm.grid();
2848 if (numberOfLines > 1) { 1294 if (numberOfLines > 1) {
2849 // If we have collapsed tracks we just ignore gaps here and add them later 1295 // If we have collapsed tracks we just ignore gaps here and add them later
2850 // as we might not compute the gap between two consecutive tracks without 1296 // as we might not compute the gap between two consecutive tracks without
2851 // examining the surrounding ones. 1297 // examining the surrounding ones.
2852 bool hasCollapsedTracks = grid.hasAutoRepeatEmptyTracks(direction); 1298 bool hasCollapsedTracks = grid.hasAutoRepeatEmptyTracks(direction);
2853 LayoutUnit gap = 1299 LayoutUnit gap = !hasCollapsedTracks
2854 !hasCollapsedTracks 1300 ? gridGapForDirection(direction, TrackSizing)
2855 ? gridGapForDirection(direction, sizingData.sizingOperation) 1301 : LayoutUnit();
2856 : LayoutUnit();
2857 size_t nextToLastLine = numberOfLines - 2; 1302 size_t nextToLastLine = numberOfLines - 2;
2858 for (size_t i = 0; i < nextToLastLine; ++i) 1303 for (size_t i = 0; i < nextToLastLine; ++i)
2859 positions[i + 1] = 1304 positions[i + 1] =
2860 positions[i] + offset.distributionOffset + tracks[i].baseSize() + gap; 1305 positions[i] + offset.distributionOffset + tracks[i].baseSize() + gap;
2861 positions[lastLine] = 1306 positions[lastLine] =
2862 positions[nextToLastLine] + tracks[nextToLastLine].baseSize(); 1307 positions[nextToLastLine] + tracks[nextToLastLine].baseSize();
2863 1308
2864 // Adjust collapsed gaps. Collapsed tracks cause the surrounding gutters to 1309 // Adjust collapsed gaps. Collapsed tracks cause the surrounding gutters to
2865 // collapse (they coincide exactly) except on the edges of the grid where 1310 // collapse (they coincide exactly) except on the edges of the grid where
2866 // they become 0. 1311 // they become 0.
2867 if (hasCollapsedTracks) { 1312 if (hasCollapsedTracks) {
2868 gap = gridGapForDirection(direction, sizingData.sizingOperation); 1313 gap = gridGapForDirection(direction, TrackSizing);
2869 size_t remainingEmptyTracks = 1314 size_t remainingEmptyTracks =
2870 grid.autoRepeatEmptyTracks(direction)->size(); 1315 grid.autoRepeatEmptyTracks(direction)->size();
2871 LayoutUnit gapAccumulator; 1316 LayoutUnit gapAccumulator;
2872 for (size_t i = 1; i < lastLine; ++i) { 1317 for (size_t i = 1; i < lastLine; ++i) {
2873 if (grid.isEmptyAutoRepeatTrack(direction, i - 1)) { 1318 if (grid.isEmptyAutoRepeatTrack(direction, i - 1)) {
2874 --remainingEmptyTracks; 1319 --remainingEmptyTracks;
2875 } else { 1320 } else {
2876 // Add gap between consecutive non empty tracks. Add it also just once 1321 // Add gap between consecutive non empty tracks. Add it also just once
2877 // for an arbitrary number of empty tracks between two non empty ones. 1322 // for an arbitrary number of empty tracks between two non empty ones.
2878 bool allRemainingTracksAreEmpty = 1323 bool allRemainingTracksAreEmpty =
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
2970 const LayoutBox& child) const { 1415 const LayoutBox& child) const {
2971 if (!child.isAnonymous()) 1416 if (!child.isAnonymous())
2972 return child.styleRef().resolvedJustifySelf(ItemPositionStretch); 1417 return child.styleRef().resolvedJustifySelf(ItemPositionStretch);
2973 // All the 'auto' values has been solved by the StyleAdjuster, but it's 1418 // All the 'auto' values has been solved by the StyleAdjuster, but it's
2974 // possible that some grid items generate Anonymous boxes, which need to be 1419 // possible that some grid items generate Anonymous boxes, which need to be
2975 // solved during layout. 1420 // solved during layout.
2976 return child.styleRef().resolvedJustifySelf(selfAlignmentNormalBehavior(), 1421 return child.styleRef().resolvedJustifySelf(selfAlignmentNormalBehavior(),
2977 style()); 1422 style());
2978 } 1423 }
2979 1424
1425 GridTrackSizingDirection LayoutGrid::flowAwareDirectionForChild(
1426 const LayoutBox& child,
1427 GridTrackSizingDirection direction) const {
1428 return !isOrthogonalChild(child)
1429 ? direction
1430 : (direction == ForColumns ? ForRows : ForColumns);
1431 }
1432
2980 // FIXME: This logic is shared by LayoutFlexibleBox, so it should be moved to 1433 // FIXME: This logic is shared by LayoutFlexibleBox, so it should be moved to
2981 // LayoutBox. 1434 // LayoutBox.
2982 void LayoutGrid::applyStretchAlignmentToChildIfNeeded(LayoutBox& child) { 1435 void LayoutGrid::applyStretchAlignmentToChildIfNeeded(LayoutBox& child) {
2983 // We clear height override values because we will decide now whether it's 1436 // We clear height override values because we will decide now whether it's
2984 // allowed or not, evaluating the conditions which might have changed since 1437 // allowed or not, evaluating the conditions which might have changed since
2985 // the old values were set. 1438 // the old values were set.
2986 child.clearOverrideLogicalContentHeight(); 1439 child.clearOverrideLogicalContentHeight();
2987 1440
2988 GridTrackSizingDirection childBlockDirection = 1441 GridTrackSizingDirection childBlockDirection =
2989 flowAwareDirectionForChild(child, ForRows); 1442 flowAwareDirectionForChild(child, ForRows);
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
3335 return GridAxisStart; 1788 return GridAxisStart;
3336 case ItemPositionAuto: 1789 case ItemPositionAuto:
3337 case ItemPositionNormal: 1790 case ItemPositionNormal:
3338 break; 1791 break;
3339 } 1792 }
3340 1793
3341 ASSERT_NOT_REACHED(); 1794 ASSERT_NOT_REACHED();
3342 return GridAxisStart; 1795 return GridAxisStart;
3343 } 1796 }
3344 1797
3345 LayoutUnit LayoutGrid::columnAxisOffsetForChild( 1798 LayoutUnit LayoutGrid::columnAxisOffsetForChild(const LayoutBox& child) const {
3346 const LayoutBox& child, 1799 const GridSpan& rowsSpan =
3347 GridSizingData& sizingData) const { 1800 m_trackSizingAlgorithm.grid().gridItemSpan(child, ForRows);
3348 const GridSpan& rowsSpan = sizingData.grid().gridItemSpan(child, ForRows);
3349 size_t childStartLine = rowsSpan.startLine(); 1801 size_t childStartLine = rowsSpan.startLine();
3350 LayoutUnit startOfRow = m_rowPositions[childStartLine]; 1802 LayoutUnit startOfRow = m_rowPositions[childStartLine];
3351 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child); 1803 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child);
3352 if (hasAutoMarginsInColumnAxis(child)) 1804 if (hasAutoMarginsInColumnAxis(child))
3353 return startPosition; 1805 return startPosition;
3354 GridAxisPosition axisPosition = columnAxisPositionForChild(child); 1806 GridAxisPosition axisPosition = columnAxisPositionForChild(child);
3355 switch (axisPosition) { 1807 switch (axisPosition) {
3356 case GridAxisStart: 1808 case GridAxisStart:
3357 return startPosition; 1809 return startPosition;
3358 case GridAxisEnd: 1810 case GridAxisEnd:
3359 case GridAxisCenter: { 1811 case GridAxisCenter: {
3360 size_t childEndLine = rowsSpan.endLine(); 1812 size_t childEndLine = rowsSpan.endLine();
3361 LayoutUnit endOfRow = m_rowPositions[childEndLine]; 1813 LayoutUnit endOfRow = m_rowPositions[childEndLine];
3362 // m_rowPositions include distribution offset (because of content 1814 // m_rowPositions include distribution offset (because of content
3363 // alignment) and gutters so we need to subtract them to get the actual 1815 // alignment) and gutters so we need to subtract them to get the actual
3364 // end position for a given row (this does not have to be done for the 1816 // end position for a given row (this does not have to be done for the
3365 // last track as there are no more m_columnPositions after it). 1817 // last track as there are no more m_columnPositions after it).
3366 LayoutUnit trackGap = 1818 LayoutUnit trackGap = gridGapForDirection(ForRows, TrackSizing);
3367 gridGapForDirection(ForRows, sizingData.sizingOperation);
3368 if (childEndLine < m_rowPositions.size() - 1) { 1819 if (childEndLine < m_rowPositions.size() - 1) {
3369 endOfRow -= trackGap; 1820 endOfRow -= trackGap;
3370 endOfRow -= m_offsetBetweenRows; 1821 endOfRow -= m_offsetBetweenRows;
3371 } 1822 }
3372 LayoutUnit columnAxisChildSize = 1823 LayoutUnit columnAxisChildSize =
3373 isOrthogonalChild(child) 1824 isOrthogonalChild(child)
3374 ? child.logicalWidth() + child.marginLogicalWidth() 1825 ? child.logicalWidth() + child.marginLogicalWidth()
3375 : child.logicalHeight() + child.marginLogicalHeight(); 1826 : child.logicalHeight() + child.marginLogicalHeight();
3376 OverflowAlignment overflow = alignSelfForChild(child).overflow(); 1827 OverflowAlignment overflow = alignSelfForChild(child).overflow();
3377 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset( 1828 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(
3378 overflow, endOfRow - startOfRow, columnAxisChildSize); 1829 overflow, endOfRow - startOfRow, columnAxisChildSize);
3379 return startPosition + (axisPosition == GridAxisEnd 1830 return startPosition + (axisPosition == GridAxisEnd
3380 ? offsetFromStartPosition 1831 ? offsetFromStartPosition
3381 : offsetFromStartPosition / 2); 1832 : offsetFromStartPosition / 2);
3382 } 1833 }
3383 } 1834 }
3384 1835
3385 ASSERT_NOT_REACHED(); 1836 ASSERT_NOT_REACHED();
3386 return LayoutUnit(); 1837 return LayoutUnit();
3387 } 1838 }
3388 1839
3389 LayoutUnit LayoutGrid::rowAxisOffsetForChild(const LayoutBox& child, 1840 LayoutUnit LayoutGrid::rowAxisOffsetForChild(const LayoutBox& child) const {
3390 GridSizingData& sizingData) const {
3391 const GridSpan& columnsSpan = 1841 const GridSpan& columnsSpan =
3392 sizingData.grid().gridItemSpan(child, ForColumns); 1842 m_trackSizingAlgorithm.grid().gridItemSpan(child, ForColumns);
3393 size_t childStartLine = columnsSpan.startLine(); 1843 size_t childStartLine = columnsSpan.startLine();
3394 LayoutUnit startOfColumn = m_columnPositions[childStartLine]; 1844 LayoutUnit startOfColumn = m_columnPositions[childStartLine];
3395 LayoutUnit startPosition = startOfColumn + marginStartForChild(child); 1845 LayoutUnit startPosition = startOfColumn + marginStartForChild(child);
3396 if (hasAutoMarginsInRowAxis(child)) 1846 if (hasAutoMarginsInRowAxis(child))
3397 return startPosition; 1847 return startPosition;
3398 GridAxisPosition axisPosition = rowAxisPositionForChild(child); 1848 GridAxisPosition axisPosition = rowAxisPositionForChild(child);
3399 switch (axisPosition) { 1849 switch (axisPosition) {
3400 case GridAxisStart: 1850 case GridAxisStart:
3401 return startPosition; 1851 return startPosition;
3402 case GridAxisEnd: 1852 case GridAxisEnd:
3403 case GridAxisCenter: { 1853 case GridAxisCenter: {
3404 size_t childEndLine = columnsSpan.endLine(); 1854 size_t childEndLine = columnsSpan.endLine();
3405 LayoutUnit endOfColumn = m_columnPositions[childEndLine]; 1855 LayoutUnit endOfColumn = m_columnPositions[childEndLine];
3406 // m_columnPositions include distribution offset (because of content 1856 // m_columnPositions include distribution offset (because of content
3407 // alignment) and gutters so we need to subtract them to get the actual 1857 // alignment) and gutters so we need to subtract them to get the actual
3408 // end position for a given column (this does not have to be done for the 1858 // end position for a given column (this does not have to be done for the
3409 // last track as there are no more m_columnPositions after it). 1859 // last track as there are no more m_columnPositions after it).
3410 LayoutUnit trackGap = 1860 LayoutUnit trackGap = gridGapForDirection(ForColumns, TrackSizing);
3411 gridGapForDirection(ForColumns, sizingData.sizingOperation);
3412 if (childEndLine < m_columnPositions.size() - 1) { 1861 if (childEndLine < m_columnPositions.size() - 1) {
3413 endOfColumn -= trackGap; 1862 endOfColumn -= trackGap;
3414 endOfColumn -= m_offsetBetweenColumns; 1863 endOfColumn -= m_offsetBetweenColumns;
3415 } 1864 }
3416 LayoutUnit rowAxisChildSize = 1865 LayoutUnit rowAxisChildSize =
3417 isOrthogonalChild(child) 1866 isOrthogonalChild(child)
3418 ? child.logicalHeight() + child.marginLogicalHeight() 1867 ? child.logicalHeight() + child.marginLogicalHeight()
3419 : child.logicalWidth() + child.marginLogicalWidth(); 1868 : child.logicalWidth() + child.marginLogicalWidth();
3420 OverflowAlignment overflow = justifySelfForChild(child).overflow(); 1869 OverflowAlignment overflow = justifySelfForChild(child).overflow();
3421 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset( 1870 LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
3562 2011
3563 LayoutUnit LayoutGrid::translateRTLCoordinate(LayoutUnit coordinate) const { 2012 LayoutUnit LayoutGrid::translateRTLCoordinate(LayoutUnit coordinate) const {
3564 ASSERT(!styleRef().isLeftToRightDirection()); 2013 ASSERT(!styleRef().isLeftToRightDirection());
3565 2014
3566 LayoutUnit alignmentOffset = m_columnPositions[0]; 2015 LayoutUnit alignmentOffset = m_columnPositions[0];
3567 LayoutUnit rightGridEdgePosition = 2016 LayoutUnit rightGridEdgePosition =
3568 m_columnPositions[m_columnPositions.size() - 1]; 2017 m_columnPositions[m_columnPositions.size() - 1];
3569 return rightGridEdgePosition + alignmentOffset - coordinate; 2018 return rightGridEdgePosition + alignmentOffset - coordinate;
3570 } 2019 }
3571 2020
3572 LayoutPoint LayoutGrid::findChildLogicalPosition( 2021 LayoutPoint LayoutGrid::findChildLogicalPosition(const LayoutBox& child) const {
3573 const LayoutBox& child, 2022 LayoutUnit columnAxisOffset = columnAxisOffsetForChild(child);
3574 GridSizingData& sizingData) const { 2023 LayoutUnit rowAxisOffset = rowAxisOffsetForChild(child);
3575 LayoutUnit columnAxisOffset = columnAxisOffsetForChild(child, sizingData);
3576 LayoutUnit rowAxisOffset = rowAxisOffsetForChild(child, sizingData);
3577 // We stored m_columnPosition's data ignoring the direction, hence we might 2024 // We stored m_columnPosition's data ignoring the direction, hence we might
3578 // need now to translate positions from RTL to LTR, as it's more convenient 2025 // need now to translate positions from RTL to LTR, as it's more convenient
3579 // for painting. 2026 // for painting.
3580 if (!style()->isLeftToRightDirection()) 2027 if (!style()->isLeftToRightDirection())
3581 rowAxisOffset = translateRTLCoordinate(rowAxisOffset) - 2028 rowAxisOffset = translateRTLCoordinate(rowAxisOffset) -
3582 (isOrthogonalChild(child) ? child.logicalHeight() 2029 (isOrthogonalChild(child) ? child.logicalHeight()
3583 : child.logicalWidth()); 2030 : child.logicalWidth());
3584 2031
3585 // "In the positioning phase [...] calculations are performed according to the 2032 // "In the positioning phase [...] calculations are performed according to the
3586 // writing mode of the containing block of the box establishing the orthogonal 2033 // writing mode of the containing block of the box establishing the orthogonal
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3628 if (direction == ForRows) 2075 if (direction == ForRows)
3629 return grid.numTracks(ForRows); 2076 return grid.numTracks(ForRows);
3630 2077
3631 return grid.numTracks(ForRows) 2078 return grid.numTracks(ForRows)
3632 ? grid.numTracks(ForColumns) 2079 ? grid.numTracks(ForColumns)
3633 : GridPositionsResolver::explicitGridColumnCount( 2080 : GridPositionsResolver::explicitGridColumnCount(
3634 styleRef(), grid.autoRepeatTracks(ForColumns)); 2081 styleRef(), grid.autoRepeatTracks(ForColumns));
3635 } 2082 }
3636 2083
3637 } // namespace blink 2084 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutGrid.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698