Bug 383883: {inc} issues with block moving through non-moving float. r+sr+a=dbaron
authorsharparrow1@yahoo.com
Mon, 20 Aug 2007 13:07:50 -0700
changeset 4831 ffda74c63ca42e0c92381d84969e600c2864800f
parent 4830 5dbb75a70008768f71140dd18eaa849931e804f1
child 4832 5d8e34ec31759ec02edb60321d28bc03275e4db6
push id1
push userbsmedberg@mozilla.com
push dateThu, 20 Mar 2008 16:49:24 +0000
treeherdermozilla-central@61007906a1f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs383883
milestone1.9a8pre
Bug 383883: {inc} issues with block moving through non-moving float. r+sr+a=dbaron
layout/generic/nsBlockFrame.cpp
layout/generic/nsBlockReflowContext.cpp
layout/generic/nsBlockReflowContext.h
layout/generic/nsHTMLReflowState.cpp
layout/generic/nsHTMLReflowState.h
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -1572,62 +1572,62 @@ nsBlockFrame::FindLineFor(nsIFrame* aFra
  * |aDeltaY| indicates how much it will later be slid (assuming it
  * doesn't get marked dirty and reflowed entirely).
  */
 void
 nsBlockFrame::PropagateFloatDamage(nsBlockReflowState& aState,
                                    nsLineBox* aLine,
                                    nscoord aDeltaY)
 {
-  NS_PRECONDITION(!aLine->IsDirty(), "should never be called on dirty lines");
+  nsSpaceManager *spaceManager = aState.mReflowState.mSpaceManager;
+  NS_ASSERTION((aState.mReflowState.parentReflowState &&
+                aState.mReflowState.parentReflowState->mSpaceManager == spaceManager) ||
+                aState.mReflowState.mBlockDelta == 0, "Bad block delta passed in");
+
+  // Check to see if there are any floats; if there aren't, there can't
+  // be any float damage
+  if (!spaceManager->HasAnyFloats())
+    return;
 
   // Check the damage region recorded in the float damage.
-  nsSpaceManager *spaceManager = aState.mReflowState.mSpaceManager;
   if (spaceManager->HasFloatDamage()) {
     nscoord lineYA = aLine->mBounds.y + aDeltaY;
     nscoord lineYB = lineYA + aLine->mBounds.height;
     if (spaceManager->IntersectsDamage(lineYA, lineYB)) {
       aLine->MarkDirty();
       return;
     }
   }
 
-  if (aDeltaY) {
-    // Cases we need to find:
-    //
-    // 1. the line was impacted by a float and now isn't
-    // 2. the line wasn't impacted by a float and now is
-    // 3. the line is impacted by a float both before and after and 
-    //    the float has changed position relative to the line (or it's
-    //    a different float).  (XXXPerf we don't currently
-    //    check whether the float changed size.  We currently just
-    //    mark blocks dirty and ignore any possibility of damage to
-    //    inlines by it being a different float with a different
-    //    size.)
-    //
-    //    XXXPerf: An optimization: if the line was and is completely
-    //    impacted by a float and the float hasn't changed size,
-    //    then we don't need to mark the line dirty.
-    aState.GetAvailableSpace(aLine->mBounds.y + aDeltaY, PR_FALSE);
-    PRBool wasImpactedByFloat = aLine->IsImpactedByFloat();
-    PRBool isImpactedByFloat = aState.IsImpactedByFloat();
+  // Check if the line is moving relative to the space manager
+  if (aDeltaY + aState.mReflowState.mBlockDelta != 0) {
+    if (aLine->IsBlock()) {
+      // Unconditionally reflow sliding blocks; we only really need to reflow
+      // if there's a float impacting this block, but the current space manager
+      // makes it difficult to check that.  Therefore, we let the child block
+      // decide what it needs to reflow.
+      aLine->MarkDirty();
+    } else {
+      // Note that this check will become incorrect once bug 25888 is fixed
+      // because we are only checking the top of the line
+      aState.GetAvailableSpace(aLine->mBounds.y + aDeltaY, PR_FALSE);
+      PRBool wasImpactedByFloat = aLine->IsImpactedByFloat();
+      PRBool isImpactedByFloat = aState.IsImpactedByFloat();
+
 #ifdef REALLY_NOISY_REFLOW
     printf("nsBlockFrame::PropagateFloatDamage %p was = %d, is=%d\n", 
        this, wasImpactedByFloat, isImpactedByFloat);
 #endif
-    // Mark the line dirty if:
-    //  1. It used to be impacted by a float and now isn't, or vice
-    //     versa.
-    //  2. It is impacted by a float and it is a block, which means
-    //     that more or less of the line could be impacted than was in
-    //     the past.  (XXXPerf This could be optimized further, since
-    //     we're marking the whole line dirty.)
-    if ((wasImpactedByFloat != isImpactedByFloat) ||
-        (isImpactedByFloat && aLine->IsBlock())) {
-      aLine->MarkDirty();
+
+      // Mark the line dirty if it was or is affected by a float
+      // We actually only really need to reflow if the amount of impact
+      // changes, but that's not straightforward to check
+      if (wasImpactedByFloat || isImpactedByFloat) {
+        aLine->MarkDirty();
+      }
     }
   }
 }
 
 static void PlaceFrameView(nsIFrame* aFrame);
 
 static PRBool LineHasClear(nsLineBox* aLine) {
   return aLine->GetBreakTypeBefore() || aLine->HasFloatBreakAfter()
@@ -2914,17 +2914,17 @@ nsBlockFrame::ReflowBlockFrame(nsBlockRe
       aState.mSpaceManager->PushState(&spaceManagerState);
     } else if (!applyTopMargin) {
       blockHtmlRS.mDiscoveredClearance = aState.mReflowState.mDiscoveredClearance;
     }
     
     nsReflowStatus frameReflowStatus = NS_FRAME_COMPLETE;
     rv = brc.ReflowBlock(availSpace, applyTopMargin, aState.mPrevBottomMargin,
                          clearance, aState.IsAdjacentWithTop(), computedOffsets,
-                         blockHtmlRS, frameReflowStatus);
+                         aLine.get(), blockHtmlRS, frameReflowStatus);
 
     // If this was a second-pass reflow and the block's vertical position
     // changed, invalidates from the first pass might have happened in the
     // wrong places.  Invalidate the entire overflow rect at the new position.
     if (!mayNeedRetry && clearanceFrame &&
         frame->GetRect().y != passOriginalY) {
       Invalidate(frame->GetOverflowRect() + frame->GetPosition());
     }
@@ -5479,17 +5479,17 @@ nsBlockFrame::ReflowFloat(nsBlockReflowS
         // space manager that will be destroyed and recreated
       }
     }
 
     nsMargin offsets; // Don't bother returning this to the caller; it's stored
                       // on a frame property anyawy
     rv = brc.ReflowBlock(availSpace, PR_TRUE, margin,
                          0, isAdjacentWithTop,
-                         offsets, floatRS,
+                         offsets, nsnull, floatRS,
                          aReflowStatus);
   } while (NS_SUCCEEDED(rv) && clearanceFrame);
 
   // An incomplete reflow status means we should split the float 
   // if the height is constrained (bug 145305). 
   if (NS_FRAME_IS_NOT_COMPLETE(aReflowStatus) && (NS_UNCONSTRAINEDSIZE == availHeight))
     aReflowStatus = NS_FRAME_COMPLETE;
 
@@ -5521,17 +5521,17 @@ nsBlockFrame::ReflowFloat(nsBlockReflowS
       aReflowStatus = NS_FRAME_COMPLETE;
   }
 
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   // Capture the margin information for the caller
-  const nsMargin& m = brc.GetMargin();
+  const nsMargin& m = floatRS.mComputedMargin;
   aFloatMargin.top = brc.GetTopMargin();
   aFloatMargin.right = m.right;
   // Only last in flows get a bottom margin
   if (NS_FRAME_IS_COMPLETE(aReflowStatus)) {
     brc.GetCarriedOutBottomMargin().Include(m.bottom);
   }
   aFloatMargin.bottom = brc.GetCarriedOutBottomMargin().get();
   aFloatMargin.left = m.left;
--- a/layout/generic/nsBlockReflowContext.cpp
+++ b/layout/generic/nsBlockReflowContext.cpp
@@ -67,19 +67,16 @@
 #endif
 
 nsBlockReflowContext::nsBlockReflowContext(nsPresContext* aPresContext,
                                            const nsHTMLReflowState& aParentRS)
   : mPresContext(aPresContext),
     mOuterReflowState(aParentRS),
     mMetrics()
 {
-  mStyleBorder = nsnull;
-  mStyleMargin = nsnull;
-  mStylePadding = nsnull;
 }
 
 static nsIFrame* DescendIntoBlockLevelFrame(nsIFrame* aFrame)
 {
   nsIAtom* type = aFrame->GetType();
   if (type == nsGkAtoms::columnSetFrame)
     return DescendIntoBlockLevelFrame(aFrame->GetFirstChild(nsnull));
   return aFrame;
@@ -246,16 +243,17 @@ nsPointDtor(void *aFrame, nsIAtom *aProp
 
 nsresult
 nsBlockReflowContext::ReflowBlock(const nsRect&       aSpace,
                                   PRBool              aApplyTopMargin,
                                   nsCollapsingMargin& aPrevMargin,
                                   nscoord             aClearance,
                                   PRBool              aIsAdjacentWithTop,
                                   nsMargin&           aComputedOffsets,
+                                  nsLineBox*          aLine,
                                   nsHTMLReflowState&  aFrameRS,
                                   nsReflowStatus&     aFrameReflowStatus)
 {
   nsresult rv = NS_OK;
   mFrame = aFrameRS.frame;
   mSpace = aSpace;
 
   const nsStyleDisplay* display = mFrame->GetStyleDisplay();
@@ -275,17 +273,16 @@ nsBlockReflowContext::ReflowBlock(const 
         propTable->SetProperty(mFrame, nsGkAtoms::computedOffsetProperty,
                                offsets, nsPointDtor, nsnull);
     }
   }
 
   if (!aIsAdjacentWithTop) {
     aFrameRS.mFlags.mIsTopOfPage = PR_FALSE;  // make sure this is cleared
   }
-  mComputedWidth = aFrameRS.ComputedWidth();
 
   if (aApplyTopMargin) {
     mTopMargin = aPrevMargin;
 
 #ifdef NOISY_VERTICAL_MARGINS
     nsFrame::ListTag(stdout, mOuterReflowState.frame);
     printf(": reflowing ");
     nsFrame::ListTag(stdout, mFrame);
@@ -294,78 +291,49 @@ nsBlockReflowContext::ReflowBlock(const 
 
     // Adjust the available height if its constrained so that the
     // child frame doesn't think it can reflow into its margin area.
     if (NS_UNCONSTRAINEDSIZE != aFrameRS.availableHeight) {
       aFrameRS.availableHeight -= mTopMargin.get() + aClearance;
     }
   }
 
-  // Compute x/y coordinate where reflow will begin. Use the rules
-  // from 10.3.3 to determine what to apply. At this point in the
-  // reflow auto left/right margins will have a zero value.
-  mMargin = aFrameRS.mComputedMargin;
-  mStyleBorder = aFrameRS.mStyleBorder;
-  mStyleMargin = aFrameRS.mStyleMargin;
-  mStylePadding = aFrameRS.mStylePadding;
-  nscoord x;
-  nscoord y = mSpace.y + mTopMargin.get() + aClearance;
+  nscoord tx = 0, ty = 0;
+  // The values of x and y do not matter for floats, so don't bother calculating
+  // them. Floats are guaranteed to have their own space manager, so tx and ty
+  // don't matter.  mX and mY don't matter becacuse they are only used in
+  // PlaceBlock, which is not used for floats.
+  if (aLine) {
+    // Compute x/y coordinate where reflow will begin. Use the rules
+    // from 10.3.3 to determine what to apply. At this point in the
+    // reflow auto left/right margins will have a zero value.
 
-  // If it's a right floated element, then calculate the x-offset
-  // differently
-  if (NS_STYLE_FLOAT_RIGHT == aFrameRS.mStyleDisplay->mFloats) {
-    nscoord frameWidth;
-     
-    if (NS_UNCONSTRAINEDSIZE == aFrameRS.ComputedWidth()) {
-      // Use the current frame width
-      frameWidth = mFrame->GetSize().width;
-    } else {
-      frameWidth = aFrameRS.ComputedWidth() +
-                   aFrameRS.mComputedBorderPadding.left +
-                   aFrameRS.mComputedBorderPadding.right;
-    }
+    nscoord x = mSpace.x + aFrameRS.mComputedMargin.left;
+    nscoord y = mSpace.y + mTopMargin.get() + aClearance;
 
-    // if this is an unconstrained width reflow, then just place the float at the left margin
-    if (NS_UNCONSTRAINEDSIZE == mSpace.width)
-      x = mSpace.x;
-    else
-      x = mSpace.XMost() - mMargin.right - frameWidth;
+    if ((mFrame->GetStateBits() & NS_BLOCK_SPACE_MGR) == 0)
+      aFrameRS.mBlockDelta = mOuterReflowState.mBlockDelta + y - aLine->mBounds.y;
 
-  } else {
-    x = mSpace.x + mMargin.left;
-  }
-  mX = x;
-  mY = y;
+    mX = x;
+    mY = y;
 
-   // Compute the translation to be used for adjusting the spacemanagager
-   // coordinate system for the frame.  The spacemanager coordinates are
-   // <b>inside</b> the callers border+padding, but the x/y coordinates
-   // are not (recall that frame coordinates are relative to the parents
-   // origin and that the parents border/padding is <b>inside</b> the
-   // parent frame. Therefore we have to subtract out the parents
-   // border+padding before translating.
-   nscoord tx = x - mOuterReflowState.mComputedBorderPadding.left;
-   nscoord ty = y - mOuterReflowState.mComputedBorderPadding.top;
- 
-  // If the element is relatively positioned, then adjust x and y accordingly
-  if (NS_STYLE_POSITION_RELATIVE == aFrameRS.mStyleDisplay->mPosition) {
-    x += aFrameRS.mComputedOffsets.left;
-    y += aFrameRS.mComputedOffsets.top;
+    // Compute the translation to be used for adjusting the spacemanagager
+    // coordinate system for the frame.  The spacemanager coordinates are
+    // <b>inside</b> the callers border+padding, but the x/y coordinates
+    // are not (recall that frame coordinates are relative to the parents
+    // origin and that the parents border/padding is <b>inside</b> the
+    // parent frame. Therefore we have to subtract out the parents
+    // border+padding before translating.
+    tx = x - mOuterReflowState.mComputedBorderPadding.left;
+    ty = y - mOuterReflowState.mComputedBorderPadding.top;
   }
 
   // Let frame know that we are reflowing it
   mFrame->WillReflow(mPresContext);
 
-  // Position it and its view (if it has one)
-  // Note: Use "x" and "y" and not "mX" and "mY" because they more accurately
-  // represents where we think the block will be placed
-  // XXXldb That's fine for view positioning, but not for reflow!
-  mFrame->SetPosition(nsPoint(x, y));
-  nsContainerFrame::PositionFrameView(mFrame);
-
 #ifdef DEBUG
   mMetrics.width = nscoord(0xdeadbeef);
   mMetrics.height = nscoord(0xdeadbeef);
 #endif
 
   mOuterReflowState.mSpaceManager->Translate(tx, ty);
   rv = mFrame->Reflow(mPresContext, mMetrics, aFrameRS, aFrameReflowStatus);
   mOuterReflowState.mSpaceManager->Translate(-tx, -ty);
@@ -431,17 +399,17 @@ nsBlockReflowContext::PlaceBlock(const n
                                  nsCollapsingMargin&      aBottomMarginResult,
                                  nsRect&                  aInFlowBounds,
                                  nsRect&                  aCombinedRect,
                                  nsReflowStatus           aReflowStatus)
 {
   // Compute collapsed bottom margin value.
   if (NS_FRAME_IS_COMPLETE(aReflowStatus)) {
     aBottomMarginResult = mMetrics.mCarriedOutBottomMargin;
-    aBottomMarginResult.Include(mMargin.bottom);
+    aBottomMarginResult.Include(aReflowState.mComputedMargin.bottom);
   } else {
     // The used bottom-margin is set to zero above a break.
     aBottomMarginResult.Zero();
   }
 
   nscoord x = mX;
   nscoord y = mY;
   nscoord backupContainingBlockAdvance = 0;
--- a/layout/generic/nsBlockReflowContext.h
+++ b/layout/generic/nsBlockReflowContext.h
@@ -64,16 +64,17 @@ public:
   ~nsBlockReflowContext() { }
 
   nsresult ReflowBlock(const nsRect&       aSpace,
                        PRBool              aApplyTopMargin,
                        nsCollapsingMargin& aPrevMargin,
                        nscoord             aClearance,
                        PRBool              aIsAdjacentWithTop,
                        nsMargin&           aComputedOffsets,
+                       nsLineBox*          aLine,
                        nsHTMLReflowState&  aReflowState,
                        nsReflowStatus&     aReflowStatus);
 
   PRBool PlaceBlock(const nsHTMLReflowState& aReflowState,
                     PRBool                   aForceFit,
                     nsLineBox*               aLine,
                     const nsMargin&          aComputedOffsets,
                     nsCollapsingMargin&      aBottomMarginResult /* out */,
@@ -84,20 +85,16 @@ public:
   nsCollapsingMargin& GetCarriedOutBottomMargin() {
     return mMetrics.mCarriedOutBottomMargin;
   }
 
   nscoord GetTopMargin() const {
     return mTopMargin.get();
   }
 
-  const nsMargin& GetMargin() const {
-    return mMargin;
-  }
-
   const nsHTMLReflowMetrics& GetMetrics() const {
     return mMetrics;
   }
 
   /**
    * Computes the collapsed top margin for a block whose reflow state is in aRS.
    * The computed margin is added into aMargin.
    * If aClearanceFrame is null then this is the first optimistic pass which shall assume
@@ -117,21 +114,14 @@ public:
 
 protected:
   nsPresContext* mPresContext;
   const nsHTMLReflowState& mOuterReflowState;
 
   nsIFrame* mFrame;
   nsRect mSpace;
 
-  // Spacing style for the frame we are reflowing; only valid after reflow
-  const nsStyleBorder* mStyleBorder;
-  const nsStyleMargin* mStyleMargin;
-  const nsStylePadding* mStylePadding;
-
-  nscoord mComputedWidth;               // copy of reflowstate's computedWidth
-  nsMargin mMargin;
   nscoord mX, mY;
   nsHTMLReflowMetrics mMetrics;
   nsCollapsingMargin mTopMargin;
 };
 
 #endif /* nsBlockReflowContext_h___ */
--- a/layout/generic/nsHTMLReflowState.cpp
+++ b/layout/generic/nsHTMLReflowState.cpp
@@ -85,16 +85,17 @@ static eNormalLineHeightControl sNormalL
 // Initialize a <b>root</b> reflow state with a rendering context to
 // use for measuring things.
 nsHTMLReflowState::nsHTMLReflowState(nsPresContext*       aPresContext,
                                      nsIFrame*            aFrame,
                                      nsIRenderingContext* aRenderingContext,
                                      const nsSize&        aAvailableSpace)
   : nsCSSOffsetState(aFrame, aRenderingContext)
   , mReflowDepth(0)
+  , mBlockDelta(0)
 {
   NS_PRECONDITION(aPresContext, "no pres context");
   NS_PRECONDITION(aRenderingContext, "no rendering context");
   NS_PRECONDITION(aFrame, "no frame");
   parentReflowState = nsnull;
   availableWidth = aAvailableSpace.width;
   availableHeight = aAvailableSpace.height;
   mSpaceManager = nsnull;
@@ -129,16 +130,17 @@ nsHTMLReflowState::nsHTMLReflowState(nsP
                                      nsIFrame*                aFrame,
                                      const nsSize&            aAvailableSpace,
                                      nscoord                  aContainingBlockWidth,
                                      nscoord                  aContainingBlockHeight,
                                      PRBool                   aInit)
   : nsCSSOffsetState(aFrame, aParentReflowState.rendContext)
   , mReflowDepth(aParentReflowState.mReflowDepth + 1)
   , mFlags(aParentReflowState.mFlags)
+  , mBlockDelta(0)
 {
   NS_PRECONDITION(aPresContext, "no pres context");
   NS_PRECONDITION(aFrame, "no frame");
   NS_PRECONDITION((aContainingBlockWidth == -1) ==
                     (aContainingBlockHeight == -1),
                   "cb width and height should only be non-default together");
   NS_PRECONDITION(aInit == PR_TRUE || aInit == PR_FALSE,
                   "aInit out of range for PRBool");
--- a/layout/generic/nsHTMLReflowState.h
+++ b/layout/generic/nsHTMLReflowState.h
@@ -163,20 +163,16 @@ public:
   nsCSSOffsetState(nsIFrame *aFrame, nsIRenderingContext *aRenderingContext,
                    nscoord aContainingBlockWidth)
     : frame(aFrame)
     , rendContext(aRenderingContext)
   {
     InitOffsets(aContainingBlockWidth);
   }
 
-  void InitOffsets(nscoord aContainingBlockWidth,
-                   const nsMargin *aBorder = nsnull,
-                   const nsMargin *aPadding = nsnull);
-
   // Destructor for usedPaddingProperty
   static void DestroyMarginFunc(void*    aFrame,
                                 nsIAtom* aPropertyName,
                                 void*    aPropertyValue,
                                 void*    aDtorData);
 
 private:
   // Computes margin values from the specified margin style information, and
@@ -184,16 +180,20 @@ private:
   void ComputeMargin(nscoord aContainingBlockWidth);
   
   // Computes padding values from the specified padding style information, and
   // fills in the mComputedPadding member
   void ComputePadding(nscoord aContainingBlockWidth);
 
 protected:
 
+  void InitOffsets(nscoord aContainingBlockWidth,
+                   const nsMargin *aBorder = nsnull,
+                   const nsMargin *aPadding = nsnull);
+
   /*
    * Convert nsStyleCoord to nscoord when percentages depend on the
    * containing block width.
    */
   // XXX Make aResult a return value
   inline void ComputeWidthDependentValue(nscoord aContainingBlockWidth,
                                          const nsStyleCoord& aCoord,
                                          nscoord& aResult);
@@ -255,16 +255,26 @@ struct nsHTMLReflowState : public nsCSSO
 
   // The type of frame, from css's perspective. This value is
   // initialized by the Init method below.
   nsCSSFrameType   mFrameType;
 
   // pointer to the space manager associated with this area
   nsSpaceManager* mSpaceManager;
 
+  // The amount the in-flow position of the block is moving vertically relative
+  // to its previous in-flow position (i.e. the amount the line containing the
+  // block is moving).
+  // This should be zero for anything which is not a block outside, and it
+  // should be zero for anything which has a non-block parent.
+  // The intended use of this value is to allow the accurate determination
+  // of the potential impact of a float
+  // This takes on an arbitrary value the first time a block is reflowed
+  nscoord mBlockDelta;
+
   // LineLayout object (only for inline reflow; set to NULL otherwise)
   nsLineLayout*    mLineLayout;
 
   // The appropriate reflow state for the containing block (for
   // percentage widths, etc.) of this reflow state's frame.
   const nsHTMLReflowState *mCBReflowState;
 
 private:
@@ -411,26 +421,22 @@ public:
   static nscoord CalcLineHeight(nsIRenderingContext* aRenderingContext,
                                 nsIFrame* aFrame);
   /**
    * Same as above, but doesn't need quite as much info.
    */
   static nscoord CalcLineHeight(nsStyleContext* aStyleContext,
                                 nsIDeviceContext* aDeviceContext);
 
-  void InitFrameType();
 
   void ComputeContainingBlockRectangle(nsPresContext*          aPresContext,
                                        const nsHTMLReflowState* aContainingBlockRS,
                                        nscoord&                 aContainingBlockWidth,
                                        nscoord&                 aContainingBlockHeight);
 
-  void CalculateBlockSideMargins(nscoord aAvailWidth,
-                                 nscoord aComputedWidth);
-
   /**
    * Apply the mComputed(Min/Max)(Width/Height) values to the content
    * size computed so far. If a passed-in pointer is null, we skip
    * adjusting that dimension.
    */
   void ApplyMinMaxConstraints(nscoord* aContentWidth, nscoord* aContentHeight) const;
 
   PRBool ShouldReflowAllKids() const {
@@ -452,17 +458,17 @@ public:
 
   nscoord ComputedHeight() const { return mComputedHeight; }
   // This method doesn't apply min/max computed heights to the value passed in.
   void SetComputedHeight(nscoord aComputedHeight);
 
   void SetTruncated(const nsHTMLReflowMetrics& aMetrics, nsReflowStatus* aStatus) const;
 
 protected:
-
+  void InitFrameType();
   void InitCBReflowState();
   void InitResizeFlags(nsPresContext* aPresContext);
 
   void InitConstraints(nsPresContext* aPresContext,
                        nscoord         aContainingBlockWidth,
                        nscoord         aContainingBlockHeight,
                        const nsMargin* aBorder,
                        const nsMargin* aPadding);
@@ -496,12 +502,14 @@ protected:
   void ComputeMinMaxValues(nscoord                  aContainingBlockWidth,
                            nscoord                  aContainingBlockHeight,
                            const nsHTMLReflowState* aContainingBlockRS);
 
   void CalculateHorizBorderPaddingMargin(nscoord aContainingBlockWidth,
                                          nscoord* aInsideBoxSizing,
                                          nscoord* aOutsideBoxSizing);
 
+  void CalculateBlockSideMargins(nscoord aAvailWidth,
+                                 nscoord aComputedWidth);
 };
 
 #endif /* nsHTMLReflowState_h___ */