Bug 775624 Part 10b - Convert NS_FRAME_TRUNCATED to use bit-field and methods. r?dholbert draft
authorTing-Yu Lin <tlin@mozilla.com>
Mon, 13 Feb 2017 16:16:44 +0800
changeset 488473 7d289785024ce47eec3d4ba14b5f86373fc527e5
parent 488472 dcf513cd9191031d45f34ee3d954bb99fe56e3c9
child 488474 48f69d6d526582d6c0f824fed2cb479006acebbc
push id46538
push userbmo:tlin@mozilla.com
push dateThu, 23 Feb 2017 05:39:06 +0000
reviewersdholbert
bugs775624
milestone54.0a1
Bug 775624 Part 10b - Convert NS_FRAME_TRUNCATED to use bit-field and methods. r?dholbert NS_FRAME_TRUNCATED will be removed when NS_MergeReflowStatusInto() is removed. MozReview-Commit-ID: 21lit9xSAE1
layout/generic/BlockReflowInput.cpp
layout/generic/nsColumnSetFrame.cpp
layout/generic/nsFrame.cpp
layout/generic/nsIFrame.h
layout/tables/nsTableRowFrame.cpp
--- a/layout/generic/BlockReflowInput.cpp
+++ b/layout/generic/BlockReflowInput.cpp
@@ -915,25 +915,25 @@ BlockReflowInput::FlowAndPlaceFloat(nsIF
   if (reflowStatus.IsIncomplete())
     floatMargin.BEnd(wm) = 0;
 
   // In the case that we're in columns and not splitting floats, we need
   // to check here that the float's height fit, and if it didn't, bail.
   // (controlled by the pref "layout.float-fragments-inside-column.enabled")
   //
   // Likewise, if none of the float fit, and it needs to be pushed in
-  // its entirety to the next page (NS_FRAME_IS_TRUNCATED or
+  // its entirety to the next page (IsTruncated() or
   // NS_INLINE_IS_BREAK_BEFORE), we need to do the same.
   if ((ContentBSize() != NS_UNCONSTRAINEDSIZE &&
        !mFlags.mFloatFragmentsInsideColumnEnabled &&
        adjustedAvailableSpace.BSize(wm) == NS_UNCONSTRAINEDSIZE &&
        !mustPlaceFloat &&
        aFloat->BSize(wm) + floatMargin.BStartEnd(wm) >
        ContentBEnd() - floatPos.B(wm)) ||
-      NS_FRAME_IS_TRUNCATED(reflowStatus) ||
+      reflowStatus.IsTruncated() ||
       NS_INLINE_IS_BREAK_BEFORE(reflowStatus)) {
     PushFloatPastBreak(aFloat);
     return false;
   }
 
   // We can't use aFloat->ShouldAvoidBreakInside(mReflowInput) here since
   // its mIsTopOfPage may be true even though the float isn't at the
   // top when floatPos.B(wm) > 0.
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -678,17 +678,17 @@ nsColumnSetFrame::ReflowChildren(ReflowO
     ConsiderChildOverflow(overflowRects, child);
     contentBEnd = std::max(contentBEnd, childContentBEnd);
     aColData.mLastBSize = childContentBEnd;
     aColData.mSumBSize += childContentBEnd;
 
     // Build a continuation column if necessary
     nsIFrame* kidNextInFlow = child->GetNextInFlow();
 
-    if (aStatus.IsFullyComplete() && !NS_FRAME_IS_TRUNCATED(aStatus)) {
+    if (aStatus.IsFullyComplete() && !aStatus.IsTruncated()) {
       NS_ASSERTION(!kidNextInFlow, "next in flow should have been deleted");
       child = nullptr;
       break;
     } else {
       ++columnCount;
       // Make sure that the column has a next-in-flow. If not, we must
       // create one to hold the overflowing stuff, even if we're just
       // going to put it on our overflow list and let *our*
@@ -824,20 +824,20 @@ nsColumnSetFrame::ReflowChildren(ReflowO
       // dummy containerSize, and reset with the correct container size.
       child->SetPosition(wm, child->GetLogicalPosition(wm, containerSize),
                          finalContainerSize);
     }
   }
 
 #ifdef DEBUG_roc
   printf("*** DONE PASS feasible=%d\n", allFit && aStatus.IsFullyComplete()
-         && !NS_FRAME_IS_TRUNCATED(aStatus));
+         && !aStatus.IsTruncated());
 #endif
   return allFit && aStatus.IsFullyComplete()
-    && !NS_FRAME_IS_TRUNCATED(aStatus);
+    && !aStatus.IsTruncated();
 }
 
 void
 nsColumnSetFrame::DrainOverflowColumns()
 {
   // First grab the prev-in-flows overflows and reparent them to this
   // frame.
   nsPresContext* presContext = PresContext();
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -191,23 +191,23 @@ IsXULBoxWrapped(const nsIFrame* aFrame)
 void
 nsReflowStatus::UpdateTruncated(const ReflowInput& aReflowInput,
                                 const ReflowOutput& aMetrics)
 {
   const WritingMode containerWM = aMetrics.GetWritingMode();
   if (aReflowInput.GetWritingMode().IsOrthogonalTo(containerWM)) {
     // Orthogonal flows are always reflowed with an unconstrained dimension,
     // so should never end up truncated (see ReflowInput::Init()).
-    mStatus &= ~NS_FRAME_TRUNCATED;
+    mTruncated = false;
   } else if (aReflowInput.AvailableBSize() != NS_UNCONSTRAINEDSIZE &&
              aReflowInput.AvailableBSize() < aMetrics.BSize(containerWM) &&
              !aReflowInput.mFlags.mIsTopOfPage) {
-    mStatus |= NS_FRAME_TRUNCATED;
+    mTruncated = true;
   } else {
-    mStatus &= ~NS_FRAME_TRUNCATED;
+    mTruncated = false;
   }
 }
 
 // Formerly the nsIFrameDebug interface
 
 #ifdef DEBUG
 static bool gShowFrameBorders = false;
 
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -198,23 +198,25 @@ enum nsSpread {
 // Reflow status returned by the Reflow() methods.
 class nsReflowStatus final {
 public:
   nsReflowStatus()
     : mStatus(0)
     , mIncomplete(false)
     , mOverflowIncomplete(false)
     , mNextInFlowNeedsReflow(false)
+    , mTruncated(false)
   {}
 
   // Reset all the bit-fields.
   void Reset() {
     mIncomplete = false;
     mOverflowIncomplete = false;
     mNextInFlowNeedsReflow = false;
+    mTruncated = false;
   }
 
   nsReflowStatus(uint32_t aStatus)
     : mStatus(aStatus)
   {}
 
   uint32_t& operator=(uint32_t aRhs) {
     mStatus = aRhs;
@@ -281,26 +283,33 @@ public:
 
   // mNextInFlowNeedsReflow bit flag means that the next-in-flow is dirty,
   // and also needs to be reflowed. This status only makes sense for a frame
   // that is not complete, i.e. you wouldn't set mNextInFlowNeedsReflow when
   // IsComplete() is true.
   bool NextInFlowNeedsReflow() const { return mNextInFlowNeedsReflow; }
   void SetNextInFlowNeedsReflow() { mNextInFlowNeedsReflow = true; }
 
+  // mTruncated bit flag means that the part of the frame before the first
+  // possible break point was unable to fit in the available space.
+  // Therefore, the entire frame should be moved to the next continuation of
+  // the parent frame. A frame that begins at the top of the page must never
+  // be truncated. Doing so would likely cause an infinite loop.
+  bool IsTruncated() const { return mTruncated; }
   void UpdateTruncated(const mozilla::ReflowInput& aReflowInput,
                        const mozilla::ReflowOutput& aMetrics);
 
 private:
   uint32_t mStatus;
 
   // Frame completion status bit flags.
   bool mIncomplete : 1;
   bool mOverflowIncomplete : 1;
   bool mNextInFlowNeedsReflow : 1;
+  bool mTruncated : 1;
 };
 
 #define NS_FRAME_COMPLETE             0       // Note: not a bit!
 #define NS_FRAME_NOT_COMPLETE         0x1
 #define NS_FRAME_REFLOW_NEXTINFLOW    0x2
 #define NS_FRAME_OVERFLOW_INCOMPLETE  0x4
 
 // This bit is set, when a break is requested. This bit is orthogonal
@@ -347,24 +356,18 @@ private:
 // Take a completion status and add to it the desire to have a
 // line-break after. For this macro we do need the completion status
 // because the user of the status will need to know whether to
 // continue the frame or not.
 #define NS_INLINE_LINE_BREAK_AFTER(_completionStatus)                   \
   ((_completionStatus) | NS_INLINE_BREAK | NS_INLINE_BREAK_AFTER |      \
    NS_INLINE_MAKE_BREAK_TYPE(StyleClear::Line))
 
-// A frame is "truncated" if the part of the frame before the first
-// possible break point was unable to fit in the available vertical
-// space.  Therefore, the entire frame should be moved to the next page.
-// A frame that begins at the top of the page must never be "truncated".
-// Doing so would likely cause an infinite loop.
 #define NS_FRAME_TRUNCATED  0x0010
-#define NS_FRAME_IS_TRUNCATED(status) \
-  (0 != ((status) & NS_FRAME_TRUNCATED))
+
 #define NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aMetrics) \
   aStatus.UpdateTruncated(aReflowInput, aMetrics);
 
 // Merge the incompleteness, truncation and NS_FRAME_REFLOW_NEXTINFLOW
 // status from aSecondary into aPrimary.
 void NS_MergeReflowStatusInto(nsReflowStatus* aPrimary,
                               nsReflowStatus aSecondary);
 
--- a/layout/tables/nsTableRowFrame.cpp
+++ b/layout/tables/nsTableRowFrame.cpp
@@ -1172,17 +1172,17 @@ nsTableRowFrame::ReflowCellFrame(nsPresC
                     ReflowInput::CALLER_WILL_INIT);
   InitChildReflowInput(*aPresContext, availSize, borderCollapse, cellReflowInput);
   cellReflowInput.mFlags.mIsTopOfPage = aIsTopOfPage;
 
   ReflowOutput desiredSize(aReflowInput);
 
   ReflowChild(aCellFrame, aPresContext, desiredSize, cellReflowInput,
               0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
-  bool fullyComplete = aStatus.IsComplete() && !NS_FRAME_IS_TRUNCATED(aStatus);
+  bool fullyComplete = aStatus.IsComplete() && !aStatus.IsTruncated();
   if (fullyComplete) {
     desiredSize.BSize(wm) = aAvailableBSize;
   }
   aCellFrame->SetSize(wm, LogicalSize(wm, cellSize.ISize(wm),
                                       desiredSize.BSize(wm)));
 
   // Note: BlockDirAlignChild can affect the overflow rect.
   // XXX What happens if this cell has 'vertical-align: baseline' ?