Bug 1235922 Part 1: Introduce a helper-function to share code for justify-content and align-content space-around and space-between in flexbox layout. r?mats
MozReview-Commit-ID: tncRJiojh
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -2668,42 +2668,22 @@ MainAxisPositionTracker::
// All packing space goes at the beginning
mPosition += mPackingSpaceRemaining;
break;
case NS_STYLE_JUSTIFY_CENTER:
// Half the packing space goes at the beginning
mPosition += mPackingSpaceRemaining / 2;
break;
case NS_STYLE_JUSTIFY_SPACE_BETWEEN:
- MOZ_ASSERT(mPackingSpaceRemaining >= 0,
- "negative packing space should make us use 'flex-start' "
- "instead of 'space-between'");
- // 1 packing space between each flex item, no packing space at ends.
- mNumPackingSpacesRemaining = aLine->NumItems() - 1;
- break;
case NS_STYLE_JUSTIFY_SPACE_AROUND:
- MOZ_ASSERT(mPackingSpaceRemaining >= 0,
- "negative packing space should make us use 'center' "
- "instead of 'space-around'");
- // 1 packing space between each flex item, plus half a packing space
- // at beginning & end. So our number of full packing-spaces is equal
- // to the number of flex items.
- mNumPackingSpacesRemaining = aLine->NumItems();
- if (mNumPackingSpacesRemaining > 0) {
- // The edges (start/end) share one full packing space
- nscoord totalEdgePackingSpace =
- mPackingSpaceRemaining / mNumPackingSpacesRemaining;
-
- // ...and we'll use half of that right now, at the start
- mPosition += totalEdgePackingSpace / 2;
- // ...but we need to subtract all of it right away, so that we won't
- // hand out any of it to intermediate packing spaces.
- mPackingSpaceRemaining -= totalEdgePackingSpace;
- mNumPackingSpacesRemaining--;
- }
+ nsFlexContainerFrame::CalculatePackingSpace(aLine->NumItems(),
+ mJustifyContent,
+ &mPosition,
+ &mNumPackingSpacesRemaining,
+ &mPackingSpaceRemaining);
break;
default:
MOZ_ASSERT_UNREACHABLE("Unexpected justify-content value");
}
}
MOZ_ASSERT(mNumPackingSpacesRemaining == 0 ||
mNumAutoMarginsInMainAxis == 0,
@@ -2887,42 +2867,23 @@ CrossAxisPositionTracker::
// All packing space goes at the beginning
mPosition += mPackingSpaceRemaining;
break;
case NS_STYLE_ALIGN_CENTER:
// Half the packing space goes at the beginning
mPosition += mPackingSpaceRemaining / 2;
break;
case NS_STYLE_ALIGN_SPACE_BETWEEN:
- MOZ_ASSERT(mPackingSpaceRemaining >= 0,
- "negative packing space should make us use 'flex-start' "
- "instead of 'space-between'");
- // 1 packing space between each flex line, no packing space at ends.
- mNumPackingSpacesRemaining = numLines - 1;
+ case NS_STYLE_ALIGN_SPACE_AROUND:
+ nsFlexContainerFrame::CalculatePackingSpace(numLines,
+ mAlignContent,
+ &mPosition,
+ &mNumPackingSpacesRemaining,
+ &mPackingSpaceRemaining);
break;
- case NS_STYLE_ALIGN_SPACE_AROUND: {
- MOZ_ASSERT(mPackingSpaceRemaining >= 0,
- "negative packing space should make us use 'center' "
- "instead of 'space-around'");
- // 1 packing space between each flex line, plus half a packing space
- // at beginning & end. So our number of full packing-spaces is equal
- // to the number of flex lines.
- mNumPackingSpacesRemaining = numLines;
- // The edges (start/end) share one full packing space
- nscoord totalEdgePackingSpace =
- mPackingSpaceRemaining / mNumPackingSpacesRemaining;
-
- // ...and we'll use half of that right now, at the start
- mPosition += totalEdgePackingSpace / 2;
- // ...but we need to subtract all of it right away, so that we won't
- // hand out any of it to intermediate packing spaces.
- mPackingSpaceRemaining -= totalEdgePackingSpace;
- mNumPackingSpacesRemaining--;
- break;
- }
case NS_STYLE_ALIGN_STRETCH: {
// Split space equally between the lines:
MOZ_ASSERT(mPackingSpaceRemaining > 0,
"negative packing space should make us use 'flex-start' "
"instead of 'stretch' (and we shouldn't bother with this "
"code if we have 0 packing space)");
uint32_t numLinesLeft = numLines;
@@ -4003,16 +3964,63 @@ public:
}
private:
const FrameProperties mItemProps;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
void
+nsFlexContainerFrame::CalculatePackingSpace(uint32_t aNumThingsToPack,
+ uint8_t aAlignVal,
+ nscoord* aFirstSubjectOffset,
+ uint32_t* aNumPackingSpacesRemaining,
+ nscoord* aPackingSpaceRemaining)
+{
+ MOZ_ASSERT(NS_STYLE_ALIGN_SPACE_BETWEEN == NS_STYLE_JUSTIFY_SPACE_BETWEEN &&
+ NS_STYLE_ALIGN_SPACE_AROUND == NS_STYLE_JUSTIFY_SPACE_AROUND,
+ "CalculatePackingSpace assumes that NS_STYLE_ALIGN_SPACE and "
+ "NS_STYLE_JUSTIFY_SPACE constants are interchangeable");
+
+ MOZ_ASSERT(aAlignVal == NS_STYLE_ALIGN_SPACE_BETWEEN ||
+ aAlignVal == NS_STYLE_ALIGN_SPACE_AROUND,
+ "Unexpected alignment value");
+
+ MOZ_ASSERT(*aPackingSpaceRemaining >= 0,
+ "Should not be called with negative packing space");
+
+ MOZ_ASSERT(aNumThingsToPack >= 1,
+ "Should not be called with less than 1 thing to pack");
+
+ // Packing spaces between items:
+ *aNumPackingSpacesRemaining = aNumThingsToPack - 1;
+
+ if (aAlignVal == NS_STYLE_ALIGN_SPACE_BETWEEN) {
+ // No need to reserve space at beginning/end, so we're done.
+ return;
+ }
+
+ // We need to add 1 packing space, split between beginning/end, for
+ // space-around:
+ size_t numPackingSpacesForEdges = 1;
+
+ // How big will each "full" packing space be:
+ nscoord packingSpaceSize = *aPackingSpaceRemaining /
+ (*aNumPackingSpacesRemaining + numPackingSpacesForEdges);
+ // How much packing-space are we allocating to the edges:
+ nscoord totalEdgePackingSpace = numPackingSpacesForEdges * packingSpaceSize;
+
+ // Use half of that edge packing space right now:
+ *aFirstSubjectOffset += totalEdgePackingSpace / 2;
+ // ...but we need to subtract all of it right away, so that we won't
+ // hand out any of it to intermediate packing spaces.
+ *aPackingSpaceRemaining -= totalEdgePackingSpace;
+}
+
+void
nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext,
ReflowOutput& aDesiredSize,
const ReflowInput& aReflowInput,
nsReflowStatus& aStatus,
nscoord aContentBoxMainSize,
nscoord aAvailableBSizeForContent,
nsTArray<StrutInfo>& aStruts,
const FlexboxAxisTracker& aAxisTracker)
--- a/layout/generic/nsFlexContainerFrame.h
+++ b/layout/generic/nsFlexContainerFrame.h
@@ -77,16 +77,36 @@ public:
virtual nsresult GetFrameName(nsAString& aResult) const override;
#endif
nscoord GetLogicalBaseline(mozilla::WritingMode aWM) const override;
// Flexbox-specific public methods
bool IsHorizontal();
+ /**
+ * Helper function to calculate packing space and initial offset of alignment
+ * subjects in MainAxisPositionTracker() and CrossAxisPositionTracker() for
+ * space-between and space-around.
+ *
+ * @param aNumThingsToPack Number of alignment subjects.
+ * @param aAlignVal Value for align-self or justify-self.
+ * @param aFirstSubjectOffset Outparam for first subject offset.
+ * @param aNumPackingSpacesRemaining Outparam for number of equal-sized
+ * packing spaces to apply between each
+ * alignment subject.
+ * @param aPackingSpaceRemaining Outparam for total amount of packing
+ * space to be divided up.
+ */
+ static void CalculatePackingSpace(uint32_t aNumThingsToPack,
+ uint8_t aAlignVal,
+ nscoord* aFirstSubjectOffset,
+ uint32_t* aNumPackingSpacesRemaining,
+ nscoord* aPackingSpaceRemaining);
+
protected:
// Protected constructor & destructor
explicit nsFlexContainerFrame(nsStyleContext* aContext)
: nsContainerFrame(aContext)
, mBaselineFromLastReflow(NS_INTRINSIC_WIDTH_UNKNOWN)
{}
virtual ~nsFlexContainerFrame();