Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #ifndef GridTrackSizingAlgorithm_h | |
| 2 #define GridTrackSizingAlgorithm_h | |
| 3 | |
| 4 #include "core/style/GridPositionsResolver.h" | |
| 5 #include "core/style/GridTrackSize.h" | |
| 6 #include "platform/LayoutUnit.h" | |
| 7 #include "wtf/HashSet.h" | |
| 8 #include "wtf/Optional.h" | |
| 9 #include <memory> | |
| 10 | |
| 11 namespace blink { | |
| 12 | |
| 13 static const int infinity = -1; | |
| 14 | |
| 15 class Grid; | |
| 16 class GridTrackSizingAlgorithmStrategy; | |
| 17 class LayoutGrid; | |
| 18 | |
| 19 enum SizingOperation { TrackSizing, IntrinsicSizeComputation }; | |
| 20 | |
| 21 enum TrackSizeComputationPhase { | |
| 22 ResolveIntrinsicMinimums, | |
| 23 ResolveContentBasedMinimums, | |
| 24 ResolveMaxContentMinimums, | |
| 25 ResolveIntrinsicMaximums, | |
| 26 ResolveMaxContentMaximums, | |
| 27 MaximizeTracks, | |
| 28 }; | |
| 29 | |
| 30 class GridTrack { | |
| 31 public: | |
| 32 GridTrack() : m_infinitelyGrowable(false) {} | |
| 33 | |
| 34 LayoutUnit baseSize() const; | |
| 35 void setBaseSize(LayoutUnit); | |
| 36 | |
| 37 LayoutUnit growthLimit() const; | |
| 38 void setGrowthLimit(LayoutUnit); | |
| 39 | |
| 40 bool infiniteGrowthPotential() const { | |
| 41 return growthLimitIsInfinite() || m_infinitelyGrowable; | |
| 42 } | |
| 43 | |
| 44 LayoutUnit plannedSize() const { return m_plannedSize; } | |
| 45 void setPlannedSize(const LayoutUnit&); | |
|
jfernandez
2017/01/30 08:48:49
Why we use a const LayoutUnit reference as input a
svillar
2017/01/30 09:35:45
Yeah it does not really pay off, but I didn't chan
| |
| 46 | |
| 47 LayoutUnit sizeDuringDistribution() const { return m_sizeDuringDistribution; } | |
| 48 void setSizeDuringDistribution(const LayoutUnit&); | |
|
jfernandez
2017/01/30 08:48:49
ditto
| |
| 49 | |
| 50 void growSizeDuringDistribution(const LayoutUnit&); | |
|
jfernandez
2017/01/30 08:48:49
ditto
| |
| 51 | |
| 52 bool infinitelyGrowable() const { return m_infinitelyGrowable; } | |
| 53 void setInfinitelyGrowable(bool infinitelyGrowable) { | |
| 54 m_infinitelyGrowable = infinitelyGrowable; | |
| 55 } | |
| 56 | |
| 57 Optional<LayoutUnit> growthLimitCap() const { return m_growthLimitCap; } | |
| 58 void setGrowthLimitCap(Optional<LayoutUnit>); | |
| 59 | |
| 60 private: | |
| 61 bool growthLimitIsInfinite() const { return m_growthLimit == infinity; } | |
| 62 bool isGrowthLimitBiggerThanBaseSize() const; | |
| 63 void ensureGrowthLimitIsBiggerThanBaseSize(); | |
| 64 | |
| 65 LayoutUnit m_baseSize; | |
| 66 LayoutUnit m_growthLimit; | |
| 67 LayoutUnit m_plannedSize; | |
| 68 LayoutUnit m_sizeDuringDistribution; | |
| 69 Optional<LayoutUnit> m_growthLimitCap; | |
| 70 bool m_infinitelyGrowable; | |
| 71 }; | |
| 72 | |
| 73 class GridTrackSizingAlgorithm final { | |
| 74 public: | |
| 75 GridTrackSizingAlgorithm(const LayoutGrid* layoutGrid, Grid& grid) | |
|
jfernandez
2017/01/30 08:48:49
Wouldn't be better to use a reference ? I guess la
svillar
2017/01/30 09:35:45
Same reason here, we need to use the "this" pointe
| |
| 76 : m_grid(grid), | |
| 77 m_layoutGrid(layoutGrid), | |
| 78 m_sizingState(ColumnSizingFirstIteration) {} | |
| 79 | |
| 80 // setup() must be run before calling run() as it configures the behaviour of | |
| 81 // the algorithm. | |
| 82 void setup(GridTrackSizingDirection, | |
| 83 size_t numTracks, | |
| 84 SizingOperation, | |
| 85 LayoutUnit availableSpace, | |
| 86 LayoutUnit freeSpace); | |
| 87 void run(); | |
| 88 void reset(); | |
| 89 | |
| 90 // Required by LayoutGrid. Try to minimize the exposed surface. | |
| 91 const Grid& grid() const { return m_grid; } | |
| 92 GridTrackSize gridTrackSize(GridTrackSizingDirection, | |
| 93 size_t translatedIndex, | |
| 94 SizingOperation) const; | |
| 95 LayoutUnit minContentSize() const { return m_minContentSize; }; | |
| 96 LayoutUnit maxContentSize() const { return m_maxContentSize; }; | |
| 97 | |
| 98 Vector<GridTrack>& tracks(GridTrackSizingDirection); | |
| 99 const Vector<GridTrack>& tracks(GridTrackSizingDirection) const; | |
| 100 | |
| 101 LayoutUnit& freeSpace(GridTrackSizingDirection direction) { | |
|
jfernandez
2017/01/30 08:48:49
Why we return a reference here ?
svillar
2017/01/30 09:35:45
This hasn't changed. The reason is because some fu
Manuel Rego
2017/01/30 11:00:46
Just a suggestion, maybe we could rename the metho
svillar
2017/01/30 11:28:29
I don't think the problem is the name. As mentione
| |
| 102 return direction == ForRows ? m_freeSpaceRows : m_freeSpaceColumns; | |
| 103 } | |
| 104 | |
| 105 #if DCHECK_IS_ON() | |
| 106 bool tracksAreWiderThanMinTrackBreadth() const; | |
| 107 #endif | |
| 108 | |
| 109 private: | |
| 110 GridTrackSize gridTrackSize(GridTrackSizingDirection, | |
| 111 size_t translatedIndex) const; | |
| 112 GridTrackSize rawGridTrackSize(GridTrackSizingDirection, | |
| 113 size_t translatedIndex) const; | |
| 114 LayoutUnit assumedRowsSizeForOrthogonalChild(const LayoutBox&) const; | |
| 115 LayoutUnit computeTrackBasedSize() const; | |
| 116 | |
| 117 // Helper methods for step 1. initializeTrackSizes(). | |
| 118 LayoutUnit initialBaseSize(const GridTrackSize&) const; | |
| 119 LayoutUnit initialGrowthLimit(const GridTrackSize&, | |
| 120 LayoutUnit baseSize) const; | |
| 121 | |
| 122 // Helper methods for step 2. resolveIntrinsicTrackSizes(). | |
| 123 void sizeTrackToFitNonSpanningItem(const GridSpan&, | |
| 124 LayoutBox& gridItem, | |
| 125 GridTrack&); | |
| 126 bool spanningItemCrossesFlexibleSizedTracks(const GridSpan&) const; | |
| 127 typedef struct GridItemsSpanGroupRange GridItemsSpanGroupRange; | |
| 128 template <TrackSizeComputationPhase phase> | |
| 129 void increaseSizesToAccommodateSpanningItems( | |
| 130 const GridItemsSpanGroupRange& gridItemsWithSpan); | |
| 131 LayoutUnit itemSizeForTrackSizeComputationPhase(TrackSizeComputationPhase, | |
| 132 LayoutBox&) const; | |
| 133 template <TrackSizeComputationPhase phase> | |
| 134 void distributeSpaceToTracks(Vector<GridTrack*>& tracks, | |
| 135 Vector<GridTrack*>* growBeyondGrowthLimitsTracks, | |
| 136 LayoutUnit& availableLogicalSpace) const; | |
| 137 LayoutUnit gridAreaBreadthForChild(const LayoutBox&, | |
| 138 GridTrackSizingDirection); | |
| 139 | |
| 140 void computeGridContainerIntrinsicSizes(); | |
| 141 | |
| 142 // Helper methods for step 4. | |
| 143 typedef HashSet<size_t, | |
| 144 DefaultHash<size_t>::Hash, | |
| 145 WTF::UnsignedWithZeroKeyHashTraits<size_t>> | |
| 146 TrackIndexSet; | |
| 147 double computeFlexFactorUnitSize( | |
| 148 const Vector<GridTrack>& tracks, | |
| 149 double flexFactorSum, | |
| 150 LayoutUnit& leftOverSpace, | |
| 151 const Vector<size_t, 8>& flexibleTracksIndexes, | |
| 152 std::unique_ptr<TrackIndexSet> tracksToTreatAsInflexible = nullptr) const; | |
| 153 void computeFlexSizedTracksGrowth(double flexFraction, | |
| 154 Vector<LayoutUnit>& increments, | |
| 155 LayoutUnit& totalGrowth) const; | |
| 156 double findFrUnitSize(const GridSpan& tracksSpan, | |
| 157 LayoutUnit leftOverSpace) const; | |
| 158 | |
| 159 // Track sizing algorithm steps. | |
|
Manuel Rego
2017/01/30 11:00:46
Here I see 3 steps.
But before I see helper method
svillar
2017/01/30 11:28:29
Because the maximizeTracks step is done entirely i
| |
| 160 void initializeTrackSizes(); | |
| 161 void resolveIntrinsicTrackSizes(); | |
| 162 void stretchFlexibleTracks(LayoutUnit freeSpace); | |
| 163 | |
| 164 // State machine. | |
| 165 void advanceNextState(); | |
| 166 bool isValidTransition() const; | |
| 167 | |
| 168 // Data. | |
| 169 bool m_needsSetup{true}; | |
| 170 LayoutUnit m_availableSpace; | |
| 171 | |
| 172 LayoutUnit m_freeSpaceColumns; | |
| 173 LayoutUnit m_freeSpaceRows; | |
| 174 | |
| 175 // We need to keep both alive in order to properly size grids with orthogonal | |
| 176 // writing modes. | |
| 177 Vector<GridTrack> m_columns; | |
| 178 Vector<GridTrack> m_rows; | |
| 179 Vector<size_t> m_contentSizedTracksIndex; | |
| 180 Vector<size_t> m_flexibleSizedTracksIndex; | |
| 181 | |
| 182 GridTrackSizingDirection m_direction; | |
| 183 SizingOperation m_sizingOperation; | |
|
jfernandez
2017/01/30 08:48:49
Wouldn't make sense to initialize this field ?
svillar
2017/01/30 09:35:45
I don't think so. You need to specify it in the se
| |
| 184 | |
| 185 Grid& m_grid; | |
| 186 | |
| 187 const LayoutGrid* m_layoutGrid; | |
|
jfernandez
2017/01/30 08:48:49
Why not using a reference here ?
svillar
2017/01/30 09:35:45
See comments about the "this" pointer.
| |
| 188 std::unique_ptr<GridTrackSizingAlgorithmStrategy> m_strategy; | |
| 189 | |
| 190 // The track sizing algorithm is used for both layout and intrinsic size | |
|
jfernandez
2017/01/30 08:48:48
I think these comments need some formatting.
svillar
2017/01/30 09:35:45
Acknowledged.
| |
| 191 // computation. We're | |
| 192 // normally just interested in intrinsic inline sizes (a.k.a widths in most of | |
| 193 // the cases) for the | |
| 194 // computeIntrinsicLogicalWidths() computations. That's why we don't need to | |
| 195 // keep around different | |
| 196 // values for rows/columns. | |
| 197 LayoutUnit m_minContentSize; | |
| 198 LayoutUnit m_maxContentSize; | |
| 199 | |
| 200 enum SizingState { | |
| 201 ColumnSizingFirstIteration, | |
| 202 RowSizingFirstIteration, | |
| 203 ColumnSizingSecondIteration, | |
| 204 RowSizingSecondIteration | |
| 205 }; | |
| 206 SizingState m_sizingState; | |
| 207 | |
| 208 // This is a RAII class used to ensure that the track sizing algorithm is | |
|
jfernandez
2017/01/30 08:48:49
need some formatting ?
svillar
2017/01/30 09:35:45
Acknowledged.
| |
| 209 // executed as it is | |
| 210 // suppossed to be, i.e., first resolve columns and then rows. Only if | |
| 211 // required a second iteration | |
| 212 // is run following the same order, first columns and then rows. | |
| 213 class GridTrackSizingAlgorithmMachineState { | |
| 214 public: | |
| 215 GridTrackSizingAlgorithmMachineState(GridTrackSizingAlgorithm& algorithm) | |
| 216 : m_algorithm(algorithm) { | |
| 217 DCHECK(m_algorithm.isValidTransition()); | |
| 218 DCHECK(!m_algorithm.m_needsSetup); | |
| 219 } | |
| 220 | |
| 221 ~GridTrackSizingAlgorithmMachineState() { | |
| 222 m_algorithm.advanceNextState(); | |
|
jfernandez
2017/01/30 08:48:48
Why we need to call advanceNextState() when destro
svillar
2017/01/30 09:35:45
Because that's how this class works. It's created
| |
| 223 m_algorithm.m_needsSetup = true; | |
| 224 } | |
| 225 | |
| 226 private: | |
| 227 GridTrackSizingAlgorithm& m_algorithm; | |
| 228 }; | |
| 229 | |
| 230 friend class GridTrackSizingAlgorithmStrategy; | |
| 231 }; | |
| 232 | |
| 233 class GridTrackSizingAlgorithmStrategy { | |
| 234 WTF_MAKE_NONCOPYABLE(GridTrackSizingAlgorithmStrategy); | |
| 235 USING_FAST_MALLOC(GridTrackSizingAlgorithmStrategy); | |
| 236 | |
| 237 public: | |
| 238 virtual LayoutUnit minContentForChild(LayoutBox& child); | |
|
jfernandez
2017/01/30 08:48:49
the argument name is not needed.
svillar
2017/01/30 09:35:45
Acknowledged.
| |
| 239 virtual LayoutUnit maxContentForChild(LayoutBox& child) const; | |
| 240 virtual LayoutUnit minSizeForChild(LayoutBox& child); | |
| 241 | |
| 242 virtual void maximizeTracks(Vector<GridTrack>&, LayoutUnit& freeSpace); | |
|
jfernandez
2017/01/30 08:48:48
Why freeSpace is a reference ?
svillar
2017/01/30 09:35:45
Because the maximize operation reduces the free sp
| |
| 243 virtual double findUsedFlexFraction(Vector<size_t>& flexibleSizedTracksIndex, | |
| 244 GridTrackSizingDirection, | |
| 245 LayoutUnit initialFreeSpace) const; | |
| 246 virtual bool recomputeUsedFlexFractionIfNeeded( | |
| 247 Vector<size_t>& flexibleSizedTracksIndex, | |
| 248 double& flexFraction, | |
| 249 Vector<LayoutUnit>& increments, | |
| 250 LayoutUnit& totalGrowth) const; | |
| 251 | |
| 252 protected: | |
| 253 GridTrackSizingAlgorithmStrategy(GridTrackSizingAlgorithm& algorithm) | |
| 254 : m_algorithm(algorithm) {} | |
| 255 | |
| 256 LayoutUnit logicalHeightForChild(LayoutBox&) const; | |
| 257 | |
| 258 bool updateOverrideContainingBlockContentSizeForChild( | |
| 259 LayoutBox&, | |
| 260 GridTrackSizingDirection) const; | |
| 261 LayoutUnit computeTrackBasedSize() const { | |
| 262 return m_algorithm.computeTrackBasedSize(); | |
| 263 } | |
| 264 GridTrackSizingDirection direction() const { return m_algorithm.m_direction; } | |
| 265 double findFrUnitSize(const GridSpan& tracksSpan, | |
| 266 LayoutUnit leftOverSpace) const { | |
| 267 return m_algorithm.findFrUnitSize(tracksSpan, leftOverSpace); | |
| 268 } | |
| 269 void distributeSpaceToTracks(Vector<GridTrack*>& tracks, | |
| 270 LayoutUnit& availableLogicalSpace) const { | |
| 271 m_algorithm.distributeSpaceToTracks<MaximizeTracks>(tracks, nullptr, | |
| 272 availableLogicalSpace); | |
| 273 } | |
| 274 const LayoutGrid* layoutGrid() const { return m_algorithm.m_layoutGrid; } | |
| 275 | |
| 276 GridTrackSizingAlgorithm& m_algorithm; | |
| 277 }; | |
| 278 } | |
| 279 | |
| 280 #endif // GridTrackSizingAlgorithm_h | |
| OLD | NEW |