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:
Tiaan Louw 2024-02-12 14:34:53 +00:00
Родитель 9bb5d5f55d
Коммит 1253566d0d
1 изменённых файлов: 59 добавлений и 40 удалений

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

@ -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;
} }
} }