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 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 GridTrackSizingDirection m_direction; | 223 GridTrackSizingDirection m_direction; |
224 size_t m_rowIndex; | 224 size_t m_rowIndex; |
225 size_t m_columnIndex; | 225 size_t m_columnIndex; |
226 size_t m_childIndex; | 226 size_t m_childIndex; |
227 }; | 227 }; |
228 | 228 |
229 struct LayoutGrid::GridSizingData { | 229 struct LayoutGrid::GridSizingData { |
230 WTF_MAKE_NONCOPYABLE(GridSizingData); | 230 WTF_MAKE_NONCOPYABLE(GridSizingData); |
231 STACK_ALLOCATED(); | 231 STACK_ALLOCATED(); |
232 public: | 232 public: |
233 GridSizingData(size_t gridColumnCount, size_t gridRowCount, const LayoutUnit
& freeSpaceForColumns, const LayoutUnit& freeSpaceForRows) | 233 GridSizingData(size_t gridColumnCount, size_t gridRowCount) |
234 : columnTracks(gridColumnCount) | 234 : columnTracks(gridColumnCount) |
235 , rowTracks(gridRowCount) | 235 , rowTracks(gridRowCount) |
236 , freeSpaceForColumns(freeSpaceForColumns) | |
237 , freeSpaceForRows(freeSpaceForRows) | |
238 { | 236 { |
239 } | 237 } |
240 | 238 |
241 Vector<GridTrack> columnTracks; | 239 Vector<GridTrack> columnTracks; |
242 Vector<GridTrack> rowTracks; | 240 Vector<GridTrack> rowTracks; |
243 Vector<size_t> contentSizedTracksIndex; | 241 Vector<size_t> contentSizedTracksIndex; |
244 | 242 |
245 // Performance optimization: hold onto these Vectors until the end of Layout
to avoid repeated malloc / free. | 243 // Performance optimization: hold onto these Vectors until the end of Layout
to avoid repeated malloc / free. |
246 Vector<GridTrack*> filteredTracks; | 244 Vector<GridTrack*> filteredTracks; |
247 Vector<GridItemWithSpan> itemsSortedByIncreasingSpan; | 245 Vector<GridItemWithSpan> itemsSortedByIncreasingSpan; |
248 Vector<GridTrack*> growBeyondGrowthLimitsTracks; | 246 Vector<GridTrack*> growBeyondGrowthLimitsTracks; |
249 | 247 |
250 LayoutUnit& freeSpaceForDirection(GridTrackSizingDirection direction) { retu
rn direction == ForColumns ? freeSpaceForColumns : freeSpaceForRows; } | 248 LayoutUnit& freeSpaceForDirection(GridTrackSizingDirection direction) { retu
rn direction == ForColumns ? freeSpaceForColumns : freeSpaceForRows; } |
251 | 249 |
252 private: | 250 private: |
253 LayoutUnit freeSpaceForColumns; | 251 LayoutUnit freeSpaceForColumns { }; |
254 LayoutUnit freeSpaceForRows; | 252 LayoutUnit freeSpaceForRows { }; |
255 }; | 253 }; |
256 | 254 |
257 struct GridItemsSpanGroupRange { | 255 struct GridItemsSpanGroupRange { |
258 Vector<GridItemWithSpan>::iterator rangeStart; | 256 Vector<GridItemWithSpan>::iterator rangeStart; |
259 Vector<GridItemWithSpan>::iterator rangeEnd; | 257 Vector<GridItemWithSpan>::iterator rangeEnd; |
260 }; | 258 }; |
261 | 259 |
262 LayoutGrid::LayoutGrid(Element* element) | 260 LayoutGrid::LayoutGrid(Element* element) |
263 : LayoutBlock(element) | 261 : LayoutBlock(element) |
264 , m_gridIsDirty(true) | 262 , m_gridIsDirty(true) |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 return oldStyle.gridTemplateColumns().size() != styleRef().gridTemplateColum
ns().size() | 307 return oldStyle.gridTemplateColumns().size() != styleRef().gridTemplateColum
ns().size() |
310 || oldStyle.gridTemplateRows().size() != styleRef().gridTemplateRows().s
ize(); | 308 || oldStyle.gridTemplateRows().size() != styleRef().gridTemplateRows().s
ize(); |
311 } | 309 } |
312 | 310 |
313 bool LayoutGrid::namedGridLinesDefinitionDidChange(const ComputedStyle& oldStyle
) const | 311 bool LayoutGrid::namedGridLinesDefinitionDidChange(const ComputedStyle& oldStyle
) const |
314 { | 312 { |
315 return oldStyle.namedGridRowLines() != styleRef().namedGridRowLines() | 313 return oldStyle.namedGridRowLines() != styleRef().namedGridRowLines() |
316 || oldStyle.namedGridColumnLines() != styleRef().namedGridColumnLines(); | 314 || oldStyle.namedGridColumnLines() != styleRef().namedGridColumnLines(); |
317 } | 315 } |
318 | 316 |
| 317 LayoutUnit LayoutGrid::computeTrackBasedLogicalHeight(const GridSizingData& sizi
ngData) const |
| 318 { |
| 319 LayoutUnit logicalHeight; |
| 320 |
| 321 for (const auto& row : sizingData.rowTracks) |
| 322 logicalHeight += row.baseSize(); |
| 323 |
| 324 logicalHeight += guttersSize(ForRows, sizingData.rowTracks.size()); |
| 325 |
| 326 return logicalHeight; |
| 327 } |
| 328 |
| 329 void LayoutGrid::computeTrackSizesForDirection(GridTrackSizingDirection directio
n, GridSizingData& sizingData, LayoutUnit freeSpace) |
| 330 { |
| 331 if (freeSpace != -1) { |
| 332 LayoutUnit totalGuttersSize = guttersSize(direction, direction == ForRow
s ? gridRowCount() : gridColumnCount()); |
| 333 freeSpace = std::max<LayoutUnit>(0, freeSpace - totalGuttersSize); |
| 334 } |
| 335 sizingData.freeSpaceForDirection(direction) = freeSpace; |
| 336 |
| 337 LayoutUnit baseSizes, growthLimits; |
| 338 computeUsedBreadthOfGridTracks(direction, sizingData, baseSizes, growthLimit
s); |
| 339 ASSERT(tracksAreWiderThanMinTrackBreadth(direction, sizingData)); |
| 340 } |
| 341 |
319 void LayoutGrid::layoutBlock(bool relayoutChildren) | 342 void LayoutGrid::layoutBlock(bool relayoutChildren) |
320 { | 343 { |
321 ASSERT(needsLayout()); | 344 ASSERT(needsLayout()); |
322 | 345 |
323 if (!relayoutChildren && simplifiedLayout()) | 346 if (!relayoutChildren && simplifiedLayout()) |
324 return; | 347 return; |
325 | 348 |
326 // FIXME: Much of this method is boiler plate that matches LayoutBox::layout
Block and Layout*FlexibleBox::layoutBlock. | |
327 // It would be nice to refactor some of the duplicate code. | |
328 { | 349 { |
329 // LayoutState needs this deliberate scope to pop before updating scroll
information (which | 350 // LayoutState needs this deliberate scope to pop before updating scroll
information (which |
330 // may trigger relayout). | 351 // may trigger relayout). |
331 LayoutState state(*this, locationOffset()); | 352 LayoutState state(*this, locationOffset()); |
332 | 353 |
333 LayoutSize previousSize = size(); | 354 LayoutSize previousSize = size(); |
334 | 355 |
335 setLogicalHeight(0); | |
336 updateLogicalWidth(); | 356 updateLogicalWidth(); |
| 357 bool logicalHeightWasIndefinite = computeContentLogicalHeight(MainOrPref
erredSize, style()->logicalHeight(), -1) == -1; |
337 | 358 |
338 TextAutosizer::LayoutScope textAutosizerLayoutScope(this); | 359 TextAutosizer::LayoutScope textAutosizerLayoutScope(this); |
339 | 360 |
340 layoutGridItems(); | 361 placeItemsOnGrid(); |
| 362 |
| 363 GridSizingData sizingData(gridColumnCount(), gridRowCount()); |
| 364 |
| 365 // At this point the logical width is always definite as the above call
to updateLogicalWidth() |
| 366 // properly resolves intrinsic sizes. We cannot do the same for heights
though because many code |
| 367 // paths inside updateLogicalHeight() require a previous call to setLogi
calHeight() to resolve |
| 368 // heights properly (like for positioned items for example). |
| 369 computeTrackSizesForDirection(ForColumns, sizingData, availableLogicalWi
dth()); |
| 370 |
| 371 if (logicalHeightWasIndefinite) |
| 372 computeIntrinsicLogicalHeight(sizingData); |
| 373 else |
| 374 computeTrackSizesForDirection(ForRows, sizingData, availableLogicalH
eight(ExcludeMarginBorderPadding)); |
| 375 setLogicalHeight(computeTrackBasedLogicalHeight(sizingData) + borderAndP
addingLogicalHeight()); |
341 | 376 |
342 LayoutUnit oldClientAfterEdge = clientLogicalBottom(); | 377 LayoutUnit oldClientAfterEdge = clientLogicalBottom(); |
343 updateLogicalHeight(); | 378 updateLogicalHeight(); |
344 | 379 |
| 380 // The above call might have changed the grid's logical height depending
on min|max height restrictions. |
| 381 // Update the sizes of the rows whose size depends on the logical height
(also on definite|indefinite sizes). |
| 382 if (logicalHeightWasIndefinite) |
| 383 computeTrackSizesForDirection(ForRows, sizingData, logicalHeight()); |
| 384 |
| 385 // Grid container should have the minimum height of a line if it's edita
ble. That doesn't affect track sizing though. |
| 386 if (hasLineIfEmpty()) |
| 387 setLogicalHeight(std::max(logicalHeight(), minimumLogicalHeightForEm
ptyLine())); |
| 388 |
| 389 applyStretchAlignmentToTracksIfNeeded(ForColumns, sizingData); |
| 390 applyStretchAlignmentToTracksIfNeeded(ForRows, sizingData); |
| 391 |
| 392 layoutGridItems(sizingData); |
| 393 |
345 if (size() != previousSize) | 394 if (size() != previousSize) |
346 relayoutChildren = true; | 395 relayoutChildren = true; |
347 | 396 |
348 layoutPositionedObjects(relayoutChildren || isDocumentElement()); | 397 layoutPositionedObjects(relayoutChildren || isDocumentElement()); |
349 | 398 |
350 computeOverflow(oldClientAfterEdge); | 399 computeOverflow(oldClientAfterEdge); |
351 } | 400 } |
352 | 401 |
353 updateLayerTransformAfterLayout(); | 402 updateLayerTransformAfterLayout(); |
354 updateScrollInfoAfterLayout(); | 403 updateScrollInfoAfterLayout(); |
355 | 404 |
356 clearNeedsLayout(); | 405 clearNeedsLayout(); |
357 } | 406 } |
358 | 407 |
359 LayoutUnit LayoutGrid::guttersSize(GridTrackSizingDirection direction, size_t sp
an) const | 408 LayoutUnit LayoutGrid::guttersSize(GridTrackSizingDirection direction, size_t sp
an) const |
360 { | 409 { |
361 ASSERT(span >= 1); | 410 ASSERT(span >= 1); |
362 | 411 |
363 if (span == 1) | 412 if (span == 1) |
364 return 0; | 413 return 0; |
365 | 414 |
366 const Length& trackGap = direction == ForColumns ? styleRef().gridColumnGap(
) : styleRef().gridRowGap(); | 415 const Length& trackGap = direction == ForColumns ? styleRef().gridColumnGap(
) : styleRef().gridRowGap(); |
367 return valueForLength(trackGap, 0) * (span - 1); | 416 return valueForLength(trackGap, 0) * (span - 1); |
368 } | 417 } |
369 | 418 |
370 void LayoutGrid::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, Layo
utUnit& maxLogicalWidth) const | 419 void LayoutGrid::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, Layo
utUnit& maxLogicalWidth) const |
371 { | 420 { |
372 const_cast<LayoutGrid*>(this)->placeItemsOnGrid(); | 421 const_cast<LayoutGrid*>(this)->placeItemsOnGrid(); |
373 | 422 |
374 GridSizingData sizingData(gridColumnCount(), gridRowCount(), 0, 0); | 423 GridSizingData sizingData(gridColumnCount(), gridRowCount()); |
375 const_cast<LayoutGrid*>(this)->computeUsedBreadthOfGridTracks(ForColumns, si
zingData); | 424 sizingData.freeSpaceForDirection(ForColumns) = -1; |
376 | 425 const_cast<LayoutGrid*>(this)->computeUsedBreadthOfGridTracks(ForColumns, si
zingData, minLogicalWidth, maxLogicalWidth); |
377 for (const auto& column : sizingData.columnTracks) { | |
378 const LayoutUnit& minTrackBreadth = column.baseSize(); | |
379 const LayoutUnit& maxTrackBreadth = column.growthLimit(); | |
380 | |
381 minLogicalWidth += minTrackBreadth; | |
382 maxLogicalWidth += maxTrackBreadth; | |
383 } | |
384 | 426 |
385 LayoutUnit totalGuttersSize = guttersSize(ForColumns, sizingData.columnTrack
s.size()); | 427 LayoutUnit totalGuttersSize = guttersSize(ForColumns, sizingData.columnTrack
s.size()); |
386 minLogicalWidth += totalGuttersSize; | 428 minLogicalWidth += totalGuttersSize; |
387 maxLogicalWidth += totalGuttersSize; | 429 maxLogicalWidth += totalGuttersSize; |
388 | 430 |
389 LayoutUnit scrollbarWidth = intrinsicScrollbarLogicalWidth(); | 431 LayoutUnit scrollbarWidth = intrinsicScrollbarLogicalWidth(); |
390 minLogicalWidth += scrollbarWidth; | 432 minLogicalWidth += scrollbarWidth; |
391 maxLogicalWidth += scrollbarWidth; | 433 maxLogicalWidth += scrollbarWidth; |
392 } | 434 } |
393 | 435 |
394 bool LayoutGrid::gridElementIsShrinkToFit() | 436 void LayoutGrid::computeIntrinsicLogicalHeight(GridSizingData& sizingData) |
395 { | 437 { |
396 return isFloatingOrOutOfFlowPositioned(); | 438 ASSERT(tracksAreWiderThanMinTrackBreadth(ForColumns, sizingData)); |
| 439 sizingData.freeSpaceForDirection(ForRows) = -1; |
| 440 computeUsedBreadthOfGridTracks(ForRows, sizingData, m_minContentHeight, m_ma
xContentHeight); |
| 441 |
| 442 LayoutUnit totalGuttersSize = guttersSize(ForRows, gridRowCount()); |
| 443 m_minContentHeight += totalGuttersSize; |
| 444 m_maxContentHeight += totalGuttersSize; |
| 445 |
| 446 ASSERT(tracksAreWiderThanMinTrackBreadth(ForRows, sizingData)); |
| 447 } |
| 448 |
| 449 LayoutUnit LayoutGrid::computeIntrinsicLogicalContentHeightUsing(const Length& l
ogicalHeightLength, LayoutUnit intrinsicContentHeight, LayoutUnit borderAndPaddi
ng) const |
| 450 { |
| 451 if (logicalHeightLength.isMinContent()) |
| 452 return m_minContentHeight; |
| 453 |
| 454 if (logicalHeightLength.isMaxContent()) |
| 455 return m_maxContentHeight; |
| 456 |
| 457 if (logicalHeightLength.isFitContent()) { |
| 458 if (m_minContentHeight == -1 || m_maxContentHeight == -1) |
| 459 return -1; |
| 460 LayoutUnit fillAvailableExtent = containingBlock()->availableLogicalHeig
ht(ExcludeMarginBorderPadding); |
| 461 return std::min<LayoutUnit>(m_maxContentHeight, std::max<LayoutUnit>(m_m
inContentHeight, fillAvailableExtent)); |
| 462 } |
| 463 |
| 464 if (logicalHeightLength.isFillAvailable()) |
| 465 return containingBlock()->availableLogicalHeight(ExcludeMarginBorderPadd
ing) - borderAndPadding; |
| 466 ASSERT_NOT_REACHED(); |
| 467 return 0; |
397 } | 468 } |
398 | 469 |
399 static inline double normalizedFlexFraction(const GridTrack& track, double flexF
actor) | 470 static inline double normalizedFlexFraction(const GridTrack& track, double flexF
actor) |
400 { | 471 { |
401 return track.baseSize() / std::max<double>(1, flexFactor); | 472 return track.baseSize() / std::max<double>(1, flexFactor); |
402 } | 473 } |
403 | 474 |
404 void LayoutGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection directi
on, GridSizingData& sizingData) | 475 void LayoutGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection directi
on, GridSizingData& sizingData, LayoutUnit& baseSizesWithoutMaximization, Layout
Unit& growthLimitsWithoutMaximization) |
405 { | 476 { |
406 LayoutUnit& freeSpace = sizingData.freeSpaceForDirection(direction); | 477 LayoutUnit& freeSpace = sizingData.freeSpaceForDirection(direction); |
407 const LayoutUnit initialFreeSpace = freeSpace; | 478 const LayoutUnit initialFreeSpace = freeSpace; |
408 Vector<GridTrack>& tracks = (direction == ForColumns) ? sizingData.columnTra
cks : sizingData.rowTracks; | 479 Vector<GridTrack>& tracks = (direction == ForColumns) ? sizingData.columnTra
cks : sizingData.rowTracks; |
409 Vector<size_t> flexibleSizedTracksIndex; | 480 Vector<size_t> flexibleSizedTracksIndex; |
410 sizingData.contentSizedTracksIndex.shrink(0); | 481 sizingData.contentSizedTracksIndex.shrink(0); |
411 | 482 |
412 const LayoutUnit maxSize = direction == ForColumns ? contentLogicalWidth() :
std::max(LayoutUnit(), computeContentLogicalHeight(MainOrPreferredSize, style()
->logicalHeight(), -1)); | 483 const LayoutUnit maxSize = std::max(LayoutUnit(), initialFreeSpace); |
413 // 1. Initialize per Grid track variables. | 484 // 1. Initialize per Grid track variables. |
414 for (size_t i = 0; i < tracks.size(); ++i) { | 485 for (size_t i = 0; i < tracks.size(); ++i) { |
415 GridTrack& track = tracks[i]; | 486 GridTrack& track = tracks[i]; |
416 GridTrackSize trackSize = gridTrackSize(direction, i); | 487 GridTrackSize trackSize = gridTrackSize(direction, i); |
417 const GridLength& minTrackBreadth = trackSize.minTrackBreadth(); | 488 const GridLength& minTrackBreadth = trackSize.minTrackBreadth(); |
418 const GridLength& maxTrackBreadth = trackSize.maxTrackBreadth(); | 489 const GridLength& maxTrackBreadth = trackSize.maxTrackBreadth(); |
419 | 490 |
420 track.setBaseSize(computeUsedBreadthOfMinLength(minTrackBreadth, maxSize
)); | 491 track.setBaseSize(computeUsedBreadthOfMinLength(minTrackBreadth, maxSize
)); |
421 track.setGrowthLimit(computeUsedBreadthOfMaxLength(maxTrackBreadth, trac
k.baseSize(), maxSize)); | 492 track.setGrowthLimit(computeUsedBreadthOfMaxLength(maxTrackBreadth, trac
k.baseSize(), maxSize)); |
422 track.setInfinitelyGrowable(false); | 493 track.setInfinitelyGrowable(false); |
423 | 494 |
424 if (trackSize.isContentSized()) | 495 if (trackSize.isContentSized()) |
425 sizingData.contentSizedTracksIndex.append(i); | 496 sizingData.contentSizedTracksIndex.append(i); |
426 if (trackSize.maxTrackBreadth().isFlex()) | 497 if (trackSize.maxTrackBreadth().isFlex()) |
427 flexibleSizedTracksIndex.append(i); | 498 flexibleSizedTracksIndex.append(i); |
428 } | 499 } |
429 | 500 |
430 // 2. Resolve content-based TrackSizingFunctions. | 501 // 2. Resolve content-based TrackSizingFunctions. |
431 if (!sizingData.contentSizedTracksIndex.isEmpty()) | 502 if (!sizingData.contentSizedTracksIndex.isEmpty()) |
432 resolveContentBasedTrackSizingFunctions(direction, sizingData); | 503 resolveContentBasedTrackSizingFunctions(direction, sizingData); |
433 | 504 |
| 505 baseSizesWithoutMaximization = growthLimitsWithoutMaximization = 0; |
| 506 |
434 for (const auto& track: tracks) { | 507 for (const auto& track: tracks) { |
435 ASSERT(!track.infiniteGrowthPotential()); | 508 ASSERT(!track.infiniteGrowthPotential()); |
436 freeSpace -= track.baseSize(); | 509 baseSizesWithoutMaximization += track.baseSize(); |
| 510 growthLimitsWithoutMaximization += track.growthLimit(); |
437 } | 511 } |
| 512 freeSpace = initialFreeSpace - baseSizesWithoutMaximization; |
438 | 513 |
439 const bool hasUndefinedRemainingSpace = (direction == ForRows) ? style()->lo
gicalHeight().isAuto() : gridElementIsShrinkToFit(); | 514 const bool hasDefiniteFreeSpace = initialFreeSpace != -1; |
440 | 515 if (hasDefiniteFreeSpace && freeSpace <= 0) |
441 if (!hasUndefinedRemainingSpace && freeSpace <= 0) | |
442 return; | 516 return; |
443 | 517 |
444 // 3. Grow all Grid tracks in GridTracks from their baseSize up to their gro
wthLimit value until freeSpace is exhausted. | 518 // 3. Grow all Grid tracks in GridTracks from their baseSize up to their gro
wthLimit value until freeSpace is exhausted. |
445 const size_t tracksSize = tracks.size(); | 519 const size_t tracksSize = tracks.size(); |
446 if (!hasUndefinedRemainingSpace) { | 520 if (hasDefiniteFreeSpace) { |
447 Vector<GridTrack*> tracksForDistribution(tracksSize); | 521 Vector<GridTrack*> tracksForDistribution(tracksSize); |
448 for (size_t i = 0; i < tracksSize; ++i) { | 522 for (size_t i = 0; i < tracksSize; ++i) { |
449 tracksForDistribution[i] = tracks.data() + i; | 523 tracksForDistribution[i] = tracks.data() + i; |
450 tracksForDistribution[i]->setPlannedSize(tracksForDistribution[i]->b
aseSize()); | 524 tracksForDistribution[i]->setPlannedSize(tracksForDistribution[i]->b
aseSize()); |
451 } | 525 } |
452 | 526 |
453 distributeSpaceToTracks<MaximizeTracks>(tracksForDistribution, nullptr,
sizingData, freeSpace); | 527 distributeSpaceToTracks<MaximizeTracks>(tracksForDistribution, nullptr,
sizingData, freeSpace); |
454 | 528 |
455 for (auto* track : tracksForDistribution) | 529 for (auto* track : tracksForDistribution) |
456 track->setBaseSize(track->plannedSize()); | 530 track->setBaseSize(track->plannedSize()); |
457 } else { | 531 } else { |
458 for (auto& track : tracks) | 532 for (auto& track : tracks) |
459 track.setBaseSize(track.growthLimit()); | 533 track.setBaseSize(track.growthLimit()); |
460 } | 534 } |
461 | 535 |
462 if (flexibleSizedTracksIndex.isEmpty()) | 536 if (flexibleSizedTracksIndex.isEmpty()) |
463 return; | 537 return; |
464 | 538 |
465 // 4. Grow all Grid tracks having a fraction as the MaxTrackSizingFunction. | 539 // 4. Grow all Grid tracks having a fraction as the MaxTrackSizingFunction. |
466 double flexFraction = 0; | 540 double flexFraction = 0; |
467 if (!hasUndefinedRemainingSpace) { | 541 if (hasDefiniteFreeSpace) { |
468 flexFraction = findFlexFactorUnitSize(tracks, GridSpan(0, tracks.size()
- 1), direction, initialFreeSpace); | 542 flexFraction = findFlexFactorUnitSize(tracks, GridSpan(0, tracks.size()
- 1), direction, initialFreeSpace); |
469 } else { | 543 } else { |
470 for (const auto& trackIndex : flexibleSizedTracksIndex) | 544 for (const auto& trackIndex : flexibleSizedTracksIndex) |
471 flexFraction = std::max(flexFraction, normalizedFlexFraction(tracks[
trackIndex], gridTrackSize(direction, trackIndex).maxTrackBreadth().flex())); | 545 flexFraction = std::max(flexFraction, normalizedFlexFraction(tracks[
trackIndex], gridTrackSize(direction, trackIndex).maxTrackBreadth().flex())); |
472 | 546 |
473 for (size_t i = 0; i < flexibleSizedTracksIndex.size(); ++i) { | 547 for (size_t i = 0; i < flexibleSizedTracksIndex.size(); ++i) { |
474 GridIterator iterator(m_grid, direction, flexibleSizedTracksIndex[i]
); | 548 GridIterator iterator(m_grid, direction, flexibleSizedTracksIndex[i]
); |
475 while (LayoutBox* gridItem = iterator.nextGridItem()) { | 549 while (LayoutBox* gridItem = iterator.nextGridItem()) { |
476 const GridCoordinate coordinate = cachedGridCoordinate(*gridItem
); | 550 const GridCoordinate coordinate = cachedGridCoordinate(*gridItem
); |
477 const GridSpan span = (direction == ForColumns) ? coordinate.col
umns : coordinate.rows; | 551 const GridSpan span = (direction == ForColumns) ? coordinate.col
umns : coordinate.rows; |
478 | 552 |
479 // Do not include already processed items. | 553 // Do not include already processed items. |
480 if (i > 0 && span.resolvedInitialPosition.toInt() <= flexibleSiz
edTracksIndex[i - 1]) | 554 if (i > 0 && span.resolvedInitialPosition.toInt() <= flexibleSiz
edTracksIndex[i - 1]) |
481 continue; | 555 continue; |
482 | 556 |
483 flexFraction = std::max(flexFraction, findFlexFactorUnitSize(tra
cks, span, direction, maxContentForChild(*gridItem, direction, sizingData.column
Tracks))); | 557 flexFraction = std::max(flexFraction, findFlexFactorUnitSize(tra
cks, span, direction, maxContentForChild(*gridItem, direction, sizingData.column
Tracks))); |
484 } | 558 } |
485 } | 559 } |
486 } | 560 } |
487 | 561 |
488 for (const auto& trackIndex : flexibleSizedTracksIndex) { | 562 for (const auto& trackIndex : flexibleSizedTracksIndex) { |
489 GridTrackSize trackSize = gridTrackSize(direction, trackIndex); | 563 GridTrackSize trackSize = gridTrackSize(direction, trackIndex); |
490 | 564 |
491 LayoutUnit oldBaseSize = tracks[trackIndex].baseSize(); | 565 LayoutUnit oldBaseSize = tracks[trackIndex].baseSize(); |
492 LayoutUnit baseSize = std::max<LayoutUnit>(oldBaseSize, flexFraction * t
rackSize.maxTrackBreadth().flex()); | 566 LayoutUnit baseSize = std::max<LayoutUnit>(oldBaseSize, flexFraction * t
rackSize.maxTrackBreadth().flex()); |
493 if (LayoutUnit increment = baseSize - oldBaseSize) { | 567 if (LayoutUnit increment = baseSize - oldBaseSize) { |
494 tracks[trackIndex].setBaseSize(baseSize); | 568 tracks[trackIndex].setBaseSize(baseSize); |
495 freeSpace -= increment; | 569 freeSpace -= increment; |
| 570 |
| 571 baseSizesWithoutMaximization += increment; |
| 572 growthLimitsWithoutMaximization += increment; |
496 } | 573 } |
497 } | 574 } |
498 | |
499 // FIXME: Should ASSERT flexible tracks exhaust the freeSpace ? (see issue 7
39613002). | |
500 } | 575 } |
501 | 576 |
502 LayoutUnit LayoutGrid::computeUsedBreadthOfMinLength(const GridLength& gridLengt
h, LayoutUnit maxSize) const | 577 LayoutUnit LayoutGrid::computeUsedBreadthOfMinLength(const GridLength& gridLengt
h, LayoutUnit maxSize) const |
503 { | 578 { |
504 if (gridLength.isFlex()) | 579 if (gridLength.isFlex()) |
505 return 0; | 580 return 0; |
506 | 581 |
507 const Length& trackLength = gridLength.length(); | 582 const Length& trackLength = gridLength.length(); |
508 if (trackLength.isSpecified()) | 583 if (trackLength.isSpecified()) |
509 return valueForLength(trackLength, maxSize); | 584 return valueForLength(trackLength, maxSize); |
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1012 track->growSizeDuringDistribution(growthShare); | 1087 track->growSizeDuringDistribution(growthShare); |
1013 availableLogicalSpace -= growthShare; | 1088 availableLogicalSpace -= growthShare; |
1014 } | 1089 } |
1015 } | 1090 } |
1016 | 1091 |
1017 for (auto* track : tracks) | 1092 for (auto* track : tracks) |
1018 track->setPlannedSize(track->plannedSize() == infinity ? track->sizeDuri
ngDistribution() : std::max(track->plannedSize(), track->sizeDuringDistribution(
))); | 1093 track->setPlannedSize(track->plannedSize() == infinity ? track->sizeDuri
ngDistribution() : std::max(track->plannedSize(), track->sizeDuringDistribution(
))); |
1019 } | 1094 } |
1020 | 1095 |
1021 #if ENABLE(ASSERT) | 1096 #if ENABLE(ASSERT) |
1022 bool LayoutGrid::tracksAreWiderThanMinTrackBreadth(GridTrackSizingDirection dire
ction, const Vector<GridTrack>& tracks) | 1097 bool LayoutGrid::tracksAreWiderThanMinTrackBreadth(GridTrackSizingDirection dire
ction, GridSizingData& sizingData) |
1023 { | 1098 { |
1024 const LayoutUnit maxSize = direction == ForColumns ? contentLogicalWidth() :
std::max(LayoutUnit(), computeContentLogicalHeight(MainOrPreferredSize, style()
->logicalHeight(), -1)); | 1099 const Vector<GridTrack>& tracks = (direction == ForColumns) ? sizingData.col
umnTracks : sizingData.rowTracks; |
| 1100 LayoutUnit& maxSize = sizingData.freeSpaceForDirection(direction); |
1025 for (size_t i = 0; i < tracks.size(); ++i) { | 1101 for (size_t i = 0; i < tracks.size(); ++i) { |
1026 GridTrackSize trackSize = gridTrackSize(direction, i); | 1102 GridTrackSize trackSize = gridTrackSize(direction, i); |
1027 const GridLength& minTrackBreadth = trackSize.minTrackBreadth(); | 1103 const GridLength& minTrackBreadth = trackSize.minTrackBreadth(); |
1028 if (computeUsedBreadthOfMinLength(minTrackBreadth, maxSize) > tracks[i].
baseSize()) | 1104 if (computeUsedBreadthOfMinLength(minTrackBreadth, maxSize) > tracks[i].
baseSize()) |
1029 return false; | 1105 return false; |
1030 } | 1106 } |
1031 return true; | 1107 return true; |
1032 } | 1108 } |
1033 #endif | 1109 #endif |
1034 | 1110 |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1303 | 1379 |
1304 LayoutUnit sizeToIncrease = availableSpace / numberOfAutoSizedTracks; | 1380 LayoutUnit sizeToIncrease = availableSpace / numberOfAutoSizedTracks; |
1305 for (const auto& trackIndex : autoSizedTracksIndex) { | 1381 for (const auto& trackIndex : autoSizedTracksIndex) { |
1306 GridTrack* track = tracks.data() + trackIndex; | 1382 GridTrack* track = tracks.data() + trackIndex; |
1307 LayoutUnit baseSize = track->baseSize() + sizeToIncrease; | 1383 LayoutUnit baseSize = track->baseSize() + sizeToIncrease; |
1308 track->setBaseSize(baseSize); | 1384 track->setBaseSize(baseSize); |
1309 } | 1385 } |
1310 availableSpace = 0; | 1386 availableSpace = 0; |
1311 } | 1387 } |
1312 | 1388 |
1313 void LayoutGrid::layoutGridItems() | 1389 void LayoutGrid::layoutGridItems(GridSizingData& sizingData) |
1314 { | 1390 { |
1315 placeItemsOnGrid(); | |
1316 | |
1317 LayoutUnit availableSpaceForColumns = availableLogicalWidth(); | |
1318 LayoutUnit availableSpaceForRows = availableLogicalHeight(IncludeMarginBorde
rPadding); | |
1319 | |
1320 // Remove space consumed by gutters from the available logical space. | |
1321 availableSpaceForColumns -= guttersSize(ForColumns, gridColumnCount()); | |
1322 availableSpaceForRows -= guttersSize(ForRows, gridRowCount()); | |
1323 | |
1324 GridSizingData sizingData(gridColumnCount(), gridRowCount(), availableSpaceF
orColumns, availableSpaceForRows); | |
1325 computeUsedBreadthOfGridTracks(ForColumns, sizingData); | |
1326 ASSERT(tracksAreWiderThanMinTrackBreadth(ForColumns, sizingData.columnTracks
)); | |
1327 computeUsedBreadthOfGridTracks(ForRows, sizingData); | |
1328 ASSERT(tracksAreWiderThanMinTrackBreadth(ForRows, sizingData.rowTracks)); | |
1329 | |
1330 applyStretchAlignmentToTracksIfNeeded(ForColumns, sizingData); | |
1331 applyStretchAlignmentToTracksIfNeeded(ForRows, sizingData); | |
1332 | |
1333 populateGridPositions(sizingData); | 1391 populateGridPositions(sizingData); |
1334 m_gridItemsOverflowingGridArea.resize(0); | 1392 m_gridItemsOverflowingGridArea.resize(0); |
1335 | 1393 |
1336 for (LayoutBox* child = firstChildBox(); child; child = child->nextSiblingBo
x()) { | 1394 for (LayoutBox* child = firstChildBox(); child; child = child->nextSiblingBo
x()) { |
1337 if (child->isOutOfFlowPositioned()) { | 1395 if (child->isOutOfFlowPositioned()) { |
1338 prepareChildForPositionedLayout(*child); | 1396 prepareChildForPositionedLayout(*child); |
1339 continue; | 1397 continue; |
1340 } | 1398 } |
1341 | 1399 |
1342 // Because the grid area cannot be styled, we don't need to adjust | 1400 // Because the grid area cannot be styled, we don't need to adjust |
(...skipping 28 matching lines...) Expand all Loading... |
1371 ASSERT(coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowT
racks.size()); | 1429 ASSERT(coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowT
racks.size()); |
1372 #endif | 1430 #endif |
1373 child->setLogicalLocation(findChildLogicalPosition(*child, sizingData)); | 1431 child->setLogicalLocation(findChildLogicalPosition(*child, sizingData)); |
1374 | 1432 |
1375 // Keep track of children overflowing their grid area as we might need t
o paint them even if the grid-area is | 1433 // Keep track of children overflowing their grid area as we might need t
o paint them even if the grid-area is |
1376 // not visible | 1434 // not visible |
1377 if (child->logicalHeight() > overrideContainingBlockContentLogicalHeight | 1435 if (child->logicalHeight() > overrideContainingBlockContentLogicalHeight |
1378 || child->logicalWidth() > overrideContainingBlockContentLogicalWidt
h) | 1436 || child->logicalWidth() > overrideContainingBlockContentLogicalWidt
h) |
1379 m_gridItemsOverflowingGridArea.append(child); | 1437 m_gridItemsOverflowingGridArea.append(child); |
1380 } | 1438 } |
1381 | |
1382 LayoutUnit height = borderAndPaddingLogicalHeight() + scrollbarLogicalHeight
(); | |
1383 for (const auto& row : sizingData.rowTracks) | |
1384 height += row.baseSize(); | |
1385 | |
1386 height += guttersSize(ForRows, sizingData.rowTracks.size()); | |
1387 | |
1388 if (hasLineIfEmpty()) | |
1389 height = std::max(height, minimumLogicalHeightForEmptyLine()); | |
1390 | |
1391 // Min / max logical height is handled by the call to updateLogicalHeight in
layoutBlock. | |
1392 setLogicalHeight(height); | |
1393 } | 1439 } |
1394 | 1440 |
1395 void LayoutGrid::prepareChildForPositionedLayout(LayoutBox& child) | 1441 void LayoutGrid::prepareChildForPositionedLayout(LayoutBox& child) |
1396 { | 1442 { |
1397 ASSERT(child.isOutOfFlowPositioned()); | 1443 ASSERT(child.isOutOfFlowPositioned()); |
1398 child.containingBlock()->insertPositionedObject(&child); | 1444 child.containingBlock()->insertPositionedObject(&child); |
1399 | 1445 |
1400 PaintLayer* childLayer = child.layer(); | 1446 PaintLayer* childLayer = child.layer(); |
1401 childLayer->setStaticInlinePosition(borderAndPaddingStart()); | 1447 childLayer->setStaticInlinePosition(borderAndPaddingStart()); |
1402 childLayer->setStaticBlockPosition(borderAndPaddingBefore()); | 1448 childLayer->setStaticBlockPosition(borderAndPaddingBefore()); |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2014 | 2060 |
2015 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child)); | 2061 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child)); |
2016 } | 2062 } |
2017 | 2063 |
2018 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa
intOffset) const | 2064 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa
intOffset) const |
2019 { | 2065 { |
2020 GridPainter(*this).paintChildren(paintInfo, paintOffset); | 2066 GridPainter(*this).paintChildren(paintInfo, paintOffset); |
2021 } | 2067 } |
2022 | 2068 |
2023 } // namespace blink | 2069 } // namespace blink |
OLD | NEW |