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 25 matching lines...) Expand all Loading... | |
36 | 36 |
37 namespace blink { | 37 namespace blink { |
38 | 38 |
39 static const int infinity = -1; | 39 static const int infinity = -1; |
40 | 40 |
41 class GridTrack { | 41 class GridTrack { |
42 public: | 42 public: |
43 GridTrack() | 43 GridTrack() |
44 : m_baseSize(0) | 44 : m_baseSize(0) |
45 , m_growthLimit(0) | 45 , m_growthLimit(0) |
46 , m_plannedIncrease(0) | |
46 { | 47 { |
47 } | 48 } |
48 | 49 |
49 const LayoutUnit& baseSize() const | 50 const LayoutUnit& baseSize() const |
50 { | 51 { |
51 ASSERT(isGrowthLimitBiggerThanBaseSize()); | 52 ASSERT(isGrowthLimitBiggerThanBaseSize()); |
52 return m_baseSize; | 53 return m_baseSize; |
53 } | 54 } |
54 | 55 |
55 const LayoutUnit& growthLimit() const | 56 const LayoutUnit& growthLimit() const |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
92 { | 93 { |
93 return m_growthLimit == infinity; | 94 return m_growthLimit == infinity; |
94 } | 95 } |
95 | 96 |
96 const LayoutUnit& growthLimitIfNotInfinite() const | 97 const LayoutUnit& growthLimitIfNotInfinite() const |
97 { | 98 { |
98 ASSERT(isGrowthLimitBiggerThanBaseSize()); | 99 ASSERT(isGrowthLimitBiggerThanBaseSize()); |
99 return (m_growthLimit == infinity) ? m_baseSize : m_growthLimit; | 100 return (m_growthLimit == infinity) ? m_baseSize : m_growthLimit; |
100 } | 101 } |
101 | 102 |
103 const LayoutUnit& plannedIncrease() const { return m_plannedIncrease; } | |
104 | |
105 void growPlannedIncrease(const LayoutUnit& plannedIncrease) | |
106 { | |
107 ASSERT(plannedIncrease >= 0); | |
108 m_plannedIncrease += plannedIncrease; | |
109 } | |
110 | |
111 void updateFromPlannedIncrease(RenderGrid::AccumulatorGrowFunction trackGrow thFunction) | |
112 { | |
113 if (m_plannedIncrease == 0) | |
114 return; | |
115 | |
116 (this->*trackGrowthFunction)(m_plannedIncrease); | |
117 m_plannedIncrease = 0; | |
118 } | |
119 | |
102 private: | 120 private: |
103 bool isGrowthLimitBiggerThanBaseSize() const { return growthLimitIsInfinite( ) || m_growthLimit >= m_baseSize; } | 121 bool isGrowthLimitBiggerThanBaseSize() const { return growthLimitIsInfinite( ) || m_growthLimit >= m_baseSize; } |
104 | 122 |
105 void ensureGrowthLimitIsBiggerThanBaseSize() | 123 void ensureGrowthLimitIsBiggerThanBaseSize() |
106 { | 124 { |
107 if (m_growthLimit != infinity && m_growthLimit < m_baseSize) | 125 if (m_growthLimit != infinity && m_growthLimit < m_baseSize) |
108 m_growthLimit = m_baseSize; | 126 m_growthLimit = m_baseSize; |
109 } | 127 } |
110 | 128 |
111 LayoutUnit m_baseSize; | 129 LayoutUnit m_baseSize; |
112 LayoutUnit m_growthLimit; | 130 LayoutUnit m_growthLimit; |
131 LayoutUnit m_plannedIncrease; | |
113 }; | 132 }; |
114 | 133 |
115 struct GridTrackForNormalization { | 134 struct GridTrackForNormalization { |
116 GridTrackForNormalization(const GridTrack& track, double flex) | 135 GridTrackForNormalization(const GridTrack& track, double flex) |
117 : m_track(&track) | 136 : m_track(&track) |
118 , m_flex(flex) | 137 , m_flex(flex) |
119 , m_normalizedFlexValue(track.baseSize() / flex) | 138 , m_normalizedFlexValue(track.baseSize() / flex) |
120 { | 139 { |
121 } | 140 } |
122 | 141 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
221 : columnTracks(gridColumnCount) | 240 : columnTracks(gridColumnCount) |
222 , rowTracks(gridRowCount) | 241 , rowTracks(gridRowCount) |
223 { | 242 { |
224 } | 243 } |
225 | 244 |
226 Vector<GridTrack> columnTracks; | 245 Vector<GridTrack> columnTracks; |
227 Vector<GridTrack> rowTracks; | 246 Vector<GridTrack> rowTracks; |
228 Vector<size_t> contentSizedTracksIndex; | 247 Vector<size_t> contentSizedTracksIndex; |
229 | 248 |
230 // Performance optimization: hold onto these Vectors until the end of Layout to avoid repeated malloc / free. | 249 // Performance optimization: hold onto these Vectors until the end of Layout to avoid repeated malloc / free. |
231 Vector<LayoutUnit> distributeTrackVector; | |
232 Vector<GridTrack*> filteredTracks; | 250 Vector<GridTrack*> filteredTracks; |
233 WillBeHeapVector<GridItemWithSpan> itemsSortedByIncreasingSpan; | 251 WillBeHeapVector<GridItemWithSpan> itemsSortedByIncreasingSpan; |
234 Vector<size_t> growAboveMaxBreadthTrackIndexes; | 252 Vector<GridTrack*> growBeyondGrowthLimitsTracks; |
235 }; | 253 }; |
236 | 254 |
237 RenderGrid::RenderGrid(Element* element) | 255 RenderGrid::RenderGrid(Element* element) |
238 : RenderBlock(element) | 256 : RenderBlock(element) |
239 , m_gridIsDirty(true) | 257 , m_gridIsDirty(true) |
240 , m_orderIterator(this) | 258 , m_orderIterator(this) |
241 { | 259 { |
242 ASSERT(!childrenInline()); | 260 ASSERT(!childrenInline()); |
243 } | 261 } |
244 | 262 |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
431 return; | 449 return; |
432 | 450 |
433 // 3. Grow all Grid tracks in GridTracks from their UsedBreadth up to their MaxBreadth value until | 451 // 3. Grow all Grid tracks in GridTracks from their UsedBreadth up to their MaxBreadth value until |
434 // availableLogicalSpace (RemainingSpace in the specs) is exhausted. | 452 // availableLogicalSpace (RemainingSpace in the specs) is exhausted. |
435 const size_t tracksSize = tracks.size(); | 453 const size_t tracksSize = tracks.size(); |
436 if (!hasUndefinedRemainingSpace) { | 454 if (!hasUndefinedRemainingSpace) { |
437 Vector<GridTrack*> tracksForDistribution(tracksSize); | 455 Vector<GridTrack*> tracksForDistribution(tracksSize); |
438 for (size_t i = 0; i < tracksSize; ++i) | 456 for (size_t i = 0; i < tracksSize; ++i) |
439 tracksForDistribution[i] = tracks.data() + i; | 457 tracksForDistribution[i] = tracks.data() + i; |
440 | 458 |
441 distributeSpaceToTracks(tracksForDistribution, 0, &GridTrack::baseSize, &GridTrack::growBaseSize, sizingData, availableLogicalSpace); | 459 distributeSpaceToTracks(tracksForDistribution, nullptr, &GridTrack::base Size, &GridTrack::growBaseSize, sizingData, availableLogicalSpace); |
442 } else { | 460 } else { |
443 for (auto& track : tracks) | 461 for (auto& track : tracks) |
444 track.setBaseSize(track.growthLimit()); | 462 track.setBaseSize(track.growthLimit()); |
445 } | 463 } |
446 | 464 |
447 if (flexibleSizedTracksIndex.isEmpty()) | 465 if (flexibleSizedTracksIndex.isEmpty()) |
448 return; | 466 return; |
449 | 467 |
450 // 4. Grow all Grid tracks having a fraction as the MaxTrackSizingFunction. | 468 // 4. Grow all Grid tracks having a fraction as the MaxTrackSizingFunction. |
451 double normalizedFractionBreadth = 0; | 469 double normalizedFractionBreadth = 0; |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
746 track.setGrowthLimit(std::max(track.growthLimit(), maxContentForChild(gr idItem, direction, columnTracks))); | 764 track.setGrowthLimit(std::max(track.growthLimit(), maxContentForChild(gr idItem, direction, columnTracks))); |
747 } | 765 } |
748 | 766 |
749 void RenderGrid::resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizing Direction direction, GridSizingData& sizingData, GridItemWithSpan& gridItemWithS pan, FilterFunction filterFunction, SizingFunction sizingFunction, AccumulatorGe tter trackGetter, AccumulatorGrowFunction trackGrowthFunction, FilterFunction gr owAboveMaxBreadthFilterFunction) | 767 void RenderGrid::resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizing Direction direction, GridSizingData& sizingData, GridItemWithSpan& gridItemWithS pan, FilterFunction filterFunction, SizingFunction sizingFunction, AccumulatorGe tter trackGetter, AccumulatorGrowFunction trackGrowthFunction, FilterFunction gr owAboveMaxBreadthFilterFunction) |
750 { | 768 { |
751 ASSERT(gridItemWithSpan.span() > 1); | 769 ASSERT(gridItemWithSpan.span() > 1); |
752 const GridCoordinate coordinate = gridItemWithSpan.coordinate(); | 770 const GridCoordinate coordinate = gridItemWithSpan.coordinate(); |
753 const GridResolvedPosition initialTrackPosition = (direction == ForColumns) ? coordinate.columns.resolvedInitialPosition : coordinate.rows.resolvedInitialPo sition; | 771 const GridResolvedPosition initialTrackPosition = (direction == ForColumns) ? coordinate.columns.resolvedInitialPosition : coordinate.rows.resolvedInitialPo sition; |
754 const GridResolvedPosition finalTrackPosition = (direction == ForColumns) ? coordinate.columns.resolvedFinalPosition : coordinate.rows.resolvedFinalPosition ; | 772 const GridResolvedPosition finalTrackPosition = (direction == ForColumns) ? coordinate.columns.resolvedFinalPosition : coordinate.rows.resolvedFinalPosition ; |
755 | 773 |
756 sizingData.growAboveMaxBreadthTrackIndexes.shrink(0); | 774 sizingData.growBeyondGrowthLimitsTracks.shrink(0); |
757 sizingData.filteredTracks.shrink(0); | 775 sizingData.filteredTracks.shrink(0); |
758 for (GridResolvedPosition trackPosition = initialTrackPosition; trackPositio n <= finalTrackPosition; ++trackPosition) { | 776 for (GridResolvedPosition trackPosition = initialTrackPosition; trackPositio n <= finalTrackPosition; ++trackPosition) { |
759 GridTrackSize trackSize = gridTrackSize(direction, trackPosition.toInt() ); | 777 GridTrackSize trackSize = gridTrackSize(direction, trackPosition.toInt() ); |
760 if (!(trackSize.*filterFunction)()) | 778 if (!(trackSize.*filterFunction)()) |
761 continue; | 779 continue; |
762 | 780 |
763 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[t rackPosition.toInt()] : sizingData.rowTracks[trackPosition.toInt()]; | 781 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[t rackPosition.toInt()] : sizingData.rowTracks[trackPosition.toInt()]; |
764 sizingData.filteredTracks.append(&track); | 782 sizingData.filteredTracks.append(&track); |
765 | 783 |
766 if (growAboveMaxBreadthFilterFunction && (trackSize.*growAboveMaxBreadth FilterFunction)()) | 784 if (!growAboveMaxBreadthFilterFunction || (trackSize.*growAboveMaxBreadt hFilterFunction)()) |
767 sizingData.growAboveMaxBreadthTrackIndexes.append(sizingData.filtere dTracks.size() - 1); | 785 sizingData.growBeyondGrowthLimitsTracks.append(&track); |
768 } | 786 } |
769 | 787 |
770 if (sizingData.filteredTracks.isEmpty()) | 788 if (sizingData.filteredTracks.isEmpty()) |
771 return; | 789 return; |
772 | 790 |
773 LayoutUnit additionalBreadthSpace = (this->*sizingFunction)(gridItemWithSpan .gridItem(), direction, sizingData.columnTracks); | 791 LayoutUnit extraSpace = (this->*sizingFunction)(gridItemWithSpan.gridItem(), direction, sizingData.columnTracks); |
774 for (GridResolvedPosition trackIndexForSpace = initialTrackPosition; trackIn dexForSpace <= finalTrackPosition; ++trackIndexForSpace) { | 792 for (GridResolvedPosition trackIndexForSpace = initialTrackPosition; trackIn dexForSpace <= finalTrackPosition; ++trackIndexForSpace) { |
775 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[t rackIndexForSpace.toInt()] : sizingData.rowTracks[trackIndexForSpace.toInt()]; | 793 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[t rackIndexForSpace.toInt()] : sizingData.rowTracks[trackIndexForSpace.toInt()]; |
776 additionalBreadthSpace -= (track.*trackGetter)(); | 794 extraSpace -= (track.*trackGetter)(); |
777 } | 795 } |
778 | 796 |
779 // Specs mandate to floor additionalBreadthSpace (extra-space in specs) to 0 . Instead we directly avoid the function | 797 // Specs mandate to floor additionalBreadthSpace (extra-space in specs) to 0 . Instead we directly avoid the function |
Julien - ping for review
2015/01/23 10:20:12
The comment still talks about |additionalBreadthSp
| |
780 // call in those cases as it will be a noop in terms of track sizing. | 798 // call in those cases as it will be a noop in terms of track sizing. |
781 if (additionalBreadthSpace > 0) | 799 if (extraSpace > 0) { |
782 distributeSpaceToTracks(sizingData.filteredTracks, &sizingData.growAbove MaxBreadthTrackIndexes, trackGetter, trackGrowthFunction, sizingData, additional BreadthSpace); | 800 Vector<GridTrack*>* tracksToGrowBeyondGrowthLimits = sizingData.growBeyo ndGrowthLimitsTracks.isEmpty() ? &sizingData.filteredTracks : &sizingData.growBe yondGrowthLimitsTracks; |
801 distributeSpaceToTracks(sizingData.filteredTracks, tracksToGrowBeyondGro wthLimits, trackGetter, trackGrowthFunction, sizingData, extraSpace); | |
802 } | |
783 } | 803 } |
784 | 804 |
785 static bool sortByGridTrackGrowthPotential(const GridTrack* track1, const GridTr ack* track2) | 805 static bool sortByGridTrackGrowthPotential(const GridTrack* track1, const GridTr ack* track2) |
786 { | 806 { |
787 // This check ensures that we respect the irreflexivity property of the stri ct weak ordering required by std::sort | 807 // This check ensures that we respect the irreflexivity property of the stri ct weak ordering required by std::sort |
788 // (forall x: NOT x < x). | 808 // (forall x: NOT x < x). |
789 if (track1->growthLimitIsInfinite() && track2->growthLimitIsInfinite()) | 809 if (track1->growthLimitIsInfinite() && track2->growthLimitIsInfinite()) |
790 return false; | 810 return false; |
791 | 811 |
792 if (track1->growthLimitIsInfinite() || track2->growthLimitIsInfinite()) | 812 if (track1->growthLimitIsInfinite() || track2->growthLimitIsInfinite()) |
793 return track2->growthLimitIsInfinite(); | 813 return track2->growthLimitIsInfinite(); |
794 | 814 |
795 return (track1->growthLimit() - track1->baseSize()) < (track2->growthLimit() - track2->baseSize()); | 815 return (track1->growthLimit() - track1->baseSize()) < (track2->growthLimit() - track2->baseSize()); |
796 } | 816 } |
797 | 817 |
798 void RenderGrid::distributeSpaceToTracks(Vector<GridTrack*>& tracks, Vector<size _t>* growAboveMaxBreadthTrackIndexes, AccumulatorGetter trackGetter, Accumulator GrowFunction trackGrowthFunction, GridSizingData& sizingData, LayoutUnit& availa bleLogicalSpace) | 818 void RenderGrid::distributeSpaceToTracks(Vector<GridTrack*>& tracks, const Vecto r<GridTrack*>* growBeyondGrowthLimitsTracks, AccumulatorGetter trackGetter, Accu mulatorGrowFunction trackGrowthFunction, GridSizingData& sizingData, LayoutUnit& availableLogicalSpace) |
799 { | 819 { |
800 ASSERT(availableLogicalSpace > 0); | 820 ASSERT(availableLogicalSpace > 0); |
801 std::sort(tracks.begin(), tracks.end(), sortByGridTrackGrowthPotential); | 821 std::sort(tracks.begin(), tracks.end(), sortByGridTrackGrowthPotential); |
802 | 822 |
803 size_t tracksSize = tracks.size(); | 823 size_t tracksSize = tracks.size(); |
804 sizingData.distributeTrackVector.resize(tracksSize); | |
805 | |
806 for (size_t i = 0; i < tracksSize; ++i) { | 824 for (size_t i = 0; i < tracksSize; ++i) { |
Julien - ping for review
2015/01/23 10:20:12
How about we use a C++11 auto loop here too?
svillar
2015/01/23 13:44:10
I did it in the first patch but you said "The patt
| |
807 GridTrack& track = *tracks[i]; | 825 GridTrack& track = *tracks[i]; |
826 ASSERT(track.plannedIncrease() == 0); | |
808 LayoutUnit availableLogicalSpaceShare = availableLogicalSpace / (tracksS ize - i); | 827 LayoutUnit availableLogicalSpaceShare = availableLogicalSpace / (tracksS ize - i); |
809 const LayoutUnit& trackBreadth = (tracks[i]->*trackGetter)(); | 828 const LayoutUnit& trackBreadth = (track.*trackGetter)(); |
810 LayoutUnit growthShare = track.growthLimitIsInfinite() ? availableLogica lSpaceShare : std::min(availableLogicalSpaceShare, track.growthLimit() - trackBr eadth); | 829 LayoutUnit growthShare = track.growthLimitIsInfinite() ? availableLogica lSpaceShare : std::min(availableLogicalSpaceShare, track.growthLimit() - trackBr eadth); |
811 sizingData.distributeTrackVector[i] = trackBreadth; | |
812 // We should never shrink any grid track or else we can't guarantee we a bide by our min-sizing function. | 830 // We should never shrink any grid track or else we can't guarantee we a bide by our min-sizing function. |
813 if (growthShare > 0) { | 831 if (growthShare > 0) { |
814 sizingData.distributeTrackVector[i] += growthShare; | 832 track.growPlannedIncrease(growthShare); |
815 availableLogicalSpace -= growthShare; | 833 availableLogicalSpace -= growthShare; |
816 } | 834 } |
817 } | 835 } |
818 | 836 |
819 if (availableLogicalSpace > 0 && growAboveMaxBreadthTrackIndexes) { | 837 if (availableLogicalSpace > 0 && growBeyondGrowthLimitsTracks) { |
820 size_t indexesSize = growAboveMaxBreadthTrackIndexes->size(); | 838 size_t tracksGrowingAboveMaxBreadthSize = growBeyondGrowthLimitsTracks-> size(); |
821 size_t tracksGrowingAboveMaxBreadthSize = indexesSize ? indexesSize : tr acksSize; | |
822 // If we have a non-null empty vector of track indexes to grow above max breadth means that we should grow all | |
823 // affected tracks. | |
824 for (size_t i = 0; i < tracksGrowingAboveMaxBreadthSize; ++i) { | 839 for (size_t i = 0; i < tracksGrowingAboveMaxBreadthSize; ++i) { |
840 GridTrack* track = growBeyondGrowthLimitsTracks->at(i); | |
825 LayoutUnit growthShare = availableLogicalSpace / (tracksGrowingAbove MaxBreadthSize - i); | 841 LayoutUnit growthShare = availableLogicalSpace / (tracksGrowingAbove MaxBreadthSize - i); |
826 size_t distributeTrackIndex = indexesSize ? growAboveMaxBreadthTrack Indexes->at(i) : i; | 842 track->growPlannedIncrease(growthShare); |
827 sizingData.distributeTrackVector[distributeTrackIndex] += growthShar e; | |
828 availableLogicalSpace -= growthShare; | 843 availableLogicalSpace -= growthShare; |
829 } | 844 } |
830 } | 845 } |
831 | 846 |
832 for (size_t i = 0; i < tracksSize; ++i) { | 847 for (auto* track: tracks) { |
833 LayoutUnit growth = sizingData.distributeTrackVector[i] - (tracks[i]->*t rackGetter)(); | 848 track->updateFromPlannedIncrease(trackGrowthFunction); |
834 if (growth >= 0) | 849 ASSERT(track->plannedIncrease() == 0); |
835 (tracks[i]->*trackGrowthFunction)(growth); | |
836 } | 850 } |
837 } | 851 } |
838 | 852 |
839 #if ENABLE(ASSERT) | 853 #if ENABLE(ASSERT) |
840 bool RenderGrid::tracksAreWiderThanMinTrackBreadth(GridTrackSizingDirection dire ction, const Vector<GridTrack>& tracks) | 854 bool RenderGrid::tracksAreWiderThanMinTrackBreadth(GridTrackSizingDirection dire ction, const Vector<GridTrack>& tracks) |
841 { | 855 { |
842 for (size_t i = 0; i < tracks.size(); ++i) { | 856 for (size_t i = 0; i < tracks.size(); ++i) { |
843 GridTrackSize trackSize = gridTrackSize(direction, i); | 857 GridTrackSize trackSize = gridTrackSize(direction, i); |
844 const GridLength& minTrackBreadth = trackSize.minTrackBreadth(); | 858 const GridLength& minTrackBreadth = trackSize.minTrackBreadth(); |
845 if (computeUsedBreadthOfMinLength(direction, minTrackBreadth) > tracks[i ].baseSize()) | 859 if (computeUsedBreadthOfMinLength(direction, minTrackBreadth) > tracks[i ].baseSize()) |
(...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1659 if (isOutOfFlowPositioned()) | 1673 if (isOutOfFlowPositioned()) |
1660 return "RenderGrid (positioned)"; | 1674 return "RenderGrid (positioned)"; |
1661 if (isAnonymous()) | 1675 if (isAnonymous()) |
1662 return "RenderGrid (generated)"; | 1676 return "RenderGrid (generated)"; |
1663 if (isRelPositioned()) | 1677 if (isRelPositioned()) |
1664 return "RenderGrid (relative positioned)"; | 1678 return "RenderGrid (relative positioned)"; |
1665 return "RenderGrid"; | 1679 return "RenderGrid"; |
1666 } | 1680 } |
1667 | 1681 |
1668 } // namespace blink | 1682 } // namespace blink |
OLD | NEW |