OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/layout/GridTrackSizingAlgorithm.h" | 5 #include "core/layout/GridTrackSizingAlgorithm.h" |
6 | 6 |
7 #include "core/frame/FrameView.h" | 7 #include "core/frame/FrameView.h" |
8 #include "core/layout/Grid.h" | 8 #include "core/layout/Grid.h" |
9 #include "core/layout/LayoutGrid.h" | 9 #include "core/layout/LayoutGrid.h" |
10 #include "platform/LengthFunctions.h" | 10 #include "platform/LengthFunctions.h" |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 IndefiniteSizeStrategy(GridTrackSizingAlgorithm& algorithm) | 81 IndefiniteSizeStrategy(GridTrackSizingAlgorithm& algorithm) |
82 : GridTrackSizingAlgorithmStrategy(algorithm) {} | 82 : GridTrackSizingAlgorithmStrategy(algorithm) {} |
83 | 83 |
84 private: | 84 private: |
85 LayoutUnit minLogicalWidthForChild(LayoutBox&, | 85 LayoutUnit minLogicalWidthForChild(LayoutBox&, |
86 Length childMinSize, | 86 Length childMinSize, |
87 GridTrackSizingDirection) const override; | 87 GridTrackSizingDirection) const override; |
88 void layoutGridItemForMinSizeComputation( | 88 void layoutGridItemForMinSizeComputation( |
89 LayoutBox&, | 89 LayoutBox&, |
90 bool overrideSizeHasChanged) const override; | 90 bool overrideSizeHasChanged) const override; |
91 void maximizeTracks(Vector<GridTrack>&, LayoutUnit& freeSpace) override; | 91 void maximizeTracks(Vector<GridTrack>&, |
| 92 Optional<LayoutUnit>& freeSpace) override; |
92 double findUsedFlexFraction(Vector<size_t>& flexibleSizedTracksIndex, | 93 double findUsedFlexFraction(Vector<size_t>& flexibleSizedTracksIndex, |
93 GridTrackSizingDirection, | 94 GridTrackSizingDirection, |
94 LayoutUnit freeSpace) const override; | 95 Optional<LayoutUnit> freeSpace) const override; |
95 bool recomputeUsedFlexFractionIfNeeded( | 96 bool recomputeUsedFlexFractionIfNeeded( |
96 Vector<size_t>& flexibleSizedTracksIndex, | 97 Vector<size_t>& flexibleSizedTracksIndex, |
97 double& flexFraction, | 98 double& flexFraction, |
98 Vector<LayoutUnit>& increments, | 99 Vector<LayoutUnit>& increments, |
99 LayoutUnit& totalGrowth) const override; | 100 LayoutUnit& totalGrowth) const override; |
100 }; | 101 }; |
101 | 102 |
102 class DefiniteSizeStrategy final : public GridTrackSizingAlgorithmStrategy { | 103 class DefiniteSizeStrategy final : public GridTrackSizingAlgorithmStrategy { |
103 public: | 104 public: |
104 DefiniteSizeStrategy(GridTrackSizingAlgorithm& algorithm) | 105 DefiniteSizeStrategy(GridTrackSizingAlgorithm& algorithm) |
105 : GridTrackSizingAlgorithmStrategy(algorithm) {} | 106 : GridTrackSizingAlgorithmStrategy(algorithm) {} |
106 | 107 |
107 private: | 108 private: |
108 LayoutUnit minLogicalWidthForChild(LayoutBox&, | 109 LayoutUnit minLogicalWidthForChild(LayoutBox&, |
109 Length childMinSize, | 110 Length childMinSize, |
110 GridTrackSizingDirection) const override; | 111 GridTrackSizingDirection) const override; |
111 void layoutGridItemForMinSizeComputation( | 112 void layoutGridItemForMinSizeComputation( |
112 LayoutBox&, | 113 LayoutBox&, |
113 bool overrideSizeHasChanged) const override; | 114 bool overrideSizeHasChanged) const override; |
114 void maximizeTracks(Vector<GridTrack>&, LayoutUnit& freeSpace) override; | 115 void maximizeTracks(Vector<GridTrack>&, |
| 116 Optional<LayoutUnit>& freeSpace) override; |
115 double findUsedFlexFraction(Vector<size_t>& flexibleSizedTracksIndex, | 117 double findUsedFlexFraction(Vector<size_t>& flexibleSizedTracksIndex, |
116 GridTrackSizingDirection, | 118 GridTrackSizingDirection, |
117 LayoutUnit freeSpace) const override; | 119 Optional<LayoutUnit> freeSpace) const override; |
118 bool recomputeUsedFlexFractionIfNeeded( | 120 bool recomputeUsedFlexFractionIfNeeded( |
119 Vector<size_t>& flexibleSizedTracksIndex, | 121 Vector<size_t>& flexibleSizedTracksIndex, |
120 double& flexFraction, | 122 double& flexFraction, |
121 Vector<LayoutUnit>& increments, | 123 Vector<LayoutUnit>& increments, |
122 LayoutUnit& totalGrowth) const override { | 124 LayoutUnit& totalGrowth) const override { |
123 return false; | 125 return false; |
124 } | 126 } |
125 }; | 127 }; |
126 | 128 |
127 // TODO(svillar): Repeated in LayoutGrid. | 129 // TODO(svillar): Repeated in LayoutGrid. |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 | 441 |
440 void DefiniteSizeStrategy::layoutGridItemForMinSizeComputation( | 442 void DefiniteSizeStrategy::layoutGridItemForMinSizeComputation( |
441 LayoutBox& child, | 443 LayoutBox& child, |
442 bool overrideSizeHasChanged) const { | 444 bool overrideSizeHasChanged) const { |
443 if (overrideSizeHasChanged) | 445 if (overrideSizeHasChanged) |
444 setGridItemNeedsLayout(child); | 446 setGridItemNeedsLayout(child); |
445 child.layoutIfNeeded(); | 447 child.layoutIfNeeded(); |
446 } | 448 } |
447 | 449 |
448 void DefiniteSizeStrategy::maximizeTracks(Vector<GridTrack>& tracks, | 450 void DefiniteSizeStrategy::maximizeTracks(Vector<GridTrack>& tracks, |
449 LayoutUnit& freeSpace) { | 451 Optional<LayoutUnit>& freeSpace) { |
450 size_t tracksSize = tracks.size(); | 452 size_t tracksSize = tracks.size(); |
451 Vector<GridTrack*> tracksForDistribution(tracksSize); | 453 Vector<GridTrack*> tracksForDistribution(tracksSize); |
452 for (size_t i = 0; i < tracksSize; ++i) { | 454 for (size_t i = 0; i < tracksSize; ++i) { |
453 tracksForDistribution[i] = tracks.data() + i; | 455 tracksForDistribution[i] = tracks.data() + i; |
454 tracksForDistribution[i]->setPlannedSize( | 456 tracksForDistribution[i]->setPlannedSize( |
455 tracksForDistribution[i]->baseSize()); | 457 tracksForDistribution[i]->baseSize()); |
456 } | 458 } |
457 | 459 |
458 distributeSpaceToTracks(tracksForDistribution, freeSpace); | 460 DCHECK(freeSpace); |
| 461 distributeSpaceToTracks(tracksForDistribution, freeSpace.value()); |
459 | 462 |
460 for (auto* track : tracksForDistribution) | 463 for (auto* track : tracksForDistribution) |
461 track->setBaseSize(track->plannedSize()); | 464 track->setBaseSize(track->plannedSize()); |
462 } | 465 } |
463 | 466 |
464 double DefiniteSizeStrategy::findUsedFlexFraction( | 467 double DefiniteSizeStrategy::findUsedFlexFraction( |
465 Vector<size_t>& flexibleSizedTracksIndex, | 468 Vector<size_t>& flexibleSizedTracksIndex, |
466 GridTrackSizingDirection direction, | 469 GridTrackSizingDirection direction, |
467 LayoutUnit freeSpace) const { | 470 Optional<LayoutUnit> freeSpace) const { |
468 GridSpan allTracksSpan = GridSpan::translatedDefiniteGridSpan( | 471 GridSpan allTracksSpan = GridSpan::translatedDefiniteGridSpan( |
469 0, m_algorithm.tracks(direction).size()); | 472 0, m_algorithm.tracks(direction).size()); |
470 return findFrUnitSize(allTracksSpan, freeSpace); | 473 DCHECK(freeSpace); |
| 474 return findFrUnitSize(allTracksSpan, freeSpace.value()); |
471 } | 475 } |
472 | 476 |
473 LayoutUnit IndefiniteSizeStrategy::minLogicalWidthForChild( | 477 LayoutUnit IndefiniteSizeStrategy::minLogicalWidthForChild( |
474 LayoutBox& child, | 478 LayoutBox& child, |
475 Length childMinSize, | 479 Length childMinSize, |
476 GridTrackSizingDirection childInlineDirection) const { | 480 GridTrackSizingDirection childInlineDirection) const { |
477 // TODO(svillar): we should use marginIntrinsicLogicalWidthForChild() instead | 481 // TODO(svillar): we should use marginIntrinsicLogicalWidthForChild() instead |
478 // but it is protected for LayoutObjects. Apparently none of the current tests | 482 // but it is protected for LayoutObjects. Apparently none of the current tests |
479 // fail, so we need a test case for this too. | 483 // fail, so we need a test case for this too. |
480 LayoutUnit marginLogicalWidth = LayoutUnit(); | 484 LayoutUnit marginLogicalWidth = LayoutUnit(); |
481 return child.computeLogicalWidthUsing( | 485 return child.computeLogicalWidthUsing( |
482 MinSize, childMinSize, overrideContainingBlockContentSizeForChild( | 486 MinSize, childMinSize, overrideContainingBlockContentSizeForChild( |
483 child, childInlineDirection), | 487 child, childInlineDirection), |
484 layoutGrid()) + | 488 layoutGrid()) + |
485 marginLogicalWidth; | 489 marginLogicalWidth; |
486 } | 490 } |
487 | 491 |
488 void IndefiniteSizeStrategy::layoutGridItemForMinSizeComputation( | 492 void IndefiniteSizeStrategy::layoutGridItemForMinSizeComputation( |
489 LayoutBox& child, | 493 LayoutBox& child, |
490 bool overrideSizeHasChanged) const { | 494 bool overrideSizeHasChanged) const { |
491 if (overrideSizeHasChanged && direction() != ForColumns) | 495 if (overrideSizeHasChanged && direction() != ForColumns) |
492 setGridItemNeedsLayout(child); | 496 setGridItemNeedsLayout(child); |
493 child.layoutIfNeeded(); | 497 child.layoutIfNeeded(); |
494 } | 498 } |
495 | 499 |
496 void IndefiniteSizeStrategy::maximizeTracks(Vector<GridTrack>& tracks, | 500 void IndefiniteSizeStrategy::maximizeTracks(Vector<GridTrack>& tracks, |
497 LayoutUnit&) { | 501 Optional<LayoutUnit>&) { |
498 for (auto& track : tracks) | 502 for (auto& track : tracks) |
499 track.setBaseSize(track.growthLimit()); | 503 track.setBaseSize(track.growthLimit()); |
500 } | 504 } |
501 | 505 |
502 static inline double normalizedFlexFraction(const GridTrack& track, | 506 static inline double normalizedFlexFraction(const GridTrack& track, |
503 double flexFactor) { | 507 double flexFactor) { |
504 return track.baseSize() / std::max<double>(1, flexFactor); | 508 return track.baseSize() / std::max<double>(1, flexFactor); |
505 } | 509 } |
506 | 510 |
507 double IndefiniteSizeStrategy::findUsedFlexFraction( | 511 double IndefiniteSizeStrategy::findUsedFlexFraction( |
508 Vector<size_t>& flexibleSizedTracksIndex, | 512 Vector<size_t>& flexibleSizedTracksIndex, |
509 GridTrackSizingDirection direction, | 513 GridTrackSizingDirection direction, |
510 LayoutUnit freeSpace) const { | 514 Optional<LayoutUnit>) const { |
511 auto allTracks = m_algorithm.tracks(direction); | 515 auto allTracks = m_algorithm.tracks(direction); |
512 | 516 |
513 double flexFraction = 0; | 517 double flexFraction = 0; |
514 for (const auto& trackIndex : flexibleSizedTracksIndex) { | 518 for (const auto& trackIndex : flexibleSizedTracksIndex) { |
515 // TODO(svillar): we pass TrackSizing to gridTrackSize() because it does not | 519 // TODO(svillar): we pass TrackSizing to gridTrackSize() because it does not |
516 // really matter as we know the track is a flex sized track. It'd be nice | 520 // really matter as we know the track is a flex sized track. It'd be nice |
517 // not to have to do that. | 521 // not to have to do that. |
518 flexFraction = std::max( | 522 flexFraction = std::max( |
519 flexFraction, | 523 flexFraction, |
520 normalizedFlexFraction( | 524 normalizedFlexFraction( |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
573 freeSpace = std::max(freeSpace, minSize) - | 577 freeSpace = std::max(freeSpace, minSize) - |
574 layoutGrid->guttersSize(grid, ForRows, 0, grid.numTracks(ForRows), | 578 layoutGrid->guttersSize(grid, ForRows, 0, grid.numTracks(ForRows), |
575 IntrinsicSizeComputation); | 579 IntrinsicSizeComputation); |
576 | 580 |
577 size_t numberOfTracks = m_algorithm.tracks(direction()).size(); | 581 size_t numberOfTracks = m_algorithm.tracks(direction()).size(); |
578 flexFraction = findFrUnitSize( | 582 flexFraction = findFrUnitSize( |
579 GridSpan::translatedDefiniteGridSpan(0, numberOfTracks), freeSpace); | 583 GridSpan::translatedDefiniteGridSpan(0, numberOfTracks), freeSpace); |
580 return true; | 584 return true; |
581 } | 585 } |
582 | 586 |
583 LayoutUnit& GridTrackSizingAlgorithm::freeSpace( | 587 Optional<LayoutUnit> GridTrackSizingAlgorithm::freeSpace( |
584 GridTrackSizingDirection direction) { | 588 GridTrackSizingDirection direction) { |
585 return direction == ForRows ? m_freeSpaceRows : m_freeSpaceColumns; | 589 return direction == ForRows ? m_freeSpaceRows : m_freeSpaceColumns; |
586 } | 590 } |
587 | 591 |
588 Vector<GridTrack>& GridTrackSizingAlgorithm::tracks( | 592 Vector<GridTrack>& GridTrackSizingAlgorithm::tracks( |
589 GridTrackSizingDirection direction) { | 593 GridTrackSizingDirection direction) { |
590 return direction == ForColumns ? m_columns : m_rows; | 594 return direction == ForColumns ? m_columns : m_rows; |
591 } | 595 } |
592 | 596 |
593 const Vector<GridTrack>& GridTrackSizingAlgorithm::tracks( | 597 const Vector<GridTrack>& GridTrackSizingAlgorithm::tracks( |
594 GridTrackSizingDirection direction) const { | 598 GridTrackSizingDirection direction) const { |
595 return direction == ForColumns ? m_columns : m_rows; | 599 return direction == ForColumns ? m_columns : m_rows; |
596 } | 600 } |
597 | 601 |
| 602 void GridTrackSizingAlgorithm::setFreeSpace(GridTrackSizingDirection direction, |
| 603 Optional<LayoutUnit> freeSpace) { |
| 604 if (direction == ForColumns) |
| 605 m_freeSpaceColumns = freeSpace; |
| 606 else |
| 607 m_freeSpaceRows = freeSpace; |
| 608 } |
| 609 |
598 GridTrackSize GridTrackSizingAlgorithm::rawGridTrackSize( | 610 GridTrackSize GridTrackSizingAlgorithm::rawGridTrackSize( |
599 GridTrackSizingDirection direction, | 611 GridTrackSizingDirection direction, |
600 size_t translatedIndex) const { | 612 size_t translatedIndex) const { |
601 bool isRowAxis = direction == ForColumns; | 613 bool isRowAxis = direction == ForColumns; |
602 const Vector<GridTrackSize>& trackStyles = | 614 const Vector<GridTrackSize>& trackStyles = |
603 isRowAxis ? m_layoutGrid->styleRef().gridTemplateColumns() | 615 isRowAxis ? m_layoutGrid->styleRef().gridTemplateColumns() |
604 : m_layoutGrid->styleRef().gridTemplateRows(); | 616 : m_layoutGrid->styleRef().gridTemplateRows(); |
605 const Vector<GridTrackSize>& autoRepeatTrackStyles = | 617 const Vector<GridTrackSize>& autoRepeatTrackStyles = |
606 isRowAxis ? m_layoutGrid->styleRef().gridAutoRepeatColumns() | 618 isRowAxis ? m_layoutGrid->styleRef().gridAutoRepeatColumns() |
607 : m_layoutGrid->styleRef().gridAutoRepeatRows(); | 619 : m_layoutGrid->styleRef().gridAutoRepeatRows(); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 } | 706 } |
695 | 707 |
696 LayoutUnit GridTrackSizingAlgorithm::initialBaseSize( | 708 LayoutUnit GridTrackSizingAlgorithm::initialBaseSize( |
697 const GridTrackSize& trackSize) const { | 709 const GridTrackSize& trackSize) const { |
698 const GridLength& gridLength = trackSize.minTrackBreadth(); | 710 const GridLength& gridLength = trackSize.minTrackBreadth(); |
699 if (gridLength.isFlex()) | 711 if (gridLength.isFlex()) |
700 return LayoutUnit(); | 712 return LayoutUnit(); |
701 | 713 |
702 const Length& trackLength = gridLength.length(); | 714 const Length& trackLength = gridLength.length(); |
703 if (trackLength.isSpecified()) | 715 if (trackLength.isSpecified()) |
704 return valueForLength(trackLength, m_availableSpace.clampNegativeToZero()); | 716 return valueForLength(trackLength, m_availableSpace.value_or(LayoutUnit())); |
705 | 717 |
706 DCHECK(trackLength.isMinContent() || trackLength.isAuto() || | 718 DCHECK(trackLength.isMinContent() || trackLength.isAuto() || |
707 trackLength.isMaxContent()); | 719 trackLength.isMaxContent()); |
708 return LayoutUnit(); | 720 return LayoutUnit(); |
709 } | 721 } |
710 | 722 |
711 LayoutUnit GridTrackSizingAlgorithm::initialGrowthLimit( | 723 LayoutUnit GridTrackSizingAlgorithm::initialGrowthLimit( |
712 const GridTrackSize& trackSize, | 724 const GridTrackSize& trackSize, |
713 LayoutUnit baseSize) const { | 725 LayoutUnit baseSize) const { |
714 const GridLength& gridLength = trackSize.maxTrackBreadth(); | 726 const GridLength& gridLength = trackSize.maxTrackBreadth(); |
715 if (gridLength.isFlex()) | 727 if (gridLength.isFlex()) |
716 return baseSize; | 728 return baseSize; |
717 | 729 |
718 const Length& trackLength = gridLength.length(); | 730 const Length& trackLength = gridLength.length(); |
719 if (trackLength.isSpecified()) | 731 if (trackLength.isSpecified()) |
720 return valueForLength(trackLength, m_availableSpace.clampNegativeToZero()); | 732 return valueForLength(trackLength, m_availableSpace.value_or(LayoutUnit())); |
721 | 733 |
722 DCHECK(trackLength.isMinContent() || trackLength.isAuto() || | 734 DCHECK(trackLength.isMinContent() || trackLength.isAuto() || |
723 trackLength.isMaxContent()); | 735 trackLength.isMaxContent()); |
724 return LayoutUnit(infinity); | 736 return LayoutUnit(infinity); |
725 } | 737 } |
726 | 738 |
727 void GridTrackSizingAlgorithm::initializeTrackSizes() { | 739 void GridTrackSizingAlgorithm::initializeTrackSizes() { |
728 DCHECK(m_contentSizedTracksIndex.isEmpty()); | 740 DCHECK(m_contentSizedTracksIndex.isEmpty()); |
729 DCHECK(m_flexibleSizedTracksIndex.isEmpty()); | 741 DCHECK(m_flexibleSizedTracksIndex.isEmpty()); |
730 Vector<GridTrack>& trackList = tracks(m_direction); | 742 Vector<GridTrack>& trackList = tracks(m_direction); |
731 bool hasDefiniteFreeSpace = m_sizingOperation == TrackSizing; | 743 bool hasDefiniteFreeSpace = !!m_availableSpace; |
732 size_t numTracks = trackList.size(); | 744 size_t numTracks = trackList.size(); |
733 for (size_t i = 0; i < numTracks; ++i) { | 745 for (size_t i = 0; i < numTracks; ++i) { |
734 GridTrackSize trackSize = gridTrackSize(m_direction, i); | 746 GridTrackSize trackSize = gridTrackSize(m_direction, i); |
735 GridTrack& track = trackList[i]; | 747 GridTrack& track = trackList[i]; |
736 track.setBaseSize(initialBaseSize(trackSize)); | 748 track.setBaseSize(initialBaseSize(trackSize)); |
737 track.setGrowthLimit(initialGrowthLimit(trackSize, track.baseSize())); | 749 track.setGrowthLimit(initialGrowthLimit(trackSize, track.baseSize())); |
738 track.setInfinitelyGrowable(false); | 750 track.setInfinitelyGrowable(false); |
739 | 751 |
740 if (trackSize.isFitContent()) { | 752 if (trackSize.isFitContent()) { |
741 GridLength gridLength = trackSize.fitContentTrackBreadth(); | 753 GridLength gridLength = trackSize.fitContentTrackBreadth(); |
742 if (!gridLength.hasPercentage() || hasDefiniteFreeSpace) { | 754 if (!gridLength.hasPercentage() || hasDefiniteFreeSpace) { |
743 track.setGrowthLimitCap(valueForLength( | 755 track.setGrowthLimitCap(valueForLength( |
744 gridLength.length(), m_availableSpace.clampNegativeToZero())); | 756 gridLength.length(), m_availableSpace.value_or(LayoutUnit()))); |
745 } | 757 } |
746 } | 758 } |
747 | 759 |
748 if (trackSize.isContentSized()) | 760 if (trackSize.isContentSized()) |
749 m_contentSizedTracksIndex.push_back(i); | 761 m_contentSizedTracksIndex.push_back(i); |
750 if (trackSize.maxTrackBreadth().isFlex()) | 762 if (trackSize.maxTrackBreadth().isFlex()) |
751 m_flexibleSizedTracksIndex.push_back(i); | 763 m_flexibleSizedTracksIndex.push_back(i); |
752 } | 764 } |
753 } | 765 } |
754 | 766 |
(...skipping 17 matching lines...) Expand all Loading... |
772 | 784 |
773 if (trackSize.hasMinContentMaxTrackBreadth()) { | 785 if (trackSize.hasMinContentMaxTrackBreadth()) { |
774 track.setGrowthLimit(std::max(track.growthLimit(), | 786 track.setGrowthLimit(std::max(track.growthLimit(), |
775 m_strategy->minContentForChild(gridItem))); | 787 m_strategy->minContentForChild(gridItem))); |
776 } else if (trackSize.hasMaxContentOrAutoMaxTrackBreadth()) { | 788 } else if (trackSize.hasMaxContentOrAutoMaxTrackBreadth()) { |
777 LayoutUnit growthLimit = m_strategy->maxContentForChild(gridItem); | 789 LayoutUnit growthLimit = m_strategy->maxContentForChild(gridItem); |
778 if (trackSize.isFitContent()) { | 790 if (trackSize.isFitContent()) { |
779 growthLimit = | 791 growthLimit = |
780 std::min(growthLimit, | 792 std::min(growthLimit, |
781 valueForLength(trackSize.fitContentTrackBreadth().length(), | 793 valueForLength(trackSize.fitContentTrackBreadth().length(), |
782 m_availableSpace)); | 794 m_availableSpace.value_or(LayoutUnit()))); |
783 } | 795 } |
784 track.setGrowthLimit(std::max(track.growthLimit(), growthLimit)); | 796 track.setGrowthLimit(std::max(track.growthLimit(), growthLimit)); |
785 } | 797 } |
786 } | 798 } |
787 | 799 |
788 bool GridTrackSizingAlgorithm::spanningItemCrossesFlexibleSizedTracks( | 800 bool GridTrackSizingAlgorithm::spanningItemCrossesFlexibleSizedTracks( |
789 const GridSpan& span) const { | 801 const GridSpan& span) const { |
790 for (const auto& trackPosition : span) { | 802 for (const auto& trackPosition : span) { |
791 const GridTrackSize& trackSize = gridTrackSize(m_direction, trackPosition); | 803 const GridTrackSize& trackSize = gridTrackSize(m_direction, trackPosition); |
792 if (trackSize.minTrackBreadth().isFlex() || | 804 if (trackSize.minTrackBreadth().isFlex() || |
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1289 DCHECK(trackSize.maxTrackBreadth().isFlex()); | 1301 DCHECK(trackSize.maxTrackBreadth().isFlex()); |
1290 LayoutUnit oldBaseSize = allTracks[trackIndex].baseSize(); | 1302 LayoutUnit oldBaseSize = allTracks[trackIndex].baseSize(); |
1291 LayoutUnit newBaseSize = | 1303 LayoutUnit newBaseSize = |
1292 std::max(oldBaseSize, | 1304 std::max(oldBaseSize, |
1293 LayoutUnit(flexFraction * trackSize.maxTrackBreadth().flex())); | 1305 LayoutUnit(flexFraction * trackSize.maxTrackBreadth().flex())); |
1294 increments[i] = newBaseSize - oldBaseSize; | 1306 increments[i] = newBaseSize - oldBaseSize; |
1295 totalGrowth += increments[i]; | 1307 totalGrowth += increments[i]; |
1296 } | 1308 } |
1297 } | 1309 } |
1298 | 1310 |
1299 void GridTrackSizingAlgorithm::stretchFlexibleTracks(LayoutUnit freeSpace) { | 1311 void GridTrackSizingAlgorithm::stretchFlexibleTracks( |
| 1312 Optional<LayoutUnit> freeSpace) { |
1300 double flexFraction = m_strategy->findUsedFlexFraction( | 1313 double flexFraction = m_strategy->findUsedFlexFraction( |
1301 m_flexibleSizedTracksIndex, m_direction, freeSpace); | 1314 m_flexibleSizedTracksIndex, m_direction, freeSpace); |
1302 | 1315 |
1303 LayoutUnit totalGrowth; | 1316 LayoutUnit totalGrowth; |
1304 Vector<LayoutUnit> increments; | 1317 Vector<LayoutUnit> increments; |
1305 increments.grow(m_flexibleSizedTracksIndex.size()); | 1318 increments.grow(m_flexibleSizedTracksIndex.size()); |
1306 computeFlexSizedTracksGrowth(flexFraction, increments, totalGrowth); | 1319 computeFlexSizedTracksGrowth(flexFraction, increments, totalGrowth); |
1307 | 1320 |
1308 if (m_strategy->recomputeUsedFlexFractionIfNeeded( | 1321 if (m_strategy->recomputeUsedFlexFractionIfNeeded( |
1309 m_flexibleSizedTracksIndex, flexFraction, increments, totalGrowth)) { | 1322 m_flexibleSizedTracksIndex, flexFraction, increments, totalGrowth)) { |
1310 totalGrowth = LayoutUnit(0); | 1323 totalGrowth = LayoutUnit(0); |
1311 computeFlexSizedTracksGrowth(flexFraction, increments, totalGrowth); | 1324 computeFlexSizedTracksGrowth(flexFraction, increments, totalGrowth); |
1312 } | 1325 } |
1313 | 1326 |
1314 size_t i = 0; | 1327 size_t i = 0; |
1315 Vector<GridTrack>& allTracks = tracks(m_direction); | 1328 Vector<GridTrack>& allTracks = tracks(m_direction); |
1316 for (auto trackIndex : m_flexibleSizedTracksIndex) { | 1329 for (auto trackIndex : m_flexibleSizedTracksIndex) { |
1317 auto& track = allTracks[trackIndex]; | 1330 auto& track = allTracks[trackIndex]; |
1318 if (LayoutUnit increment = increments[i++]) | 1331 if (LayoutUnit increment = increments[i++]) |
1319 track.setBaseSize(track.baseSize() + increment); | 1332 track.setBaseSize(track.baseSize() + increment); |
1320 } | 1333 } |
1321 this->freeSpace(m_direction) -= totalGrowth; | 1334 if (this->freeSpace(m_direction)) { |
| 1335 setFreeSpace(m_direction, |
| 1336 this->freeSpace(m_direction).value() - totalGrowth); |
| 1337 } |
1322 m_maxContentSize += totalGrowth; | 1338 m_maxContentSize += totalGrowth; |
1323 } | 1339 } |
1324 | 1340 |
1325 void GridTrackSizingAlgorithm::advanceNextState() { | 1341 void GridTrackSizingAlgorithm::advanceNextState() { |
1326 switch (m_sizingState) { | 1342 switch (m_sizingState) { |
1327 case ColumnSizingFirstIteration: | 1343 case ColumnSizingFirstIteration: |
1328 m_sizingState = RowSizingFirstIteration; | 1344 m_sizingState = RowSizingFirstIteration; |
1329 return; | 1345 return; |
1330 case RowSizingFirstIteration: | 1346 case RowSizingFirstIteration: |
1331 m_sizingState = ColumnSizingSecondIteration; | 1347 m_sizingState = ColumnSizingSecondIteration; |
(...skipping 18 matching lines...) Expand all Loading... |
1350 case RowSizingSecondIteration: | 1366 case RowSizingSecondIteration: |
1351 return m_direction == ForRows; | 1367 return m_direction == ForRows; |
1352 } | 1368 } |
1353 NOTREACHED(); | 1369 NOTREACHED(); |
1354 return false; | 1370 return false; |
1355 } | 1371 } |
1356 | 1372 |
1357 void GridTrackSizingAlgorithm::setup(GridTrackSizingDirection direction, | 1373 void GridTrackSizingAlgorithm::setup(GridTrackSizingDirection direction, |
1358 size_t numTracks, | 1374 size_t numTracks, |
1359 SizingOperation sizingOperation, | 1375 SizingOperation sizingOperation, |
1360 LayoutUnit availableSpace, | 1376 Optional<LayoutUnit> availableSpace, |
1361 LayoutUnit freeSpace) { | 1377 Optional<LayoutUnit> freeSpace) { |
1362 DCHECK(m_needsSetup); | 1378 DCHECK(m_needsSetup); |
| 1379 DCHECK_EQ(!!availableSpace, !!freeSpace); |
1363 m_direction = direction; | 1380 m_direction = direction; |
1364 m_availableSpace = availableSpace; | 1381 m_availableSpace = availableSpace |
| 1382 ? availableSpace.value().clampNegativeToZero() |
| 1383 : availableSpace; |
1365 | 1384 |
1366 m_sizingOperation = sizingOperation; | 1385 m_sizingOperation = sizingOperation; |
1367 switch (m_sizingOperation) { | 1386 |
1368 case IntrinsicSizeComputation: | 1387 if (availableSpace) |
1369 m_strategy = WTF::makeUnique<IndefiniteSizeStrategy>(*this); | 1388 m_strategy = WTF::makeUnique<DefiniteSizeStrategy>(*this); |
1370 break; | 1389 else |
1371 case TrackSizing: | 1390 m_strategy = WTF::makeUnique<IndefiniteSizeStrategy>(*this); |
1372 m_strategy = WTF::makeUnique<DefiniteSizeStrategy>(*this); | |
1373 break; | |
1374 } | |
1375 | 1391 |
1376 m_contentSizedTracksIndex.shrink(0); | 1392 m_contentSizedTracksIndex.shrink(0); |
1377 m_flexibleSizedTracksIndex.shrink(0); | 1393 m_flexibleSizedTracksIndex.shrink(0); |
1378 | 1394 |
1379 this->freeSpace(direction) = freeSpace; | 1395 setFreeSpace(direction, freeSpace); |
1380 tracks(direction).resize(numTracks); | 1396 tracks(direction).resize(numTracks); |
1381 | 1397 |
1382 m_needsSetup = false; | 1398 m_needsSetup = false; |
1383 } | 1399 } |
1384 | 1400 |
1385 // Described in https://drafts.csswg.org/css-grid/#algo-track-sizing | 1401 // Described in https://drafts.csswg.org/css-grid/#algo-track-sizing |
1386 void GridTrackSizingAlgorithm::run() { | 1402 void GridTrackSizingAlgorithm::run() { |
1387 StateMachine stateMachine(*this); | 1403 StateMachine stateMachine(*this); |
1388 | 1404 |
1389 // Step 1. | 1405 // Step 1. |
1390 LayoutUnit initialFreeSpace = freeSpace(m_direction); | 1406 Optional<LayoutUnit> initialFreeSpace = freeSpace(m_direction); |
1391 initializeTrackSizes(); | 1407 initializeTrackSizes(); |
1392 | 1408 |
1393 // Step 2. | 1409 // Step 2. |
1394 if (!m_contentSizedTracksIndex.isEmpty()) | 1410 if (!m_contentSizedTracksIndex.isEmpty()) |
1395 resolveIntrinsicTrackSizes(); | 1411 resolveIntrinsicTrackSizes(); |
1396 | 1412 |
1397 // This is not exactly a step of the track sizing algorithm, but we use the | 1413 // This is not exactly a step of the track sizing algorithm, but we use the |
1398 // track sizes computed | 1414 // track sizes computed |
1399 // up to this moment (before maximization) to calculate the grid container | 1415 // up to this moment (before maximization) to calculate the grid container |
1400 // intrinsic sizes. | 1416 // intrinsic sizes. |
1401 computeGridContainerIntrinsicSizes(); | 1417 computeGridContainerIntrinsicSizes(); |
1402 freeSpace(m_direction) -= m_minContentSize; | |
1403 | 1418 |
1404 if (m_sizingOperation == TrackSizing && freeSpace(m_direction) <= 0) | 1419 if (freeSpace(m_direction)) { |
1405 return; | 1420 LayoutUnit updatedFreeSpace = |
| 1421 freeSpace(m_direction).value() - m_minContentSize; |
| 1422 setFreeSpace(m_direction, updatedFreeSpace); |
| 1423 if (updatedFreeSpace <= 0) |
| 1424 return; |
| 1425 } |
1406 | 1426 |
1407 // Step 3. | 1427 // Step 3. |
1408 m_strategy->maximizeTracks(tracks(m_direction), freeSpace(m_direction)); | 1428 m_strategy->maximizeTracks(tracks(m_direction), m_direction == ForColumns |
| 1429 ? m_freeSpaceColumns |
| 1430 : m_freeSpaceRows); |
1409 | 1431 |
1410 if (m_flexibleSizedTracksIndex.isEmpty()) | 1432 if (m_flexibleSizedTracksIndex.isEmpty()) |
1411 return; | 1433 return; |
1412 | 1434 |
1413 // Step 4. | 1435 // Step 4. |
1414 stretchFlexibleTracks(initialFreeSpace); | 1436 stretchFlexibleTracks(initialFreeSpace); |
1415 } | 1437 } |
1416 | 1438 |
1417 void GridTrackSizingAlgorithm::reset() { | 1439 void GridTrackSizingAlgorithm::reset() { |
1418 m_sizingState = ColumnSizingFirstIteration; | 1440 m_sizingState = ColumnSizingFirstIteration; |
(...skipping 21 matching lines...) Expand all Loading... |
1440 DCHECK(m_algorithm.isValidTransition()); | 1462 DCHECK(m_algorithm.isValidTransition()); |
1441 DCHECK(!m_algorithm.m_needsSetup); | 1463 DCHECK(!m_algorithm.m_needsSetup); |
1442 } | 1464 } |
1443 | 1465 |
1444 GridTrackSizingAlgorithm::StateMachine::~StateMachine() { | 1466 GridTrackSizingAlgorithm::StateMachine::~StateMachine() { |
1445 m_algorithm.advanceNextState(); | 1467 m_algorithm.advanceNextState(); |
1446 m_algorithm.m_needsSetup = true; | 1468 m_algorithm.m_needsSetup = true; |
1447 } | 1469 } |
1448 | 1470 |
1449 } // namespace blink | 1471 } // namespace blink |
OLD | NEW |