nscoord topMargin = 0, bottomMargin = 0; PRBool haveCarriedMargins = CalculateMargins(aState, aLine, PR_TRUE, topMargin, bottomMargin); if (!haveCarriedMargins) {      if (0 != aLine->mBounds.height) { topMargin = aState.mPrevBottomMargin; } } else {    if (0 == aLine->mBounds.height) { bottomMargin = nsInlineReflow::MaxMargin(topMargin, bottomMargin); topMargin = 0; } }
nscoord topMargin, bottomMargin; PRUintn marginFlags = CalculateMargins(aState, aLine, PR_TRUE, topMargin, bottomMargin);
nsBlockFrame::PlaceLine(nsBlockReflowState& aState,                        LineData* aLine,                        nsReflowStatus aReflowStatus){  // Align the children. This also determines the actual height and  // width of the line.  nsInlineReflow& ir = *aState.mInlineReflow;  ir.VerticalAlignFrames(aLine->mBounds);  ir.HorizontalAlignFrames(aLine->mBounds);  ir.RelativePositionFrames();  // Calculate the bottom margin for the line.  nscoord lineBottomMargin = 0;  if (0 == aLine->mBounds.height) {    nsIFrame* brFrame = aState.mLineLayout.GetBRFrame();    if (nsnull != brFrame) {      // If a line ends in a BR and the line is empty of height then we      // make sure that the line ends up with some height anyway. Note      // that the height looks like vertical margin so that it can      // compress with other block margins.      nsIStyleContext* brSC;      nsIPresContext& px = aState.mPresContext;      nsresult rv = brFrame->GetStyleContext(&px, brSC);      if ((NS_OK == rv) && (nsnull != brSC)) {        const nsStyleFont* font = (const nsStyleFont*)          brSC->GetStyleData(eStyleStruct_Font);        nsIFontMetrics* fm = px.GetMetricsFor(font->mFont);        if (nsnull != fm) {          fm->GetHeight(lineBottomMargin);          NS_RELEASE(fm);        }        NS_RELEASE(brSC);      }    }  }  // Apply margin collapsing when the line has some height  nscoord topMargin = 0, bottomMargin = 0;  PRBool haveCarriedMargins =     CalculateMargins(aState, aLine, PR_TRUE, topMargin, bottomMargin);  if (!haveCarriedMargins) {    // When the child being reflowed has no margin to give, we still    // need to make sure that the previous lines bottom margin is    // applied, but only if the line has a non-zero height (lines with    // no height and no carried margin need to not upset the margin    // state)    if (0 != aLine->mBounds.height) {      topMargin = aState.mPrevBottomMargin;    }  }  else {    // A special hack: if we have carried margins but the line has no    // height then collapse the carried margins down into a single    // (bottom margin) value.    if (0 == aLine->mBounds.height) {      bottomMargin = nsInlineReflow::MaxMargin(topMargin, bottomMargin);      topMargin = 0;    }  }  // See if the line fit. If it doesn't we need to push it. Our first  // line will always fit.  // XXX This is a good place to check and see if we have  // below-current-line floaters, and if we do make sure that they fit  // too.  // XXX don't forget to factor in the top/bottom margin when sharing  // this with the block code  nscoord newY = aLine->mBounds.YMost() + topMargin + lineBottomMargin;  NS_FRAME_TRACE(NS_FRAME_TRACE_CHILD_REFLOW,     ("nsBlockFrame::PlaceLine: newY=%d limit=%d lineHeight=%d",      newY, aState.mBottomEdge, aLine->mBounds.height));  if ((mLines != aLine) && (newY > aState.mBottomEdge)) {    // Push this line and all of it's children and anything else that    // follows to our next-in-flow    PushLines(aState);    return PR_FALSE;  }  // Apply collapsed top-margin value  // XXX I bet the bullet placement just got broken by this code  if (0 != topMargin) {    SlideFrames(aLine, topMargin);  }  // Adjust running margin value when either we have carried margins  // from the line or we have a non-zero height line.  if (haveCarriedMargins || (0 != aLine->mBounds.height)) {    aState.mPrevBottomMargin = bottomMargin;  }  aLine->mCarriedOutTopMargin = ir.GetCarriedOutTopMargin();  aLine->mCarriedOutBottomMargin = ir.GetCarriedOutBottomMargin();  // Now that we know the line is staying put, put in the outside  // bullet if we have one.  if ((nsnull == mPrevInFlow) && (aLine == mLines) && (nsnull != mBullet)) {    const nsStyleList* list;    GetStyleData(eStyleStruct_List, (const nsStyleStruct*&)list);    if (NS_STYLE_LIST_STYLE_POSITION_OUTSIDE == list->mListStylePosition) {      // Reflow the bullet now      nsSize availSize;      availSize.width = NS_UNCONSTRAINEDSIZE;      availSize.height = NS_UNCONSTRAINEDSIZE;      nsHTMLReflowState reflowState(mBullet, aState, availSize, &aState.mLineLayout);      nsHTMLReflowMetrics metrics(nsnull);      nsIHTMLReflow* htmlReflow;      if (NS_OK == mBullet->QueryInterface(kIHTMLReflowIID, (void**) &htmlReflow)) {        nsReflowStatus  status;        htmlReflow->WillReflow(aState.mPresContext);        htmlReflow->Reflow(aState.mPresContext, metrics, reflowState, status);        htmlReflow->DidReflow(aState.mPresContext, NS_FRAME_REFLOW_FINISHED);      }      // Place the bullet now      nsMargin padding;      aState.mStyleSpacing->CalcPaddingFor(this, padding);      nscoord x = aState.mBorderPadding.left - (padding.left/2) -        metrics.width;      // XXX This calculation is wrong, especially if      // vertical-alignment occurs on the line!      nscoord y = aState.mBorderPadding.top + ir.GetMaxAscent() -        metrics.ascent + topMargin;      mBullet->SetRect(nsRect(x, y, metrics.width, metrics.height));    }  }  // Update max-element-size  // Update max-element-size  if (aState.mComputeMaxElementSize) {    const nsSize& kidMaxElementSize = ir.GetMaxElementSize();    if (kidMaxElementSize.width > aState.mMaxElementSize.width) {      aState.mMaxElementSize.width = kidMaxElementSize.width;    }    if (kidMaxElementSize.height > aState.mMaxElementSize.height) {      aState.mMaxElementSize.height = kidMaxElementSize.height;    }  }  nscoord xmost = aLine->mBounds.XMost();  if (xmost > aState.mKidXMost) {    aState.mKidXMost = xmost;  }  aState.mY = newY;  // Any below current line floaters to place?  if (0 != aState.mPendingFloaters.Count()) {    aState.PlaceFloaters(&aState.mPendingFloaters);    aState.mPendingFloaters.Clear();    // XXX Factor in the height of the floaters as well when considering    // whether the line fits.    // The default policy is that if there isn't room for the floaters then    // both the line and the floaters are pushed to the next-in-flow...  }  // Based on the last child we reflowed reflow status, we may need to  // clear past any floaters.  if (NS_INLINE_IS_BREAK_AFTER(aReflowStatus)) {    PRUint8 breakType = NS_INLINE_GET_BREAK_TYPE(aReflowStatus);    // Apply break to the line    switch (breakType) {    default:      break;    case NS_STYLE_CLEAR_LEFT:    case NS_STYLE_CLEAR_RIGHT:    case NS_STYLE_CLEAR_LEFT_AND_RIGHT:      NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,         ("nsBlockFrame::PlaceLine: clearing floaters=%d",          breakType));      aState.ClearFloaters(breakType);      break;    }    // XXX page breaks, etc, need to be passed upwards too!  }  // Update available space after placing line in case below current  // line floaters were placed or in case we just used up the space in  // the current band and are ready to move into a new band.  aState.GetAvailableSpace();  return PR_TRUE;}