Bug 1174003 part 8: [css-flexbox] Change flex item intrinsic ratio calculations to use logical axes and a LogicalSize. r?mats draft
authorDaniel Holbert <dholbert@cs.stanford.edu>
Tue, 27 Feb 2018 16:32:58 -0800
changeset 760720 69780811f58b21177071441c56b55ab7f916cc17
parent 760699 3e05d3091220f592b6d7e202792ace6130204bca
child 760721 e3dea540ad2b45143d8fec186317d6a7c8d7ef07
child 761086 3253b51cd61de12c57d66a1a551bc24ac4291c81
child 761089 c62879621af1823e7a8075d425648f6be90042c6
push id100734
push userdholbert@mozilla.com
push dateWed, 28 Feb 2018 00:46:29 +0000
reviewersmats
bugs1174003
milestone60.0a1
Bug 1174003 part 8: [css-flexbox] Change flex item intrinsic ratio calculations to use logical axes and a LogicalSize. r?mats This patch doesn't affect behavior. It does the following: - Changes the AxisOrientationTracker "GetMainComponent/GetCrossComponent" APIs to take a LogicalSize rather than a nsSize. - Changes FlexItem::mIntrinsicRatio to be a LogicalSize rather than a nsSize. - Simplifies the MainSizeFromAspectRatio() helper-function (in particular, it removes a call to IsCrossAxisHorizontal(), which is an API I'm gradually removing in this patch series.) MozReview-Commit-ID: KXUmaUVPMZa
layout/generic/nsFlexContainerFrame.cpp
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -324,25 +324,27 @@ public:
   // writing mode's corresponding axis. (From 'flex-wrap: *-reverse')
   bool IsCrossAxisReversed() const {
     return mIsCrossAxisReversed;
   }
 
   bool IsRowOriented() const { return mIsRowOriented; }
   bool IsColumnOriented() const { return !mIsRowOriented; }
 
-  nscoord GetMainComponent(const nsSize& aSize) const {
-    return GET_MAIN_COMPONENT(*this, aSize.width, aSize.height);
+  // aSize is expected to match the flex container's WritingMode.
+  nscoord GetMainComponent(const LogicalSize& aSize) const {
+    return IsRowOriented() ? aSize.ISize(mWM) : aSize.BSize(mWM);
   }
   int32_t GetMainComponent(const LayoutDeviceIntSize& aIntSize) const {
     return GET_MAIN_COMPONENT(*this, aIntSize.width, aIntSize.height);
   }
 
-  nscoord GetCrossComponent(const nsSize& aSize) const {
-    return GET_CROSS_COMPONENT(*this, aSize.width, aSize.height);
+  // aSize is expected to match the flex container's WritingMode.
+  nscoord GetCrossComponent(const LogicalSize& aSize) const {
+    return IsRowOriented() ? aSize.BSize(mWM) : aSize.ISize(mWM);
   }
   int32_t GetCrossComponent(const LayoutDeviceIntSize& aIntSize) const {
     return GET_CROSS_COMPONENT(*this, aIntSize.width, aIntSize.height);
   }
 
   // NOTE: aMargin is expected to use the flex container's WritingMode.
   nscoord GetMarginSizeInMainAxis(const LogicalMargin& aMargin) const {
     // If we're row-oriented, our main axis is the inline axis.
@@ -615,18 +617,20 @@ public:
       // regardless of mFlexShrink, we should just return 0.
       // (This is really a special-case for when mFlexShrink is infinity, to
       // avoid performing mFlexShrink * mFlexBaseSize = inf * 0 = undefined.)
       return 0.0f;
     }
     return mFlexShrink * mFlexBaseSize;
   }
 
-  const nsSize& IntrinsicRatio() const { return mIntrinsicRatio; }
-  bool HasIntrinsicRatio() const { return mIntrinsicRatio != nsSize(); }
+  // Returns a LogicalSize representing the flex item's logical intrinsic ratio
+  // (ISize:BSize), as expressed in the *flex container's* writing mode.
+  const LogicalSize& IntrinsicRatio() const { return mIntrinsicRatio; }
+  bool HasIntrinsicRatio() const { return !mIntrinsicRatio.IsAllZero(); }
 
   // Getters for margin:
   // ===================
   const nsMargin& GetMargin() const { return mMargin; }
 
   // Returns the margin component for a given mozilla::Side
   nscoord GetMarginComponentForSide(mozilla::Side aSide) const
   { return mMargin.Side(aSide); }
@@ -811,17 +815,17 @@ protected:
   // Helper called by the constructor, to set mNeedsMinSizeAutoResolution:
   void CheckForMinSizeAuto(const ReflowInput& aFlexItemReflowInput,
                            const FlexboxAxisTracker& aAxisTracker);
 
   // Values that we already know in constructor (and are hence mostly 'const'):
   nsIFrame* const mFrame; // The flex item's frame.
   const float mFlexGrow;
   const float mFlexShrink;
-  const nsSize mIntrinsicRatio;
+  const LogicalSize mIntrinsicRatio;
   const nsMargin mBorderPadding;
   nsMargin mMargin; // non-const because we need to resolve auto margins
 
   // These are non-const so that we can lazily update them with the item's
   // intrinsic size (obtained via a "measuring" reflow), when necessary.
   // (e.g. for "flex-basis:auto;height:auto" & "min-height:auto")
   nscoord mFlexBaseSize;
   nscoord mMainMinSize;
@@ -1397,32 +1401,29 @@ CrossSizeToUseWithRatio(const FlexItem& 
                                        aItemReflowInput.ComputedMinBSize());
   }
 
   // Indefinite cross-size.
   return NS_AUTOHEIGHT;
 }
 
 // Convenience function; returns a main-size, given a cross-size and an
