Bug 1269046 part 8: Rewrite CSSAlignUtils::AlignJustifySelf to use a single "flags" arg instead of boolean args. r=mats

MozReview-Commit-ID: 5loE21U7FF6
This commit is contained in:
Daniel Holbert
2016-10-31 08:59:40 -07:00
parent 046bfe73d7
commit 087210301f
4 changed files with 82 additions and 49 deletions

View File

@@ -19,8 +19,8 @@ SpaceToFill(WritingMode aWM, const LogicalSize& aSize, nscoord aMargin,
}
nscoord
CSSAlignUtils::AlignJustifySelf(uint8_t aAlignment, bool aOverflowSafe,
LogicalAxis aAxis, bool aSameSide,
CSSAlignUtils::AlignJustifySelf(uint8_t aAlignment, LogicalAxis aAxis,
AlignJustifyFlags aFlags,
nscoord aBaselineAdjust, nscoord aCBSize,
const ReflowInput& aRI,
const LogicalSize& aChildSize)
@@ -31,15 +31,19 @@ CSSAlignUtils::AlignJustifySelf(uint8_t aAlignment, bool aOverflowSafe,
aAlignment != NS_STYLE_ALIGN_RIGHT,
"caller should map that to the corresponding START/END");
// Promote aFlags to convenience bools:
const bool isOverflowSafe = !!(aFlags & AlignJustifyFlags::eOverflowSafe);
const bool isSameSide = !!(aFlags & AlignJustifyFlags::eSameSide);
// Map some alignment values to 'start' / 'end'.
switch (aAlignment) {
case NS_STYLE_ALIGN_SELF_START: // align/justify-self: self-start
aAlignment = MOZ_LIKELY(aSameSide) ? NS_STYLE_ALIGN_START
: NS_STYLE_ALIGN_END;
aAlignment = MOZ_LIKELY(isSameSide) ? NS_STYLE_ALIGN_START
: NS_STYLE_ALIGN_END;
break;
case NS_STYLE_ALIGN_SELF_END: // align/justify-self: self-end
aAlignment = MOZ_LIKELY(aSameSide) ? NS_STYLE_ALIGN_END
: NS_STYLE_ALIGN_START;
aAlignment = MOZ_LIKELY(isSameSide) ? NS_STYLE_ALIGN_END
: NS_STYLE_ALIGN_START;
break;
// flex-start/flex-end are the same as start/end, in most contexts.
// (They have special behavior in flex containers, so flex containers
@@ -60,7 +64,7 @@ CSSAlignUtils::AlignJustifySelf(uint8_t aAlignment, bool aOverflowSafe,
WritingMode wm = aRI.GetWritingMode();
nscoord marginStart, marginEnd;
if (aAxis == eLogicalAxisBlock) {
if (MOZ_LIKELY(aSameSide)) {
if (MOZ_LIKELY(isSameSide)) {
marginStart = margin.BStart(wm);
marginEnd = margin.BEnd(wm);
} else {
@@ -68,7 +72,7 @@ CSSAlignUtils::AlignJustifySelf(uint8_t aAlignment, bool aOverflowSafe,
marginEnd = margin.BStart(wm);
}
} else {
if (MOZ_LIKELY(aSameSide)) {
if (MOZ_LIKELY(isSameSide)) {
marginStart = margin.IStart(wm);
marginEnd = margin.IEnd(wm);
} else {
@@ -91,7 +95,7 @@ CSSAlignUtils::AlignJustifySelf(uint8_t aAlignment, bool aOverflowSafe,
// https://drafts.csswg.org/css-align-3/#overflow-values
// This implements <overflow-position> = 'safe'.
// And auto-margins: https://drafts.csswg.org/css-grid/#auto-margins
if ((MOZ_UNLIKELY(aOverflowSafe) && aAlignment != NS_STYLE_ALIGN_START) ||
if ((MOZ_UNLIKELY(isOverflowSafe) && aAlignment != NS_STYLE_ALIGN_START) ||
hasAutoMarginStart || hasAutoMarginEnd) {
nscoord space = SpaceToFill(wm, aChildSize, marginStart + marginEnd,
aAxis, aCBSize);
@@ -103,10 +107,10 @@ CSSAlignUtils::AlignJustifySelf(uint8_t aAlignment, bool aOverflowSafe,
aAlignment = NS_STYLE_ALIGN_START;
} else if (hasAutoMarginEnd) {
aAlignment = hasAutoMarginStart ? NS_STYLE_ALIGN_CENTER
: (aSameSide ? NS_STYLE_ALIGN_START
: NS_STYLE_ALIGN_END);
: (isSameSide ? NS_STYLE_ALIGN_START
: NS_STYLE_ALIGN_END);
} else if (hasAutoMarginStart) {
aAlignment = aSameSide ? NS_STYLE_ALIGN_END : NS_STYLE_ALIGN_START;
aAlignment = isSameSide ? NS_STYLE_ALIGN_END : NS_STYLE_ALIGN_START;
}
}
@@ -116,7 +120,7 @@ CSSAlignUtils::AlignJustifySelf(uint8_t aAlignment, bool aOverflowSafe,
switch (aAlignment) {
case NS_STYLE_ALIGN_BASELINE:
case NS_STYLE_ALIGN_LAST_BASELINE:
if (MOZ_LIKELY(aSameSide == (aAlignment == NS_STYLE_ALIGN_BASELINE))) {
if (MOZ_LIKELY(isSameSide == (aAlignment == NS_STYLE_ALIGN_BASELINE))) {
offset = marginStart + aBaselineAdjust;
} else {
nscoord size = aAxis == eLogicalAxisBlock ? aChildSize.BSize(wm)

View File

@@ -14,6 +14,18 @@ namespace mozilla {
class CSSAlignUtils {
public:
/**
* Flags to customize the behavior of AlignJustifySelf:
*/
enum class AlignJustifyFlags {
eNoFlags = 0,
// Indicates that we have <overflow-position> = safe.
eOverflowSafe = 1 << 0,
// Indicates that the container's start side in aAxis is the same
// as the child's start side in the child's parallel axis.
eSameSide = 1 << 1,
};
/**
* This computes the aligned offset of a CSS-aligned child within its
* alignment container. The returned offset is distance between the
@@ -25,23 +37,21 @@ public:
* NS_STYLE_ALIGN_{AUTO,LEFT,RIGHT} must *not* be
* passed here; this method expects the caller to have
* already resolved those to 'start', 'end', or 'stretch'.
* @param aOverflowSafe Indicates whether we have <overflow-position> = safe.
* @param aAxis The container's axis in which we're doing alignment.
* @param aSameSide Indicates whether the container's start side in aAxis is
* the same as the child's start side, in the child's
* parallel axis.
* @param aBaselineAdjust The amount to offset baseline-aligned children.
* @param aCBSize The size of the alignment container, in its aAxis.
* @param aRI A ReflowInput for the child.
* @param aChildSize The child's LogicalSize (in its own writing mode).
*/
static nscoord AlignJustifySelf(uint8_t aAlignment, bool aOverflowSafe,
LogicalAxis aAxis, bool aSameSide,
static nscoord AlignJustifySelf(uint8_t aAlignment, LogicalAxis aAxis,
AlignJustifyFlags aFlags,
nscoord aBaselineAdjust, nscoord aCBSize,
const ReflowInput& aRI,
const LogicalSize& aChildSize);
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CSSAlignUtils::AlignJustifyFlags)
} // namespace mozilla
#endif // mozilla_CSSAlignUtils_h

View File

@@ -40,6 +40,8 @@ static void PrettyUC(nscoord aSize, char* aBuf, int aBufSize)
using namespace mozilla;
typedef mozilla::CSSAlignUtils::AlignJustifyFlags AlignJustifyFlags;
void
nsAbsoluteContainingBlock::SetInitialChildList(nsIFrame* aDelegatingFrame,
ChildListID aListID,
@@ -420,21 +422,24 @@ OffsetToAlignedStaticPos(const ReflowInput& aKidReflowInput,
nscoord alignAreaSizeInAxis = (pcAxis == eLogicalAxisInline)
? alignAreaSize.ISize(pcWM)
: alignAreaSize.BSize(pcWM);
// XXXdholbert: Handle <overflow-position> in bug 1311892. For now, behave
AlignJustifyFlags flags = AlignJustifyFlags::eNoFlags;
uint16_t alignConst =
aPlaceholderContainer->CSSAlignmentForAbsPosChild(aKidReflowInput, pcAxis);
// XXXdholbert: Handle <overflow-position> in bug 1311892 (by conditionally
// setting AlignJustifyFlags::eOverflowSafe in |flags|.) For now, we behave
// as if "unsafe" was the specified value (which is basically equivalent to
// the default behavior, when no value is specified -- though the default
// behavior also has some [at-risk] extra nuance about scroll containers...)
const bool overflowSafe = false;
uint16_t alignConst =
aPlaceholderContainer->CSSAlignmentForAbsPosChild(aKidReflowInput, pcAxis);
// XXX strip off <overflow-position> bits until we implement it (bug 1311892)
// For now we ignore & strip off <overflow-position> bits, until bug 1311892.
alignConst &= ~NS_STYLE_ALIGN_FLAG_BITS;
// Find out if placeholder-container & the OOF child have the same start-sides
// in the placeholder-container's pcAxis.
WritingMode kidWM = aKidReflowInput.GetWritingMode();
bool sameSidePCAndKid = pcWM.ParallelAxisStartsOnSameSide(pcAxis, kidWM);
if (pcWM.ParallelAxisStartsOnSameSide(pcAxis, kidWM)) {
flags |= AlignJustifyFlags::eSameSide;
}
// (baselineAdjust is unused. CSSAlignmentForAbsPosChild() should've
// converted 'baseline'/'last-baseline' enums to their fallback values.)
@@ -449,10 +454,9 @@ OffsetToAlignedStaticPos(const ReflowInput& aKidReflowInput,
: aAbsPosCBAxis);
nscoord offset =
CSSAlignUtils::AlignJustifySelf(alignConst, overflowSafe,
kidAxis, sameSidePCAndKid, baselineAdjust,
alignAreaSizeInAxis, aKidReflowInput,
kidSizeInOwnWM);
CSSAlignUtils::AlignJustifySelf(alignConst, kidAxis, flags,
baselineAdjust, alignAreaSizeInAxis,
aKidReflowInput, kidSizeInOwnWM);
// "offset" is in terms of the CSS Box Alignment container (i.e. it's in
// terms of pcWM). But our return value needs to in terms of the containing

View File

@@ -35,12 +35,14 @@
#endif
using namespace mozilla;
typedef nsAbsoluteContainingBlock::AbsPosReflowFlags AbsPosReflowFlags;
typedef nsGridContainerFrame::TrackSize TrackSize;
const uint32_t nsGridContainerFrame::kTranslatedMaxLine =
uint32_t(nsStyleGridLine::kMaxLine - nsStyleGridLine::kMinLine);
const uint32_t nsGridContainerFrame::kAutoLine = kTranslatedMaxLine + 3457U;
typedef nsTHashtable< nsPtrHashKey<nsIFrame> > FrameHashtable;
typedef mozilla::CSSAlignUtils::AlignJustifyFlags AlignJustifyFlags;
// https://drafts.csswg.org/css-sizing/#constraints
enum class SizingConstraint
@@ -2586,8 +2588,9 @@ GetDisplayFlagsForGridItem(nsIFrame* aFrame)
// Align an item's margin box in its aAxis inside aCBSize.
static void
AlignJustifySelf(uint8_t aAlignment, bool aOverflowSafe, LogicalAxis aAxis,
bool aSameSide, nscoord aBaselineAdjust, nscoord aCBSize,
AlignJustifySelf(uint8_t aAlignment, LogicalAxis aAxis,
AlignJustifyFlags aFlags,
nscoord aBaselineAdjust, nscoord aCBSize,
const ReflowInput& aRI, const LogicalSize& aChildSize,
LogicalPoint* aPos)
{
@@ -2596,15 +2599,15 @@ AlignJustifySelf(uint8_t aAlignment, bool aOverflowSafe, LogicalAxis aAxis,
// NOTE: this is the resulting frame offset (border box).
nscoord offset =
CSSAlignUtils::AlignJustifySelf(aAlignment, aOverflowSafe, aAxis,
aSameSide, aBaselineAdjust, aCBSize,
CSSAlignUtils::AlignJustifySelf(aAlignment, aAxis, aFlags,
aBaselineAdjust, aCBSize,
aRI, aChildSize);
// Set the position (aPos) for the requested alignment.
if (offset != 0) {
WritingMode wm = aRI.GetWritingMode();
nscoord& pos = aAxis == eLogicalAxisBlock ? aPos->B(wm) : aPos->I(wm);
pos += MOZ_LIKELY(aSameSide) ? offset : -offset;
pos += MOZ_LIKELY(aFlags & AlignJustifyFlags::eSameSide) ? offset : -offset;
}
}
@@ -2615,8 +2618,18 @@ AlignSelf(const nsGridContainerFrame::GridItemInfo& aGridItem,
LogicalPoint* aPos)
{
auto alignSelf = aAlignSelf;
bool overflowSafe = alignSelf & NS_STYLE_ALIGN_SAFE;
AlignJustifyFlags flags = AlignJustifyFlags::eNoFlags;
if (alignSelf & NS_STYLE_ALIGN_SAFE) {
flags |= AlignJustifyFlags::eOverflowSafe;
}
alignSelf &= ~NS_STYLE_ALIGN_FLAG_BITS;
WritingMode childWM = aRI.GetWritingMode();
if (aCBWM.ParallelAxisStartsOnSameSide(eLogicalAxisBlock, childWM)) {
flags |= AlignJustifyFlags::eSameSide;
}
// Grid's 'align-self' axis is never parallel to the container's inline axis.
if (alignSelf == NS_STYLE_ALIGN_LEFT || alignSelf == NS_STYLE_ALIGN_RIGHT) {
alignSelf = NS_STYLE_ALIGN_START;
@@ -2624,11 +2637,7 @@ AlignSelf(const nsGridContainerFrame::GridItemInfo& aGridItem,
if (MOZ_LIKELY(alignSelf == NS_STYLE_ALIGN_NORMAL)) {
alignSelf = NS_STYLE_ALIGN_STRETCH;
}
WritingMode childWM = aRI.GetWritingMode();
// |sameSide| is true if the container's start side in this axis is the same
// as the child's start side, in the child's parallel axis.
bool sameSide = aCBWM.ParallelAxisStartsOnSameSide(eLogicalAxisBlock,
childWM);
nscoord baselineAdjust = 0;
if (alignSelf == NS_STYLE_ALIGN_BASELINE ||
alignSelf == NS_STYLE_ALIGN_LAST_BASELINE) {
@@ -2638,7 +2647,7 @@ AlignSelf(const nsGridContainerFrame::GridItemInfo& aGridItem,
bool isOrthogonal = aCBWM.IsOrthogonalTo(childWM);
LogicalAxis axis = isOrthogonal ? eLogicalAxisInline : eLogicalAxisBlock;
AlignJustifySelf(alignSelf, overflowSafe, axis, sameSide, baselineAdjust,
AlignJustifySelf(alignSelf, axis, flags, baselineAdjust,
aCBSize, aRI, aSize, aPos);
}
@@ -2649,16 +2658,22 @@ JustifySelf(const nsGridContainerFrame::GridItemInfo& aGridItem,
LogicalPoint* aPos)
{
auto justifySelf = aJustifySelf;
bool overflowSafe = justifySelf & NS_STYLE_JUSTIFY_SAFE;
AlignJustifyFlags flags = AlignJustifyFlags::eNoFlags;
if (justifySelf & NS_STYLE_JUSTIFY_SAFE) {
flags |= AlignJustifyFlags::eOverflowSafe;
}
justifySelf &= ~NS_STYLE_JUSTIFY_FLAG_BITS;
WritingMode childWM = aRI.GetWritingMode();
if (aCBWM.ParallelAxisStartsOnSameSide(eLogicalAxisInline, childWM)) {
flags |= AlignJustifyFlags::eSameSide;
}
if (MOZ_LIKELY(justifySelf == NS_STYLE_ALIGN_NORMAL)) {
justifySelf = NS_STYLE_ALIGN_STRETCH;
}
WritingMode childWM = aRI.GetWritingMode();
// |sameSide| is true if the container's start side in this axis is the same
// as the child's start side, in the child's parallel axis.
bool sameSide = aCBWM.ParallelAxisStartsOnSameSide(eLogicalAxisInline,
childWM);
nscoord baselineAdjust = 0;
// Grid's 'justify-self' axis is always parallel to the container's inline
// axis, so justify-self:left|right always applies.
@@ -2680,7 +2695,7 @@ JustifySelf(const nsGridContainerFrame::GridItemInfo& aGridItem,
bool isOrthogonal = aCBWM.IsOrthogonalTo(childWM);
LogicalAxis axis = isOrthogonal ? eLogicalAxisBlock : eLogicalAxisInline;
AlignJustifySelf(justifySelf, overflowSafe, axis, sameSide, baselineAdjust,
AlignJustifySelf(justifySelf, axis, flags, baselineAdjust,
aCBSize, aRI, aSize, aPos);
}