--- a/layout/generic/WritingModes.h
+++ b/layout/generic/WritingModes.h
@@ -38,16 +38,21 @@ struct IMENotification;
} // namespace widget
// Physical axis constants.
enum PhysicalAxis {
eAxisVertical = 0x0,
eAxisHorizontal = 0x1
};
+inline LogicalAxis GetOrthogonalAxis(LogicalAxis aAxis)
+{
+ return (aAxis == eLogicalAxisBlock) ? eLogicalAxisInline : eLogicalAxisBlock;
+}
+
inline bool IsInline(LogicalSide aSide) { return aSide & 0x2; }
inline bool IsBlock(LogicalSide aSide) { return !IsInline(aSide); }
inline bool IsEnd(LogicalSide aSide) { return aSide & 0x1; }
inline bool IsStart(LogicalSide aSide) { return !IsEnd(aSide); }
inline LogicalAxis GetAxis(LogicalSide aSide)
{
return IsInline(aSide) ? eLogicalAxisInline : eLogicalAxisBlock;
@@ -582,16 +587,45 @@ public:
/**
* Check whether two modes are orthogonal to each other.
*/
bool IsOrthogonalTo(const WritingMode& aOther) const
{
return IsVertical() != aOther.IsVertical();
}
+ /**
+ * Returns true if this writing mode's aLogicalAxis has the same "polarity"
+ * (i.e. same start/end edges) as the parallel axis in aOtherWM.
+ *
+ * @param aLogicalAxis The axis to compare from this WritingMode.
+ * @param aSecondWM The second WritingMode (from which we'll choose the
+ * axis that's parallel to this WritingMode's aLogicalAxis,
+ * for comparison).
+ */
+ bool ParallelAxisHasSamePolarity(LogicalAxis aLogicalAxis,
+ const WritingMode& aOther) const
+ {
+ Side myStartSide =
+ this->PhysicalSide(MakeLogicalSide(aLogicalAxis,
+ eLogicalEdgeStart));
+
+ // Figure out which of aOther's axes is parallel to |this| WritingMode's
+ // aLogicalAxis, and get its physical start side as well.
+ LogicalAxis otherWMAxis = aOther.IsOrthogonalTo(*this) ?
+ GetOrthogonalAxis(aLogicalAxis) : aLogicalAxis;
+ Side otherWMStartSide =
+ aOther.PhysicalSide(MakeLogicalSide(otherWMAxis,
+ eLogicalEdgeStart));
+
+ NS_ASSERTION(myStartSide % 2 == otherWMStartSide % 2,
+ "Should end up with sides in the same physical axis");
+ return myStartSide == otherWMStartSide;
+ }
+
uint8_t GetBits() const { return mWritingMode; }
const char* DebugString() const {
return IsVertical()
? IsVerticalLR()
? IsBidiLTR()
? IsSideways() ? "sw-lr-ltr" : "v-lr-ltr"
: IsSideways() ? "sw-lr-rtl" : "v-lr-rtl"
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -2714,26 +2714,16 @@ AlignJustifySelf(uint8_t aAlignment, boo
MOZ_ASSERT_UNREACHABLE("unknown align-/justify-self value");
}
if (offset != 0) {
nscoord& pos = aAxis == eLogicalAxisBlock ? aPos->B(wm) : aPos->I(wm);
pos += MOZ_LIKELY(aSameSide) ? offset : -offset;
}
}
-static bool
-SameSide(WritingMode aContainerWM, LogicalSide aContainerSide,
- WritingMode aChildWM, LogicalSide aChildSide)
-{
- MOZ_ASSERT(aContainerWM.PhysicalAxis(GetAxis(aContainerSide)) ==
- aChildWM.PhysicalAxis(GetAxis(aChildSide)));
- return aContainerWM.PhysicalSide(aContainerSide) ==
- aChildWM.PhysicalSide(aChildSide);
-}
-
static void
AlignSelf(const nsGridContainerFrame::GridItemInfo& aGridItem,
uint8_t aAlignSelf, nscoord aCBSize, const WritingMode aCBWM,
const ReflowInput& aRI, const LogicalSize& aSize,
LogicalPoint* aPos)
{
auto alignSelf = aAlignSelf;
bool overflowSafe = alignSelf & NS_STYLE_ALIGN_SAFE;
@@ -2741,28 +2731,28 @@ AlignSelf(const nsGridContainerFrame::Gr
// 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;
}
if (MOZ_LIKELY(alignSelf == NS_STYLE_ALIGN_NORMAL)) {
alignSelf = NS_STYLE_ALIGN_STRETCH;
}
WritingMode childWM = aRI.GetWritingMode();
- bool isOrthogonal = aCBWM.IsOrthogonalTo(childWM);
// |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 = SameSide(aCBWM, eLogicalSideBStart,
- childWM, isOrthogonal ? eLogicalSideIStart
- : eLogicalSideBStart);
+ bool sameSide = aCBWM.ParallelAxisHasSamePolarity(eLogicalAxisBlock,
+ childWM);
nscoord baselineAdjust = 0;
if (alignSelf == NS_STYLE_ALIGN_BASELINE ||
alignSelf == NS_STYLE_ALIGN_LAST_BASELINE) {
alignSelf = aGridItem.GetSelfBaseline(alignSelf, eLogicalAxisBlock,
&baselineAdjust);
}
+
+ bool isOrthogonal = aCBWM.IsOrthogonalTo(childWM);
LogicalAxis axis = isOrthogonal ? eLogicalAxisInline : eLogicalAxisBlock;
AlignJustifySelf(alignSelf, overflowSafe, axis, sameSide, baselineAdjust,
aCBSize, aRI, aSize, aPos);
}
static void
JustifySelf(const nsGridContainerFrame::GridItemInfo& aGridItem,
uint8_t aJustifySelf, nscoord aCBSize, const WritingMode aCBWM,
@@ -2771,22 +2761,20 @@ JustifySelf(const nsGridContainerFrame::
{
auto justifySelf = aJustifySelf;
bool overflowSafe = justifySelf & NS_STYLE_JUSTIFY_SAFE;
justifySelf &= ~NS_STYLE_JUSTIFY_FLAG_BITS;
if (MOZ_LIKELY(justifySelf == NS_STYLE_ALIGN_NORMAL)) {
justifySelf = NS_STYLE_ALIGN_STRETCH;
}
WritingMode childWM = aRI.GetWritingMode();
- bool isOrthogonal = aCBWM.IsOrthogonalTo(childWM);
// |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 = SameSide(aCBWM, eLogicalSideIStart,
- childWM, isOrthogonal ? eLogicalSideBStart
- : eLogicalSideIStart);
+ bool sameSide = aCBWM.ParallelAxisHasSamePolarity(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.
switch (justifySelf) {
case NS_STYLE_JUSTIFY_LEFT:
justifySelf = aCBWM.IsBidiLTR() ? NS_STYLE_JUSTIFY_START
: NS_STYLE_JUSTIFY_END;
break;
@@ -2796,16 +2784,17 @@ JustifySelf(const nsGridContainerFrame::
break;
case NS_STYLE_JUSTIFY_BASELINE:
case NS_STYLE_JUSTIFY_LAST_BASELINE:
justifySelf = aGridItem.GetSelfBaseline(justifySelf, eLogicalAxisInline,
&baselineAdjust);
break;
}
+ bool isOrthogonal = aCBWM.IsOrthogonalTo(childWM);
LogicalAxis axis = isOrthogonal ? eLogicalAxisBlock : eLogicalAxisInline;
AlignJustifySelf(justifySelf, overflowSafe, axis, sameSide, baselineAdjust,
aCBSize, aRI, aSize, aPos);
}
static uint16_t
GetAlignJustifyValue(uint16_t aAlignment, const WritingMode aWM,
const bool aIsAlign, bool* aOverflowSafe)
@@ -4175,27 +4164,21 @@ nsGridContainerFrame::Tracks::Initialize
if (alignContent == NS_STYLE_ALIGN_BASELINE ||
alignContent == NS_STYLE_ALIGN_LAST_BASELINE) {
const auto selfAlignEdge = alignContent == NS_STYLE_ALIGN_BASELINE ?
NS_STYLE_ALIGN_SELF_START : NS_STYLE_ALIGN_SELF_END;
bool validCombo = selfAlignment == NS_STYLE_ALIGN_NORMAL ||
selfAlignment == NS_STYLE_ALIGN_STRETCH ||
selfAlignment == selfAlignEdge;
if (!validCombo) {
+ // We're doing alignment in the axis that's orthogonal to mAxis here.
+ LogicalAxis alignAxis = GetOrthogonalAxis(mAxis);
// |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.
- // XXX SameSide is way to complicated to use! - add a WritingMode
- // XXX method instead that does this in a better way.
- auto side = isInlineAxis ? eLogicalSideBStart : eLogicalSideIStart;
- // XXX the "isInlineAxis == isOrthogonal" is currently redundant, but
- // might be relevant if we change the itemHasBaselineParallelToTrack
- // condition above?
- auto childSide = isInlineAxis == isOrthogonal ? eLogicalSideIStart
- : eLogicalSideBStart;
- bool sameSide = SameSide(wm, side, childWM, childSide);
+ bool sameSide = wm.ParallelAxisHasSamePolarity(alignAxis, childWM);
switch (selfAlignment) {
case NS_STYLE_ALIGN_LEFT:
selfAlignment = !isInlineAxis || wm.IsBidiLTR() ? NS_STYLE_ALIGN_START
: NS_STYLE_ALIGN_END;
break;
case NS_STYLE_ALIGN_RIGHT:
selfAlignment = isInlineAxis && wm.IsBidiLTR() ? NS_STYLE_ALIGN_END
: NS_STYLE_ALIGN_START;