-// intrinsic ratio. The intrinsic ratio must not have 0 in its cross-axis
-// component (or else we'll divide by 0).
+// intrinsic ratio. The caller is responsible for ensuring that the passed-in
+// intrinsic ratio must not have 0 in its cross-axis component (or else we'll
+// divide by 0).
 static nscoord
 MainSizeFromAspectRatio(nscoord aCrossSize,
-                        const nsSize& aIntrinsicRatio,
+                        const LogicalSize& aIntrinsicRatio,
                         const FlexboxAxisTracker& aAxisTracker)
 {
   MOZ_ASSERT(aAxisTracker.GetCrossComponent(aIntrinsicRatio) != 0,
              "Invalid ratio; will divide by 0! Caller should've checked...");
-
-  if (aAxisTracker.IsCrossAxisHorizontal()) {
-    // cross axis horiz --> aCrossSize is a width. Converting to height.
-    return NSCoordMulDiv(aCrossSize, aIntrinsicRatio.height, aIntrinsicRatio.width);
-  }
-  // cross axis vert --> aCrossSize is a height. Converting to width.
-  return NSCoordMulDiv(aCrossSize, aIntrinsicRatio.width, aIntrinsicRatio.height);
+  return NSCoordMulDiv(aCrossSize,
+                       aAxisTracker.GetMainComponent(aIntrinsicRatio),
+                       aAxisTracker.GetCrossComponent(aIntrinsicRatio));
 }
 
 // Partially resolves "min-[width|height]:auto" and returns the resulting value.
 // By "partially", I mean we don't consider the min-content size (but we do
 // consider flex-basis, main max-size, and the intrinsic aspect ratio).
 // The caller is responsible for computing & considering the min-content size
 // in combination with the partially-resolved value that this function returns.
 //
@@ -1794,17 +1795,18 @@ FlexItem::FlexItem(ReflowInput& aFlexIte
                    float aFlexGrow, float aFlexShrink, nscoord aFlexBaseSize,
                    nscoord aMainMinSize,  nscoord aMainMaxSize,
                    nscoord aTentativeCrossSize,
                    nscoord aCrossMinSize, nscoord aCrossMaxSize,
                    const FlexboxAxisTracker& aAxisTracker)
   : mFrame(aFlexItemReflowInput.mFrame),
     mFlexGrow(aFlexGrow),
     mFlexShrink(aFlexShrink),
-    mIntrinsicRatio(mFrame->GetIntrinsicRatio()),
+    // We store the intrinsic ratio in the *flex container's* WM:
+    mIntrinsicRatio(aAxisTracker.GetWritingMode(), mFrame->GetIntrinsicRatio()),
     mBorderPadding(aFlexItemReflowInput.ComputedPhysicalBorderPadding()),
     mMargin(aFlexItemReflowInput.ComputedPhysicalMargin()),
     mMainMinSize(aMainMinSize),
     mMainMaxSize(aMainMaxSize),
     mCrossMinSize(aCrossMinSize),
     mCrossMaxSize(aCrossMaxSize),
     mMainPosn(0),
     mCrossSize(aTentativeCrossSize),
@@ -1890,17 +1892,17 @@ FlexItem::FlexItem(ReflowInput& aFlexIte
 // Simplified constructor for creating a special "strut" FlexItem, for a child
 // with visibility:collapse. The strut has 0 main-size, and it only exists to
 // impose a minimum cross size on whichever FlexLine it ends up in.
 FlexItem::FlexItem(nsIFrame* aChildFrame, nscoord aCrossSize,
                    WritingMode aContainerWM)
   : mFrame(aChildFrame),
     mFlexGrow(0.0f),
     mFlexShrink(0.0f),
-    mIntrinsicRatio(),
+    mIntrinsicRatio(aContainerWM),
     // mBorderPadding uses default constructor,
     // mMargin uses default constructor,
     mFlexBaseSize(0),
     mMainMinSize(0),
     mMainMaxSize(0),
     mCrossMinSize(0),
     mCrossMaxSize(0),
     mMainSize(0),