Bug 1311865: Refactor the grid "same sides" code into a simpler WritingMode::ParallelAxisHasSamePolarity() utility function. r?mats draft
authorDaniel Holbert <dholbert@cs.stanford.edu>
Thu, 20 Oct 2016 15:51:47 -0700
changeset 427832 88bc44dfc8018fba4336fdfdac088e6e4e939faf
parent 427724 06d4b91875087e77e8a6569b5df9db9b1ade7569
child 534568 5a3d96436dece81234e0c9b1ca8bb489f6919287
push id33132
push userdholbert@mozilla.com
push dateThu, 20 Oct 2016 23:00:15 +0000
reviewersmats
bugs1311865
milestone52.0a1
Bug 1311865: Refactor the grid "same sides" code into a simpler WritingMode::ParallelAxisHasSamePolarity() utility function. r?mats MozReview-Commit-ID: G9FRriSlZaG
layout/generic/WritingModes.h
layout/generic/nsGridContainerFrame.cpp
--- 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;