OLD | NEW |
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 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 enum TrackSizeRestriction { | 143 enum TrackSizeRestriction { |
144 AllowInfinity, | 144 AllowInfinity, |
145 ForbidInfinity, | 145 ForbidInfinity, |
146 }; | 146 }; |
147 | 147 |
148 class LayoutGrid::GridIterator { | 148 class LayoutGrid::GridIterator { |
149 WTF_MAKE_NONCOPYABLE(GridIterator); | 149 WTF_MAKE_NONCOPYABLE(GridIterator); |
150 | 150 |
151 public: | 151 public: |
152 // |direction| is the direction that is fixed to |fixedTrackIndex| so e.g | 152 // |direction| is the direction that is fixed to |fixedTrackIndex| so e.g |
153 // GridIterator(m_grid, ForColumns, 1) will walk over the rows of the 2nd colu
mn. | 153 // GridIterator(m_grid, ForColumns, 1) will walk over the rows of the 2nd |
| 154 // column. |
154 GridIterator(const GridRepresentation& grid, | 155 GridIterator(const GridRepresentation& grid, |
155 GridTrackSizingDirection direction, | 156 GridTrackSizingDirection direction, |
156 size_t fixedTrackIndex, | 157 size_t fixedTrackIndex, |
157 size_t varyingTrackIndex = 0) | 158 size_t varyingTrackIndex = 0) |
158 : m_grid(grid), | 159 : m_grid(grid), |
159 m_direction(direction), | 160 m_direction(direction), |
160 m_rowIndex((direction == ForColumns) ? varyingTrackIndex | 161 m_rowIndex((direction == ForColumns) ? varyingTrackIndex |
161 : fixedTrackIndex), | 162 : fixedTrackIndex), |
162 m_columnIndex((direction == ForColumns) ? fixedTrackIndex | 163 m_columnIndex((direction == ForColumns) ? fixedTrackIndex |
163 : varyingTrackIndex), | 164 : varyingTrackIndex), |
(...skipping 23 matching lines...) Expand all Loading... |
187 } | 188 } |
188 | 189 |
189 bool checkEmptyCells(size_t rowSpan, size_t columnSpan) const { | 190 bool checkEmptyCells(size_t rowSpan, size_t columnSpan) const { |
190 DCHECK(!m_grid.isEmpty()); | 191 DCHECK(!m_grid.isEmpty()); |
191 DCHECK(!m_grid[0].isEmpty()); | 192 DCHECK(!m_grid[0].isEmpty()); |
192 | 193 |
193 // Ignore cells outside current grid as we will grow it later if needed. | 194 // Ignore cells outside current grid as we will grow it later if needed. |
194 size_t maxRows = std::min(m_rowIndex + rowSpan, m_grid.size()); | 195 size_t maxRows = std::min(m_rowIndex + rowSpan, m_grid.size()); |
195 size_t maxColumns = std::min(m_columnIndex + columnSpan, m_grid[0].size()); | 196 size_t maxColumns = std::min(m_columnIndex + columnSpan, m_grid[0].size()); |
196 | 197 |
197 // This adds a O(N^2) behavior that shouldn't be a big deal as we expect spa
nning areas to be small. | 198 // This adds a O(N^2) behavior that shouldn't be a big deal as we expect |
| 199 // spanning areas to be small. |
198 for (size_t row = m_rowIndex; row < maxRows; ++row) { | 200 for (size_t row = m_rowIndex; row < maxRows; ++row) { |
199 for (size_t column = m_columnIndex; column < maxColumns; ++column) { | 201 for (size_t column = m_columnIndex; column < maxColumns; ++column) { |
200 const GridCell& children = m_grid[row][column]; | 202 const GridCell& children = m_grid[row][column]; |
201 if (!children.isEmpty()) | 203 if (!children.isEmpty()) |
202 return false; | 204 return false; |
203 } | 205 } |
204 } | 206 } |
205 | 207 |
206 return true; | 208 return true; |
207 } | 209 } |
(...skipping 13 matching lines...) Expand all Loading... |
221 (m_direction == ForColumns) ? m_rowIndex : m_columnIndex; | 223 (m_direction == ForColumns) ? m_rowIndex : m_columnIndex; |
222 const size_t endOfVaryingTrackIndex = | 224 const size_t endOfVaryingTrackIndex = |
223 (m_direction == ForColumns) ? m_grid.size() : m_grid[0].size(); | 225 (m_direction == ForColumns) ? m_grid.size() : m_grid[0].size(); |
224 for (; varyingTrackIndex < endOfVaryingTrackIndex; ++varyingTrackIndex) { | 226 for (; varyingTrackIndex < endOfVaryingTrackIndex; ++varyingTrackIndex) { |
225 if (checkEmptyCells(rowSpan, columnSpan)) { | 227 if (checkEmptyCells(rowSpan, columnSpan)) { |
226 std::unique_ptr<GridArea> result = wrapUnique( | 228 std::unique_ptr<GridArea> result = wrapUnique( |
227 new GridArea(GridSpan::translatedDefiniteGridSpan( | 229 new GridArea(GridSpan::translatedDefiniteGridSpan( |
228 m_rowIndex, m_rowIndex + rowSpan), | 230 m_rowIndex, m_rowIndex + rowSpan), |
229 GridSpan::translatedDefiniteGridSpan( | 231 GridSpan::translatedDefiniteGridSpan( |
230 m_columnIndex, m_columnIndex + columnSpan))); | 232 m_columnIndex, m_columnIndex + columnSpan))); |
231 // Advance the iterator to avoid an infinite loop where we would return
the same grid area over and over. | 233 // Advance the iterator to avoid an infinite loop where we would return |
| 234 // the same grid area over and over. |
232 ++varyingTrackIndex; | 235 ++varyingTrackIndex; |
233 return result; | 236 return result; |
234 } | 237 } |
235 } | 238 } |
236 return nullptr; | 239 return nullptr; |
237 } | 240 } |
238 | 241 |
239 private: | 242 private: |
240 const GridRepresentation& m_grid; | 243 const GridRepresentation& m_grid; |
241 GridTrackSizingDirection m_direction; | 244 GridTrackSizingDirection m_direction; |
242 size_t m_rowIndex; | 245 size_t m_rowIndex; |
243 size_t m_columnIndex; | 246 size_t m_columnIndex; |
244 size_t m_childIndex; | 247 size_t m_childIndex; |
245 }; | 248 }; |
246 | 249 |
247 struct LayoutGrid::GridSizingData { | 250 struct LayoutGrid::GridSizingData { |
248 WTF_MAKE_NONCOPYABLE(GridSizingData); | 251 WTF_MAKE_NONCOPYABLE(GridSizingData); |
249 STACK_ALLOCATED(); | 252 STACK_ALLOCATED(); |
250 | 253 |
251 public: | 254 public: |
252 GridSizingData(size_t gridColumnCount, size_t gridRowCount) | 255 GridSizingData(size_t gridColumnCount, size_t gridRowCount) |
253 : columnTracks(gridColumnCount), rowTracks(gridRowCount) {} | 256 : columnTracks(gridColumnCount), rowTracks(gridRowCount) {} |
254 | 257 |
255 Vector<GridTrack> columnTracks; | 258 Vector<GridTrack> columnTracks; |
256 Vector<GridTrack> rowTracks; | 259 Vector<GridTrack> rowTracks; |
257 Vector<size_t> contentSizedTracksIndex; | 260 Vector<size_t> contentSizedTracksIndex; |
258 | 261 |
259 // Performance optimization: hold onto these Vectors until the end of Layout t
o avoid repeated malloc / free. | 262 // Performance optimization: hold onto these Vectors until the end of Layout |
| 263 // to avoid repeated malloc / free. |
260 Vector<GridTrack*> filteredTracks; | 264 Vector<GridTrack*> filteredTracks; |
261 Vector<GridItemWithSpan> itemsSortedByIncreasingSpan; | 265 Vector<GridItemWithSpan> itemsSortedByIncreasingSpan; |
262 Vector<GridTrack*> growBeyondGrowthLimitsTracks; | 266 Vector<GridTrack*> growBeyondGrowthLimitsTracks; |
263 | 267 |
264 LayoutUnit& freeSpace(GridTrackSizingDirection direction) { | 268 LayoutUnit& freeSpace(GridTrackSizingDirection direction) { |
265 return direction == ForColumns ? freeSpaceForColumns : freeSpaceForRows; | 269 return direction == ForColumns ? freeSpaceForColumns : freeSpaceForRows; |
266 } | 270 } |
267 | 271 |
268 LayoutUnit availableSpace() const { return m_availableSpace; } | 272 LayoutUnit availableSpace() const { return m_availableSpace; } |
269 void setAvailableSpace(LayoutUnit availableSpace) { | 273 void setAvailableSpace(LayoutUnit availableSpace) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 case RowSizingSecondIteration: | 309 case RowSizingSecondIteration: |
306 return direction == ForRows; | 310 return direction == ForRows; |
307 } | 311 } |
308 NOTREACHED(); | 312 NOTREACHED(); |
309 return false; | 313 return false; |
310 } | 314 } |
311 | 315 |
312 private: | 316 private: |
313 LayoutUnit freeSpaceForColumns{}; | 317 LayoutUnit freeSpaceForColumns{}; |
314 LayoutUnit freeSpaceForRows{}; | 318 LayoutUnit freeSpaceForRows{}; |
315 // No need to store one per direction as it will be only used for computations
during each axis | 319 // No need to store one per direction as it will be only used for computations |
316 // track sizing. It's cached here because we need it to compute relative sizes
. | 320 // during each axis track sizing. It's cached here because we need it to |
| 321 // compute relative sizes. |
317 LayoutUnit m_availableSpace; | 322 LayoutUnit m_availableSpace; |
318 }; | 323 }; |
319 | 324 |
320 struct GridItemsSpanGroupRange { | 325 struct GridItemsSpanGroupRange { |
321 Vector<GridItemWithSpan>::iterator rangeStart; | 326 Vector<GridItemWithSpan>::iterator rangeStart; |
322 Vector<GridItemWithSpan>::iterator rangeEnd; | 327 Vector<GridItemWithSpan>::iterator rangeEnd; |
323 }; | 328 }; |
324 | 329 |
325 LayoutGrid::LayoutGrid(Element* element) | 330 LayoutGrid::LayoutGrid(Element* element) |
326 : LayoutBlock(element), m_gridIsDirty(true), m_orderIterator(this) { | 331 : LayoutBlock(element), m_gridIsDirty(true), m_orderIterator(this) { |
327 ASSERT(!childrenInline()); | 332 ASSERT(!childrenInline()); |
328 } | 333 } |
329 | 334 |
330 LayoutGrid::~LayoutGrid() {} | 335 LayoutGrid::~LayoutGrid() {} |
331 | 336 |
332 LayoutGrid* LayoutGrid::createAnonymous(Document* document) { | 337 LayoutGrid* LayoutGrid::createAnonymous(Document* document) { |
333 LayoutGrid* layoutGrid = new LayoutGrid(nullptr); | 338 LayoutGrid* layoutGrid = new LayoutGrid(nullptr); |
334 layoutGrid->setDocumentForAnonymous(document); | 339 layoutGrid->setDocumentForAnonymous(document); |
335 return layoutGrid; | 340 return layoutGrid; |
336 } | 341 } |
337 | 342 |
338 void LayoutGrid::addChild(LayoutObject* newChild, LayoutObject* beforeChild) { | 343 void LayoutGrid::addChild(LayoutObject* newChild, LayoutObject* beforeChild) { |
339 LayoutBlock::addChild(newChild, beforeChild); | 344 LayoutBlock::addChild(newChild, beforeChild); |
340 | 345 |
341 // The grid needs to be recomputed as it might contain auto-placed items that
will change their position. | 346 // The grid needs to be recomputed as it might contain auto-placed items that |
| 347 // will change their position. |
342 dirtyGrid(); | 348 dirtyGrid(); |
343 } | 349 } |
344 | 350 |
345 void LayoutGrid::removeChild(LayoutObject* child) { | 351 void LayoutGrid::removeChild(LayoutObject* child) { |
346 LayoutBlock::removeChild(child); | 352 LayoutBlock::removeChild(child); |
347 | 353 |
348 // The grid needs to be recomputed as it might contain auto-placed items that
will change their position. | 354 // The grid needs to be recomputed as it might contain auto-placed items that |
| 355 // will change their position. |
349 dirtyGrid(); | 356 dirtyGrid(); |
350 } | 357 } |
351 | 358 |
352 void LayoutGrid::styleDidChange(StyleDifference diff, | 359 void LayoutGrid::styleDidChange(StyleDifference diff, |
353 const ComputedStyle* oldStyle) { | 360 const ComputedStyle* oldStyle) { |
354 LayoutBlock::styleDidChange(diff, oldStyle); | 361 LayoutBlock::styleDidChange(diff, oldStyle); |
355 if (!oldStyle) | 362 if (!oldStyle) |
356 return; | 363 return; |
357 | 364 |
358 // FIXME: The following checks could be narrowed down if we kept track of whic
h type of grid items we have: | 365 // FIXME: The following checks could be narrowed down if we kept track of |
359 // - explicit grid size changes impact negative explicitely positioned and aut
o-placed grid items. | 366 // which type of grid items we have: |
| 367 // - explicit grid size changes impact negative explicitely positioned and |
| 368 // auto-placed grid items. |
360 // - named grid lines only impact grid items with named grid lines. | 369 // - named grid lines only impact grid items with named grid lines. |
361 // - auto-flow changes only impacts auto-placed children. | 370 // - auto-flow changes only impacts auto-placed children. |
362 | 371 |
363 if (explicitGridDidResize(*oldStyle) || | 372 if (explicitGridDidResize(*oldStyle) || |
364 namedGridLinesDefinitionDidChange(*oldStyle) || | 373 namedGridLinesDefinitionDidChange(*oldStyle) || |
365 oldStyle->getGridAutoFlow() != styleRef().getGridAutoFlow() || | 374 oldStyle->getGridAutoFlow() != styleRef().getGridAutoFlow() || |
366 (diff.needsLayout() && (styleRef().gridAutoRepeatColumns().size() || | 375 (diff.needsLayout() && (styleRef().gridAutoRepeatColumns().size() || |
367 styleRef().gridAutoRepeatRows().size()))) | 376 styleRef().gridAutoRepeatRows().size()))) |
368 dirtyGrid(); | 377 dirtyGrid(); |
369 } | 378 } |
(...skipping 14 matching lines...) Expand all Loading... |
384 } | 393 } |
385 | 394 |
386 bool LayoutGrid::namedGridLinesDefinitionDidChange( | 395 bool LayoutGrid::namedGridLinesDefinitionDidChange( |
387 const ComputedStyle& oldStyle) const { | 396 const ComputedStyle& oldStyle) const { |
388 return oldStyle.namedGridRowLines() != styleRef().namedGridRowLines() || | 397 return oldStyle.namedGridRowLines() != styleRef().namedGridRowLines() || |
389 oldStyle.namedGridColumnLines() != styleRef().namedGridColumnLines(); | 398 oldStyle.namedGridColumnLines() != styleRef().namedGridColumnLines(); |
390 } | 399 } |
391 | 400 |
392 size_t LayoutGrid::gridColumnCount() const { | 401 size_t LayoutGrid::gridColumnCount() const { |
393 DCHECK(!m_gridIsDirty); | 402 DCHECK(!m_gridIsDirty); |
394 // Due to limitations in our internal representation, we cannot know the numbe
r of columns from | 403 // Due to limitations in our internal representation, we cannot know the |
395 // m_grid *if* there is no row (because m_grid would be empty). That's why in
that case we need | 404 // number of columns from m_grid *if* there is no row (because m_grid would be |
396 // to get it from the style. Note that we know for sure that there are't any i
mplicit tracks, | 405 // empty). That's why in that case we need to get it from the style. Note that |
397 // because not having rows implies that there are no "normal" children (out-of
-flow children are | 406 // we know for sure that there are't any implicit tracks, because not having |
| 407 // rows implies that there are no "normal" children (out-of-flow children are |
398 // not stored in m_grid). | 408 // not stored in m_grid). |
399 return m_grid.size() ? m_grid[0].size() | 409 return m_grid.size() ? m_grid[0].size() |
400 : GridPositionsResolver::explicitGridColumnCount( | 410 : GridPositionsResolver::explicitGridColumnCount( |
401 styleRef(), m_autoRepeatColumns); | 411 styleRef(), m_autoRepeatColumns); |
402 } | 412 } |
403 | 413 |
404 size_t LayoutGrid::gridRowCount() const { | 414 size_t LayoutGrid::gridRowCount() const { |
405 DCHECK(!m_gridIsDirty); | 415 DCHECK(!m_gridIsDirty); |
406 return m_grid.size(); | 416 return m_grid.size(); |
407 } | 417 } |
(...skipping 29 matching lines...) Expand all Loading... |
437 growthLimits); | 447 growthLimits); |
438 ASSERT(tracksAreWiderThanMinTrackBreadth(direction, sizingData)); | 448 ASSERT(tracksAreWiderThanMinTrackBreadth(direction, sizingData)); |
439 sizingData.nextState(); | 449 sizingData.nextState(); |
440 } | 450 } |
441 | 451 |
442 void LayoutGrid::repeatTracksSizingIfNeeded(GridSizingData& sizingData, | 452 void LayoutGrid::repeatTracksSizingIfNeeded(GridSizingData& sizingData, |
443 LayoutUnit availableSpaceForColumns, | 453 LayoutUnit availableSpaceForColumns, |
444 LayoutUnit availableSpaceForRows) { | 454 LayoutUnit availableSpaceForRows) { |
445 DCHECK(sizingData.sizingState > GridSizingData::RowSizingFirstIteration); | 455 DCHECK(sizingData.sizingState > GridSizingData::RowSizingFirstIteration); |
446 | 456 |
447 // In orthogonal flow cases column track's size is determined by using the com
puted | 457 // In orthogonal flow cases column track's size is determined by using the |
448 // row track's size, which it was estimated during the first cycle of the sizi
ng | 458 // computed row track's size, which it was estimated during the first cycle of |
449 // algorithm. Hence we need to repeat computeUsedBreadthOfGridTracks for both, | 459 // the sizing algorithm. |
450 // columns and rows, to determine the final values. | 460 // Hence we need to repeat computeUsedBreadthOfGridTracks for both, columns |
| 461 // and rows, to determine the final values. |
451 // TODO (lajava): orthogonal flows is just one of the cases which may require | 462 // TODO (lajava): orthogonal flows is just one of the cases which may require |
452 // a new cycle of the sizing algorithm; there may be more. In addition, not al
l the | 463 // a new cycle of the sizing algorithm; there may be more. In addition, not |
453 // cases with orthogonal flows require this extra cycle; we need a more specif
ic | 464 // all the cases with orthogonal flows require this extra cycle; we need a |
454 // condition to detect whether child's min-content contribution has changed or
not. | 465 // more specific condition to detect whether child's min-content contribution |
| 466 // has changed or not. |
455 if (m_hasAnyOrthogonalChild) { | 467 if (m_hasAnyOrthogonalChild) { |
456 computeTrackSizesForDefiniteSize(ForColumns, sizingData, | 468 computeTrackSizesForDefiniteSize(ForColumns, sizingData, |
457 availableSpaceForColumns); | 469 availableSpaceForColumns); |
458 computeTrackSizesForDefiniteSize(ForRows, sizingData, | 470 computeTrackSizesForDefiniteSize(ForRows, sizingData, |
459 availableSpaceForRows); | 471 availableSpaceForRows); |
460 } | 472 } |
461 } | 473 } |
462 | 474 |
463 void LayoutGrid::layoutBlock(bool relayoutChildren) { | 475 void LayoutGrid::layoutBlock(bool relayoutChildren) { |
464 ASSERT(needsLayout()); | 476 ASSERT(needsLayout()); |
465 | 477 |
466 if (!relayoutChildren && simplifiedLayout()) | 478 if (!relayoutChildren && simplifiedLayout()) |
467 return; | 479 return; |
468 | 480 |
469 SubtreeLayoutScope layoutScope(*this); | 481 SubtreeLayoutScope layoutScope(*this); |
470 | 482 |
471 { | 483 { |
472 // LayoutState needs this deliberate scope to pop before updating scroll inf
ormation (which | 484 // LayoutState needs this deliberate scope to pop before updating scroll |
473 // may trigger relayout). | 485 // information (which may trigger relayout). |
474 LayoutState state(*this, locationOffset()); | 486 LayoutState state(*this, locationOffset()); |
475 | 487 |
476 LayoutSize previousSize = size(); | 488 LayoutSize previousSize = size(); |
477 | 489 |
478 updateLogicalWidth(); | 490 updateLogicalWidth(); |
479 m_hasDefiniteLogicalHeight = hasDefiniteLogicalHeight(); | 491 m_hasDefiniteLogicalHeight = hasDefiniteLogicalHeight(); |
480 | 492 |
481 TextAutosizer::LayoutScope textAutosizerLayoutScope(this, &layoutScope); | 493 TextAutosizer::LayoutScope textAutosizerLayoutScope(this, &layoutScope); |
482 | 494 |
483 // TODO(svillar): we won't need to do this once the intrinsic width computat
ion is isolated | 495 // TODO(svillar): we won't need to do this once the intrinsic width |
484 // from the LayoutGrid object state (it should not touch any attribute) (see
crbug.com/627812) | 496 // computation is isolated from the LayoutGrid object state (it should not |
| 497 // touch any attribute) (see crbug.com/627812) |
485 if (m_autoRepeatColumns && | 498 if (m_autoRepeatColumns && |
486 m_autoRepeatColumns != | 499 m_autoRepeatColumns != |
487 computeAutoRepeatTracksCount(ForColumns, TrackSizing)) | 500 computeAutoRepeatTracksCount(ForColumns, TrackSizing)) |
488 dirtyGrid(); | 501 dirtyGrid(); |
489 placeItemsOnGrid(TrackSizing); | 502 placeItemsOnGrid(TrackSizing); |
490 | 503 |
491 GridSizingData sizingData(gridColumnCount(), gridRowCount()); | 504 GridSizingData sizingData(gridColumnCount(), gridRowCount()); |
492 | 505 |
493 // 1- First, the track sizing algorithm is used to resolve the sizes of the
grid columns. | 506 // 1- First, the track sizing algorithm is used to resolve the sizes of the |
494 // At this point the logical width is always definite as the above call to u
pdateLogicalWidth() | 507 // grid columns. |
495 // properly resolves intrinsic sizes. We cannot do the same for heights thou
gh because many code | 508 // At this point the logical width is always definite as the above call to |
496 // paths inside updateLogicalHeight() require a previous call to setLogicalH
eight() to resolve | 509 // updateLogicalWidth() properly resolves intrinsic sizes. We cannot do the |
497 // heights properly (like for positioned items for example). | 510 // same for heights though because many code paths inside |
| 511 // updateLogicalHeight() require a previous call to setLogicalHeight() to |
| 512 // resolve heights properly (like for positioned items for example). |
498 LayoutUnit availableSpaceForColumns = availableLogicalWidth(); | 513 LayoutUnit availableSpaceForColumns = availableLogicalWidth(); |
499 computeTrackSizesForDefiniteSize(ForColumns, sizingData, | 514 computeTrackSizesForDefiniteSize(ForColumns, sizingData, |
500 availableSpaceForColumns); | 515 availableSpaceForColumns); |
501 | 516 |
502 // 2- Next, the track sizing algorithm resolves the sizes of the grid rows,
using the | 517 // 2- Next, the track sizing algorithm resolves the sizes of the grid rows, |
503 // grid column sizes calculated in the previous step. | 518 // using the grid column sizes calculated in the previous step. |
504 if (cachedHasDefiniteLogicalHeight()) { | 519 if (cachedHasDefiniteLogicalHeight()) { |
505 computeTrackSizesForDefiniteSize( | 520 computeTrackSizesForDefiniteSize( |
506 ForRows, sizingData, | 521 ForRows, sizingData, |
507 availableLogicalHeight(ExcludeMarginBorderPadding)); | 522 availableLogicalHeight(ExcludeMarginBorderPadding)); |
508 } else { | 523 } else { |
509 computeTrackSizesForIndefiniteSize( | 524 computeTrackSizesForIndefiniteSize( |
510 ForRows, sizingData, m_minContentHeight, m_maxContentHeight); | 525 ForRows, sizingData, m_minContentHeight, m_maxContentHeight); |
511 sizingData.nextState(); | 526 sizingData.nextState(); |
512 sizingData.sizingOperation = TrackSizing; | 527 sizingData.sizingOperation = TrackSizing; |
513 } | 528 } |
514 setLogicalHeight(computeTrackBasedLogicalHeight(sizingData) + | 529 setLogicalHeight(computeTrackBasedLogicalHeight(sizingData) + |
515 borderAndPaddingLogicalHeight() + | 530 borderAndPaddingLogicalHeight() + |
516 scrollbarLogicalHeight()); | 531 scrollbarLogicalHeight()); |
517 | 532 |
518 LayoutUnit oldClientAfterEdge = clientLogicalBottom(); | 533 LayoutUnit oldClientAfterEdge = clientLogicalBottom(); |
519 updateLogicalHeight(); | 534 updateLogicalHeight(); |
520 | 535 |
521 // 3- If the min-content contribution of any grid items have changed based o
n the row | 536 // 3- If the min-content contribution of any grid items have changed based |
522 // sizes calculated in step 2, steps 1 and 2 are repeated with the new min-c
ontent | 537 // on the row sizes calculated in step 2, steps 1 and 2 are repeated with |
523 // contribution (once only). | 538 // the new min-content contribution (once only). |
524 repeatTracksSizingIfNeeded(sizingData, availableSpaceForColumns, | 539 repeatTracksSizingIfNeeded(sizingData, availableSpaceForColumns, |
525 contentLogicalHeight()); | 540 contentLogicalHeight()); |
526 | 541 |
527 // Grid container should have the minimum height of a line if it's editable.
That doesn't affect track sizing though. | 542 // Grid container should have the minimum height of a line if it's editable. |
| 543 // That doesn't affect track sizing though. |
528 if (hasLineIfEmpty()) | 544 if (hasLineIfEmpty()) |
529 setLogicalHeight( | 545 setLogicalHeight( |
530 std::max(logicalHeight(), minimumLogicalHeightForEmptyLine())); | 546 std::max(logicalHeight(), minimumLogicalHeightForEmptyLine())); |
531 | 547 |
532 applyStretchAlignmentToTracksIfNeeded(ForColumns, sizingData); | 548 applyStretchAlignmentToTracksIfNeeded(ForColumns, sizingData); |
533 applyStretchAlignmentToTracksIfNeeded(ForRows, sizingData); | 549 applyStretchAlignmentToTracksIfNeeded(ForRows, sizingData); |
534 | 550 |
535 layoutGridItems(sizingData); | 551 layoutGridItems(sizingData); |
536 | 552 |
537 if (size() != previousSize) | 553 if (size() != previousSize) |
(...skipping 27 matching lines...) Expand all Loading... |
565 GridTrackSizingDirection direction, | 581 GridTrackSizingDirection direction, |
566 SizingOperation sizingOperation) const { | 582 SizingOperation sizingOperation) const { |
567 LayoutUnit availableSize; | 583 LayoutUnit availableSize; |
568 const Length& gap = direction == ForColumns ? styleRef().gridColumnGap() | 584 const Length& gap = direction == ForColumns ? styleRef().gridColumnGap() |
569 : styleRef().gridRowGap(); | 585 : styleRef().gridRowGap(); |
570 if (sizingOperation == TrackSizing && gap.isPercent()) | 586 if (sizingOperation == TrackSizing && gap.isPercent()) |
571 availableSize = direction == ForColumns | 587 availableSize = direction == ForColumns |
572 ? availableLogicalWidth() | 588 ? availableLogicalWidth() |
573 : availableLogicalHeightForPercentageComputation(); | 589 : availableLogicalHeightForPercentageComputation(); |
574 | 590 |
575 // TODO(rego): Maybe we could cache the computed percentage as a performance i
mprovement. | 591 // TODO(rego): Maybe we could cache the computed percentage as a performance |
| 592 // improvement. |
576 return valueForLength(gap, availableSize); | 593 return valueForLength(gap, availableSize); |
577 } | 594 } |
578 | 595 |
579 LayoutUnit LayoutGrid::guttersSize(GridTrackSizingDirection direction, | 596 LayoutUnit LayoutGrid::guttersSize(GridTrackSizingDirection direction, |
580 size_t startLine, | 597 size_t startLine, |
581 size_t span, | 598 size_t span, |
582 SizingOperation sizingOperation) const { | 599 SizingOperation sizingOperation) const { |
583 if (span <= 1) | 600 if (span <= 1) |
584 return LayoutUnit(); | 601 return LayoutUnit(); |
585 | 602 |
586 bool isRowAxis = direction == ForColumns; | 603 bool isRowAxis = direction == ForColumns; |
587 LayoutUnit gap = gridGapForDirection(direction, sizingOperation); | 604 LayoutUnit gap = gridGapForDirection(direction, sizingOperation); |
588 | 605 |
589 // Fast path, no collapsing tracks. | 606 // Fast path, no collapsing tracks. |
590 if (!hasAutoRepeatEmptyTracks(direction)) | 607 if (!hasAutoRepeatEmptyTracks(direction)) |
591 return gap * (span - 1); | 608 return gap * (span - 1); |
592 | 609 |
593 // If there are collapsing tracks we need to be sure that gutters are properly
collapsed. Apart | 610 // If there are collapsing tracks we need to be sure that gutters are properly |
594 // from that, if we have a collapsed track in the edges of the span we're cons
idering, we need | 611 // collapsed. Apart from that, if we have a collapsed track in the edges of |
595 // to move forward (or backwards) in order to know whether the collapsed track
s reach the end of | 612 // the span we're considering, we need to move forward (or backwards) in order |
596 // the grid (so the gap becomes 0) or there is a non empty track before that. | 613 // to know whether the collapsed tracks reach the end of the grid (so the gap |
| 614 // becomes 0) or there is a non empty track before that. |
597 | 615 |
598 LayoutUnit gapAccumulator; | 616 LayoutUnit gapAccumulator; |
599 size_t endLine = startLine + span; | 617 size_t endLine = startLine + span; |
600 | 618 |
601 for (size_t line = startLine; line < endLine - 1; ++line) { | 619 for (size_t line = startLine; line < endLine - 1; ++line) { |
602 if (!isEmptyAutoRepeatTrack(direction, line)) | 620 if (!isEmptyAutoRepeatTrack(direction, line)) |
603 gapAccumulator += gap; | 621 gapAccumulator += gap; |
604 } | 622 } |
605 | 623 |
606 // The above loop adds one extra gap for trailing collapsed tracks. | 624 // The above loop adds one extra gap for trailing collapsed tracks. |
607 if (gapAccumulator && isEmptyAutoRepeatTrack(direction, endLine - 1)) { | 625 if (gapAccumulator && isEmptyAutoRepeatTrack(direction, endLine - 1)) { |
608 DCHECK_GE(gapAccumulator, gap); | 626 DCHECK_GE(gapAccumulator, gap); |
609 gapAccumulator -= gap; | 627 gapAccumulator -= gap; |
610 } | 628 } |
611 | 629 |
612 // If the startLine is the start line of a collapsed track we need to go backw
ards till we reach | 630 // If the startLine is the start line of a collapsed track we need to go |
613 // a non collapsed track. If we find a non collapsed track we need to add that
gap. | 631 // backwards till we reach a non collapsed track. If we find a non collapsed |
| 632 // track we need to add that gap. |
614 if (startLine && isEmptyAutoRepeatTrack(direction, startLine)) { | 633 if (startLine && isEmptyAutoRepeatTrack(direction, startLine)) { |
615 size_t nonEmptyTracksBeforeStartLine = startLine; | 634 size_t nonEmptyTracksBeforeStartLine = startLine; |
616 auto begin = isRowAxis ? m_autoRepeatEmptyColumns->begin() | 635 auto begin = isRowAxis ? m_autoRepeatEmptyColumns->begin() |
617 : m_autoRepeatEmptyRows->begin(); | 636 : m_autoRepeatEmptyRows->begin(); |
618 for (auto it = begin; *it != startLine; ++it) { | 637 for (auto it = begin; *it != startLine; ++it) { |
619 DCHECK(nonEmptyTracksBeforeStartLine); | 638 DCHECK(nonEmptyTracksBeforeStartLine); |
620 --nonEmptyTracksBeforeStartLine; | 639 --nonEmptyTracksBeforeStartLine; |
621 } | 640 } |
622 if (nonEmptyTracksBeforeStartLine) | 641 if (nonEmptyTracksBeforeStartLine) |
623 gapAccumulator += gap; | 642 gapAccumulator += gap; |
624 } | 643 } |
625 | 644 |
626 // If the endLine is the end line of a collapsed track we need to go forward t
ill we reach a non | 645 // If the endLine is the end line of a collapsed track we need to go forward |
627 // collapsed track. If we find a non collapsed track we need to add that gap. | 646 // till we reach a non collapsed track. If we find a non collapsed track we |
| 647 // need to add that gap. |
628 if (isEmptyAutoRepeatTrack(direction, endLine - 1)) { | 648 if (isEmptyAutoRepeatTrack(direction, endLine - 1)) { |
629 size_t nonEmptyTracksAfterEndLine = | 649 size_t nonEmptyTracksAfterEndLine = |
630 (isRowAxis ? gridColumnCount() : gridRowCount()) - endLine; | 650 (isRowAxis ? gridColumnCount() : gridRowCount()) - endLine; |
631 auto currentEmptyTrack = isRowAxis | 651 auto currentEmptyTrack = isRowAxis |
632 ? m_autoRepeatEmptyColumns->find(endLine - 1) | 652 ? m_autoRepeatEmptyColumns->find(endLine - 1) |
633 : m_autoRepeatEmptyRows->find(endLine - 1); | 653 : m_autoRepeatEmptyRows->find(endLine - 1); |
634 auto endEmptyTrack = isRowAxis ? m_autoRepeatEmptyColumns->end() | 654 auto endEmptyTrack = isRowAxis ? m_autoRepeatEmptyColumns->end() |
635 : m_autoRepeatEmptyRows->end(); | 655 : m_autoRepeatEmptyRows->end(); |
636 // HashSet iterators do not implement operator- so we have to manually itera
te to know the number of remaining empty tracks. | 656 // HashSet iterators do not implement operator- so we have to manually |
| 657 // iterate to know the number of remaining empty tracks. |
637 for (auto it = ++currentEmptyTrack; it != endEmptyTrack; ++it) { | 658 for (auto it = ++currentEmptyTrack; it != endEmptyTrack; ++it) { |
638 DCHECK(nonEmptyTracksAfterEndLine); | 659 DCHECK(nonEmptyTracksAfterEndLine); |
639 --nonEmptyTracksAfterEndLine; | 660 --nonEmptyTracksAfterEndLine; |
640 } | 661 } |
641 if (nonEmptyTracksAfterEndLine) | 662 if (nonEmptyTracksAfterEndLine) |
642 gapAccumulator += gap; | 663 gapAccumulator += gap; |
643 } | 664 } |
644 | 665 |
645 return gapAccumulator; | 666 return gapAccumulator; |
646 } | 667 } |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
723 LayoutUnit& baseSizesWithoutMaximization, | 744 LayoutUnit& baseSizesWithoutMaximization, |
724 LayoutUnit& growthLimitsWithoutMaximization) const { | 745 LayoutUnit& growthLimitsWithoutMaximization) const { |
725 LayoutUnit& freeSpace = sizingData.freeSpace(direction); | 746 LayoutUnit& freeSpace = sizingData.freeSpace(direction); |
726 const LayoutUnit initialFreeSpace = freeSpace; | 747 const LayoutUnit initialFreeSpace = freeSpace; |
727 Vector<GridTrack>& tracks = (direction == ForColumns) | 748 Vector<GridTrack>& tracks = (direction == ForColumns) |
728 ? sizingData.columnTracks | 749 ? sizingData.columnTracks |
729 : sizingData.rowTracks; | 750 : sizingData.rowTracks; |
730 Vector<size_t> flexibleSizedTracksIndex; | 751 Vector<size_t> flexibleSizedTracksIndex; |
731 sizingData.contentSizedTracksIndex.shrink(0); | 752 sizingData.contentSizedTracksIndex.shrink(0); |
732 | 753 |
733 // Grid gutters were removed from freeSpace by the caller, but we must use the
m to compute relative (i.e. percentages) sizes. | 754 // Grid gutters were removed from freeSpace by the caller, but we must use |
| 755 // them to compute relative (i.e. percentages) sizes. |
734 LayoutUnit maxSize = sizingData.availableSpace().clampNegativeToZero(); | 756 LayoutUnit maxSize = sizingData.availableSpace().clampNegativeToZero(); |
735 bool hasDefiniteFreeSpace = sizingData.sizingOperation == TrackSizing; | 757 bool hasDefiniteFreeSpace = sizingData.sizingOperation == TrackSizing; |
736 | 758 |
737 // 1. Initialize per Grid track variables. | 759 // 1. Initialize per Grid track variables. |
738 for (size_t i = 0; i < tracks.size(); ++i) { | 760 for (size_t i = 0; i < tracks.size(); ++i) { |
739 GridTrack& track = tracks[i]; | 761 GridTrack& track = tracks[i]; |
740 GridTrackSize trackSize = | 762 GridTrackSize trackSize = |
741 gridTrackSize(direction, i, sizingData.sizingOperation); | 763 gridTrackSize(direction, i, sizingData.sizingOperation); |
742 | 764 |
743 track.setBaseSize(computeUsedBreadthOfMinLength(trackSize, maxSize)); | 765 track.setBaseSize(computeUsedBreadthOfMinLength(trackSize, maxSize)); |
(...skipping 16 matching lines...) Expand all Loading... |
760 // 2. Resolve content-based TrackSizingFunctions. | 782 // 2. Resolve content-based TrackSizingFunctions. |
761 if (!sizingData.contentSizedTracksIndex.isEmpty()) | 783 if (!sizingData.contentSizedTracksIndex.isEmpty()) |
762 resolveContentBasedTrackSizingFunctions(direction, sizingData); | 784 resolveContentBasedTrackSizingFunctions(direction, sizingData); |
763 | 785 |
764 baseSizesWithoutMaximization = growthLimitsWithoutMaximization = LayoutUnit(); | 786 baseSizesWithoutMaximization = growthLimitsWithoutMaximization = LayoutUnit(); |
765 | 787 |
766 for (auto& track : tracks) { | 788 for (auto& track : tracks) { |
767 ASSERT(!track.infiniteGrowthPotential()); | 789 ASSERT(!track.infiniteGrowthPotential()); |
768 baseSizesWithoutMaximization += track.baseSize(); | 790 baseSizesWithoutMaximization += track.baseSize(); |
769 growthLimitsWithoutMaximization += track.growthLimit(); | 791 growthLimitsWithoutMaximization += track.growthLimit(); |
770 // The growth limit caps must be cleared now in order to properly sort track
s by growth | 792 // The growth limit caps must be cleared now in order to properly sort |
771 // potential on an eventual "Maximize Tracks". | 793 // tracks by growth potential on an eventual "Maximize Tracks". |
772 track.setGrowthLimitCap(WTF::nullopt); | 794 track.setGrowthLimitCap(WTF::nullopt); |
773 } | 795 } |
774 freeSpace = initialFreeSpace - baseSizesWithoutMaximization; | 796 freeSpace = initialFreeSpace - baseSizesWithoutMaximization; |
775 | 797 |
776 if (hasDefiniteFreeSpace && freeSpace <= 0) | 798 if (hasDefiniteFreeSpace && freeSpace <= 0) |
777 return; | 799 return; |
778 | 800 |
779 // 3. Grow all Grid tracks in GridTracks from their baseSize up to their growt
hLimit value until freeSpace is exhausted. | 801 // 3. Grow all Grid tracks in GridTracks from their baseSize up to their |
| 802 // growthLimit value until freeSpace is exhausted. |
780 const size_t tracksSize = tracks.size(); | 803 const size_t tracksSize = tracks.size(); |
781 if (hasDefiniteFreeSpace) { | 804 if (hasDefiniteFreeSpace) { |
782 Vector<GridTrack*> tracksForDistribution(tracksSize); | 805 Vector<GridTrack*> tracksForDistribution(tracksSize); |
783 for (size_t i = 0; i < tracksSize; ++i) { | 806 for (size_t i = 0; i < tracksSize; ++i) { |
784 tracksForDistribution[i] = tracks.data() + i; | 807 tracksForDistribution[i] = tracks.data() + i; |
785 tracksForDistribution[i]->setPlannedSize( | 808 tracksForDistribution[i]->setPlannedSize( |
786 tracksForDistribution[i]->baseSize()); | 809 tracksForDistribution[i]->baseSize()); |
787 } | 810 } |
788 | 811 |
789 distributeSpaceToTracks<MaximizeTracks>(tracksForDistribution, nullptr, | 812 distributeSpaceToTracks<MaximizeTracks>(tracksForDistribution, nullptr, |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
881 return LayoutUnit(infinity); | 904 return LayoutUnit(infinity); |
882 } | 905 } |
883 | 906 |
884 double LayoutGrid::computeFlexFactorUnitSize( | 907 double LayoutGrid::computeFlexFactorUnitSize( |
885 const Vector<GridTrack>& tracks, | 908 const Vector<GridTrack>& tracks, |
886 GridTrackSizingDirection direction, | 909 GridTrackSizingDirection direction, |
887 double flexFactorSum, | 910 double flexFactorSum, |
888 LayoutUnit& leftOverSpace, | 911 LayoutUnit& leftOverSpace, |
889 const Vector<size_t, 8>& flexibleTracksIndexes, | 912 const Vector<size_t, 8>& flexibleTracksIndexes, |
890 std::unique_ptr<TrackIndexSet> tracksToTreatAsInflexible) const { | 913 std::unique_ptr<TrackIndexSet> tracksToTreatAsInflexible) const { |
891 // We want to avoid the effect of flex factors sum below 1 making the factor u
nit size to grow exponentially. | 914 // We want to avoid the effect of flex factors sum below 1 making the factor |
| 915 // unit size to grow exponentially. |
892 double hypotheticalFactorUnitSize = | 916 double hypotheticalFactorUnitSize = |
893 leftOverSpace / std::max<double>(1, flexFactorSum); | 917 leftOverSpace / std::max<double>(1, flexFactorSum); |
894 | 918 |
895 // product of the hypothetical "flex factor unit" and any flexible track's "fl
ex factor" must be grater than such track's "base size". | 919 // product of the hypothetical "flex factor unit" and any flexible track's |
| 920 // "flex factor" must be grater than such track's "base size". |
896 std::unique_ptr<TrackIndexSet> additionalTracksToTreatAsInflexible = | 921 std::unique_ptr<TrackIndexSet> additionalTracksToTreatAsInflexible = |
897 std::move(tracksToTreatAsInflexible); | 922 std::move(tracksToTreatAsInflexible); |
898 bool validFlexFactorUnit = true; | 923 bool validFlexFactorUnit = true; |
899 for (auto index : flexibleTracksIndexes) { | 924 for (auto index : flexibleTracksIndexes) { |
900 if (additionalTracksToTreatAsInflexible && | 925 if (additionalTracksToTreatAsInflexible && |
901 additionalTracksToTreatAsInflexible->contains(index)) | 926 additionalTracksToTreatAsInflexible->contains(index)) |
902 continue; | 927 continue; |
903 LayoutUnit baseSize = tracks[index].baseSize(); | 928 LayoutUnit baseSize = tracks[index].baseSize(); |
904 double flexFactor = | 929 double flexFactor = |
905 gridTrackSize(direction, index).maxTrackBreadth().flex(); | 930 gridTrackSize(direction, index).maxTrackBreadth().flex(); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
992 const Vector<GridTrackSize>& autoRepeatTrackStyles = | 1017 const Vector<GridTrackSize>& autoRepeatTrackStyles = |
993 isRowAxis ? styleRef().gridAutoRepeatColumns() | 1018 isRowAxis ? styleRef().gridAutoRepeatColumns() |
994 : styleRef().gridAutoRepeatRows(); | 1019 : styleRef().gridAutoRepeatRows(); |
995 const Vector<GridTrackSize>& autoTrackStyles = | 1020 const Vector<GridTrackSize>& autoTrackStyles = |
996 isRowAxis ? styleRef().gridAutoColumns() : styleRef().gridAutoRows(); | 1021 isRowAxis ? styleRef().gridAutoColumns() : styleRef().gridAutoRows(); |
997 size_t insertionPoint = isRowAxis | 1022 size_t insertionPoint = isRowAxis |
998 ? styleRef().gridAutoRepeatColumnsInsertionPoint() | 1023 ? styleRef().gridAutoRepeatColumnsInsertionPoint() |
999 : styleRef().gridAutoRepeatRowsInsertionPoint(); | 1024 : styleRef().gridAutoRepeatRowsInsertionPoint(); |
1000 size_t autoRepeatTracksCount = autoRepeatCountForDirection(direction); | 1025 size_t autoRepeatTracksCount = autoRepeatCountForDirection(direction); |
1001 | 1026 |
1002 // We should not use GridPositionsResolver::explicitGridXXXCount() for this be
cause the | 1027 // We should not use GridPositionsResolver::explicitGridXXXCount() for this |
1003 // explicit grid might be larger than the number of tracks in grid-template-ro
ws|columns (if | 1028 // because the explicit grid might be larger than the number of tracks in |
1004 // grid-template-areas is specified for example). | 1029 // grid-template-rows|columns (if grid-template-areas is specified for |
| 1030 // example). |
1005 size_t explicitTracksCount = trackStyles.size() + autoRepeatTracksCount; | 1031 size_t explicitTracksCount = trackStyles.size() + autoRepeatTracksCount; |
1006 | 1032 |
1007 int untranslatedIndexAsInt = | 1033 int untranslatedIndexAsInt = |
1008 translatedIndex + | 1034 translatedIndex + |
1009 (isRowAxis ? m_smallestColumnStart : m_smallestRowStart); | 1035 (isRowAxis ? m_smallestColumnStart : m_smallestRowStart); |
1010 size_t autoTrackStylesSize = autoTrackStyles.size(); | 1036 size_t autoTrackStylesSize = autoTrackStyles.size(); |
1011 if (untranslatedIndexAsInt < 0) { | 1037 if (untranslatedIndexAsInt < 0) { |
1012 int index = untranslatedIndexAsInt % static_cast<int>(autoTrackStylesSize); | 1038 int index = untranslatedIndexAsInt % static_cast<int>(autoTrackStylesSize); |
1013 // We need to traspose the index because the first negative implicit line wi
ll get the last defined auto track and so on. | 1039 // We need to traspose the index because the first negative implicit line |
| 1040 // will get the last defined auto track and so on. |
1014 index += index ? autoTrackStylesSize : 0; | 1041 index += index ? autoTrackStylesSize : 0; |
1015 return autoTrackStyles[index]; | 1042 return autoTrackStyles[index]; |
1016 } | 1043 } |
1017 | 1044 |
1018 size_t untranslatedIndex = static_cast<size_t>(untranslatedIndexAsInt); | 1045 size_t untranslatedIndex = static_cast<size_t>(untranslatedIndexAsInt); |
1019 if (untranslatedIndex >= explicitTracksCount) | 1046 if (untranslatedIndex >= explicitTracksCount) |
1020 return autoTrackStyles[(untranslatedIndex - explicitTracksCount) % | 1047 return autoTrackStyles[(untranslatedIndex - explicitTracksCount) % |
1021 autoTrackStylesSize]; | 1048 autoTrackStylesSize]; |
1022 | 1049 |
1023 if (LIKELY(!autoRepeatTracksCount) || untranslatedIndex < insertionPoint) | 1050 if (LIKELY(!autoRepeatTracksCount) || untranslatedIndex < insertionPoint) |
(...skipping 15 matching lines...) Expand all Loading... |
1039 if (hasAutoRepeatEmptyTracks(direction) && | 1066 if (hasAutoRepeatEmptyTracks(direction) && |
1040 isEmptyAutoRepeatTrack(direction, translatedIndex)) | 1067 isEmptyAutoRepeatTrack(direction, translatedIndex)) |
1041 return {Length(Fixed), LengthTrackSizing}; | 1068 return {Length(Fixed), LengthTrackSizing}; |
1042 | 1069 |
1043 const GridTrackSize& trackSize = rawGridTrackSize(direction, translatedIndex); | 1070 const GridTrackSize& trackSize = rawGridTrackSize(direction, translatedIndex); |
1044 if (trackSize.isFitContent()) | 1071 if (trackSize.isFitContent()) |
1045 return trackSize; | 1072 return trackSize; |
1046 | 1073 |
1047 GridLength minTrackBreadth = trackSize.minTrackBreadth(); | 1074 GridLength minTrackBreadth = trackSize.minTrackBreadth(); |
1048 GridLength maxTrackBreadth = trackSize.maxTrackBreadth(); | 1075 GridLength maxTrackBreadth = trackSize.maxTrackBreadth(); |
1049 // If the logical width/height of the grid container is indefinite, percentage
values are treated as <auto>. | 1076 // If the logical width/height of the grid container is indefinite, percentage |
| 1077 // values are treated as <auto>. |
1050 if (minTrackBreadth.hasPercentage() || maxTrackBreadth.hasPercentage()) { | 1078 if (minTrackBreadth.hasPercentage() || maxTrackBreadth.hasPercentage()) { |
1051 // For the inline axis this only happens when we're computing the intrinsic
sizes (AvailableSpaceIndefinite). | 1079 // For the inline axis this only happens when we're computing the intrinsic |
| 1080 // sizes (AvailableSpaceIndefinite). |
1052 if ((sizingOperation == IntrinsicSizeComputation) || | 1081 if ((sizingOperation == IntrinsicSizeComputation) || |
1053 (direction == ForRows && !cachedHasDefiniteLogicalHeight())) { | 1082 (direction == ForRows && !cachedHasDefiniteLogicalHeight())) { |
1054 if (minTrackBreadth.hasPercentage()) | 1083 if (minTrackBreadth.hasPercentage()) |
1055 minTrackBreadth = Length(Auto); | 1084 minTrackBreadth = Length(Auto); |
1056 if (maxTrackBreadth.hasPercentage()) | 1085 if (maxTrackBreadth.hasPercentage()) |
1057 maxTrackBreadth = Length(Auto); | 1086 maxTrackBreadth = Length(Auto); |
1058 } | 1087 } |
1059 } | 1088 } |
1060 | 1089 |
1061 // Flex sizes are invalid as a min sizing function. However we still can have
a flexible |minTrackBreadth| | 1090 // Flex sizes are invalid as a min sizing function. However we still can have |
1062 // if the track had a flex size directly (e.g. "1fr"), the spec says that in t
his case it implies an automatic minimum. | 1091 // a flexible |minTrackBreadth| if the track had a flex size directly (e.g. |
| 1092 // "1fr"), the spec says that in this case it implies an automatic minimum. |
1063 if (minTrackBreadth.isFlex()) | 1093 if (minTrackBreadth.isFlex()) |
1064 minTrackBreadth = Length(Auto); | 1094 minTrackBreadth = Length(Auto); |
1065 | 1095 |
1066 return GridTrackSize(minTrackBreadth, maxTrackBreadth); | 1096 return GridTrackSize(minTrackBreadth, maxTrackBreadth); |
1067 } | 1097 } |
1068 | 1098 |
1069 bool LayoutGrid::isOrthogonalChild(const LayoutBox& child) const { | 1099 bool LayoutGrid::isOrthogonalChild(const LayoutBox& child) const { |
1070 return child.isHorizontalWritingMode() != isHorizontalWritingMode(); | 1100 return child.isHorizontalWritingMode() != isHorizontalWritingMode(); |
1071 } | 1101 } |
1072 | 1102 |
1073 LayoutUnit LayoutGrid::logicalHeightForChild(LayoutBox& child, | 1103 LayoutUnit LayoutGrid::logicalHeightForChild(LayoutBox& child, |
1074 GridSizingData& sizingData) const { | 1104 GridSizingData& sizingData) const { |
1075 GridTrackSizingDirection childBlockDirection = | 1105 GridTrackSizingDirection childBlockDirection = |
1076 flowAwareDirectionForChild(child, ForRows); | 1106 flowAwareDirectionForChild(child, ForRows); |
1077 // If |child| has a relative logical height, we shouldn't let it override its
intrinsic height, which is | 1107 // If |child| has a relative logical height, we shouldn't let it override its |
1078 // what we are interested in here. Thus we need to set the block-axis override
size to -1 (no possible resolution). | 1108 // intrinsic height, which is what we are interested in here. Thus we need to |
| 1109 // set the block-axis override size to -1 (no possible resolution). |
1079 if (shouldClearOverrideContainingBlockContentSizeForChild(child, ForRows)) { | 1110 if (shouldClearOverrideContainingBlockContentSizeForChild(child, ForRows)) { |
1080 setOverrideContainingBlockContentSizeForChild(child, childBlockDirection, | 1111 setOverrideContainingBlockContentSizeForChild(child, childBlockDirection, |
1081 LayoutUnit(-1)); | 1112 LayoutUnit(-1)); |
1082 child.setNeedsLayout(LayoutInvalidationReason::GridChanged); | 1113 child.setNeedsLayout(LayoutInvalidationReason::GridChanged); |
1083 } | 1114 } |
1084 | 1115 |
1085 // We need to clear the stretched height to properly compute logical height du
ring layout. | 1116 // We need to clear the stretched height to properly compute logical height |
| 1117 // during layout. |
1086 if (child.needsLayout()) | 1118 if (child.needsLayout()) |
1087 child.clearOverrideLogicalContentHeight(); | 1119 child.clearOverrideLogicalContentHeight(); |
1088 | 1120 |
1089 child.layoutIfNeeded(); | 1121 child.layoutIfNeeded(); |
1090 return child.logicalHeight() + child.marginLogicalHeight(); | 1122 return child.logicalHeight() + child.marginLogicalHeight(); |
1091 } | 1123 } |
1092 | 1124 |
1093 GridTrackSizingDirection LayoutGrid::flowAwareDirectionForChild( | 1125 GridTrackSizingDirection LayoutGrid::flowAwareDirectionForChild( |
1094 const LayoutBox& child, | 1126 const LayoutBox& child, |
1095 GridTrackSizingDirection direction) const { | 1127 GridTrackSizingDirection direction) const { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1152 return true; | 1184 return true; |
1153 } | 1185 } |
1154 | 1186 |
1155 DISABLE_CFI_PERF | 1187 DISABLE_CFI_PERF |
1156 LayoutUnit LayoutGrid::minContentForChild(LayoutBox& child, | 1188 LayoutUnit LayoutGrid::minContentForChild(LayoutBox& child, |
1157 GridTrackSizingDirection direction, | 1189 GridTrackSizingDirection direction, |
1158 GridSizingData& sizingData) const { | 1190 GridSizingData& sizingData) const { |
1159 GridTrackSizingDirection childInlineDirection = | 1191 GridTrackSizingDirection childInlineDirection = |
1160 flowAwareDirectionForChild(child, ForColumns); | 1192 flowAwareDirectionForChild(child, ForColumns); |
1161 if (direction == childInlineDirection) { | 1193 if (direction == childInlineDirection) { |
1162 // If |child| has a relative logical width, we shouldn't let it override its
intrinsic width, which is | 1194 // If |child| has a relative logical width, we shouldn't let it override its |
1163 // what we are interested in here. Thus we need to set the inline-axis overr
ide size to -1 (no possible resolution). | 1195 // intrinsic width, which is what we are interested in here. Thus we need to |
| 1196 // set the inline-axis override size to -1 (no possible resolution). |
1164 if (shouldClearOverrideContainingBlockContentSizeForChild(child, | 1197 if (shouldClearOverrideContainingBlockContentSizeForChild(child, |
1165 ForColumns)) | 1198 ForColumns)) |
1166 setOverrideContainingBlockContentSizeForChild(child, childInlineDirection, | 1199 setOverrideContainingBlockContentSizeForChild(child, childInlineDirection, |
1167 LayoutUnit(-1)); | 1200 LayoutUnit(-1)); |
1168 | 1201 |
1169 // FIXME: It's unclear if we should return the intrinsic width or the prefer
red width. | 1202 // FIXME: It's unclear if we should return the intrinsic width or the |
| 1203 // preferred width. |
1170 // See http://lists.w3.org/Archives/Public/www-style/2013Jan/0245.html | 1204 // See http://lists.w3.org/Archives/Public/www-style/2013Jan/0245.html |
1171 return child.minPreferredLogicalWidth() + | 1205 return child.minPreferredLogicalWidth() + |
1172 marginIntrinsicLogicalWidthForChild(child); | 1206 marginIntrinsicLogicalWidthForChild(child); |
1173 } | 1207 } |
1174 | 1208 |
1175 // All orthogonal flow boxes were already laid out during an early layout phas
e performed in FrameView::performLayout. | 1209 // All orthogonal flow boxes were already laid out during an early layout |
1176 // It's true that grid track sizing was not completed at that time and it may
afffect the final height of a | 1210 // phase performed in FrameView::performLayout. |
1177 // grid item, but since it's forbidden to perform a layout during intrinsic wi
dth computation, we have to use | 1211 // It's true that grid track sizing was not completed at that time and it may |
1178 // that computed height for now. | 1212 // afffect the final height of a grid item, but since it's forbidden to |
| 1213 // perform a layout during intrinsic width computation, we have to use that |
| 1214 // computed height for now. |
1179 if (direction == ForColumns && | 1215 if (direction == ForColumns && |
1180 sizingData.sizingOperation == IntrinsicSizeComputation) { | 1216 sizingData.sizingOperation == IntrinsicSizeComputation) { |
1181 DCHECK(isOrthogonalChild(child)); | 1217 DCHECK(isOrthogonalChild(child)); |
1182 return child.logicalHeight() + child.marginLogicalHeight(); | 1218 return child.logicalHeight() + child.marginLogicalHeight(); |
1183 } | 1219 } |
1184 | 1220 |
1185 if (updateOverrideContainingBlockContentSizeForChild( | 1221 if (updateOverrideContainingBlockContentSizeForChild( |
1186 child, childInlineDirection, sizingData)) | 1222 child, childInlineDirection, sizingData)) |
1187 child.setNeedsLayout(LayoutInvalidationReason::GridChanged); | 1223 child.setNeedsLayout(LayoutInvalidationReason::GridChanged); |
1188 return logicalHeightForChild(child, sizingData); | 1224 return logicalHeightForChild(child, sizingData); |
1189 } | 1225 } |
1190 | 1226 |
1191 DISABLE_CFI_PERF | 1227 DISABLE_CFI_PERF |
1192 LayoutUnit LayoutGrid::maxContentForChild(LayoutBox& child, | 1228 LayoutUnit LayoutGrid::maxContentForChild(LayoutBox& child, |
1193 GridTrackSizingDirection direction, | 1229 GridTrackSizingDirection direction, |
1194 GridSizingData& sizingData) const { | 1230 GridSizingData& sizingData) const { |
1195 GridTrackSizingDirection childInlineDirection = | 1231 GridTrackSizingDirection childInlineDirection = |
1196 flowAwareDirectionForChild(child, ForColumns); | 1232 flowAwareDirectionForChild(child, ForColumns); |
1197 if (direction == childInlineDirection) { | 1233 if (direction == childInlineDirection) { |
1198 // If |child| has a relative logical width, we shouldn't let it override its
intrinsic width, which is | 1234 // If |child| has a relative logical width, we shouldn't let it override its |
1199 // what we are interested in here. Thus we need to set the inline-axis overr
ide size to -1 (no possible resolution). | 1235 // intrinsic width, which is what we are interested in here. Thus we need to |
| 1236 // set the inline-axis override size to -1 (no possible resolution). |
1200 if (shouldClearOverrideContainingBlockContentSizeForChild(child, | 1237 if (shouldClearOverrideContainingBlockContentSizeForChild(child, |
1201 ForColumns)) | 1238 ForColumns)) |
1202 setOverrideContainingBlockContentSizeForChild(child, childInlineDirection, | 1239 setOverrideContainingBlockContentSizeForChild(child, childInlineDirection, |
1203 LayoutUnit(-1)); | 1240 LayoutUnit(-1)); |
1204 | 1241 |
1205 // FIXME: It's unclear if we should return the intrinsic width or the prefer
red width. | 1242 // FIXME: It's unclear if we should return the intrinsic width or the |
| 1243 // preferred width. |
1206 // See http://lists.w3.org/Archives/Public/www-style/2013Jan/0245.html | 1244 // See http://lists.w3.org/Archives/Public/www-style/2013Jan/0245.html |
1207 return child.maxPreferredLogicalWidth() + | 1245 return child.maxPreferredLogicalWidth() + |
1208 marginIntrinsicLogicalWidthForChild(child); | 1246 marginIntrinsicLogicalWidthForChild(child); |
1209 } | 1247 } |
1210 | 1248 |
1211 // All orthogonal flow boxes were already laid out during an early layout phas
e performed in FrameView::performLayout. | 1249 // All orthogonal flow boxes were already laid out during an early layout |
1212 // It's true that grid track sizing was not completed at that time and it may
afffect the final height of a | 1250 // phase performed in FrameView::performLayout. |
1213 // grid item, but since it's forbidden to perform a layout during intrinsic wi
dth computation, we have to use | 1251 // It's true that grid track sizing was not completed at that time and it may |
1214 // that computed height for now. | 1252 // afffect the final height of a grid item, but since it's forbidden to |
| 1253 // perform a layout during intrinsic width computation, we have to use that |
| 1254 // computed height for now. |
1215 if (direction == ForColumns && | 1255 if (direction == ForColumns && |
1216 sizingData.sizingOperation == IntrinsicSizeComputation) { | 1256 sizingData.sizingOperation == IntrinsicSizeComputation) { |
1217 DCHECK(isOrthogonalChild(child)); | 1257 DCHECK(isOrthogonalChild(child)); |
1218 return child.logicalHeight() + child.marginLogicalHeight(); | 1258 return child.logicalHeight() + child.marginLogicalHeight(); |
1219 } | 1259 } |
1220 | 1260 |
1221 if (updateOverrideContainingBlockContentSizeForChild( | 1261 if (updateOverrideContainingBlockContentSizeForChild( |
1222 child, childInlineDirection, sizingData)) | 1262 child, childInlineDirection, sizingData)) |
1223 child.setNeedsLayout(LayoutInvalidationReason::GridChanged); | 1263 child.setNeedsLayout(LayoutInvalidationReason::GridChanged); |
1224 return logicalHeightForChild(child, sizingData); | 1264 return logicalHeightForChild(child, sizingData); |
1225 } | 1265 } |
1226 | 1266 |
1227 // We're basically using a class instead of a std::pair because of accessing gri
dItem() or getGridSpan() is much more | 1267 // We're basically using a class instead of a std::pair because of accessing |
1228 // self-explanatory that using .first or .second members in the pair. Having a s
td::pair<LayoutBox*, size_t> | 1268 // gridItem() or getGridSpan() is much more self-explanatory that using .first |
1229 // does not work either because we still need the GridSpan so we'd have to add a
n extra hash lookup for each item | 1269 // or .second members in the pair. Having a std::pair<LayoutBox*, size_t> |
1230 // at the beginning of LayoutGrid::resolveContentBasedTrackSizingFunctionsForIte
ms(). | 1270 // does not work either because we still need the GridSpan so we'd have to add |
| 1271 // an extra hash lookup for each item at the beginning of |
| 1272 // LayoutGrid::resolveContentBasedTrackSizingFunctionsForItems(). |
1231 class GridItemWithSpan { | 1273 class GridItemWithSpan { |
1232 public: | 1274 public: |
1233 GridItemWithSpan(LayoutBox& gridItem, const GridSpan& gridSpan) | 1275 GridItemWithSpan(LayoutBox& gridItem, const GridSpan& gridSpan) |
1234 : m_gridItem(&gridItem), m_gridSpan(gridSpan) {} | 1276 : m_gridItem(&gridItem), m_gridSpan(gridSpan) {} |
1235 | 1277 |
1236 LayoutBox& gridItem() const { return *m_gridItem; } | 1278 LayoutBox& gridItem() const { return *m_gridItem; } |
1237 GridSpan getGridSpan() const { return m_gridSpan; } | 1279 GridSpan getGridSpan() const { return m_gridSpan; } |
1238 | 1280 |
1239 bool operator<(const GridItemWithSpan other) const { | 1281 bool operator<(const GridItemWithSpan other) const { |
1240 return m_gridSpan.integerSpan() < other.m_gridSpan.integerSpan(); | 1282 return m_gridSpan.integerSpan() < other.m_gridSpan.integerSpan(); |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1553 | 1595 |
1554 for (const auto& trackIndex : sizingData.contentSizedTracksIndex) { | 1596 for (const auto& trackIndex : sizingData.contentSizedTracksIndex) { |
1555 GridTrack& track = tracks[trackIndex]; | 1597 GridTrack& track = tracks[trackIndex]; |
1556 markAsInfinitelyGrowableForTrackSizeComputationPhase(phase, track); | 1598 markAsInfinitelyGrowableForTrackSizeComputationPhase(phase, track); |
1557 updateTrackSizeForTrackSizeComputationPhase(phase, track); | 1599 updateTrackSizeForTrackSizeComputationPhase(phase, track); |
1558 } | 1600 } |
1559 } | 1601 } |
1560 | 1602 |
1561 static bool sortByGridTrackGrowthPotential(const GridTrack* track1, | 1603 static bool sortByGridTrackGrowthPotential(const GridTrack* track1, |
1562 const GridTrack* track2) { | 1604 const GridTrack* track2) { |
1563 // This check ensures that we respect the irreflexivity property of the strict
weak ordering required by std::sort | 1605 // This check ensures that we respect the irreflexivity property of the strict |
1564 // (forall x: NOT x < x). | 1606 // weak ordering required by std::sort(forall x: NOT x < x). |
1565 bool track1HasInfiniteGrowthPotentialWithoutCap = | 1607 bool track1HasInfiniteGrowthPotentialWithoutCap = |
1566 track1->infiniteGrowthPotential() && !track1->growthLimitCap(); | 1608 track1->infiniteGrowthPotential() && !track1->growthLimitCap(); |
1567 bool track2HasInfiniteGrowthPotentialWithoutCap = | 1609 bool track2HasInfiniteGrowthPotentialWithoutCap = |
1568 track2->infiniteGrowthPotential() && !track2->growthLimitCap(); | 1610 track2->infiniteGrowthPotential() && !track2->growthLimitCap(); |
1569 | 1611 |
1570 if (track1HasInfiniteGrowthPotentialWithoutCap && | 1612 if (track1HasInfiniteGrowthPotentialWithoutCap && |
1571 track2HasInfiniteGrowthPotentialWithoutCap) | 1613 track2HasInfiniteGrowthPotentialWithoutCap) |
1572 return false; | 1614 return false; |
1573 | 1615 |
1574 if (track1HasInfiniteGrowthPotentialWithoutCap || | 1616 if (track1HasInfiniteGrowthPotentialWithoutCap || |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1627 clampGrowthShareIfNeeded(phase, track, growthShare); | 1669 clampGrowthShareIfNeeded(phase, track, growthShare); |
1628 DCHECK_GE(growthShare, 0) << "We must never shrink any grid track or " | 1670 DCHECK_GE(growthShare, 0) << "We must never shrink any grid track or " |
1629 "else we can't guarantee we abide by our " | 1671 "else we can't guarantee we abide by our " |
1630 "min-sizing function."; | 1672 "min-sizing function."; |
1631 track.growSizeDuringDistribution(growthShare); | 1673 track.growSizeDuringDistribution(growthShare); |
1632 availableLogicalSpace -= growthShare; | 1674 availableLogicalSpace -= growthShare; |
1633 } | 1675 } |
1634 } | 1676 } |
1635 | 1677 |
1636 if (availableLogicalSpace > 0 && growBeyondGrowthLimitsTracks) { | 1678 if (availableLogicalSpace > 0 && growBeyondGrowthLimitsTracks) { |
1637 // We need to sort them because there might be tracks with growth limit caps
(like the ones | 1679 // We need to sort them because there might be tracks with growth limit caps |
1638 // with fit-content()) which cannot indefinitely grow over the limits. | 1680 // (like the ones with fit-content()) which cannot indefinitely grow over |
| 1681 // the limits. |
1639 if (phase == ResolveMaxContentMaximums) | 1682 if (phase == ResolveMaxContentMaximums) |
1640 std::sort(growBeyondGrowthLimitsTracks->begin(), | 1683 std::sort(growBeyondGrowthLimitsTracks->begin(), |
1641 growBeyondGrowthLimitsTracks->end(), | 1684 growBeyondGrowthLimitsTracks->end(), |
1642 sortByGridTrackGrowthPotential); | 1685 sortByGridTrackGrowthPotential); |
1643 | 1686 |
1644 size_t tracksGrowingAboveMaxBreadthSize = | 1687 size_t tracksGrowingAboveMaxBreadthSize = |
1645 growBeyondGrowthLimitsTracks->size(); | 1688 growBeyondGrowthLimitsTracks->size(); |
1646 for (size_t i = 0; i < tracksGrowingAboveMaxBreadthSize; ++i) { | 1689 for (size_t i = 0; i < tracksGrowingAboveMaxBreadthSize; ++i) { |
1647 GridTrack* track = growBeyondGrowthLimitsTracks->at(i); | 1690 GridTrack* track = growBeyondGrowthLimitsTracks->at(i); |
1648 LayoutUnit growthShare = | 1691 LayoutUnit growthShare = |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1758 DCHECK(autoTrackSize.minTrackBreadth().isLength()); | 1801 DCHECK(autoTrackSize.minTrackBreadth().isLength()); |
1759 DCHECK(!autoTrackSize.minTrackBreadth().isFlex()); | 1802 DCHECK(!autoTrackSize.minTrackBreadth().isFlex()); |
1760 bool hasDefiniteMaxTrackSizingFunction = | 1803 bool hasDefiniteMaxTrackSizingFunction = |
1761 autoTrackSize.maxTrackBreadth().isLength() && | 1804 autoTrackSize.maxTrackBreadth().isLength() && |
1762 !autoTrackSize.maxTrackBreadth().isContentSized(); | 1805 !autoTrackSize.maxTrackBreadth().isContentSized(); |
1763 auto trackLength = hasDefiniteMaxTrackSizingFunction | 1806 auto trackLength = hasDefiniteMaxTrackSizingFunction |
1764 ? autoTrackSize.maxTrackBreadth().length() | 1807 ? autoTrackSize.maxTrackBreadth().length() |
1765 : autoTrackSize.minTrackBreadth().length(); | 1808 : autoTrackSize.minTrackBreadth().length(); |
1766 autoRepeatTracksSize += valueForLength(trackLength, availableSize); | 1809 autoRepeatTracksSize += valueForLength(trackLength, availableSize); |
1767 } | 1810 } |
1768 // For the purpose of finding the number of auto-repeated tracks, the UA must
floor the track size to a UA-specified | 1811 // For the purpose of finding the number of auto-repeated tracks, the UA must |
1769 // value to avoid division by zero. It is suggested that this floor be 1px. | 1812 // floor the track size to a UA-specified value to avoid division by zero. It |
| 1813 // is suggested that this floor be 1px. |
1770 autoRepeatTracksSize = | 1814 autoRepeatTracksSize = |
1771 std::max<LayoutUnit>(LayoutUnit(1), autoRepeatTracksSize); | 1815 std::max<LayoutUnit>(LayoutUnit(1), autoRepeatTracksSize); |
1772 | 1816 |
1773 // There will be always at least 1 auto-repeat track, so take it already into
account when computing the total track size. | 1817 // There will be always at least 1 auto-repeat track, so take it already into |
| 1818 // account when computing the total track size. |
1774 LayoutUnit tracksSize = autoRepeatTracksSize; | 1819 LayoutUnit tracksSize = autoRepeatTracksSize; |
1775 const Vector<GridTrackSize>& trackSizes = | 1820 const Vector<GridTrackSize>& trackSizes = |
1776 isRowAxis ? styleRef().gridTemplateColumns() | 1821 isRowAxis ? styleRef().gridTemplateColumns() |
1777 : styleRef().gridTemplateRows(); | 1822 : styleRef().gridTemplateRows(); |
1778 | 1823 |
1779 for (const auto& track : trackSizes) { | 1824 for (const auto& track : trackSizes) { |
1780 bool hasDefiniteMaxTrackBreadth = track.maxTrackBreadth().isLength() && | 1825 bool hasDefiniteMaxTrackBreadth = track.maxTrackBreadth().isLength() && |
1781 !track.maxTrackBreadth().isContentSized(); | 1826 !track.maxTrackBreadth().isContentSized(); |
1782 DCHECK(hasDefiniteMaxTrackBreadth || | 1827 DCHECK(hasDefiniteMaxTrackBreadth || |
1783 (track.minTrackBreadth().isLength() && | 1828 (track.minTrackBreadth().isLength() && |
1784 !track.minTrackBreadth().isContentSized())); | 1829 !track.minTrackBreadth().isContentSized())); |
1785 tracksSize += valueForLength(hasDefiniteMaxTrackBreadth | 1830 tracksSize += valueForLength(hasDefiniteMaxTrackBreadth |
1786 ? track.maxTrackBreadth().length() | 1831 ? track.maxTrackBreadth().length() |
1787 : track.minTrackBreadth().length(), | 1832 : track.minTrackBreadth().length(), |
1788 availableSize); | 1833 availableSize); |
1789 } | 1834 } |
1790 | 1835 |
1791 // Add gutters as if there where only 1 auto repeat track. Gaps between auto r
epeat tracks will be added later when | 1836 // Add gutters as if there where only 1 auto repeat track. Gaps between auto |
1792 // computing the repetitions. | 1837 // repeat tracks will be added later when computing the repetitions. |
1793 LayoutUnit gapSize = gridGapForDirection(direction, sizingOperation); | 1838 LayoutUnit gapSize = gridGapForDirection(direction, sizingOperation); |
1794 tracksSize += gapSize * trackSizes.size(); | 1839 tracksSize += gapSize * trackSizes.size(); |
1795 | 1840 |
1796 LayoutUnit freeSpace = availableSize - tracksSize; | 1841 LayoutUnit freeSpace = availableSize - tracksSize; |
1797 if (freeSpace <= 0) | 1842 if (freeSpace <= 0) |
1798 return autoRepeatTrackListLength; | 1843 return autoRepeatTrackListLength; |
1799 | 1844 |
1800 size_t repetitions = | 1845 size_t repetitions = |
1801 1 + (freeSpace / (autoRepeatTracksSize + gapSize)).toInt(); | 1846 1 + (freeSpace / (autoRepeatTracksSize + gapSize)).toInt(); |
1802 | 1847 |
1803 // Provided the grid container does not have a definite size or max-size in th
e relevant axis, | 1848 // Provided the grid container does not have a definite size or max-size in |
1804 // if the min size is definite then the number of repetitions is the largest p
ossible positive | 1849 // the relevant axis, if the min size is definite then the number of |
1805 // integer that fulfills that minimum requirement. | 1850 // repetitions is the largest possible positive integer that fulfills that |
| 1851 // minimum requirement. |
1806 if (needsToFulfillMinimumSize) | 1852 if (needsToFulfillMinimumSize) |
1807 ++repetitions; | 1853 ++repetitions; |
1808 | 1854 |
1809 return repetitions * autoRepeatTrackListLength; | 1855 return repetitions * autoRepeatTrackListLength; |
1810 } | 1856 } |
1811 | 1857 |
1812 std::unique_ptr<LayoutGrid::OrderedTrackIndexSet> | 1858 std::unique_ptr<LayoutGrid::OrderedTrackIndexSet> |
1813 LayoutGrid::computeEmptyTracksForAutoRepeat( | 1859 LayoutGrid::computeEmptyTracksForAutoRepeat( |
1814 GridTrackSizingDirection direction) const { | 1860 GridTrackSizingDirection direction) const { |
1815 bool isRowAxis = direction == ForColumns; | 1861 bool isRowAxis = direction == ForColumns; |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1936 ASSERT(m_gridItemsIndexesMap.isEmpty()); | 1982 ASSERT(m_gridItemsIndexesMap.isEmpty()); |
1937 size_t childIndex = 0; | 1983 size_t childIndex = 0; |
1938 for (LayoutBox* child = firstChildBox(); child; | 1984 for (LayoutBox* child = firstChildBox(); child; |
1939 child = child->nextInFlowSiblingBox()) { | 1985 child = child->nextInFlowSiblingBox()) { |
1940 if (child->isOutOfFlowPositioned()) | 1986 if (child->isOutOfFlowPositioned()) |
1941 continue; | 1987 continue; |
1942 | 1988 |
1943 populator.collectChild(child); | 1989 populator.collectChild(child); |
1944 m_gridItemsIndexesMap.set(child, childIndex++); | 1990 m_gridItemsIndexesMap.set(child, childIndex++); |
1945 | 1991 |
1946 // This function bypasses the cache (cachedGridArea()) as it is used to buil
d it. | 1992 // This function bypasses the cache (cachedGridArea()) as it is used to |
| 1993 // build it. |
1947 GridSpan rowPositions = | 1994 GridSpan rowPositions = |
1948 GridPositionsResolver::resolveGridPositionsFromStyle( | 1995 GridPositionsResolver::resolveGridPositionsFromStyle( |
1949 *style(), *child, ForRows, m_autoRepeatRows); | 1996 *style(), *child, ForRows, m_autoRepeatRows); |
1950 GridSpan columnPositions = | 1997 GridSpan columnPositions = |
1951 GridPositionsResolver::resolveGridPositionsFromStyle( | 1998 GridPositionsResolver::resolveGridPositionsFromStyle( |
1952 *style(), *child, ForColumns, m_autoRepeatColumns); | 1999 *style(), *child, ForColumns, m_autoRepeatColumns); |
1953 m_gridItemArea.set(child, GridArea(rowPositions, columnPositions)); | 2000 m_gridItemArea.set(child, GridArea(rowPositions, columnPositions)); |
1954 | 2001 |
1955 // |positions| is 0 if we need to run the auto-placement algorithm. | 2002 // |positions| is 0 if we need to run the auto-placement algorithm. |
1956 if (!rowPositions.isIndefinite()) { | 2003 if (!rowPositions.isIndefinite()) { |
1957 m_smallestRowStart = | 2004 m_smallestRowStart = |
1958 std::min(m_smallestRowStart, rowPositions.untranslatedStartLine()); | 2005 std::min(m_smallestRowStart, rowPositions.untranslatedStartLine()); |
1959 maximumRowIndex = | 2006 maximumRowIndex = |
1960 std::max<int>(maximumRowIndex, rowPositions.untranslatedEndLine()); | 2007 std::max<int>(maximumRowIndex, rowPositions.untranslatedEndLine()); |
1961 } else { | 2008 } else { |
1962 // Grow the grid for items with a definite row span, getting the largest s
uch span. | 2009 // Grow the grid for items with a definite row span, getting the largest |
| 2010 // such span. |
1963 size_t spanSize = GridPositionsResolver::spanSizeForAutoPlacedItem( | 2011 size_t spanSize = GridPositionsResolver::spanSizeForAutoPlacedItem( |
1964 *style(), *child, ForRows); | 2012 *style(), *child, ForRows); |
1965 maximumRowIndex = std::max(maximumRowIndex, spanSize); | 2013 maximumRowIndex = std::max(maximumRowIndex, spanSize); |
1966 } | 2014 } |
1967 | 2015 |
1968 if (!columnPositions.isIndefinite()) { | 2016 if (!columnPositions.isIndefinite()) { |
1969 m_smallestColumnStart = std::min(m_smallestColumnStart, | 2017 m_smallestColumnStart = std::min(m_smallestColumnStart, |
1970 columnPositions.untranslatedStartLine()); | 2018 columnPositions.untranslatedStartLine()); |
1971 maximumColumnIndex = std::max<int>(maximumColumnIndex, | 2019 maximumColumnIndex = std::max<int>(maximumColumnIndex, |
1972 columnPositions.untranslatedEndLine()); | 2020 columnPositions.untranslatedEndLine()); |
1973 } else { | 2021 } else { |
1974 // Grow the grid for items with a definite column span, getting the larges
t such span. | 2022 // Grow the grid for items with a definite column span, getting the |
| 2023 // largest such span. |
1975 size_t spanSize = GridPositionsResolver::spanSizeForAutoPlacedItem( | 2024 size_t spanSize = GridPositionsResolver::spanSizeForAutoPlacedItem( |
1976 *style(), *child, ForColumns); | 2025 *style(), *child, ForColumns); |
1977 maximumColumnIndex = std::max(maximumColumnIndex, spanSize); | 2026 maximumColumnIndex = std::max(maximumColumnIndex, spanSize); |
1978 } | 2027 } |
1979 } | 2028 } |
1980 | 2029 |
1981 m_grid.grow(maximumRowIndex + abs(m_smallestRowStart)); | 2030 m_grid.grow(maximumRowIndex + abs(m_smallestRowStart)); |
1982 for (auto& column : m_grid) | 2031 for (auto& column : m_grid) |
1983 column.grow(maximumColumnIndex + abs(m_smallestColumnStart)); | 2032 column.grow(maximumColumnIndex + abs(m_smallestColumnStart)); |
1984 } | 2033 } |
(...skipping 17 matching lines...) Expand all Loading... |
2002 : specifiedPositions, | 2051 : specifiedPositions, |
2003 specifiedDirection == ForColumns ? specifiedPositions | 2052 specifiedDirection == ForColumns ? specifiedPositions |
2004 : crossDirectionPositions)); | 2053 : crossDirectionPositions)); |
2005 } | 2054 } |
2006 | 2055 |
2007 void LayoutGrid::placeSpecifiedMajorAxisItemsOnGrid( | 2056 void LayoutGrid::placeSpecifiedMajorAxisItemsOnGrid( |
2008 const Vector<LayoutBox*>& autoGridItems) { | 2057 const Vector<LayoutBox*>& autoGridItems) { |
2009 bool isForColumns = autoPlacementMajorAxisDirection() == ForColumns; | 2058 bool isForColumns = autoPlacementMajorAxisDirection() == ForColumns; |
2010 bool isGridAutoFlowDense = style()->isGridAutoFlowAlgorithmDense(); | 2059 bool isGridAutoFlowDense = style()->isGridAutoFlowAlgorithmDense(); |
2011 | 2060 |
2012 // Mapping between the major axis tracks (rows or columns) and the last auto-p
laced item's position inserted on | 2061 // Mapping between the major axis tracks (rows or columns) and the last |
2013 // that track. This is needed to implement "sparse" packing for items locked t
o a given track. | 2062 // auto-placed item's position inserted on that track. This is needed to |
| 2063 // implement "sparse" packing for items locked to a given track. |
2014 // See http://dev.w3.org/csswg/css-grid/#auto-placement-algo | 2064 // See http://dev.w3.org/csswg/css-grid/#auto-placement-algo |
2015 HashMap<unsigned, unsigned, DefaultHash<unsigned>::Hash, | 2065 HashMap<unsigned, unsigned, DefaultHash<unsigned>::Hash, |
2016 WTF::UnsignedWithZeroKeyHashTraits<unsigned>> | 2066 WTF::UnsignedWithZeroKeyHashTraits<unsigned>> |
2017 minorAxisCursors; | 2067 minorAxisCursors; |
2018 | 2068 |
2019 for (const auto& autoGridItem : autoGridItems) { | 2069 for (const auto& autoGridItem : autoGridItems) { |
2020 GridSpan majorAxisPositions = | 2070 GridSpan majorAxisPositions = |
2021 cachedGridSpan(*autoGridItem, autoPlacementMajorAxisDirection()); | 2071 cachedGridSpan(*autoGridItem, autoPlacementMajorAxisDirection()); |
2022 ASSERT(majorAxisPositions.isTranslatedDefinite()); | 2072 ASSERT(majorAxisPositions.isTranslatedDefinite()); |
2023 ASSERT(!cachedGridSpan(*autoGridItem, autoPlacementMinorAxisDirection()) | 2073 ASSERT(!cachedGridSpan(*autoGridItem, autoPlacementMinorAxisDirection()) |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2080 autoPlacementMajorAxisDirection() == ForColumns | 2130 autoPlacementMajorAxisDirection() == ForColumns |
2081 ? autoPlacementCursor.second | 2131 ? autoPlacementCursor.second |
2082 : autoPlacementCursor.first; | 2132 : autoPlacementCursor.first; |
2083 size_t minorAxisAutoPlacementCursor = | 2133 size_t minorAxisAutoPlacementCursor = |
2084 autoPlacementMajorAxisDirection() == ForColumns | 2134 autoPlacementMajorAxisDirection() == ForColumns |
2085 ? autoPlacementCursor.first | 2135 ? autoPlacementCursor.first |
2086 : autoPlacementCursor.second; | 2136 : autoPlacementCursor.second; |
2087 | 2137 |
2088 std::unique_ptr<GridArea> emptyGridArea; | 2138 std::unique_ptr<GridArea> emptyGridArea; |
2089 if (minorAxisPositions.isTranslatedDefinite()) { | 2139 if (minorAxisPositions.isTranslatedDefinite()) { |
2090 // Move to the next track in major axis if initial position in minor axis is
before auto-placement cursor. | 2140 // Move to the next track in major axis if initial position in minor axis is |
| 2141 // before auto-placement cursor. |
2091 if (minorAxisPositions.startLine() < minorAxisAutoPlacementCursor) | 2142 if (minorAxisPositions.startLine() < minorAxisAutoPlacementCursor) |
2092 majorAxisAutoPlacementCursor++; | 2143 majorAxisAutoPlacementCursor++; |
2093 | 2144 |
2094 if (majorAxisAutoPlacementCursor < endOfMajorAxis) { | 2145 if (majorAxisAutoPlacementCursor < endOfMajorAxis) { |
2095 GridIterator iterator(m_grid, autoPlacementMinorAxisDirection(), | 2146 GridIterator iterator(m_grid, autoPlacementMinorAxisDirection(), |
2096 minorAxisPositions.startLine(), | 2147 minorAxisPositions.startLine(), |
2097 majorAxisAutoPlacementCursor); | 2148 majorAxisAutoPlacementCursor); |
2098 emptyGridArea = iterator.nextEmptyGridArea( | 2149 emptyGridArea = iterator.nextEmptyGridArea( |
2099 minorAxisPositions.integerSpan(), majorAxisSpanSize); | 2150 minorAxisPositions.integerSpan(), majorAxisSpanSize); |
2100 } | 2151 } |
2101 | 2152 |
2102 if (!emptyGridArea) | 2153 if (!emptyGridArea) |
2103 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid( | 2154 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid( |
2104 gridItem, autoPlacementMinorAxisDirection(), minorAxisPositions); | 2155 gridItem, autoPlacementMinorAxisDirection(), minorAxisPositions); |
2105 } else { | 2156 } else { |
2106 size_t minorAxisSpanSize = GridPositionsResolver::spanSizeForAutoPlacedItem( | 2157 size_t minorAxisSpanSize = GridPositionsResolver::spanSizeForAutoPlacedItem( |
2107 *style(), gridItem, autoPlacementMinorAxisDirection()); | 2158 *style(), gridItem, autoPlacementMinorAxisDirection()); |
2108 | 2159 |
2109 for (size_t majorAxisIndex = majorAxisAutoPlacementCursor; | 2160 for (size_t majorAxisIndex = majorAxisAutoPlacementCursor; |
2110 majorAxisIndex < endOfMajorAxis; ++majorAxisIndex) { | 2161 majorAxisIndex < endOfMajorAxis; ++majorAxisIndex) { |
2111 GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), | 2162 GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), |
2112 majorAxisIndex, minorAxisAutoPlacementCursor); | 2163 majorAxisIndex, minorAxisAutoPlacementCursor); |
2113 emptyGridArea = | 2164 emptyGridArea = |
2114 iterator.nextEmptyGridArea(majorAxisSpanSize, minorAxisSpanSize); | 2165 iterator.nextEmptyGridArea(majorAxisSpanSize, minorAxisSpanSize); |
2115 | 2166 |
2116 if (emptyGridArea) { | 2167 if (emptyGridArea) { |
2117 // Check that it fits in the minor axis direction, as we shouldn't grow
in that direction here (it was already managed in populateExplicitGridAndOrderIt
erator()). | 2168 // Check that it fits in the minor axis direction, as we shouldn't grow |
| 2169 // in that direction here (it was already managed in |
| 2170 // populateExplicitGridAndOrderIterator()). |
2118 size_t minorAxisFinalPositionIndex = | 2171 size_t minorAxisFinalPositionIndex = |
2119 autoPlacementMinorAxisDirection() == ForColumns | 2172 autoPlacementMinorAxisDirection() == ForColumns |
2120 ? emptyGridArea->columns.endLine() | 2173 ? emptyGridArea->columns.endLine() |
2121 : emptyGridArea->rows.endLine(); | 2174 : emptyGridArea->rows.endLine(); |
2122 const size_t endOfMinorAxis = | 2175 const size_t endOfMinorAxis = |
2123 autoPlacementMinorAxisDirection() == ForColumns ? gridColumnCount() | 2176 autoPlacementMinorAxisDirection() == ForColumns ? gridColumnCount() |
2124 : gridRowCount(); | 2177 : gridRowCount(); |
2125 if (minorAxisFinalPositionIndex <= endOfMinorAxis) | 2178 if (minorAxisFinalPositionIndex <= endOfMinorAxis) |
2126 break; | 2179 break; |
2127 | 2180 |
2128 // Discard empty grid area as it does not fit in the minor axis directio
n. | 2181 // Discard empty grid area as it does not fit in the minor axis |
2129 // We don't need to create a new empty grid area yet as we might find a
valid one in the next iteration. | 2182 // direction. We don't need to create a new empty grid area yet as we |
| 2183 // might find a valid one in the next iteration. |
2130 emptyGridArea = nullptr; | 2184 emptyGridArea = nullptr; |
2131 } | 2185 } |
2132 | 2186 |
2133 // As we're moving to the next track in the major axis we should reset the
auto-placement cursor in the minor axis. | 2187 // As we're moving to the next track in the major axis we should reset the |
| 2188 // auto-placement cursor in the minor axis. |
2134 minorAxisAutoPlacementCursor = 0; | 2189 minorAxisAutoPlacementCursor = 0; |
2135 } | 2190 } |
2136 | 2191 |
2137 if (!emptyGridArea) | 2192 if (!emptyGridArea) |
2138 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid( | 2193 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid( |
2139 gridItem, autoPlacementMinorAxisDirection(), | 2194 gridItem, autoPlacementMinorAxisDirection(), |
2140 GridSpan::translatedDefiniteGridSpan(0, minorAxisSpanSize)); | 2195 GridSpan::translatedDefiniteGridSpan(0, minorAxisSpanSize)); |
2141 } | 2196 } |
2142 | 2197 |
2143 m_gridItemArea.set(&gridItem, *emptyGridArea); | 2198 m_gridItemArea.set(&gridItem, *emptyGridArea); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2195 return tracks; | 2250 return tracks; |
2196 | 2251 |
2197 size_t remainingEmptyTracks = isRowAxis ? m_autoRepeatEmptyColumns->size() | 2252 size_t remainingEmptyTracks = isRowAxis ? m_autoRepeatEmptyColumns->size() |
2198 : m_autoRepeatEmptyRows->size(); | 2253 : m_autoRepeatEmptyRows->size(); |
2199 size_t lastLine = tracks.size(); | 2254 size_t lastLine = tracks.size(); |
2200 gap = gridGapForDirection(direction, TrackSizing); | 2255 gap = gridGapForDirection(direction, TrackSizing); |
2201 for (size_t i = 1; i < lastLine; ++i) { | 2256 for (size_t i = 1; i < lastLine; ++i) { |
2202 if (isEmptyAutoRepeatTrack(direction, i - 1)) { | 2257 if (isEmptyAutoRepeatTrack(direction, i - 1)) { |
2203 --remainingEmptyTracks; | 2258 --remainingEmptyTracks; |
2204 } else { | 2259 } else { |
2205 // Remove the gap between consecutive non empty tracks. Remove it also jus
t once for an | 2260 // Remove the gap between consecutive non empty tracks. Remove it also |
2206 // arbitrary number of empty tracks between two non empty ones. | 2261 // just once for an arbitrary number of empty tracks between two non empty |
| 2262 // ones. |
2207 bool allRemainingTracksAreEmpty = remainingEmptyTracks == (lastLine - i); | 2263 bool allRemainingTracksAreEmpty = remainingEmptyTracks == (lastLine - i); |
2208 if (!allRemainingTracksAreEmpty || !isEmptyAutoRepeatTrack(direction, i)) | 2264 if (!allRemainingTracksAreEmpty || !isEmptyAutoRepeatTrack(direction, i)) |
2209 tracks[i - 1] -= gap; | 2265 tracks[i - 1] -= gap; |
2210 } | 2266 } |
2211 } | 2267 } |
2212 | 2268 |
2213 return tracks; | 2269 return tracks; |
2214 } | 2270 } |
2215 | 2271 |
2216 static const StyleContentAlignmentData& contentAlignmentNormalBehavior() { | 2272 static const StyleContentAlignmentData& contentAlignmentNormalBehavior() { |
2217 static const StyleContentAlignmentData normalBehavior = { | 2273 static const StyleContentAlignmentData normalBehavior = { |
2218 ContentPositionNormal, ContentDistributionStretch}; | 2274 ContentPositionNormal, ContentDistributionStretch}; |
2219 return normalBehavior; | 2275 return normalBehavior; |
2220 } | 2276 } |
2221 | 2277 |
2222 void LayoutGrid::applyStretchAlignmentToTracksIfNeeded( | 2278 void LayoutGrid::applyStretchAlignmentToTracksIfNeeded( |
2223 GridTrackSizingDirection direction, | 2279 GridTrackSizingDirection direction, |
2224 GridSizingData& sizingData) { | 2280 GridSizingData& sizingData) { |
2225 LayoutUnit& availableSpace = sizingData.freeSpace(direction); | 2281 LayoutUnit& availableSpace = sizingData.freeSpace(direction); |
2226 if (availableSpace <= 0 || | 2282 if (availableSpace <= 0 || |
2227 (direction == ForColumns && | 2283 (direction == ForColumns && |
2228 styleRef().resolvedJustifyContentDistribution( | 2284 styleRef().resolvedJustifyContentDistribution( |
2229 contentAlignmentNormalBehavior()) != ContentDistributionStretch) || | 2285 contentAlignmentNormalBehavior()) != ContentDistributionStretch) || |
2230 (direction == ForRows && | 2286 (direction == ForRows && |
2231 styleRef().resolvedAlignContentDistribution( | 2287 styleRef().resolvedAlignContentDistribution( |
2232 contentAlignmentNormalBehavior()) != ContentDistributionStretch)) | 2288 contentAlignmentNormalBehavior()) != ContentDistributionStretch)) |
2233 return; | 2289 return; |
2234 | 2290 |
2235 // Spec defines auto-sized tracks as the ones with an 'auto' max-sizing functi
on. | 2291 // Spec defines auto-sized tracks as the ones with an 'auto' max-sizing |
| 2292 // function. |
2236 Vector<GridTrack>& tracks = (direction == ForColumns) | 2293 Vector<GridTrack>& tracks = (direction == ForColumns) |
2237 ? sizingData.columnTracks | 2294 ? sizingData.columnTracks |
2238 : sizingData.rowTracks; | 2295 : sizingData.rowTracks; |
2239 Vector<unsigned> autoSizedTracksIndex; | 2296 Vector<unsigned> autoSizedTracksIndex; |
2240 for (unsigned i = 0; i < tracks.size(); ++i) { | 2297 for (unsigned i = 0; i < tracks.size(); ++i) { |
2241 const GridTrackSize& trackSize = gridTrackSize(direction, i); | 2298 const GridTrackSize& trackSize = gridTrackSize(direction, i); |
2242 if (trackSize.hasAutoMaxTrackBreadth()) | 2299 if (trackSize.hasAutoMaxTrackBreadth()) |
2243 autoSizedTracksIndex.append(i); | 2300 autoSizedTracksIndex.append(i); |
2244 } | 2301 } |
2245 | 2302 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2292 (oldOverrideContainingBlockContentLogicalHeight != | 2349 (oldOverrideContainingBlockContentLogicalHeight != |
2293 overrideContainingBlockContentLogicalHeight && | 2350 overrideContainingBlockContentLogicalHeight && |
2294 child->hasRelativeLogicalHeight())) | 2351 child->hasRelativeLogicalHeight())) |
2295 child->setNeedsLayout(LayoutInvalidationReason::GridChanged); | 2352 child->setNeedsLayout(LayoutInvalidationReason::GridChanged); |
2296 | 2353 |
2297 child->setOverrideContainingBlockContentLogicalWidth( | 2354 child->setOverrideContainingBlockContentLogicalWidth( |
2298 overrideContainingBlockContentLogicalWidth); | 2355 overrideContainingBlockContentLogicalWidth); |
2299 child->setOverrideContainingBlockContentLogicalHeight( | 2356 child->setOverrideContainingBlockContentLogicalHeight( |
2300 overrideContainingBlockContentLogicalHeight); | 2357 overrideContainingBlockContentLogicalHeight); |
2301 | 2358 |
2302 // Stretching logic might force a child layout, so we need to run it before
the layoutIfNeeded | 2359 // Stretching logic might force a child layout, so we need to run it before |
2303 // call to avoid unnecessary relayouts. This might imply that child margins,
needed to correctly | 2360 // the layoutIfNeeded call to avoid unnecessary relayouts. This might imply |
2304 // determine the available space before stretching, are not set yet. | 2361 // that child margins, needed to correctly determine the available space |
| 2362 // before stretching, are not set yet. |
2305 applyStretchAlignmentToChildIfNeeded(*child); | 2363 applyStretchAlignmentToChildIfNeeded(*child); |
2306 | 2364 |
2307 child->layoutIfNeeded(); | 2365 child->layoutIfNeeded(); |
2308 | 2366 |
2309 // We need pending layouts to be done in order to compute auto-margins prope
rly. | 2367 // We need pending layouts to be done in order to compute auto-margins |
| 2368 // properly. |
2310 updateAutoMarginsInColumnAxisIfNeeded(*child); | 2369 updateAutoMarginsInColumnAxisIfNeeded(*child); |
2311 updateAutoMarginsInRowAxisIfNeeded(*child); | 2370 updateAutoMarginsInRowAxisIfNeeded(*child); |
2312 | 2371 |
2313 const GridArea& area = cachedGridArea(*child); | 2372 const GridArea& area = cachedGridArea(*child); |
2314 #if ENABLE(ASSERT) | 2373 #if ENABLE(ASSERT) |
2315 ASSERT(area.columns.startLine() < sizingData.columnTracks.size()); | 2374 ASSERT(area.columns.startLine() < sizingData.columnTracks.size()); |
2316 ASSERT(area.rows.startLine() < sizingData.rowTracks.size()); | 2375 ASSERT(area.rows.startLine() < sizingData.rowTracks.size()); |
2317 #endif | 2376 #endif |
2318 child->setLogicalLocation(findChildLogicalPosition(*child, sizingData)); | 2377 child->setLogicalLocation(findChildLogicalPosition(*child, sizingData)); |
2319 | 2378 |
2320 // Keep track of children overflowing their grid area as we might need to pa
int them even if the grid-area is not visible. | 2379 // Keep track of children overflowing their grid area as we might need to |
2321 // Using physical dimensions for simplicity, so we can forget about orthogon
alty. | 2380 // paint them even if the grid-area is not visible. Using physical |
| 2381 // dimensions for simplicity, so we can forget about orthogonalty. |
2322 LayoutUnit childGridAreaHeight = | 2382 LayoutUnit childGridAreaHeight = |
2323 isHorizontalWritingMode() ? overrideContainingBlockContentLogicalHeight | 2383 isHorizontalWritingMode() ? overrideContainingBlockContentLogicalHeight |
2324 : overrideContainingBlockContentLogicalWidth; | 2384 : overrideContainingBlockContentLogicalWidth; |
2325 LayoutUnit childGridAreaWidth = | 2385 LayoutUnit childGridAreaWidth = |
2326 isHorizontalWritingMode() ? overrideContainingBlockContentLogicalWidth | 2386 isHorizontalWritingMode() ? overrideContainingBlockContentLogicalWidth |
2327 : overrideContainingBlockContentLogicalHeight; | 2387 : overrideContainingBlockContentLogicalHeight; |
2328 LayoutRect gridAreaRect( | 2388 LayoutRect gridAreaRect( |
2329 gridAreaLogicalPosition(area), | 2389 gridAreaLogicalPosition(area), |
2330 LayoutSize(childGridAreaWidth, childGridAreaHeight)); | 2390 LayoutSize(childGridAreaWidth, childGridAreaHeight)); |
2331 if (!gridAreaRect.contains(child->frameRect())) | 2391 if (!gridAreaRect.contains(child->frameRect())) |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2386 bool isForColumns = direction == ForColumns; | 2446 bool isForColumns = direction == ForColumns; |
2387 | 2447 |
2388 GridSpan positions = GridPositionsResolver::resolveGridPositionsFromStyle( | 2448 GridSpan positions = GridPositionsResolver::resolveGridPositionsFromStyle( |
2389 *style(), child, direction, autoRepeatCountForDirection(direction)); | 2449 *style(), child, direction, autoRepeatCountForDirection(direction)); |
2390 if (positions.isIndefinite()) { | 2450 if (positions.isIndefinite()) { |
2391 offset = LayoutUnit(); | 2451 offset = LayoutUnit(); |
2392 breadth = isForColumns ? clientLogicalWidth() : clientLogicalHeight(); | 2452 breadth = isForColumns ? clientLogicalWidth() : clientLogicalHeight(); |
2393 return; | 2453 return; |
2394 } | 2454 } |
2395 | 2455 |
2396 // For positioned items we cannot use GridSpan::translate(). Because we could
end up with negative values, as the positioned items do not create implicit trac
ks per spec. | 2456 // For positioned items we cannot use GridSpan::translate(). Because we could |
| 2457 // end up with negative values, as the positioned items do not create implicit |
| 2458 // tracks per spec. |
2397 int smallestStart = | 2459 int smallestStart = |
2398 abs(isForColumns ? m_smallestColumnStart : m_smallestRowStart); | 2460 abs(isForColumns ? m_smallestColumnStart : m_smallestRowStart); |
2399 int startLine = positions.untranslatedStartLine() + smallestStart; | 2461 int startLine = positions.untranslatedStartLine() + smallestStart; |
2400 int endLine = positions.untranslatedEndLine() + smallestStart; | 2462 int endLine = positions.untranslatedEndLine() + smallestStart; |
2401 | 2463 |
2402 GridPosition startPosition = isForColumns ? child.style()->gridColumnStart() | 2464 GridPosition startPosition = isForColumns ? child.style()->gridColumnStart() |
2403 : child.style()->gridRowStart(); | 2465 : child.style()->gridRowStart(); |
2404 GridPosition endPosition = isForColumns ? child.style()->gridColumnEnd() | 2466 GridPosition endPosition = isForColumns ? child.style()->gridColumnEnd() |
2405 : child.style()->gridRowEnd(); | 2467 : child.style()->gridRowEnd(); |
2406 int lastLine = isForColumns ? gridColumnCount() : gridRowCount(); | 2468 int lastLine = isForColumns ? gridColumnCount() : gridRowCount(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2439 if (styleRef().isLeftToRightDirection()) | 2501 if (styleRef().isLeftToRightDirection()) |
2440 end = m_columnPositions[endLine] - borderLogicalLeft(); | 2502 end = m_columnPositions[endLine] - borderLogicalLeft(); |
2441 else | 2503 else |
2442 end = logicalWidth() - | 2504 end = logicalWidth() - |
2443 translateRTLCoordinate(m_columnPositions[endLine]) - | 2505 translateRTLCoordinate(m_columnPositions[endLine]) - |
2444 borderLogicalRight(); | 2506 borderLogicalRight(); |
2445 } else { | 2507 } else { |
2446 end = m_rowPositions[endLine] - borderBefore(); | 2508 end = m_rowPositions[endLine] - borderBefore(); |
2447 } | 2509 } |
2448 | 2510 |
2449 // These vectors store line positions including gaps, but we shouldn't consi
der them for the edges of the grid. | 2511 // These vectors store line positions including gaps, but we shouldn't |
| 2512 // consider them for the edges of the grid. |
2450 if (endLine > 0 && endLine < lastLine) { | 2513 if (endLine > 0 && endLine < lastLine) { |
2451 end -= guttersSize(direction, endLine - 1, 2, TrackSizing); | 2514 end -= guttersSize(direction, endLine - 1, 2, TrackSizing); |
2452 end -= isForColumns ? m_offsetBetweenColumns : m_offsetBetweenRows; | 2515 end -= isForColumns ? m_offsetBetweenColumns : m_offsetBetweenRows; |
2453 } | 2516 } |
2454 } | 2517 } |
2455 | 2518 |
2456 breadth = std::max(end - start, LayoutUnit()); | 2519 breadth = std::max(end - start, LayoutUnit()); |
2457 offset = start; | 2520 offset = start; |
2458 | 2521 |
2459 if (isForColumns && !styleRef().isLeftToRightDirection() && | 2522 if (isForColumns && !styleRef().isLeftToRightDirection() && |
2460 !child.styleRef().hasStaticInlinePosition( | 2523 !child.styleRef().hasStaticInlinePosition( |
2461 child.isHorizontalWritingMode())) { | 2524 child.isHorizontalWritingMode())) { |
2462 // If the child doesn't have a static inline position (i.e. "left" and/or "r
ight" aren't "auto", | 2525 // If the child doesn't have a static inline position (i.e. "left" and/or |
2463 // we need to calculate the offset from the left (even if we're in RTL). | 2526 // "right" aren't "auto", we need to calculate the offset from the left |
| 2527 // (even if we're in RTL). |
2464 if (endIsAuto) { | 2528 if (endIsAuto) { |
2465 offset = LayoutUnit(); | 2529 offset = LayoutUnit(); |
2466 } else { | 2530 } else { |
2467 offset = translateRTLCoordinate(m_columnPositions[endLine]) - | 2531 offset = translateRTLCoordinate(m_columnPositions[endLine]) - |
2468 borderLogicalLeft(); | 2532 borderLogicalLeft(); |
2469 | 2533 |
2470 if (endLine > 0 && endLine < lastLine) { | 2534 if (endLine > 0 && endLine < lastLine) { |
2471 offset += guttersSize(direction, endLine - 1, 2, TrackSizing); | 2535 offset += guttersSize(direction, endLine - 1, 2, TrackSizing); |
2472 offset += isForColumns ? m_offsetBetweenColumns : m_offsetBetweenRows; | 2536 offset += isForColumns ? m_offsetBetweenColumns : m_offsetBetweenRows; |
2473 } | 2537 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2511 | 2575 |
2512 return gridAreaIsIndefinite | 2576 return gridAreaIsIndefinite |
2513 ? std::max(child.maxPreferredLogicalWidth(), gridAreaSize) | 2577 ? std::max(child.maxPreferredLogicalWidth(), gridAreaSize) |
2514 : gridAreaSize; | 2578 : gridAreaSize; |
2515 } | 2579 } |
2516 | 2580 |
2517 LayoutUnit LayoutGrid::gridAreaBreadthForChild( | 2581 LayoutUnit LayoutGrid::gridAreaBreadthForChild( |
2518 const LayoutBox& child, | 2582 const LayoutBox& child, |
2519 GridTrackSizingDirection direction, | 2583 GridTrackSizingDirection direction, |
2520 const GridSizingData& sizingData) const { | 2584 const GridSizingData& sizingData) const { |
2521 // To determine the column track's size based on an orthogonal grid item we ne
ed it's logical height, which | 2585 // To determine the column track's size based on an orthogonal grid item we |
2522 // may depend on the row track's size. It's possible that the row tracks sizin
g logic has not been performed yet, | 2586 // need it's logical height, which may depend on the row track's size. It's |
2523 // so we will need to do an estimation. | 2587 // possible that the row tracks sizing logic has not been performed yet, so we |
| 2588 // will need to do an estimation. |
2524 if (direction == ForRows && | 2589 if (direction == ForRows && |
2525 sizingData.sizingState == GridSizingData::ColumnSizingFirstIteration) | 2590 sizingData.sizingState == GridSizingData::ColumnSizingFirstIteration) |
2526 return assumedRowsSizeForOrthogonalChild(child, sizingData.sizingOperation); | 2591 return assumedRowsSizeForOrthogonalChild(child, sizingData.sizingOperation); |
2527 | 2592 |
2528 const Vector<GridTrack>& tracks = | 2593 const Vector<GridTrack>& tracks = |
2529 direction == ForColumns ? sizingData.columnTracks : sizingData.rowTracks; | 2594 direction == ForColumns ? sizingData.columnTracks : sizingData.rowTracks; |
2530 const GridSpan& span = cachedGridSpan(child, direction); | 2595 const GridSpan& span = cachedGridSpan(child, direction); |
2531 LayoutUnit gridAreaBreadth; | 2596 LayoutUnit gridAreaBreadth; |
2532 for (const auto& trackPosition : span) | 2597 for (const auto& trackPosition : span) |
2533 gridAreaBreadth += tracks[trackPosition].baseSize(); | 2598 gridAreaBreadth += tracks[trackPosition].baseSize(); |
2534 | 2599 |
2535 gridAreaBreadth += | 2600 gridAreaBreadth += |
2536 guttersSize(direction, span.startLine(), span.integerSpan(), | 2601 guttersSize(direction, span.startLine(), span.integerSpan(), |
2537 sizingData.sizingOperation); | 2602 sizingData.sizingOperation); |
2538 | 2603 |
2539 return gridAreaBreadth; | 2604 return gridAreaBreadth; |
2540 } | 2605 } |
2541 | 2606 |
2542 LayoutUnit LayoutGrid::gridAreaBreadthForChildIncludingAlignmentOffsets( | 2607 LayoutUnit LayoutGrid::gridAreaBreadthForChildIncludingAlignmentOffsets( |
2543 const LayoutBox& child, | 2608 const LayoutBox& child, |
2544 GridTrackSizingDirection direction, | 2609 GridTrackSizingDirection direction, |
2545 const GridSizingData& sizingData) const { | 2610 const GridSizingData& sizingData) const { |
2546 // We need the cached value when available because Content Distribution alignm
ent properties | 2611 // We need the cached value when available because Content Distribution |
2547 // may have some influence in the final grid area breadth. | 2612 // alignment properties may have some influence in the final grid area |
| 2613 // breadth. |
2548 const Vector<GridTrack>& tracks = (direction == ForColumns) | 2614 const Vector<GridTrack>& tracks = (direction == ForColumns) |
2549 ? sizingData.columnTracks | 2615 ? sizingData.columnTracks |
2550 : sizingData.rowTracks; | 2616 : sizingData.rowTracks; |
2551 const GridSpan& span = cachedGridSpan(child, direction); | 2617 const GridSpan& span = cachedGridSpan(child, direction); |
2552 const Vector<LayoutUnit>& linePositions = | 2618 const Vector<LayoutUnit>& linePositions = |
2553 (direction == ForColumns) ? m_columnPositions : m_rowPositions; | 2619 (direction == ForColumns) ? m_columnPositions : m_rowPositions; |
2554 LayoutUnit initialTrackPosition = linePositions[span.startLine()]; | 2620 LayoutUnit initialTrackPosition = linePositions[span.startLine()]; |
2555 LayoutUnit finalTrackPosition = linePositions[span.endLine() - 1]; | 2621 LayoutUnit finalTrackPosition = linePositions[span.endLine() - 1]; |
2556 // Track Positions vector stores the 'start' grid line of each track, so w hav
e to add last track's baseSize. | 2622 // Track Positions vector stores the 'start' grid line of each track, so we |
| 2623 // have to add last track's baseSize. |
2557 return finalTrackPosition - initialTrackPosition + | 2624 return finalTrackPosition - initialTrackPosition + |
2558 tracks[span.endLine() - 1].baseSize(); | 2625 tracks[span.endLine() - 1].baseSize(); |
2559 } | 2626 } |
2560 | 2627 |
2561 void LayoutGrid::populateGridPositionsForDirection( | 2628 void LayoutGrid::populateGridPositionsForDirection( |
2562 GridSizingData& sizingData, | 2629 GridSizingData& sizingData, |
2563 GridTrackSizingDirection direction) { | 2630 GridTrackSizingDirection direction) { |
2564 // Since we add alignment offsets and track gutters, grid lines are not always
adjacent. Hence we will have to | 2631 // Since we add alignment offsets and track gutters, grid lines are not always |
2565 // assume from now on that we just store positions of the initial grid lines o
f each track, | 2632 // adjacent. Hence we will have to assume from now on that we just store |
2566 // except the last one, which is the only one considered as a final grid line
of a track. | 2633 // positions of the initial grid lines of each track, except the last one, |
| 2634 // which is the only one considered as a final grid line of a track. |
2567 | 2635 |
2568 // The grid container's frame elements (border, padding and <content-position>
offset) are sensible to the | 2636 // The grid container's frame elements (border, padding and <content-position> |
2569 // inline-axis flow direction. However, column lines positions are 'direction'
unaware. This simplification | 2637 // offset) are sensible to the inline-axis flow direction. However, column |
2570 // allows us to use the same indexes to identify the columns independently on
the inline-axis direction. | 2638 // lines positions are 'direction' unaware. This simplification allows us to |
| 2639 // use the same indexes to identify the columns independently on the |
| 2640 // inline-axis direction. |
2571 bool isRowAxis = direction == ForColumns; | 2641 bool isRowAxis = direction == ForColumns; |
2572 auto& tracks = isRowAxis ? sizingData.columnTracks : sizingData.rowTracks; | 2642 auto& tracks = isRowAxis ? sizingData.columnTracks : sizingData.rowTracks; |
2573 size_t numberOfTracks = tracks.size(); | 2643 size_t numberOfTracks = tracks.size(); |
2574 size_t numberOfLines = numberOfTracks + 1; | 2644 size_t numberOfLines = numberOfTracks + 1; |
2575 size_t lastLine = numberOfLines - 1; | 2645 size_t lastLine = numberOfLines - 1; |
2576 ContentAlignmentData offset = computeContentPositionAndDistributionOffset( | 2646 ContentAlignmentData offset = computeContentPositionAndDistributionOffset( |
2577 direction, sizingData.freeSpace(direction), numberOfTracks); | 2647 direction, sizingData.freeSpace(direction), numberOfTracks); |
2578 auto& positions = isRowAxis ? m_columnPositions : m_rowPositions; | 2648 auto& positions = isRowAxis ? m_columnPositions : m_rowPositions; |
2579 positions.resize(numberOfLines); | 2649 positions.resize(numberOfLines); |
2580 auto borderAndPadding = | 2650 auto borderAndPadding = |
2581 isRowAxis ? borderAndPaddingLogicalLeft() : borderAndPaddingBefore(); | 2651 isRowAxis ? borderAndPaddingLogicalLeft() : borderAndPaddingBefore(); |
2582 positions[0] = borderAndPadding + offset.positionOffset; | 2652 positions[0] = borderAndPadding + offset.positionOffset; |
2583 if (numberOfLines > 1) { | 2653 if (numberOfLines > 1) { |
2584 // If we have collapsed tracks we just ignore gaps here and add them later a
s we might not | 2654 // If we have collapsed tracks we just ignore gaps here and add them later |
2585 // compute the gap between two consecutive tracks without examining the surr
ounding ones. | 2655 // as we might not compute the gap between two consecutive tracks without |
| 2656 // examining the surrounding ones. |
2586 bool hasCollapsedTracks = hasAutoRepeatEmptyTracks(direction); | 2657 bool hasCollapsedTracks = hasAutoRepeatEmptyTracks(direction); |
2587 LayoutUnit gap = | 2658 LayoutUnit gap = |
2588 !hasCollapsedTracks | 2659 !hasCollapsedTracks |
2589 ? gridGapForDirection(direction, sizingData.sizingOperation) | 2660 ? gridGapForDirection(direction, sizingData.sizingOperation) |
2590 : LayoutUnit(); | 2661 : LayoutUnit(); |
2591 size_t nextToLastLine = numberOfLines - 2; | 2662 size_t nextToLastLine = numberOfLines - 2; |
2592 for (size_t i = 0; i < nextToLastLine; ++i) | 2663 for (size_t i = 0; i < nextToLastLine; ++i) |
2593 positions[i + 1] = | 2664 positions[i + 1] = |
2594 positions[i] + offset.distributionOffset + tracks[i].baseSize() + gap; | 2665 positions[i] + offset.distributionOffset + tracks[i].baseSize() + gap; |
2595 positions[lastLine] = | 2666 positions[lastLine] = |
2596 positions[nextToLastLine] + tracks[nextToLastLine].baseSize(); | 2667 positions[nextToLastLine] + tracks[nextToLastLine].baseSize(); |
2597 | 2668 |
2598 // Adjust collapsed gaps. Collapsed tracks cause the surrounding gutters to
collapse (they | 2669 // Adjust collapsed gaps. Collapsed tracks cause the surrounding gutters to |
2599 // coincide exactly) except on the edges of the grid where they become 0. | 2670 // collapse (they coincide exactly) except on the edges of the grid where |
| 2671 // they become 0. |
2600 if (hasCollapsedTracks) { | 2672 if (hasCollapsedTracks) { |
2601 gap = gridGapForDirection(direction, sizingData.sizingOperation); | 2673 gap = gridGapForDirection(direction, sizingData.sizingOperation); |
2602 size_t remainingEmptyTracks = isRowAxis ? m_autoRepeatEmptyColumns->size() | 2674 size_t remainingEmptyTracks = isRowAxis ? m_autoRepeatEmptyColumns->size() |
2603 : m_autoRepeatEmptyRows->size(); | 2675 : m_autoRepeatEmptyRows->size(); |
2604 LayoutUnit gapAccumulator; | 2676 LayoutUnit gapAccumulator; |
2605 for (size_t i = 1; i < lastLine; ++i) { | 2677 for (size_t i = 1; i < lastLine; ++i) { |
2606 if (isEmptyAutoRepeatTrack(direction, i - 1)) { | 2678 if (isEmptyAutoRepeatTrack(direction, i - 1)) { |
2607 --remainingEmptyTracks; | 2679 --remainingEmptyTracks; |
2608 } else { | 2680 } else { |
2609 // Add gap between consecutive non empty tracks. Add it also just once
for an | 2681 // Add gap between consecutive non empty tracks. Add it also just once |
2610 // arbitrary number of empty tracks between two non empty ones. | 2682 // for an arbitrary number of empty tracks between two non empty ones. |
2611 bool allRemainingTracksAreEmpty = | 2683 bool allRemainingTracksAreEmpty = |
2612 remainingEmptyTracks == (lastLine - i); | 2684 remainingEmptyTracks == (lastLine - i); |
2613 if (!allRemainingTracksAreEmpty || | 2685 if (!allRemainingTracksAreEmpty || |
2614 !isEmptyAutoRepeatTrack(direction, i)) | 2686 !isEmptyAutoRepeatTrack(direction, i)) |
2615 gapAccumulator += gap; | 2687 gapAccumulator += gap; |
2616 } | 2688 } |
2617 positions[i] += gapAccumulator; | 2689 positions[i] += gapAccumulator; |
2618 } | 2690 } |
2619 positions[lastLine] += gapAccumulator; | 2691 positions[lastLine] += gapAccumulator; |
2620 } | 2692 } |
2621 } | 2693 } |
2622 auto& offsetBetweenTracks = | 2694 auto& offsetBetweenTracks = |
2623 isRowAxis ? m_offsetBetweenColumns : m_offsetBetweenRows; | 2695 isRowAxis ? m_offsetBetweenColumns : m_offsetBetweenRows; |
2624 offsetBetweenTracks = offset.distributionOffset; | 2696 offsetBetweenTracks = offset.distributionOffset; |
2625 } | 2697 } |
2626 | 2698 |
2627 static LayoutUnit computeOverflowAlignmentOffset(OverflowAlignment overflow, | 2699 static LayoutUnit computeOverflowAlignmentOffset(OverflowAlignment overflow, |
2628 LayoutUnit trackSize, | 2700 LayoutUnit trackSize, |
2629 LayoutUnit childSize) { | 2701 LayoutUnit childSize) { |
2630 LayoutUnit offset = trackSize - childSize; | 2702 LayoutUnit offset = trackSize - childSize; |
2631 switch (overflow) { | 2703 switch (overflow) { |
2632 case OverflowAlignmentSafe: | 2704 case OverflowAlignmentSafe: |
2633 // If overflow is 'safe', we have to make sure we don't overflow the 'star
t' | 2705 // If overflow is 'safe', we have to make sure we don't overflow the |
2634 // edge (potentially cause some data loss as the overflow is unreachable). | 2706 // 'start' edge (potentially cause some data loss as the overflow is |
| 2707 // unreachable). |
2635 return offset.clampNegativeToZero(); | 2708 return offset.clampNegativeToZero(); |
2636 case OverflowAlignmentUnsafe: | 2709 case OverflowAlignmentUnsafe: |
2637 case OverflowAlignmentDefault: | 2710 case OverflowAlignmentDefault: |
2638 // If we overflow our alignment container and overflow is 'true' (default)
, we | 2711 // If we overflow our alignment container and overflow is 'true' |
2639 // ignore the overflow and just return the value regardless (which may cau
se data | 2712 // (default), we ignore the overflow and just return the value regardless |
2640 // loss as we overflow the 'start' edge). | 2713 // (which may cause data loss as we overflow the 'start' edge). |
2641 return offset; | 2714 return offset; |
2642 } | 2715 } |
2643 | 2716 |
2644 ASSERT_NOT_REACHED(); | 2717 ASSERT_NOT_REACHED(); |
2645 return LayoutUnit(); | 2718 return LayoutUnit(); |
2646 } | 2719 } |
2647 | 2720 |
2648 // FIXME: This logic is shared by LayoutFlexibleBox, so it should be moved to La
youtBox. | 2721 // FIXME: This logic is shared by LayoutFlexibleBox, so it should be moved to |
| 2722 // LayoutBox. |
2649 LayoutUnit LayoutGrid::marginLogicalHeightForChild( | 2723 LayoutUnit LayoutGrid::marginLogicalHeightForChild( |
2650 const LayoutBox& child) const { | 2724 const LayoutBox& child) const { |
2651 return isHorizontalWritingMode() ? child.marginHeight() : child.marginWidth(); | 2725 return isHorizontalWritingMode() ? child.marginHeight() : child.marginWidth(); |
2652 } | 2726 } |
2653 | 2727 |
2654 LayoutUnit LayoutGrid::computeMarginLogicalSizeForChild( | 2728 LayoutUnit LayoutGrid::computeMarginLogicalSizeForChild( |
2655 MarginDirection forDirection, | 2729 MarginDirection forDirection, |
2656 const LayoutBox& child) const { | 2730 const LayoutBox& child) const { |
2657 if (!child.styleRef().hasMargin()) | 2731 if (!child.styleRef().hasMargin()) |
2658 return LayoutUnit(); | 2732 return LayoutUnit(); |
(...skipping 12 matching lines...) Expand all Loading... |
2671 child.computeMarginsForDirection( | 2745 child.computeMarginsForDirection( |
2672 forDirection, this, child.containingBlockLogicalWidthForContent(), | 2746 forDirection, this, child.containingBlockLogicalWidthForContent(), |
2673 logicalSize, marginStart, marginEnd, marginStartLength, marginEndLength); | 2747 logicalSize, marginStart, marginEnd, marginStartLength, marginEndLength); |
2674 | 2748 |
2675 return marginStart + marginEnd; | 2749 return marginStart + marginEnd; |
2676 } | 2750 } |
2677 | 2751 |
2678 LayoutUnit LayoutGrid::availableAlignmentSpaceForChildBeforeStretching( | 2752 LayoutUnit LayoutGrid::availableAlignmentSpaceForChildBeforeStretching( |
2679 LayoutUnit gridAreaBreadthForChild, | 2753 LayoutUnit gridAreaBreadthForChild, |
2680 const LayoutBox& child) const { | 2754 const LayoutBox& child) const { |
2681 // Because we want to avoid multiple layouts, stretching logic might be perfor
med before | 2755 // Because we want to avoid multiple layouts, stretching logic might be |
2682 // children are laid out, so we can't use the child cached values. Hence, we n
eed to | 2756 // performed before children are laid out, so we can't use the child cached |
2683 // compute margins in order to determine the available height before stretchin
g. | 2757 // values. Hence, we need to compute margins in order to determine the |
| 2758 // available height before stretching. |
2684 return gridAreaBreadthForChild - | 2759 return gridAreaBreadthForChild - |
2685 (child.needsLayout() | 2760 (child.needsLayout() |
2686 ? computeMarginLogicalSizeForChild(BlockDirection, child) | 2761 ? computeMarginLogicalSizeForChild(BlockDirection, child) |
2687 : marginLogicalHeightForChild(child)); | 2762 : marginLogicalHeightForChild(child)); |
2688 } | 2763 } |
2689 | 2764 |
2690 StyleSelfAlignmentData LayoutGrid::alignSelfForChild( | 2765 StyleSelfAlignmentData LayoutGrid::alignSelfForChild( |
2691 const LayoutBox& child) const { | 2766 const LayoutBox& child) const { |
2692 if (!child.isAnonymous()) | 2767 if (!child.isAnonymous()) |
2693 return child.styleRef().resolvedAlignSelf(selfAlignmentNormalBehavior()); | 2768 return child.styleRef().resolvedAlignSelf(selfAlignmentNormalBehavior()); |
2694 // All the 'auto' values has been solved by the StyleAdjuster, but it's possib
le that | 2769 // All the 'auto' values has been solved by the StyleAdjuster, but it's |
2695 // some grid items generate Anonymous boxes, which need to be solved during la
yout. | 2770 // possible that some grid items generate Anonymous boxes, which need to be |
| 2771 // solved during layout. |
2696 return child.styleRef().resolvedAlignSelf(selfAlignmentNormalBehavior(), | 2772 return child.styleRef().resolvedAlignSelf(selfAlignmentNormalBehavior(), |
2697 style()); | 2773 style()); |
2698 } | 2774 } |
2699 | 2775 |
2700 StyleSelfAlignmentData LayoutGrid::justifySelfForChild( | 2776 StyleSelfAlignmentData LayoutGrid::justifySelfForChild( |
2701 const LayoutBox& child) const { | 2777 const LayoutBox& child) const { |
2702 if (!child.isAnonymous()) | 2778 if (!child.isAnonymous()) |
2703 return child.styleRef().resolvedJustifySelf(ItemPositionStretch); | 2779 return child.styleRef().resolvedJustifySelf(ItemPositionStretch); |
2704 // All the 'auto' values has been solved by the StyleAdjuster, but it's possib
le that | 2780 // All the 'auto' values has been solved by the StyleAdjuster, but it's |
2705 // some grid items generate Anonymous boxes, which need to be solved during la
yout. | 2781 // possible that some grid items generate Anonymous boxes, which need to be |
| 2782 // solved during layout. |
2706 return child.styleRef().resolvedJustifySelf(selfAlignmentNormalBehavior(), | 2783 return child.styleRef().resolvedJustifySelf(selfAlignmentNormalBehavior(), |
2707 style()); | 2784 style()); |
2708 } | 2785 } |
2709 | 2786 |
2710 // FIXME: This logic is shared by LayoutFlexibleBox, so it should be moved to La
youtBox. | 2787 // FIXME: This logic is shared by LayoutFlexibleBox, so it should be moved to |
| 2788 // LayoutBox. |
2711 void LayoutGrid::applyStretchAlignmentToChildIfNeeded(LayoutBox& child) { | 2789 void LayoutGrid::applyStretchAlignmentToChildIfNeeded(LayoutBox& child) { |
2712 // We clear height override values because we will decide now whether it's all
owed or | 2790 // We clear height override values because we will decide now whether it's |
2713 // not, evaluating the conditions which might have changed since the old value
s were set. | 2791 // allowed or not, evaluating the conditions which might have changed since |
| 2792 // the old values were set. |
2714 child.clearOverrideLogicalContentHeight(); | 2793 child.clearOverrideLogicalContentHeight(); |
2715 | 2794 |
2716 GridTrackSizingDirection childBlockDirection = | 2795 GridTrackSizingDirection childBlockDirection = |
2717 flowAwareDirectionForChild(child, ForRows); | 2796 flowAwareDirectionForChild(child, ForRows); |
2718 bool blockFlowIsColumnAxis = childBlockDirection == ForRows; | 2797 bool blockFlowIsColumnAxis = childBlockDirection == ForRows; |
2719 bool allowedToStretchChildBlockSize = | 2798 bool allowedToStretchChildBlockSize = |
2720 blockFlowIsColumnAxis ? allowedToStretchChildAlongColumnAxis(child) | 2799 blockFlowIsColumnAxis ? allowedToStretchChildAlongColumnAxis(child) |
2721 : allowedToStretchChildAlongRowAxis(child); | 2800 : allowedToStretchChildAlongRowAxis(child); |
2722 if (allowedToStretchChildBlockSize) { | 2801 if (allowedToStretchChildBlockSize) { |
2723 LayoutUnit stretchedLogicalHeight = | 2802 LayoutUnit stretchedLogicalHeight = |
2724 availableAlignmentSpaceForChildBeforeStretching( | 2803 availableAlignmentSpaceForChildBeforeStretching( |
2725 overrideContainingBlockContentSizeForChild(child, | 2804 overrideContainingBlockContentSizeForChild(child, |
2726 childBlockDirection), | 2805 childBlockDirection), |
2727 child); | 2806 child); |
2728 LayoutUnit desiredLogicalHeight = child.constrainLogicalHeightByMinMax( | 2807 LayoutUnit desiredLogicalHeight = child.constrainLogicalHeightByMinMax( |
2729 stretchedLogicalHeight, LayoutUnit(-1)); | 2808 stretchedLogicalHeight, LayoutUnit(-1)); |
2730 child.setOverrideLogicalContentHeight( | 2809 child.setOverrideLogicalContentHeight( |
2731 desiredLogicalHeight - child.borderAndPaddingLogicalHeight()); | 2810 desiredLogicalHeight - child.borderAndPaddingLogicalHeight()); |
2732 if (desiredLogicalHeight != child.logicalHeight()) { | 2811 if (desiredLogicalHeight != child.logicalHeight()) { |
2733 // TODO (lajava): Can avoid laying out here in some cases. See https://web
kit.org/b/87905. | 2812 // TODO (lajava): Can avoid laying out here in some cases. See |
| 2813 // https://webkit.org/b/87905. |
2734 child.setLogicalHeight(LayoutUnit()); | 2814 child.setLogicalHeight(LayoutUnit()); |
2735 child.setNeedsLayout(LayoutInvalidationReason::GridChanged); | 2815 child.setNeedsLayout(LayoutInvalidationReason::GridChanged); |
2736 } | 2816 } |
2737 } | 2817 } |
2738 } | 2818 } |
2739 | 2819 |
2740 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move
d to LayoutBox. | 2820 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be |
| 2821 // moved to LayoutBox. |
2741 bool LayoutGrid::hasAutoMarginsInColumnAxis(const LayoutBox& child) const { | 2822 bool LayoutGrid::hasAutoMarginsInColumnAxis(const LayoutBox& child) const { |
2742 if (isHorizontalWritingMode()) | 2823 if (isHorizontalWritingMode()) |
2743 return child.styleRef().marginTop().isAuto() || | 2824 return child.styleRef().marginTop().isAuto() || |
2744 child.styleRef().marginBottom().isAuto(); | 2825 child.styleRef().marginBottom().isAuto(); |
2745 return child.styleRef().marginLeft().isAuto() || | 2826 return child.styleRef().marginLeft().isAuto() || |
2746 child.styleRef().marginRight().isAuto(); | 2827 child.styleRef().marginRight().isAuto(); |
2747 } | 2828 } |
2748 | 2829 |
2749 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move
d to LayoutBox. | 2830 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be |
| 2831 // moved to LayoutBox. |
2750 bool LayoutGrid::hasAutoMarginsInRowAxis(const LayoutBox& child) const { | 2832 bool LayoutGrid::hasAutoMarginsInRowAxis(const LayoutBox& child) const { |
2751 if (isHorizontalWritingMode()) | 2833 if (isHorizontalWritingMode()) |
2752 return child.styleRef().marginLeft().isAuto() || | 2834 return child.styleRef().marginLeft().isAuto() || |
2753 child.styleRef().marginRight().isAuto(); | 2835 child.styleRef().marginRight().isAuto(); |
2754 return child.styleRef().marginTop().isAuto() || | 2836 return child.styleRef().marginTop().isAuto() || |
2755 child.styleRef().marginBottom().isAuto(); | 2837 child.styleRef().marginBottom().isAuto(); |
2756 } | 2838 } |
2757 | 2839 |
2758 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move
d to LayoutBox. | 2840 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be |
| 2841 // moved to LayoutBox. |
2759 DISABLE_CFI_PERF | 2842 DISABLE_CFI_PERF |
2760 void LayoutGrid::updateAutoMarginsInRowAxisIfNeeded(LayoutBox& child) { | 2843 void LayoutGrid::updateAutoMarginsInRowAxisIfNeeded(LayoutBox& child) { |
2761 ASSERT(!child.isOutOfFlowPositioned()); | 2844 ASSERT(!child.isOutOfFlowPositioned()); |
2762 | 2845 |
2763 LayoutUnit availableAlignmentSpace = | 2846 LayoutUnit availableAlignmentSpace = |
2764 child.overrideContainingBlockContentLogicalWidth() - | 2847 child.overrideContainingBlockContentLogicalWidth() - |
2765 child.logicalWidth() - child.marginLogicalWidth(); | 2848 child.logicalWidth() - child.marginLogicalWidth(); |
2766 if (availableAlignmentSpace <= 0) | 2849 if (availableAlignmentSpace <= 0) |
2767 return; | 2850 return; |
2768 | 2851 |
2769 Length marginStart = child.style()->marginStartUsing(style()); | 2852 Length marginStart = child.style()->marginStartUsing(style()); |
2770 Length marginEnd = child.style()->marginEndUsing(style()); | 2853 Length marginEnd = child.style()->marginEndUsing(style()); |
2771 if (marginStart.isAuto() && marginEnd.isAuto()) { | 2854 if (marginStart.isAuto() && marginEnd.isAuto()) { |
2772 child.setMarginStart(availableAlignmentSpace / 2, style()); | 2855 child.setMarginStart(availableAlignmentSpace / 2, style()); |
2773 child.setMarginEnd(availableAlignmentSpace / 2, style()); | 2856 child.setMarginEnd(availableAlignmentSpace / 2, style()); |
2774 } else if (marginStart.isAuto()) { | 2857 } else if (marginStart.isAuto()) { |
2775 child.setMarginStart(availableAlignmentSpace, style()); | 2858 child.setMarginStart(availableAlignmentSpace, style()); |
2776 } else if (marginEnd.isAuto()) { | 2859 } else if (marginEnd.isAuto()) { |
2777 child.setMarginEnd(availableAlignmentSpace, style()); | 2860 child.setMarginEnd(availableAlignmentSpace, style()); |
2778 } | 2861 } |
2779 } | 2862 } |
2780 | 2863 |
2781 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be move
d to LayoutBox. | 2864 // TODO(lajava): This logic is shared by LayoutFlexibleBox, so it should be |
| 2865 // moved to LayoutBox. |
2782 DISABLE_CFI_PERF | 2866 DISABLE_CFI_PERF |
2783 void LayoutGrid::updateAutoMarginsInColumnAxisIfNeeded(LayoutBox& child) { | 2867 void LayoutGrid::updateAutoMarginsInColumnAxisIfNeeded(LayoutBox& child) { |
2784 ASSERT(!child.isOutOfFlowPositioned()); | 2868 ASSERT(!child.isOutOfFlowPositioned()); |
2785 | 2869 |
2786 LayoutUnit availableAlignmentSpace = | 2870 LayoutUnit availableAlignmentSpace = |
2787 child.overrideContainingBlockContentLogicalHeight() - | 2871 child.overrideContainingBlockContentLogicalHeight() - |
2788 child.logicalHeight() - child.marginLogicalHeight(); | 2872 child.logicalHeight() - child.marginLogicalHeight(); |
2789 if (availableAlignmentSpace <= 0) | 2873 if (availableAlignmentSpace <= 0) |
2790 return; | 2874 return; |
2791 | 2875 |
(...skipping 10 matching lines...) Expand all Loading... |
2802 } | 2886 } |
2803 | 2887 |
2804 GridAxisPosition LayoutGrid::columnAxisPositionForChild( | 2888 GridAxisPosition LayoutGrid::columnAxisPositionForChild( |
2805 const LayoutBox& child) const { | 2889 const LayoutBox& child) const { |
2806 bool hasSameWritingMode = | 2890 bool hasSameWritingMode = |
2807 child.styleRef().getWritingMode() == styleRef().getWritingMode(); | 2891 child.styleRef().getWritingMode() == styleRef().getWritingMode(); |
2808 bool childIsLTR = child.styleRef().isLeftToRightDirection(); | 2892 bool childIsLTR = child.styleRef().isLeftToRightDirection(); |
2809 | 2893 |
2810 switch (alignSelfForChild(child).position()) { | 2894 switch (alignSelfForChild(child).position()) { |
2811 case ItemPositionSelfStart: | 2895 case ItemPositionSelfStart: |
2812 // TODO (lajava): Should we implement this logic in a generic utility func
tion ? | 2896 // TODO (lajava): Should we implement this logic in a generic utility |
2813 // Aligns the alignment subject to be flush with the edge of the alignment
container | 2897 // function? |
2814 // corresponding to the alignment subject's 'start' side in the column axi
s. | 2898 // Aligns the alignment subject to be flush with the edge of the alignment |
| 2899 // container corresponding to the alignment subject's 'start' side in the |
| 2900 // column axis. |
2815 if (isOrthogonalChild(child)) { | 2901 if (isOrthogonalChild(child)) { |
2816 // If orthogonal writing-modes, self-start will be based on the child's
inline-axis | 2902 // If orthogonal writing-modes, self-start will be based on the child's |
2817 // direction (inline-start), because it's the one parallel to the column
axis. | 2903 // inline-axis direction (inline-start), because it's the one parallel |
| 2904 // to the column axis. |
2818 if (styleRef().isFlippedBlocksWritingMode()) | 2905 if (styleRef().isFlippedBlocksWritingMode()) |
2819 return childIsLTR ? GridAxisEnd : GridAxisStart; | 2906 return childIsLTR ? GridAxisEnd : GridAxisStart; |
2820 return childIsLTR ? GridAxisStart : GridAxisEnd; | 2907 return childIsLTR ? GridAxisStart : GridAxisEnd; |
2821 } | 2908 } |
2822 // self-start is based on the child's block-flow direction. That's why we
need to check against the grid container's block-flow direction. | 2909 // self-start is based on the child's block-flow direction. That's why we |
| 2910 // need to check against the grid container's block-flow direction. |
2823 return hasSameWritingMode ? GridAxisStart : GridAxisEnd; | 2911 return hasSameWritingMode ? GridAxisStart : GridAxisEnd; |
2824 case ItemPositionSelfEnd: | 2912 case ItemPositionSelfEnd: |
2825 // TODO (lajava): Should we implement this logic in a generic utility func
tion ? | 2913 // TODO (lajava): Should we implement this logic in a generic utility |
2826 // Aligns the alignment subject to be flush with the edge of the alignment
container | 2914 // function? |
2827 // corresponding to the alignment subject's 'end' side in the column axis. | 2915 // Aligns the alignment subject to be flush with the edge of the alignment |
| 2916 // container corresponding to the alignment subject's 'end' side in the |
| 2917 // column axis. |
2828 if (isOrthogonalChild(child)) { | 2918 if (isOrthogonalChild(child)) { |
2829 // If orthogonal writing-modes, self-end will be based on the child's in
line-axis | 2919 // If orthogonal writing-modes, self-end will be based on the child's |
2830 // direction, (inline-end) because it's the one parallel to the column a
xis. | 2920 // inline-axis direction, (inline-end) because it's the one parallel to |
| 2921 // the column axis. |
2831 if (styleRef().isFlippedBlocksWritingMode()) | 2922 if (styleRef().isFlippedBlocksWritingMode()) |
2832 return childIsLTR ? GridAxisStart : GridAxisEnd; | 2923 return childIsLTR ? GridAxisStart : GridAxisEnd; |
2833 return childIsLTR ? GridAxisEnd : GridAxisStart; | 2924 return childIsLTR ? GridAxisEnd : GridAxisStart; |
2834 } | 2925 } |
2835 // self-end is based on the child's block-flow direction. That's why we ne
ed to check against the grid container's block-flow direction. | 2926 // self-end is based on the child's block-flow direction. That's why we |
| 2927 // need to check against the grid container's block-flow direction. |
2836 return hasSameWritingMode ? GridAxisEnd : GridAxisStart; | 2928 return hasSameWritingMode ? GridAxisEnd : GridAxisStart; |
2837 case ItemPositionLeft: | 2929 case ItemPositionLeft: |
2838 // Aligns the alignment subject to be flush with the alignment container's
'line-left' edge. | 2930 // Aligns the alignment subject to be flush with the alignment container's |
2839 // The alignment axis (column axis) is always orthogonal to the inline axi
s, hence this value behaves as 'start'. | 2931 // 'line-left' edge. The alignment axis (column axis) is always orthogonal |
| 2932 // to the inline axis, hence this value behaves as 'start'. |
2840 return GridAxisStart; | 2933 return GridAxisStart; |
2841 case ItemPositionRight: | 2934 case ItemPositionRight: |
2842 // Aligns the alignment subject to be flush with the alignment container's
'line-right' edge. | 2935 // Aligns the alignment subject to be flush with the alignment container's |
2843 // The alignment axis (column axis) is always orthogonal to the inline axi
s, hence this value behaves as 'start'. | 2936 // 'line-right' edge. The alignment axis (column axis) is always |
| 2937 // orthogonal to the inline axis, hence this value behaves as 'start'. |
2844 return GridAxisStart; | 2938 return GridAxisStart; |
2845 case ItemPositionCenter: | 2939 case ItemPositionCenter: |
2846 return GridAxisCenter; | 2940 return GridAxisCenter; |
2847 case ItemPositionFlexStart: // Only used in flex layout, otherwise equivale
nt to 'start'. | 2941 // Only used in flex layout, otherwise equivalent to 'start'. |
2848 // Aligns the alignment subject to be flush wit
h the alignment container's 'start' edge (block-start) in the column axis. | 2942 case ItemPositionFlexStart: |
| 2943 // Aligns the alignment subject to be flush with the alignment container's |
| 2944 // 'start' edge (block-start) in the column axis. |
2849 case ItemPositionStart: | 2945 case ItemPositionStart: |
2850 return GridAxisStart; | 2946 return GridAxisStart; |
2851 case ItemPositionFlexEnd: // Only used in flex layout, otherwise equivalent
to 'end'. | 2947 // Only used in flex layout, otherwise equivalent to 'end'. |
2852 // Aligns the alignment subject to be flush with
the alignment container's 'end' edge (block-end) in the column axis. | 2948 case ItemPositionFlexEnd: |
| 2949 // Aligns the alignment subject to be flush with the alignment container's |
| 2950 // 'end' edge (block-end) in the column axis. |
2853 case ItemPositionEnd: | 2951 case ItemPositionEnd: |
2854 return GridAxisEnd; | 2952 return GridAxisEnd; |
2855 case ItemPositionStretch: | 2953 case ItemPositionStretch: |
2856 return GridAxisStart; | 2954 return GridAxisStart; |
2857 case ItemPositionBaseline: | 2955 case ItemPositionBaseline: |
2858 case ItemPositionLastBaseline: | 2956 case ItemPositionLastBaseline: |
2859 // FIXME: These two require implementing Baseline Alignment. For now, we a
lways 'start' align the child. | 2957 // FIXME: These two require implementing Baseline Alignment. For now, we |
2860 // crbug.com/234191 | 2958 // always 'start' align the child. crbug.com/234191 |
2861 return GridAxisStart; | 2959 return GridAxisStart; |
2862 case ItemPositionAuto: | 2960 case ItemPositionAuto: |
2863 case ItemPositionNormal: | 2961 case ItemPositionNormal: |
2864 break; | 2962 break; |
2865 } | 2963 } |
2866 | 2964 |
2867 ASSERT_NOT_REACHED(); | 2965 ASSERT_NOT_REACHED(); |
2868 return GridAxisStart; | 2966 return GridAxisStart; |
2869 } | 2967 } |
2870 | 2968 |
2871 GridAxisPosition LayoutGrid::rowAxisPositionForChild( | 2969 GridAxisPosition LayoutGrid::rowAxisPositionForChild( |
2872 const LayoutBox& child) const { | 2970 const LayoutBox& child) const { |
2873 bool hasSameDirection = | 2971 bool hasSameDirection = |
2874 child.styleRef().direction() == styleRef().direction(); | 2972 child.styleRef().direction() == styleRef().direction(); |
2875 bool gridIsLTR = styleRef().isLeftToRightDirection(); | 2973 bool gridIsLTR = styleRef().isLeftToRightDirection(); |
2876 | 2974 |
2877 switch (justifySelfForChild(child).position()) { | 2975 switch (justifySelfForChild(child).position()) { |
2878 case ItemPositionSelfStart: | 2976 case ItemPositionSelfStart: |
2879 // TODO (lajava): Should we implement this logic in a generic utility func
tion ? | 2977 // TODO (lajava): Should we implement this logic in a generic utility |
2880 // Aligns the alignment subject to be flush with the edge of the alignment
container | 2978 // function? |
2881 // corresponding to the alignment subject's 'start' side in the row axis. | 2979 // Aligns the alignment subject to be flush with the edge of the alignment |
| 2980 // container corresponding to the alignment subject's 'start' side in the |
| 2981 // row axis. |
2882 if (isOrthogonalChild(child)) { | 2982 if (isOrthogonalChild(child)) { |
2883 // If orthogonal writing-modes, self-start will be based on the child's
block-axis | 2983 // If orthogonal writing-modes, self-start will be based on the child's |
2884 // direction, because it's the one parallel to the row axis. | 2984 // block-axis direction, because it's the one parallel to the row axis. |
2885 if (child.styleRef().isFlippedBlocksWritingMode()) | 2985 if (child.styleRef().isFlippedBlocksWritingMode()) |
2886 return gridIsLTR ? GridAxisEnd : GridAxisStart; | 2986 return gridIsLTR ? GridAxisEnd : GridAxisStart; |
2887 return gridIsLTR ? GridAxisStart : GridAxisEnd; | 2987 return gridIsLTR ? GridAxisStart : GridAxisEnd; |
2888 } | 2988 } |
2889 // self-start is based on the child's inline-flow direction. That's why we
need to check against the grid container's direction. | 2989 // self-start is based on the child's inline-flow direction. That's why we |
| 2990 // need to check against the grid container's direction. |
2890 return hasSameDirection ? GridAxisStart : GridAxisEnd; | 2991 return hasSameDirection ? GridAxisStart : GridAxisEnd; |
2891 case ItemPositionSelfEnd: | 2992 case ItemPositionSelfEnd: |
2892 // TODO (lajava): Should we implement this logic in a generic utility func
tion ? | 2993 // TODO (lajava): Should we implement this logic in a generic utility |
2893 // Aligns the alignment subject to be flush with the edge of the alignment
container | 2994 // function? |
2894 // corresponding to the alignment subject's 'end' side in the row axis. | 2995 // Aligns the alignment subject to be flush with the edge of the alignment |
| 2996 // container corresponding to the alignment subject's 'end' side in the |
| 2997 // row axis. |
2895 if (isOrthogonalChild(child)) { | 2998 if (isOrthogonalChild(child)) { |
2896 // If orthogonal writing-modes, self-end will be based on the child's bl
ock-axis | 2999 // If orthogonal writing-modes, self-end will be based on the child's |
2897 // direction, because it's the one parallel to the row axis. | 3000 // block-axis direction, because it's the one parallel to the row axis. |
2898 if (child.styleRef().isFlippedBlocksWritingMode()) | 3001 if (child.styleRef().isFlippedBlocksWritingMode()) |
2899 return gridIsLTR ? GridAxisStart : GridAxisEnd; | 3002 return gridIsLTR ? GridAxisStart : GridAxisEnd; |
2900 return gridIsLTR ? GridAxisEnd : GridAxisStart; | 3003 return gridIsLTR ? GridAxisEnd : GridAxisStart; |
2901 } | 3004 } |
2902 // self-end is based on the child's inline-flow direction. That's why we n
eed to check against the grid container's direction. | 3005 // self-end is based on the child's inline-flow direction. That's why we |
| 3006 // need to check against the grid container's direction. |
2903 return hasSameDirection ? GridAxisEnd : GridAxisStart; | 3007 return hasSameDirection ? GridAxisEnd : GridAxisStart; |
2904 case ItemPositionLeft: | 3008 case ItemPositionLeft: |
2905 // Aligns the alignment subject to be flush with the alignment container's
'line-left' edge. | 3009 // Aligns the alignment subject to be flush with the alignment container's |
2906 // We want the physical 'left' side, so we have to take account, container
's inline-flow direction. | 3010 // 'line-left' edge. We want the physical 'left' side, so we have to take |
| 3011 // account, container's inline-flow direction. |
2907 return gridIsLTR ? GridAxisStart : GridAxisEnd; | 3012 return gridIsLTR ? GridAxisStart : GridAxisEnd; |
2908 case ItemPositionRight: | 3013 case ItemPositionRight: |
2909 // Aligns the alignment subject to be flush with the alignment container's
'line-right' edge. | 3014 // Aligns the alignment subject to be flush with the alignment container's |
2910 // We want the physical 'right' side, so we have to take account, containe
r's inline-flow direction. | 3015 // 'line-right' edge. We want the physical 'right' side, so we have to |
| 3016 // take account, container's inline-flow direction. |
2911 return gridIsLTR ? GridAxisEnd : GridAxisStart; | 3017 return gridIsLTR ? GridAxisEnd : GridAxisStart; |
2912 case ItemPositionCenter: | 3018 case ItemPositionCenter: |
2913 return GridAxisCenter; | 3019 return GridAxisCenter; |
2914 case ItemPositionFlexStart: // Only used in flex layout, otherwise equivale
nt to 'start'. | 3020 // Only used in flex layout, otherwise equivalent to 'start'. |
2915 // Aligns the alignment subject to be flush wit
h the alignment container's 'start' edge (inline-start) in the row axis. | 3021 case ItemPositionFlexStart: |
| 3022 // Aligns the alignment subject to be flush with the alignment container's |
| 3023 // 'start' edge (inline-start) in the row axis. |
2916 case ItemPositionStart: | 3024 case ItemPositionStart: |
2917 return GridAxisStart; | 3025 return GridAxisStart; |
2918 case ItemPositionFlexEnd: // Only used in flex layout, otherwise equivalent
to 'end'. | 3026 // Only used in flex layout, otherwise equivalent to 'end'. |
2919 // Aligns the alignment subject to be flush with
the alignment container's 'end' edge (inline-end) in the row axis. | 3027 case ItemPositionFlexEnd: |
| 3028 // Aligns the alignment subject to be flush with the alignment container's |
| 3029 // 'end' edge (inline-end) in the row axis. |
2920 case ItemPositionEnd: | 3030 case ItemPositionEnd: |
2921 return GridAxisEnd; | 3031 return GridAxisEnd; |
2922 case ItemPositionStretch: | 3032 case ItemPositionStretch: |
2923 return GridAxisStart; | 3033 return GridAxisStart; |
2924 case ItemPositionBaseline: | 3034 case ItemPositionBaseline: |
2925 case ItemPositionLastBaseline: | 3035 case ItemPositionLastBaseline: |
2926 // FIXME: These two require implementing Baseline Alignment. For now, we a
lways 'start' align the child. | 3036 // FIXME: These two require implementing Baseline Alignment. For now, we |
2927 // crbug.com/234191 | 3037 // always 'start' align the child. crbug.com/234191 |
2928 return GridAxisStart; | 3038 return GridAxisStart; |
2929 case ItemPositionAuto: | 3039 case ItemPositionAuto: |
2930 case ItemPositionNormal: | 3040 case ItemPositionNormal: |
2931 break; | 3041 break; |
2932 } | 3042 } |
2933 | 3043 |
2934 ASSERT_NOT_REACHED(); | 3044 ASSERT_NOT_REACHED(); |
2935 return GridAxisStart; | 3045 return GridAxisStart; |
2936 } | 3046 } |
2937 | 3047 |
2938 LayoutUnit LayoutGrid::columnAxisOffsetForChild( | 3048 LayoutUnit LayoutGrid::columnAxisOffsetForChild( |
2939 const LayoutBox& child, | 3049 const LayoutBox& child, |
2940 GridSizingData& sizingData) const { | 3050 GridSizingData& sizingData) const { |
2941 const GridSpan& rowsSpan = cachedGridSpan(child, ForRows); | 3051 const GridSpan& rowsSpan = cachedGridSpan(child, ForRows); |
2942 size_t childStartLine = rowsSpan.startLine(); | 3052 size_t childStartLine = rowsSpan.startLine(); |
2943 LayoutUnit startOfRow = m_rowPositions[childStartLine]; | 3053 LayoutUnit startOfRow = m_rowPositions[childStartLine]; |
2944 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child); | 3054 LayoutUnit startPosition = startOfRow + marginBeforeForChild(child); |
2945 if (hasAutoMarginsInColumnAxis(child)) | 3055 if (hasAutoMarginsInColumnAxis(child)) |
2946 return startPosition; | 3056 return startPosition; |
2947 GridAxisPosition axisPosition = columnAxisPositionForChild(child); | 3057 GridAxisPosition axisPosition = columnAxisPositionForChild(child); |
2948 switch (axisPosition) { | 3058 switch (axisPosition) { |
2949 case GridAxisStart: | 3059 case GridAxisStart: |
2950 return startPosition; | 3060 return startPosition; |
2951 case GridAxisEnd: | 3061 case GridAxisEnd: |
2952 case GridAxisCenter: { | 3062 case GridAxisCenter: { |
2953 size_t childEndLine = rowsSpan.endLine(); | 3063 size_t childEndLine = rowsSpan.endLine(); |
2954 LayoutUnit endOfRow = m_rowPositions[childEndLine]; | 3064 LayoutUnit endOfRow = m_rowPositions[childEndLine]; |
2955 // m_rowPositions include distribution offset (because of content alignmen
t) and gutters | 3065 // m_rowPositions include distribution offset (because of content |
2956 // so we need to subtract them to get the actual end position for a given
row | 3066 // alignment) and gutters so we need to subtract them to get the actual |
2957 // (this does not have to be done for the last track as there are no more
m_columnPositions after it). | 3067 // end position for a given row (this does not have to be done for the |
| 3068 // last track as there are no more m_columnPositions after it). |
2958 LayoutUnit trackGap = | 3069 LayoutUnit trackGap = |
2959 gridGapForDirection(ForRows, sizingData.sizingOperation); | 3070 gridGapForDirection(ForRows, sizingData.sizingOperation); |
2960 if (childEndLine < m_rowPositions.size() - 1) { | 3071 if (childEndLine < m_rowPositions.size() - 1) { |
2961 endOfRow -= trackGap; | 3072 endOfRow -= trackGap; |
2962 endOfRow -= m_offsetBetweenRows; | 3073 endOfRow -= m_offsetBetweenRows; |
2963 } | 3074 } |
2964 LayoutUnit columnAxisChildSize = | 3075 LayoutUnit columnAxisChildSize = |
2965 isOrthogonalChild(child) | 3076 isOrthogonalChild(child) |
2966 ? child.logicalWidth() + child.marginLogicalWidth() | 3077 ? child.logicalWidth() + child.marginLogicalWidth() |
2967 : child.logicalHeight() + child.marginLogicalHeight(); | 3078 : child.logicalHeight() + child.marginLogicalHeight(); |
(...skipping 19 matching lines...) Expand all Loading... |
2987 if (hasAutoMarginsInRowAxis(child)) | 3098 if (hasAutoMarginsInRowAxis(child)) |
2988 return startPosition; | 3099 return startPosition; |
2989 GridAxisPosition axisPosition = rowAxisPositionForChild(child); | 3100 GridAxisPosition axisPosition = rowAxisPositionForChild(child); |
2990 switch (axisPosition) { | 3101 switch (axisPosition) { |
2991 case GridAxisStart: | 3102 case GridAxisStart: |
2992 return startPosition; | 3103 return startPosition; |
2993 case GridAxisEnd: | 3104 case GridAxisEnd: |
2994 case GridAxisCenter: { | 3105 case GridAxisCenter: { |
2995 size_t childEndLine = columnsSpan.endLine(); | 3106 size_t childEndLine = columnsSpan.endLine(); |
2996 LayoutUnit endOfColumn = m_columnPositions[childEndLine]; | 3107 LayoutUnit endOfColumn = m_columnPositions[childEndLine]; |
2997 // m_columnPositions include distribution offset (because of content align
ment) and gutters | 3108 // m_columnPositions include distribution offset (because of content |
2998 // so we need to subtract them to get the actual end position for a given
column | 3109 // alignment) and gutters so we need to subtract them to get the actual |
2999 // (this does not have to be done for the last track as there are no more
m_columnPositions after it). | 3110 // end position for a given column (this does not have to be done for the |
| 3111 // last track as there are no more m_columnPositions after it). |
3000 LayoutUnit trackGap = | 3112 LayoutUnit trackGap = |
3001 gridGapForDirection(ForColumns, sizingData.sizingOperation); | 3113 gridGapForDirection(ForColumns, sizingData.sizingOperation); |
3002 if (childEndLine < m_columnPositions.size() - 1) { | 3114 if (childEndLine < m_columnPositions.size() - 1) { |
3003 endOfColumn -= trackGap; | 3115 endOfColumn -= trackGap; |
3004 endOfColumn -= m_offsetBetweenColumns; | 3116 endOfColumn -= m_offsetBetweenColumns; |
3005 } | 3117 } |
3006 LayoutUnit rowAxisChildSize = | 3118 LayoutUnit rowAxisChildSize = |
3007 isOrthogonalChild(child) | 3119 isOrthogonalChild(child) |
3008 ? child.logicalHeight() + child.marginLogicalHeight() | 3120 ? child.logicalHeight() + child.marginLogicalHeight() |
3009 : child.logicalWidth() + child.marginLogicalWidth(); | 3121 : child.logicalWidth() + child.marginLogicalWidth(); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3083 ? styleRef().resolvedJustifyContentPosition( | 3195 ? styleRef().resolvedJustifyContentPosition( |
3084 contentAlignmentNormalBehavior()) | 3196 contentAlignmentNormalBehavior()) |
3085 : styleRef().resolvedAlignContentPosition( | 3197 : styleRef().resolvedAlignContentPosition( |
3086 contentAlignmentNormalBehavior()); | 3198 contentAlignmentNormalBehavior()); |
3087 ContentDistributionType distribution = | 3199 ContentDistributionType distribution = |
3088 isRowAxis | 3200 isRowAxis |
3089 ? styleRef().resolvedJustifyContentDistribution( | 3201 ? styleRef().resolvedJustifyContentDistribution( |
3090 contentAlignmentNormalBehavior()) | 3202 contentAlignmentNormalBehavior()) |
3091 : styleRef().resolvedAlignContentDistribution( | 3203 : styleRef().resolvedAlignContentDistribution( |
3092 contentAlignmentNormalBehavior()); | 3204 contentAlignmentNormalBehavior()); |
3093 // If <content-distribution> value can't be applied, 'position' will become th
e associated | 3205 // If <content-distribution> value can't be applied, 'position' will become |
3094 // <content-position> fallback value. | 3206 // the associated <content-position> fallback value. |
3095 ContentAlignmentData contentAlignment = contentDistributionOffset( | 3207 ContentAlignmentData contentAlignment = contentDistributionOffset( |
3096 availableFreeSpace, position, distribution, numberOfGridTracks); | 3208 availableFreeSpace, position, distribution, numberOfGridTracks); |
3097 if (contentAlignment.isValid()) | 3209 if (contentAlignment.isValid()) |
3098 return contentAlignment; | 3210 return contentAlignment; |
3099 | 3211 |
3100 OverflowAlignment overflow = | 3212 OverflowAlignment overflow = |
3101 isRowAxis ? styleRef().justifyContentOverflowAlignment() | 3213 isRowAxis ? styleRef().justifyContentOverflowAlignment() |
3102 : styleRef().alignContentOverflowAlignment(); | 3214 : styleRef().alignContentOverflowAlignment(); |
3103 if (availableFreeSpace <= 0 && overflow == OverflowAlignmentSafe) | 3215 if (availableFreeSpace <= 0 && overflow == OverflowAlignmentSafe) |
3104 return {LayoutUnit(), LayoutUnit()}; | 3216 return {LayoutUnit(), LayoutUnit()}; |
3105 | 3217 |
3106 switch (position) { | 3218 switch (position) { |
3107 case ContentPositionLeft: | 3219 case ContentPositionLeft: |
3108 // The align-content's axis is always orthogonal to the inline-axis. | 3220 // The align-content's axis is always orthogonal to the inline-axis. |
3109 return {LayoutUnit(), LayoutUnit()}; | 3221 return {LayoutUnit(), LayoutUnit()}; |
3110 case ContentPositionRight: | 3222 case ContentPositionRight: |
3111 if (isRowAxis) | 3223 if (isRowAxis) |
3112 return {availableFreeSpace, LayoutUnit()}; | 3224 return {availableFreeSpace, LayoutUnit()}; |
3113 // The align-content's axis is always orthogonal to the inline-axis. | 3225 // The align-content's axis is always orthogonal to the inline-axis. |
3114 return {LayoutUnit(), LayoutUnit()}; | 3226 return {LayoutUnit(), LayoutUnit()}; |
3115 case ContentPositionCenter: | 3227 case ContentPositionCenter: |
3116 return {availableFreeSpace / 2, LayoutUnit()}; | 3228 return {availableFreeSpace / 2, LayoutUnit()}; |
3117 case ContentPositionFlexEnd: // Only used in flex layout, for other layout,
it's equivalent to 'End'. | 3229 // Only used in flex layout, for other layout, it's equivalent to 'End'. |
| 3230 case ContentPositionFlexEnd: |
3118 case ContentPositionEnd: | 3231 case ContentPositionEnd: |
3119 if (isRowAxis) | 3232 if (isRowAxis) |
3120 return {styleRef().isLeftToRightDirection() ? availableFreeSpace | 3233 return {styleRef().isLeftToRightDirection() ? availableFreeSpace |
3121 : LayoutUnit(), | 3234 : LayoutUnit(), |
3122 LayoutUnit()}; | 3235 LayoutUnit()}; |
3123 return {availableFreeSpace, LayoutUnit()}; | 3236 return {availableFreeSpace, LayoutUnit()}; |
3124 case ContentPositionFlexStart: // Only used in flex layout, for other layou
t, it's equivalent to 'Start'. | 3237 // Only used in flex layout, for other layout, it's equivalent to 'Start'. |
| 3238 case ContentPositionFlexStart: |
3125 case ContentPositionStart: | 3239 case ContentPositionStart: |
3126 if (isRowAxis) | 3240 if (isRowAxis) |
3127 return {styleRef().isLeftToRightDirection() ? LayoutUnit() | 3241 return {styleRef().isLeftToRightDirection() ? LayoutUnit() |
3128 : availableFreeSpace, | 3242 : availableFreeSpace, |
3129 LayoutUnit()}; | 3243 LayoutUnit()}; |
3130 return {LayoutUnit(), LayoutUnit()}; | 3244 return {LayoutUnit(), LayoutUnit()}; |
3131 case ContentPositionBaseline: | 3245 case ContentPositionBaseline: |
3132 case ContentPositionLastBaseline: | 3246 case ContentPositionLastBaseline: |
3133 // FIXME: These two require implementing Baseline Alignment. For now, we a
lways 'start' align the child. | 3247 // FIXME: These two require implementing Baseline Alignment. For now, we |
3134 // crbug.com/234191 | 3248 // always 'start' align the child. crbug.com/234191 |
3135 if (isRowAxis) | 3249 if (isRowAxis) |
3136 return {styleRef().isLeftToRightDirection() ? LayoutUnit() | 3250 return {styleRef().isLeftToRightDirection() ? LayoutUnit() |
3137 : availableFreeSpace, | 3251 : availableFreeSpace, |
3138 LayoutUnit()}; | 3252 LayoutUnit()}; |
3139 return {LayoutUnit(), LayoutUnit()}; | 3253 return {LayoutUnit(), LayoutUnit()}; |
3140 case ContentPositionNormal: | 3254 case ContentPositionNormal: |
3141 break; | 3255 break; |
3142 } | 3256 } |
3143 | 3257 |
3144 ASSERT_NOT_REACHED(); | 3258 ASSERT_NOT_REACHED(); |
3145 return {LayoutUnit(), LayoutUnit()}; | 3259 return {LayoutUnit(), LayoutUnit()}; |
3146 } | 3260 } |
3147 | 3261 |
3148 LayoutUnit LayoutGrid::translateRTLCoordinate(LayoutUnit coordinate) const { | 3262 LayoutUnit LayoutGrid::translateRTLCoordinate(LayoutUnit coordinate) const { |
3149 ASSERT(!styleRef().isLeftToRightDirection()); | 3263 ASSERT(!styleRef().isLeftToRightDirection()); |
3150 | 3264 |
3151 LayoutUnit alignmentOffset = m_columnPositions[0]; | 3265 LayoutUnit alignmentOffset = m_columnPositions[0]; |
3152 LayoutUnit rightGridEdgePosition = | 3266 LayoutUnit rightGridEdgePosition = |
3153 m_columnPositions[m_columnPositions.size() - 1]; | 3267 m_columnPositions[m_columnPositions.size() - 1]; |
3154 return rightGridEdgePosition + alignmentOffset - coordinate; | 3268 return rightGridEdgePosition + alignmentOffset - coordinate; |
3155 } | 3269 } |
3156 | 3270 |
3157 LayoutPoint LayoutGrid::findChildLogicalPosition( | 3271 LayoutPoint LayoutGrid::findChildLogicalPosition( |
3158 const LayoutBox& child, | 3272 const LayoutBox& child, |
3159 GridSizingData& sizingData) const { | 3273 GridSizingData& sizingData) const { |
3160 LayoutUnit columnAxisOffset = columnAxisOffsetForChild(child, sizingData); | 3274 LayoutUnit columnAxisOffset = columnAxisOffsetForChild(child, sizingData); |
3161 LayoutUnit rowAxisOffset = rowAxisOffsetForChild(child, sizingData); | 3275 LayoutUnit rowAxisOffset = rowAxisOffsetForChild(child, sizingData); |
3162 // We stored m_columnPosition's data ignoring the direction, hence we might ne
ed now | 3276 // We stored m_columnPosition's data ignoring the direction, hence we might |
3163 // to translate positions from RTL to LTR, as it's more convenient for paintin
g. | 3277 // need now to translate positions from RTL to LTR, as it's more convenient |
| 3278 // for painting. |
3164 if (!style()->isLeftToRightDirection()) | 3279 if (!style()->isLeftToRightDirection()) |
3165 rowAxisOffset = translateRTLCoordinate(rowAxisOffset) - | 3280 rowAxisOffset = translateRTLCoordinate(rowAxisOffset) - |
3166 (isOrthogonalChild(child) ? child.logicalHeight() | 3281 (isOrthogonalChild(child) ? child.logicalHeight() |
3167 : child.logicalWidth()); | 3282 : child.logicalWidth()); |
3168 | 3283 |
3169 // "In the positioning phase [...] calculations are performed according to the
writing mode | 3284 // "In the positioning phase [...] calculations are performed according to the |
3170 // of the containing block of the box establishing the orthogonal flow." Howev
er, the | 3285 // writing mode of the containing block of the box establishing the orthogonal |
3171 // resulting LayoutPoint will be used in 'setLogicalPosition' in order to set
the child's | 3286 // flow." However, the resulting LayoutPoint will be used in |
3172 // logical position, which will only take into account the child's writing-mod
e. | 3287 // 'setLogicalPosition' in order to set the child's logical position, which |
| 3288 // will only take into account the child's writing-mode. |
3173 LayoutPoint childLocation(rowAxisOffset, columnAxisOffset); | 3289 LayoutPoint childLocation(rowAxisOffset, columnAxisOffset); |
3174 return isOrthogonalChild(child) ? childLocation.transposedPoint() | 3290 return isOrthogonalChild(child) ? childLocation.transposedPoint() |
3175 : childLocation; | 3291 : childLocation; |
3176 } | 3292 } |
3177 | 3293 |
3178 LayoutPoint LayoutGrid::gridAreaLogicalPosition(const GridArea& area) const { | 3294 LayoutPoint LayoutGrid::gridAreaLogicalPosition(const GridArea& area) const { |
3179 LayoutUnit columnAxisOffset = m_rowPositions[area.rows.startLine()]; | 3295 LayoutUnit columnAxisOffset = m_rowPositions[area.rows.startLine()]; |
3180 LayoutUnit rowAxisOffset = m_columnPositions[area.columns.startLine()]; | 3296 LayoutUnit rowAxisOffset = m_columnPositions[area.columns.startLine()]; |
3181 | 3297 |
3182 // See comment in findChildLogicalPosition() about why we need sometimes to tr
anslate from RTL | 3298 // See comment in findChildLogicalPosition() about why we need sometimes to |
3183 // to LTR the rowAxisOffset coordinate. | 3299 // translate from RTL to LTR the rowAxisOffset coordinate. |
3184 return LayoutPoint(style()->isLeftToRightDirection() | 3300 return LayoutPoint(style()->isLeftToRightDirection() |
3185 ? rowAxisOffset | 3301 ? rowAxisOffset |
3186 : translateRTLCoordinate(rowAxisOffset), | 3302 : translateRTLCoordinate(rowAxisOffset), |
3187 columnAxisOffset); | 3303 columnAxisOffset); |
3188 } | 3304 } |
3189 | 3305 |
3190 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, | 3306 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, |
3191 const LayoutPoint& paintOffset) const { | 3307 const LayoutPoint& paintOffset) const { |
3192 if (!m_gridItemArea.isEmpty()) | 3308 if (!m_gridItemArea.isEmpty()) |
3193 GridPainter(*this).paintChildren(paintInfo, paintOffset); | 3309 GridPainter(*this).paintChildren(paintInfo, paintOffset); |
3194 } | 3310 } |
3195 | 3311 |
3196 bool LayoutGrid::cachedHasDefiniteLogicalHeight() const { | 3312 bool LayoutGrid::cachedHasDefiniteLogicalHeight() const { |
3197 SECURITY_DCHECK(m_hasDefiniteLogicalHeight); | 3313 SECURITY_DCHECK(m_hasDefiniteLogicalHeight); |
3198 return m_hasDefiniteLogicalHeight.value(); | 3314 return m_hasDefiniteLogicalHeight.value(); |
3199 } | 3315 } |
3200 | 3316 |
3201 } // namespace blink | 3317 } // namespace blink |
OLD | NEW |