Commit 55b4817a authored by svillar's avatar svillar Committed by Commit bot

[css-grid] Use Optional to represent indefinite lengths

Blink has been using LayoutUnit(-1) to represent indefinite sizes or more in
general, sizes that cannot be resolved. That's unfortunate because it forces
us to use that magic number and also because negative LayoutUnits are valid
outcomes of some operations.

In our particular case, that was forcing us to check the SizingOperation
argument in the GridTrackSizingAlgorithm to know whether the passed
available and free sizes where actually indefinite or not. Actually that was
not totally correct as this was based on the assumption that we were doing
intrinsic size computations (preferred widths) whenever the sizes where
indefinite which is not correct for all the cases (it's true for widths but
a height:auto grid container would have indefinite height and require
indefinite size computations).

This does not require any additional tests as we are not changing any
behaviour. It's a step forward in the process of decoupling the concepts of
definite/indefinite sizes and intrinsicSize/layout operations.

Review-Url: https://codereview.chromium.org/2808453002
Cr-Commit-Position: refs/heads/master@{#462881}
parent e148e7ab
......@@ -88,10 +88,11 @@ class IndefiniteSizeStrategy final : public GridTrackSizingAlgorithmStrategy {
void layoutGridItemForMinSizeComputation(
LayoutBox&,
bool overrideSizeHasChanged) const override;
void maximizeTracks(Vector<GridTrack>&, LayoutUnit& freeSpace) override;
void maximizeTracks(Vector<GridTrack>&,
Optional<LayoutUnit>& freeSpace) override;
double findUsedFlexFraction(Vector<size_t>& flexibleSizedTracksIndex,
GridTrackSizingDirection,
LayoutUnit freeSpace) const override;
Optional<LayoutUnit> freeSpace) const override;
bool recomputeUsedFlexFractionIfNeeded(
Vector<size_t>& flexibleSizedTracksIndex,
double& flexFraction,
......@@ -111,10 +112,11 @@ class DefiniteSizeStrategy final : public GridTrackSizingAlgorithmStrategy {
void layoutGridItemForMinSizeComputation(
LayoutBox&,
bool overrideSizeHasChanged) const override;
void maximizeTracks(Vector<GridTrack>&, LayoutUnit& freeSpace) override;
void maximizeTracks(Vector<GridTrack>&,
Optional<LayoutUnit>& freeSpace) override;
double findUsedFlexFraction(Vector<size_t>& flexibleSizedTracksIndex,
GridTrackSizingDirection,
LayoutUnit freeSpace) const override;
Optional<LayoutUnit> freeSpace) const override;
bool recomputeUsedFlexFractionIfNeeded(
Vector<size_t>& flexibleSizedTracksIndex,
double& flexFraction,
......@@ -446,7 +448,7 @@ void DefiniteSizeStrategy::layoutGridItemForMinSizeComputation(
}
void DefiniteSizeStrategy::maximizeTracks(Vector<GridTrack>& tracks,
LayoutUnit& freeSpace) {
Optional<LayoutUnit>& freeSpace) {
size_t tracksSize = tracks.size();
Vector<GridTrack*> tracksForDistribution(tracksSize);
for (size_t i = 0; i < tracksSize; ++i) {
......@@ -455,7 +457,8 @@ void DefiniteSizeStrategy::maximizeTracks(Vector<GridTrack>& tracks,
tracksForDistribution[i]->baseSize());
}
distributeSpaceToTracks(tracksForDistribution, freeSpace);
DCHECK(freeSpace);
distributeSpaceToTracks(tracksForDistribution, freeSpace.value());
for (auto* track : tracksForDistribution)
track->setBaseSize(track->plannedSize());
......@@ -464,10 +467,11 @@ void DefiniteSizeStrategy::maximizeTracks(Vector<GridTrack>& tracks,
double DefiniteSizeStrategy::findUsedFlexFraction(
Vector<size_t>& flexibleSizedTracksIndex,
GridTrackSizingDirection direction,
LayoutUnit freeSpace) const {
Optional<LayoutUnit> freeSpace) const {
GridSpan allTracksSpan = GridSpan::translatedDefiniteGridSpan(
0, m_algorithm.tracks(direction).size());
return findFrUnitSize(allTracksSpan, freeSpace);
DCHECK(freeSpace);
return findFrUnitSize(allTracksSpan, freeSpace.value());
}
LayoutUnit IndefiniteSizeStrategy::minLogicalWidthForChild(
......@@ -494,7 +498,7 @@ void IndefiniteSizeStrategy::layoutGridItemForMinSizeComputation(
}
void IndefiniteSizeStrategy::maximizeTracks(Vector<GridTrack>& tracks,
LayoutUnit&) {
Optional<LayoutUnit>&) {
for (auto& track : tracks)
track.setBaseSize(track.growthLimit());
}
......@@ -507,7 +511,7 @@ static inline double normalizedFlexFraction(const GridTrack& track,
double IndefiniteSizeStrategy::findUsedFlexFraction(
Vector<size_t>& flexibleSizedTracksIndex,
GridTrackSizingDirection direction,
LayoutUnit freeSpace) const {
Optional<LayoutUnit>) const {
auto allTracks = m_algorithm.tracks(direction);
double flexFraction = 0;
......@@ -580,7 +584,7 @@ bool IndefiniteSizeStrategy::recomputeUsedFlexFractionIfNeeded(
return true;
}
LayoutUnit& GridTrackSizingAlgorithm::freeSpace(
Optional<LayoutUnit> GridTrackSizingAlgorithm::freeSpace(
GridTrackSizingDirection direction) {
return direction == ForRows ? m_freeSpaceRows : m_freeSpaceColumns;
}
......@@ -595,6 +599,14 @@ const Vector<GridTrack>& GridTrackSizingAlgorithm::tracks(
return direction == ForColumns ? m_columns : m_rows;
}
void GridTrackSizingAlgorithm::setFreeSpace(GridTrackSizingDirection direction,
Optional<LayoutUnit> freeSpace) {
if (direction == ForColumns)
m_freeSpaceColumns = freeSpace;
else
m_freeSpaceRows = freeSpace;
}
GridTrackSize GridTrackSizingAlgorithm::rawGridTrackSize(
GridTrackSizingDirection direction,
size_t translatedIndex) const {
......@@ -701,7 +713,7 @@ LayoutUnit GridTrackSizingAlgorithm::initialBaseSize(
const Length& trackLength = gridLength.length();
if (trackLength.isSpecified())
return valueForLength(trackLength, m_availableSpace.clampNegativeToZero());
return valueForLength(trackLength, m_availableSpace.value_or(LayoutUnit()));
DCHECK(trackLength.isMinContent() || trackLength.isAuto() ||
trackLength.isMaxContent());
......@@ -717,7 +729,7 @@ LayoutUnit GridTrackSizingAlgorithm::initialGrowthLimit(
const Length& trackLength = gridLength.length();
if (trackLength.isSpecified())
return valueForLength(trackLength, m_availableSpace.clampNegativeToZero());
return valueForLength(trackLength, m_availableSpace.value_or(LayoutUnit()));
DCHECK(trackLength.isMinContent() || trackLength.isAuto() ||
trackLength.isMaxContent());
......@@ -728,7 +740,7 @@ void GridTrackSizingAlgorithm::initializeTrackSizes() {
DCHECK(m_contentSizedTracksIndex.isEmpty());
DCHECK(m_flexibleSizedTracksIndex.isEmpty());
Vector<GridTrack>& trackList = tracks(m_direction);
bool hasDefiniteFreeSpace = m_sizingOperation == TrackSizing;
bool hasDefiniteFreeSpace = !!m_availableSpace;
size_t numTracks = trackList.size();
for (size_t i = 0; i < numTracks; ++i) {
GridTrackSize trackSize = gridTrackSize(m_direction, i);
......@@ -741,7 +753,7 @@ void GridTrackSizingAlgorithm::initializeTrackSizes() {
GridLength gridLength = trackSize.fitContentTrackBreadth();
if (!gridLength.hasPercentage() || hasDefiniteFreeSpace) {
track.setGrowthLimitCap(valueForLength(
gridLength.length(), m_availableSpace.clampNegativeToZero()));
gridLength.length(), m_availableSpace.value_or(LayoutUnit())));
}
}
......@@ -779,7 +791,7 @@ void GridTrackSizingAlgorithm::sizeTrackToFitNonSpanningItem(
growthLimit =
std::min(growthLimit,
valueForLength(trackSize.fitContentTrackBreadth().length(),
m_availableSpace));
m_availableSpace.value_or(LayoutUnit())));
}
track.setGrowthLimit(std::max(track.growthLimit(), growthLimit));
}
......@@ -1296,7 +1308,8 @@ void GridTrackSizingAlgorithm::computeFlexSizedTracksGrowth(
}
}
void GridTrackSizingAlgorithm::stretchFlexibleTracks(LayoutUnit freeSpace) {
void GridTrackSizingAlgorithm::stretchFlexibleTracks(
Optional<LayoutUnit> freeSpace) {
double flexFraction = m_strategy->findUsedFlexFraction(
m_flexibleSizedTracksIndex, m_direction, freeSpace);
......@@ -1318,7 +1331,10 @@ void GridTrackSizingAlgorithm::stretchFlexibleTracks(LayoutUnit freeSpace) {
if (LayoutUnit increment = increments[i++])
track.setBaseSize(track.baseSize() + increment);
}
this->freeSpace(m_direction) -= totalGrowth;
if (this->freeSpace(m_direction)) {
setFreeSpace(m_direction,
this->freeSpace(m_direction).value() - totalGrowth);
}
m_maxContentSize += totalGrowth;
}
......@@ -1357,26 +1373,26 @@ bool GridTrackSizingAlgorithm::isValidTransition() const {
void GridTrackSizingAlgorithm::setup(GridTrackSizingDirection direction,
size_t numTracks,
SizingOperation sizingOperation,
LayoutUnit availableSpace,
LayoutUnit freeSpace) {
Optional<LayoutUnit> availableSpace,
Optional<LayoutUnit> freeSpace) {
DCHECK(m_needsSetup);
DCHECK_EQ(!!availableSpace, !!freeSpace);
m_direction = direction;
m_availableSpace = availableSpace;
m_availableSpace = availableSpace
? availableSpace.value().clampNegativeToZero()
: availableSpace;
m_sizingOperation = sizingOperation;
switch (m_sizingOperation) {
case IntrinsicSizeComputation:
m_strategy = WTF::makeUnique<IndefiniteSizeStrategy>(*this);
break;
case TrackSizing:
m_strategy = WTF::makeUnique<DefiniteSizeStrategy>(*this);
break;
}
if (availableSpace)
m_strategy = WTF::makeUnique<DefiniteSizeStrategy>(*this);
else
m_strategy = WTF::makeUnique<IndefiniteSizeStrategy>(*this);
m_contentSizedTracksIndex.shrink(0);
m_flexibleSizedTracksIndex.shrink(0);
this->freeSpace(direction) = freeSpace;
setFreeSpace(direction, freeSpace);
tracks(direction).resize(numTracks);
m_needsSetup = false;
......@@ -1387,7 +1403,7 @@ void GridTrackSizingAlgorithm::run() {
StateMachine stateMachine(*this);
// Step 1.
LayoutUnit initialFreeSpace = freeSpace(m_direction);
Optional<LayoutUnit> initialFreeSpace = freeSpace(m_direction);
initializeTrackSizes();
// Step 2.
......@@ -1399,13 +1415,19 @@ void GridTrackSizingAlgorithm::run() {
// up to this moment (before maximization) to calculate the grid container
// intrinsic sizes.
computeGridContainerIntrinsicSizes();
freeSpace(m_direction) -= m_minContentSize;
if (m_sizingOperation == TrackSizing && freeSpace(m_direction) <= 0)
return;
if (freeSpace(m_direction)) {
LayoutUnit updatedFreeSpace =
freeSpace(m_direction).value() - m_minContentSize;
setFreeSpace(m_direction, updatedFreeSpace);
if (updatedFreeSpace <= 0)
return;
}
// Step 3.
m_strategy->maximizeTracks(tracks(m_direction), freeSpace(m_direction));
m_strategy->maximizeTracks(tracks(m_direction), m_direction == ForColumns
? m_freeSpaceColumns
: m_freeSpaceRows);
if (m_flexibleSizedTracksIndex.isEmpty())
return;
......
......@@ -84,8 +84,8 @@ class GridTrackSizingAlgorithm final {
void setup(GridTrackSizingDirection,
size_t numTracks,
SizingOperation,
LayoutUnit availableSpace,
LayoutUnit freeSpace);
Optional<LayoutUnit> availableSpace,
Optional<LayoutUnit> freeSpace);
void run();
void reset();
......@@ -100,7 +100,8 @@ class GridTrackSizingAlgorithm final {
Vector<GridTrack>& tracks(GridTrackSizingDirection);
const Vector<GridTrack>& tracks(GridTrackSizingDirection) const;
LayoutUnit& freeSpace(GridTrackSizingDirection);
Optional<LayoutUnit> freeSpace(GridTrackSizingDirection);
void setFreeSpace(GridTrackSizingDirection, Optional<LayoutUnit>);
#if DCHECK_IS_ON()
bool tracksAreWiderThanMinTrackBreadth() const;
......@@ -164,7 +165,7 @@ class GridTrackSizingAlgorithm final {
// method at thise level.
void initializeTrackSizes();
void resolveIntrinsicTrackSizes();
void stretchFlexibleTracks(LayoutUnit freeSpace);
void stretchFlexibleTracks(Optional<LayoutUnit> freeSpace);
// State machine.
void advanceNextState();
......@@ -172,10 +173,10 @@ class GridTrackSizingAlgorithm final {
// Data.
bool m_needsSetup{true};
LayoutUnit m_availableSpace;
Optional<LayoutUnit> m_availableSpace;
LayoutUnit m_freeSpaceColumns;
LayoutUnit m_freeSpaceRows;
Optional<LayoutUnit> m_freeSpaceColumns;
Optional<LayoutUnit> m_freeSpaceRows;
// We need to keep both alive in order to properly size grids with orthogonal
// writing modes.
......@@ -231,10 +232,12 @@ class GridTrackSizingAlgorithmStrategy {
LayoutUnit maxContentForChild(LayoutBox&) const;
LayoutUnit minSizeForChild(LayoutBox&) const;
virtual void maximizeTracks(Vector<GridTrack>&, LayoutUnit& freeSpace) = 0;
virtual double findUsedFlexFraction(Vector<size_t>& flexibleSizedTracksIndex,
GridTrackSizingDirection,
LayoutUnit initialFreeSpace) const = 0;
virtual void maximizeTracks(Vector<GridTrack>&,
Optional<LayoutUnit>& freeSpace) = 0;
virtual double findUsedFlexFraction(
Vector<size_t>& flexibleSizedTracksIndex,
GridTrackSizingDirection,
Optional<LayoutUnit> initialFreeSpace) const = 0;
virtual bool recomputeUsedFlexFractionIfNeeded(
Vector<size_t>& flexibleSizedTracksIndex,
double& flexFraction,
......
......@@ -284,8 +284,8 @@ void LayoutGrid::layoutBlock(bool relayoutChildren) {
// Once grid's indefinite height is resolved, we can compute the
// available free space for Content Alignment.
if (!cachedHasDefiniteLogicalHeight()) {
m_trackSizingAlgorithm.freeSpace(ForRows) =
logicalHeight() - trackBasedLogicalHeight;
m_trackSizingAlgorithm.setFreeSpace(
ForRows, logicalHeight() - trackBasedLogicalHeight);
}
// TODO (lajava): We need to compute baselines after step 2 so
......@@ -436,7 +436,7 @@ void LayoutGrid::computeTrackSizesForIndefiniteSize(
LayoutUnit& minIntrinsicSize,
LayoutUnit& maxIntrinsicSize) const {
algo.setup(direction, numTracks(direction, grid), IntrinsicSizeComputation,
LayoutUnit(), LayoutUnit());
WTF::nullopt, WTF::nullopt);
algo.run();
minIntrinsicSize = algo.minContentSize();
......@@ -1046,8 +1046,8 @@ static const StyleContentAlignmentData& contentAlignmentNormalBehavior() {
void LayoutGrid::applyStretchAlignmentToTracksIfNeeded(
GridTrackSizingDirection direction) {
LayoutUnit& availableSpace = m_trackSizingAlgorithm.freeSpace(direction);
if (availableSpace <= 0 ||
Optional<LayoutUnit> freeSpace = m_trackSizingAlgorithm.freeSpace(direction);
if (!freeSpace || freeSpace.value() <= 0 ||
(direction == ForColumns &&
styleRef().resolvedJustifyContentDistribution(
contentAlignmentNormalBehavior()) != ContentDistributionStretch) ||
......@@ -1071,14 +1071,13 @@ void LayoutGrid::applyStretchAlignmentToTracksIfNeeded(
if (numberOfAutoSizedTracks < 1)
return;
LayoutUnit sizeToIncrease = availableSpace / numberOfAutoSizedTracks;
LayoutUnit sizeToIncrease = freeSpace.value() / numberOfAutoSizedTracks;
for (const auto& trackIndex : autoSizedTracksIndex) {
GridTrack* track = allTracks.data() + trackIndex;
LayoutUnit baseSize = track->baseSize() + sizeToIncrease;
track->setBaseSize(baseSize);
}
availableSpace = LayoutUnit();
m_trackSizingAlgorithm.setFreeSpace(direction, LayoutUnit());
}
void LayoutGrid::layoutGridItems() {
......@@ -1345,7 +1344,8 @@ void LayoutGrid::populateGridPositionsForDirection(
size_t numberOfLines = numberOfTracks + 1;
size_t lastLine = numberOfLines - 1;
ContentAlignmentData offset = computeContentPositionAndDistributionOffset(
direction, m_trackSizingAlgorithm.freeSpace(direction), numberOfTracks);
direction, m_trackSizingAlgorithm.freeSpace(direction).value(),
numberOfTracks);
auto& positions = isRowAxis ? m_columnPositions : m_rowPositions;
positions.resize(numberOfLines);
auto borderAndPadding =
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment