Bug 1118820 part 3a - [css-grid] Modify TrackSizingFunctions to take a dynamic number of 'repeat(auto-fill/auto-fit)' tracks taking into account. r=dholbert

This commit is contained in:
Mats Palmgren 2015-12-22 23:03:16 +01:00
Родитель 6a0b77effc
Коммит 0fa25cd68c
2 изменённых файлов: 137 добавлений и 76 удалений

Просмотреть файл

@ -365,12 +365,62 @@ private:
*/
struct MOZ_STACK_CLASS nsGridContainerFrame::TrackSizingFunctions
{
TrackSizingFunctions(const nsStyleGridTemplate& aGridTemplate,
const nsStyleCoord& aAutoMinSizing,
const nsStyleCoord& aAutoMaxSizing)
: mMinSizingFunctions(aGridTemplate.mMinTrackSizingFunctions)
, mMaxSizingFunctions(aGridTemplate.mMaxTrackSizingFunctions)
, mAutoMinSizing(aAutoMinSizing)
, mAutoMaxSizing(aAutoMaxSizing)
, mExplicitGridOffset(0)
, mRepeatAutoStart(aGridTemplate.HasRepeatAuto() ?
aGridTemplate.mRepeatAutoIndex : 0)
, mRepeatAutoEnd(mRepeatAutoStart)
, mRepeatEndDelta(0)
, mHasRepeatAuto(aGridTemplate.HasRepeatAuto())
{
MOZ_ASSERT(mMinSizingFunctions.Length() == mMaxSizingFunctions.Length());
MOZ_ASSERT(!mHasRepeatAuto ||
(mMinSizingFunctions.Length() >= 1 &&
mRepeatAutoStart < mMinSizingFunctions.Length()));
}
/**
* Initialize the number of auto-fill/fit tracks to use and return that.
* (zero if no auto-fill/fit track was specified)
*/
uint32_t InitRepeatTracks(nscoord aGridGap, nscoord aMinSize, nscoord aSize,
nscoord aMaxSize)
{
uint32_t repeatTracks = 0; // XXX will be fixed in a later patch
SetNumRepeatTracks(repeatTracks);
return repeatTracks;
}
/**
* Compute the explicit grid end line number (in a zero-based grid).
* @param aGridTemplateAreasEnd 'grid-template-areas' end line in this axis
*/
uint32_t ComputeExplicitGridEnd(uint32_t aGridTemplateAreasEnd)
{
uint32_t end = NumExplicitTracks() + 1;
end = std::max(end, aGridTemplateAreasEnd);
end = std::min(end, uint32_t(nsStyleGridLine::kMaxLine));
return end;
}
const nsStyleCoord& MinSizingFor(uint32_t aTrackIndex) const
{
if (MOZ_UNLIKELY(aTrackIndex < mExplicitGridOffset)) {
return mAutoMinSizing;
}
uint32_t index = aTrackIndex - mExplicitGridOffset;
if (index >= mRepeatAutoStart) {
if (index < mRepeatAutoEnd) {
return mMinSizingFunctions[mRepeatAutoStart];
}
index -= mRepeatEndDelta;
}
return index < mMinSizingFunctions.Length() ?
mMinSizingFunctions[index] : mAutoMinSizing;
}
@ -380,15 +430,47 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::TrackSizingFunctions
return mAutoMaxSizing;
}
uint32_t index = aTrackIndex - mExplicitGridOffset;
if (index >= mRepeatAutoStart) {
if (index < mRepeatAutoEnd) {
return mMaxSizingFunctions[mRepeatAutoStart];
}
index -= mRepeatEndDelta;
}
return index < mMaxSizingFunctions.Length() ?
mMaxSizingFunctions[index] : mAutoMaxSizing;
}
uint32_t NumExplicitTracks() const
{
return mMinSizingFunctions.Length() + mRepeatEndDelta;
}
uint32_t NumRepeatTracks() const
{
return mRepeatAutoEnd - mRepeatAutoStart;
}
void SetNumRepeatTracks(uint32_t aNumRepeatTracks)
{
MOZ_ASSERT(mHasRepeatAuto || aNumRepeatTracks == 0);
mRepeatAutoEnd = mRepeatAutoStart + aNumRepeatTracks;
mRepeatEndDelta = mHasRepeatAuto ?
int32_t(aNumRepeatTracks) - 1 :
0;
}
// Some style data references, for easy access.
const nsTArray<nsStyleCoord>& mMinSizingFunctions;
const nsTArray<nsStyleCoord>& mMaxSizingFunctions;
const nsStyleCoord& mAutoMinSizing;
const nsStyleCoord& mAutoMaxSizing;
// Offset from the start of the implicit grid to the first explicit track.
uint32_t mExplicitGridOffset;
// The index of the repeat(auto-fill/fit) track, or zero if there is none.
const uint32_t mRepeatAutoStart;
// The (hypothetical) index of the last such repeat() track.
uint32_t mRepeatAutoEnd;
// The difference between mExplicitGridEnd and mMinSizingFunctions.Length().
int32_t mRepeatEndDelta;
// True if there is a specified repeat(auto-fill/fit) track.
const bool mHasRepeatAuto;
};
/**
@ -824,18 +906,12 @@ private:
, mGridStyle(aGridStyle)
, mCols(eLogicalAxisInline)
, mRows(eLogicalAxisBlock)
, mColFunctions({
mGridStyle->mGridTemplateColumns.mMinTrackSizingFunctions,
mGridStyle->mGridTemplateColumns.mMaxTrackSizingFunctions,
mGridStyle->mGridAutoColumnsMin,
mGridStyle->mGridAutoColumnsMax,
})
, mRowFunctions({
mGridStyle->mGridTemplateRows.mMinTrackSizingFunctions,
mGridStyle->mGridTemplateRows.mMaxTrackSizingFunctions,
mGridStyle->mGridAutoRowsMin,
mGridStyle->mGridAutoRowsMax,
})
, mColFunctions(mGridStyle->mGridTemplateColumns,
mGridStyle->mGridAutoColumnsMin,
mGridStyle->mGridAutoColumnsMax)
, mRowFunctions(mGridStyle->mGridTemplateRows,
mGridStyle->mGridAutoRowsMin,
mGridStyle->mGridAutoRowsMax)
, mReflowState(aReflowState)
, mRenderingContext(aRenderingContext)
, mWM(aWM)
@ -1777,36 +1853,38 @@ nsGridContainerFrame::PlaceAutoAutoInColOrder(uint32_t aStartCol,
}
void
nsGridContainerFrame::InitializeGridBounds(const nsStylePosition* aStyle)
{
// http://dev.w3.org/csswg/css-grid/#grid-definition
// Note that this is for a grid with a 1,1 origin. We'll change that
// to a 0,0 based grid after placing definite lines.
uint32_t colEnd = aStyle->mGridTemplateColumns.mLineNameLists.Length();
uint32_t rowEnd = aStyle->mGridTemplateRows.mLineNameLists.Length();
auto areas = aStyle->mGridTemplateAreas.get();
mExplicitGridColEnd = std::max(colEnd, areas ? areas->mNColumns + 1 : 1);
mExplicitGridRowEnd = std::max(rowEnd, areas ? areas->NRows() + 1 : 1);
mExplicitGridColEnd =
std::min(mExplicitGridColEnd, uint32_t(nsStyleGridLine::kMaxLine));
mExplicitGridRowEnd =
std::min(mExplicitGridRowEnd, uint32_t(nsStyleGridLine::kMaxLine));
mGridColEnd = mExplicitGridColEnd;
mGridRowEnd = mExplicitGridRowEnd;
}
void
nsGridContainerFrame::PlaceGridItems(GridReflowState& aState)
nsGridContainerFrame::PlaceGridItems(GridReflowState& aState,
const LogicalSize& aComputedMinSize,
const LogicalSize& aComputedSize,
const LogicalSize& aComputedMaxSize)
{
const nsStylePosition* const gridStyle = aState.mGridStyle;
mCellMap.ClearOccupied();
InitializeGridBounds(gridStyle);
uint32_t numRepeatCols = 0; // XXX will be fixed in a later patch
// http://dev.w3.org/csswg/css-grid/#grid-definition
// Initialize the end lines of the Explicit Grid (mExplicitGridCol[Row]End).
// This is determined by the larger of the number of rows/columns defined
// by 'grid-template-areas' and the 'grid-template-rows'/'-columns', plus one.
// Also initialize the Implicit Grid (mGridCol[Row]End) to the same values.
// Note that this is for a grid with a 1,1 origin. We'll change that
// to a 0,0 based grid after placing definite lines.
auto areas = gridStyle->mGridTemplateAreas.get();
uint32_t numRepeatCols = aState.mColFunctions.InitRepeatTracks(
gridStyle->mGridColumnGap,
aComputedMinSize.ISize(aState.mWM),
aComputedSize.ISize(aState.mWM),
aComputedMaxSize.ISize(aState.mWM));
mGridColEnd = mExplicitGridColEnd =
aState.mColFunctions.ComputeExplicitGridEnd(areas ? areas->mNColumns + 1 : 1);
LineNameMap colLineNameMap(gridStyle->mGridTemplateColumns, numRepeatCols);
uint32_t numRepeatRows = 0; // XXX will be fixed in a later patch
uint32_t numRepeatRows = aState.mRowFunctions.InitRepeatTracks(
gridStyle->mGridRowGap,
aComputedMinSize.BSize(aState.mWM),
aComputedSize.BSize(aState.mWM),
aComputedMaxSize.BSize(aState.mWM));
mGridRowEnd = mExplicitGridRowEnd =
aState.mRowFunctions.ComputeExplicitGridEnd(areas ? areas->NRows() + 1 : 1);
LineNameMap rowLineNameMap(gridStyle->mGridTemplateRows, numRepeatRows);
// http://dev.w3.org/csswg/css-grid/#line-placement
@ -2048,42 +2126,19 @@ nsGridContainerFrame::Tracks::Initialize(
uint32_t aNumTracks,
nscoord aContentBoxSize)
{
MOZ_ASSERT(aNumTracks >= aFunctions.mExplicitGridOffset +
aFunctions.NumExplicitTracks());
mSizes.SetLength(aNumTracks);
PodZero(mSizes.Elements(), mSizes.Length());
nscoord percentageBasis = aContentBoxSize;
if (percentageBasis == NS_UNCONSTRAINEDSIZE) {
percentageBasis = 0;
}
const uint32_t explicitGridOffset = aFunctions.mExplicitGridOffset;
MOZ_ASSERT(mSizes.Length() >=
explicitGridOffset + aFunctions.mMinSizingFunctions.Length());
MOZ_ASSERT(aFunctions.mMinSizingFunctions.Length() ==
aFunctions.mMaxSizingFunctions.Length());
// First we initialize the implicit tracks before the explicit grid starts.
uint32_t i = 0;
uint32_t sentinel = std::min<uint32_t>(explicitGridOffset, mSizes.Length());
for (; i < sentinel; ++i) {
for (uint32_t i = 0, len = mSizes.Length(); i < len; ++i) {
mSizes[i].Initialize(percentageBasis,
aFunctions.mAutoMinSizing,
aFunctions.mAutoMaxSizing);
aFunctions.MinSizingFor(i),
aFunctions.MaxSizingFor(i));
}
// Now initialize the explicit grid tracks.
sentinel = std::min<uint32_t>(i + aFunctions.mMinSizingFunctions.Length(),
mSizes.Length());
for (uint32_t j = 0; i < sentinel; ++i, ++j) {
mSizes[i].Initialize(percentageBasis,
aFunctions.mMinSizingFunctions[j],
aFunctions.mMaxSizingFunctions[j]);
}
// Finally, initialize the implicit tracks that comes after the explicit grid.
sentinel = mSizes.Length();
for (; i < sentinel; ++i) {
mSizes[i].Initialize(percentageBasis,
aFunctions.mAutoMinSizing,
aFunctions.mAutoMaxSizing);
}
mGridGap = aGridGap;
MOZ_ASSERT(mGridGap >= nscoord(0), "negative grid gap");
}
@ -3105,7 +3160,8 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
InitImplicitNamedAreas(stylePos);
GridReflowState gridReflowState(this, aReflowState);
mIsNormalFlowInCSSOrder = gridReflowState.mIter.ItemsAreAlreadyInOrder();
PlaceGridItems(gridReflowState);
LogicalSize indefinite(gridReflowState.mWM, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
PlaceGridItems(gridReflowState, indefinite, indefinite, indefinite);
const nscoord computedBSize = aReflowState.ComputedBSize();
const nscoord computedISize = aReflowState.ComputedISize();
@ -3171,7 +3227,8 @@ nsGridContainerFrame::IntrinsicISize(nsRenderingContext* aRenderingContext,
// http://dev.w3.org/csswg/css-grid/#intrinsic-sizes
GridReflowState state(this, *aRenderingContext);
InitImplicitNamedAreas(state.mGridStyle); // XXX optimize
PlaceGridItems(state); // XXX optimize
LogicalSize indefinite(state.mWM, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
PlaceGridItems(state, indefinite, indefinite, indefinite); // XXX optimize
if (mGridColEnd == 0) {
return 0;
}

Просмотреть файл

@ -470,17 +470,21 @@ protected:
* Place all child frames into the grid and expand the (implicit) grid as
* needed. The allocated GridAreas are stored in the GridAreaProperty
* frame property on the child frame.
* @param aComputedMinSize the container's min-size - used to determine
* the number of repeat(auto-fill/fit) tracks.
* @param aComputedSize the container's size - used to determine
* the number of repeat(auto-fill/fit) tracks.
* @param aComputedMaxSize the container's max-size - used to determine
* the number of repeat(auto-fill/fit) tracks.
*/
void PlaceGridItems(GridReflowState& aState);
/**
* Initialize the end lines of the Explicit Grid (mExplicitGridCol[Row]End).
* This is determined by the larger of the number of rows/columns defined
* by 'grid-template-areas' and the 'grid-template-rows'/'-columns', plus one.
* Also initialize the Implicit Grid (mGridCol[Row]End) to the same values.
* @param aStyle the StylePosition() for the grid container
*/
void InitializeGridBounds(const nsStylePosition* aStyle);
void PlaceGridItems(GridReflowState& aState,
const LogicalSize& aComputedMinSize,
const LogicalSize& aComputedSize,
const LogicalSize& aComputedMaxSize);
// Helper for the above.
void PlaceGridItems(GridReflowState& aState,
const LineNameMap& aColLineNameMap,
const LineNameMap& aRowLineNameMap);
/**
* Inflate the implicit grid to include aArea.