зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1878846 - Change grid items to use PerLogicalAxis types. r=TYLin
This avoids using raw integer values which might cause bugs. Also removed a clang-format: off block for better formatting. Differential Revision: https://phabricator.services.mozilla.com/D200767
This commit is contained in:
Родитель
9bb5d5f55d
Коммит
1253566d0d
|
@ -9,9 +9,7 @@
|
||||||
#include "nsGridContainerFrame.h"
|
#include "nsGridContainerFrame.h"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <limits>
|
|
||||||
#include <stdlib.h> // for div()
|
#include <stdlib.h> // for div()
|
||||||
#include <numeric>
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include "gfxContext.h"
|
#include "gfxContext.h"
|
||||||
#include "mozilla/AutoRestore.h"
|
#include "mozilla/AutoRestore.h"
|
||||||
|
@ -24,17 +22,14 @@
|
||||||
#include "mozilla/IntegerRange.h"
|
#include "mozilla/IntegerRange.h"
|
||||||
#include "mozilla/Maybe.h"
|
#include "mozilla/Maybe.h"
|
||||||
#include "mozilla/PodOperations.h" // for PodZero
|
#include "mozilla/PodOperations.h" // for PodZero
|
||||||
#include "mozilla/Poison.h"
|
|
||||||
#include "mozilla/PresShell.h"
|
#include "mozilla/PresShell.h"
|
||||||
#include "nsAbsoluteContainingBlock.h"
|
#include "nsAbsoluteContainingBlock.h"
|
||||||
#include "nsAlgorithm.h" // for clamped()
|
#include "nsAlgorithm.h" // for clamped()
|
||||||
#include "nsCSSAnonBoxes.h"
|
|
||||||
#include "nsCSSFrameConstructor.h"
|
#include "nsCSSFrameConstructor.h"
|
||||||
#include "nsTHashMap.h"
|
|
||||||
#include "nsDisplayList.h"
|
#include "nsDisplayList.h"
|
||||||
#include "nsHashKeys.h"
|
#include "nsHashKeys.h"
|
||||||
#include "nsFieldSetFrame.h"
|
#include "nsFieldSetFrame.h"
|
||||||
#include "nsIFrameInlines.h"
|
#include "nsLayoutUtils.h"
|
||||||
#include "nsPlaceholderFrame.h"
|
#include "nsPlaceholderFrame.h"
|
||||||
#include "nsPresContext.h"
|
#include "nsPresContext.h"
|
||||||
#include "nsReadableUtils.h"
|
#include "nsReadableUtils.h"
|
||||||
|
@ -593,43 +588,57 @@ struct nsGridContainerFrame::GridItemInfo {
|
||||||
* Item state per axis.
|
* Item state per axis.
|
||||||
*/
|
*/
|
||||||
enum StateBits : uint16_t {
|
enum StateBits : uint16_t {
|
||||||
// clang-format off
|
// Does the item span a flex track?
|
||||||
eIsFlexing = 0x1, // does the item span a flex track?
|
eIsFlexing = 0x1,
|
||||||
eFirstBaseline = 0x2, // participate in 'first baseline' alignment?
|
|
||||||
// ditto 'last baseline', mutually exclusive w. eFirstBaseline
|
// First or last baseline alignment preference. They are mutually exclusive.
|
||||||
eLastBaseline = 0x4,
|
// This does *NOT* represent the baseline alignment group. See the member
|
||||||
|
// variable for that.
|
||||||
|
// <https://drafts.csswg.org/css-align-3/#baseline-alignment-preference>
|
||||||
|
eFirstBaseline = 0x2,
|
||||||
|
eLastBaseline = 0x4,
|
||||||
eIsBaselineAligned = eFirstBaseline | eLastBaseline,
|
eIsBaselineAligned = eFirstBaseline | eLastBaseline,
|
||||||
|
|
||||||
// One of e[Self|Content]Baseline is set when eIsBaselineAligned is true
|
// One of e[Self|Content]Baseline is set when eIsBaselineAligned is true
|
||||||
eSelfBaseline = 0x8, // is it *-self:[last ]baseline alignment?
|
eSelfBaseline = 0x8, // is it *-self:[last ]baseline alignment?
|
||||||
// Ditto *-content:[last ]baseline. Mutually exclusive w. eSelfBaseline.
|
// Ditto *-content:[last ]baseline. Mutually exclusive w. eSelfBaseline.
|
||||||
eContentBaseline = 0x10,
|
eContentBaseline = 0x10,
|
||||||
|
|
||||||
// The baseline affects the margin or padding on the item's end side when
|
// The baseline affects the margin or padding on the item's end side when
|
||||||
// this bit is set. In a grid-axis it's always set for eLastBaseline and
|
// this bit is set. In a grid-axis it's always set for eLastBaseline and
|
||||||
// always unset for eFirstBaseline. In a masonry-axis, it's set for
|
// always unset for eFirstBaseline. In a masonry-axis, it's set for
|
||||||
// baseline groups in the EndStretch set and unset for the StartStretch set.
|
// baseline groups in the EndStretch set and unset for the StartStretch set.
|
||||||
eEndSideBaseline = 0x20,
|
eEndSideBaseline = 0x20,
|
||||||
eAllBaselineBits = eIsBaselineAligned | eSelfBaseline | eContentBaseline |
|
eAllBaselineBits = eIsBaselineAligned | eSelfBaseline | eContentBaseline |
|
||||||
eEndSideBaseline,
|
eEndSideBaseline,
|
||||||
|
|
||||||
// Should apply Automatic Minimum Size per:
|
// Should apply Automatic Minimum Size per:
|
||||||
// https://drafts.csswg.org/css-grid/#min-size-auto
|
// https://drafts.csswg.org/css-grid/#min-size-auto
|
||||||
eApplyAutoMinSize = 0x40,
|
eApplyAutoMinSize = 0x40,
|
||||||
// Clamp per https://drafts.csswg.org/css-grid/#min-size-auto
|
// Clamp per https://drafts.csswg.org/css-grid/#min-size-auto
|
||||||
eClampMarginBoxMinSize = 0x80,
|
eClampMarginBoxMinSize = 0x80,
|
||||||
eIsSubgrid = 0x100,
|
eIsSubgrid = 0x100,
|
||||||
// set on subgrids and items in subgrids if they are adjacent to the grid
|
// set on subgrids and items in subgrids if they are adjacent to the grid
|
||||||
// start/end edge (excluding grid-aligned abs.pos. frames)
|
// start/end edge (excluding grid-aligned abs.pos. frames)
|
||||||
eStartEdge = 0x200,
|
eStartEdge = 0x200,
|
||||||
eEndEdge = 0x400,
|
eEndEdge = 0x400,
|
||||||
eEdgeBits = eStartEdge | eEndEdge,
|
eEdgeBits = eStartEdge | eEndEdge,
|
||||||
// Set if this item was auto-placed in this axis.
|
// Set if this item was auto-placed in this axis.
|
||||||
eAutoPlacement = 0x800,
|
eAutoPlacement = 0x800,
|
||||||
// Set if this item is the last item in its track (masonry layout only)
|
// Set if this item is the last item in its track (masonry layout only)
|
||||||
eIsLastItemInMasonryTrack = 0x1000,
|
eIsLastItemInMasonryTrack = 0x1000,
|
||||||
// clang-format on
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GridItemInfo(nsIFrame* aFrame, const GridArea& aArea);
|
GridItemInfo(nsIFrame* aFrame, const GridArea& aArea);
|
||||||
|
|
||||||
|
GridItemInfo(const GridItemInfo& aOther)
|
||||||
|
: mFrame(aOther.mFrame), mArea(aOther.mArea) {
|
||||||
|
mBaselineOffset = aOther.mBaselineOffset;
|
||||||
|
mState = aOther.mState;
|
||||||
|
}
|
||||||
|
|
||||||
|
GridItemInfo& operator=(const GridItemInfo&) = delete;
|
||||||
|
|
||||||
static bool BaselineAlignmentAffectsEndSide(StateBits state) {
|
static bool BaselineAlignmentAffectsEndSide(StateBits state) {
|
||||||
return state & StateBits::eEndSideBaseline;
|
return state & StateBits::eEndSideBaseline;
|
||||||
}
|
}
|
||||||
|
@ -654,10 +663,12 @@ struct nsGridContainerFrame::GridItemInfo {
|
||||||
*/
|
*/
|
||||||
GridItemInfo Transpose() const {
|
GridItemInfo Transpose() const {
|
||||||
GridItemInfo info(mFrame, GridArea(mArea.mRows, mArea.mCols));
|
GridItemInfo info(mFrame, GridArea(mArea.mRows, mArea.mCols));
|
||||||
info.mState[0] = mState[1];
|
info.mState[eLogicalAxisBlock] = mState[eLogicalAxisInline];
|
||||||
info.mState[1] = mState[0];
|
info.mState[eLogicalAxisInline] = mState[eLogicalAxisBlock];
|
||||||
info.mBaselineOffset[0] = mBaselineOffset[1];
|
info.mBaselineOffset[eLogicalAxisBlock] =
|
||||||
info.mBaselineOffset[1] = mBaselineOffset[0];
|
mBaselineOffset[eLogicalAxisInline];
|
||||||
|
info.mBaselineOffset[eLogicalAxisInline] =
|
||||||
|
mBaselineOffset[eLogicalAxisBlock];
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -816,13 +827,16 @@ struct nsGridContainerFrame::GridItemInfo {
|
||||||
|
|
||||||
nsIFrame* const mFrame;
|
nsIFrame* const mFrame;
|
||||||
GridArea mArea;
|
GridArea mArea;
|
||||||
|
|
||||||
// Offset from the margin edge to the baseline (LogicalAxis index). It's from
|
// Offset from the margin edge to the baseline (LogicalAxis index). It's from
|
||||||
// the start edge when eFirstBaseline is set, end edge otherwise. It's mutable
|
// the start edge for first baseline sharing group, otherwise from the end
|
||||||
// since we update the value fairly late (just before reflowing the item).
|
// edge.
|
||||||
mutable nscoord mBaselineOffset[2];
|
// It's mutable since we update the value fairly late (just before reflowing
|
||||||
mutable StateBits mState[2]; // state bits per axis (LogicalAxis index)
|
// the item).
|
||||||
static_assert(mozilla::eLogicalAxisBlock == 0, "unexpected index value");
|
mutable PerLogicalAxis<nscoord> mBaselineOffset;
|
||||||
static_assert(mozilla::eLogicalAxisInline == 1, "unexpected index value");
|
|
||||||
|
// State bits per axis.
|
||||||
|
mutable PerLogicalAxis<StateBits> mState;
|
||||||
};
|
};
|
||||||
|
|
||||||
using GridItemInfo = nsGridContainerFrame::GridItemInfo;
|
using GridItemInfo = nsGridContainerFrame::GridItemInfo;
|
||||||
|
@ -830,11 +844,12 @@ using ItemState = GridItemInfo::StateBits;
|
||||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ItemState)
|
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ItemState)
|
||||||
|
|
||||||
GridItemInfo::GridItemInfo(nsIFrame* aFrame, const GridArea& aArea)
|
GridItemInfo::GridItemInfo(nsIFrame* aFrame, const GridArea& aArea)
|
||||||
: mFrame(aFrame), mArea(aArea) {
|
: mFrame(aFrame), mArea(aArea), mBaselineOffset{0, 0} {
|
||||||
mState[eLogicalAxisBlock] =
|
mState[eLogicalAxisBlock] =
|
||||||
StateBits(mArea.mRows.mStart == kAutoLine ? eAutoPlacement : 0);
|
StateBits(mArea.mRows.mStart == kAutoLine ? eAutoPlacement : 0);
|
||||||
mState[eLogicalAxisInline] =
|
mState[eLogicalAxisInline] =
|
||||||
StateBits(mArea.mCols.mStart == kAutoLine ? eAutoPlacement : 0);
|
StateBits(mArea.mCols.mStart == kAutoLine ? eAutoPlacement : 0);
|
||||||
|
|
||||||
if (auto* gridFrame = GetGridContainerFrame(mFrame)) {
|
if (auto* gridFrame = GetGridContainerFrame(mFrame)) {
|
||||||
auto parentWM = aFrame->GetParent()->GetWritingMode();
|
auto parentWM = aFrame->GetParent()->GetWritingMode();
|
||||||
bool isOrthogonal = parentWM.IsOrthogonalTo(gridFrame->GetWritingMode());
|
bool isOrthogonal = parentWM.IsOrthogonalTo(gridFrame->GetWritingMode());
|
||||||
|
@ -847,8 +862,6 @@ GridItemInfo::GridItemInfo(nsIFrame* aFrame, const GridArea& aArea)
|
||||||
StateBits::eIsSubgrid;
|
StateBits::eIsSubgrid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mBaselineOffset[eLogicalAxisBlock] = nscoord(0);
|
|
||||||
mBaselineOffset[eLogicalAxisInline] = nscoord(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GridItemInfo::ReverseDirection(LogicalAxis aAxis, uint32_t aGridEnd) {
|
void GridItemInfo::ReverseDirection(LogicalAxis aAxis, uint32_t aGridEnd) {
|
||||||
|
@ -2906,12 +2919,18 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::GridReflowInput {
|
||||||
mGridItems.AppendElement(GridItemInfo(child, itemInfo.mArea));
|
mGridItems.AppendElement(GridItemInfo(child, itemInfo.mArea));
|
||||||
// Copy the item's baseline data so that the item's last fragment can
|
// Copy the item's baseline data so that the item's last fragment can
|
||||||
// do 'last baseline' alignment if necessary.
|
// do 'last baseline' alignment if necessary.
|
||||||
item->mState[0] |= itemInfo.mState[0] & ItemState::eAllBaselineBits;
|
item->mState[eLogicalAxisBlock] |=
|
||||||
item->mState[1] |= itemInfo.mState[1] & ItemState::eAllBaselineBits;
|
itemInfo.mState[eLogicalAxisBlock] & ItemState::eAllBaselineBits;
|
||||||
item->mBaselineOffset[0] = itemInfo.mBaselineOffset[0];
|
item->mState[eLogicalAxisInline] |=
|
||||||
item->mBaselineOffset[1] = itemInfo.mBaselineOffset[1];
|
itemInfo.mState[eLogicalAxisInline] & ItemState::eAllBaselineBits;
|
||||||
item->mState[0] |= itemInfo.mState[0] & ItemState::eAutoPlacement;
|
item->mBaselineOffset[eLogicalAxisBlock] =
|
||||||
item->mState[1] |= itemInfo.mState[1] & ItemState::eAutoPlacement;
|
itemInfo.mBaselineOffset[eLogicalAxisBlock];
|
||||||
|
item->mBaselineOffset[eLogicalAxisInline] =
|
||||||
|
itemInfo.mBaselineOffset[eLogicalAxisInline];
|
||||||
|
item->mState[eLogicalAxisBlock] |=
|
||||||
|
itemInfo.mState[eLogicalAxisBlock] & ItemState::eAutoPlacement;
|
||||||
|
item->mState[eLogicalAxisInline] |=
|
||||||
|
itemInfo.mState[eLogicalAxisInline] & ItemState::eAutoPlacement;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче