printf(" r.y=%d finalDeltaY=%d (sum=%d) region={%d,%d,%d,%d}\n",
PRINTF(" r.y=%d finalDeltaY=%d (sum=%d) region={%d,%d,%d,%d}\n",
nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine,                                     PRBool aApplyTopMargin,                                     nscoord aDeltaY,                                     nsRect* aDamageRect){  // Make the line being recovered the current line  mCurrentLine = aLine;  // Update aState.mPrevChild as if we had reflowed all of the frames  // in this line.  mPrevChild = aLine->LastChild();  // Recover mKidXMost and mMaxElementSize  nscoord xmost = aLine->mBounds.XMost();  if (xmost > mKidXMost) {#ifdef DEBUG    if (CRAZY_WIDTH(xmost)) {      nsFrame::ListTag(stdout, mBlock);      printf(": WARNING: xmost:%d\n", xmost);    }#endif#ifdef NOISY_KIDXMOST    printf("%p RecoverState block %p aState.mKidXMost=%d\n", this, mBlock, xmost); #endif    mKidXMost = xmost;  }  if (GetFlag(BRS_COMPUTEMAXELEMENTSIZE)) {#ifdef NOISY_MAX_ELEMENT_SIZE    printf("nsBlockReflowState::RecoverStateFrom block %p caching max width %d\n", mBlock, aLine->mMaxElementWidth);#endif    UpdateMaxElementSize(nsSize(aLine->mMaxElementWidth, aLine->mBounds.height));  }  // If computing the maximum width, then update mMaximumWidth  if (GetFlag(BRS_COMPUTEMAXWIDTH)) {#ifdef NOISY_MAXIMUM_WIDTH    printf("nsBlockReflowState::RecoverStateFrom block %p caching max width %d\n", mBlock, aLine->mMaximumWidth);#endif    UpdateMaximumWidth(aLine->mMaximumWidth);  }  // The line may have clear before semantics.  if (aLine->IsBlock() && aLine->HasBreak()) {    // Clear past floaters before the block if the clear style is not none    aApplyTopMargin = ClearPastFloaters(aLine->GetBreakType());#ifdef NOISY_VERTICAL_MARGINS    nsFrame::ListTag(stdout, mBlock);    printf(": RecoverStateFrom: y=%d child ", mY);    nsFrame::ListTag(stdout, aLine->mFirstChild);    printf(" has clear of %d => %s, mPrevBottomMargin=%d\n", aLine->mBreakType,           aApplyTopMargin ? "applyTopMargin" : "nope", mPrevBottomMargin);#endif  }  // Recover mPrevBottomMargin and calculate the line's new Y  // coordinate (newLineY)  nscoord newLineY = mY;  nsRect lineCombinedArea;  aLine->GetCombinedArea(&lineCombinedArea);  if (aLine->IsBlock()) {    if ((0 == aLine->mBounds.height) && (0 == lineCombinedArea.height)) {      // The line's top and bottom margin values need to be collapsed      // with the mPrevBottomMargin to determine a new      // mPrevBottomMargin value.      nscoord topMargin, bottomMargin;      RecoverVerticalMargins(aLine, aApplyTopMargin,                             &topMargin, &bottomMargin);      nscoord m = nsBlockReflowContext::MaxMargin(bottomMargin,                                                  mPrevBottomMargin);      m = nsBlockReflowContext::MaxMargin(m, topMargin);      mPrevBottomMargin = m;    }    else {      // Recover the top and bottom margins for this line      nscoord topMargin, bottomMargin;      RecoverVerticalMargins(aLine, aApplyTopMargin,                             &topMargin, &bottomMargin);      // Compute the collapsed top margin value      nscoord collapsedTopMargin =        nsBlockReflowContext::MaxMargin(topMargin, mPrevBottomMargin);      // The lineY is just below the collapsed top margin value. The      // mPrevBottomMargin gets set to the bottom margin value for the      // line.      newLineY += collapsedTopMargin;      mPrevBottomMargin = bottomMargin;    }  }  else if (0 == aLine->GetHeight()) {    // For empty inline lines we leave the previous bottom margin    // alone so that it's collpased with the next line.  }  else {    // For non-empty inline lines the previous margin is applied    // before the line. Therefore apply it now and zero it out.    newLineY += mPrevBottomMargin;    mPrevBottomMargin = 0;  }  // Save away the old combined area for later  nsRect oldCombinedArea = lineCombinedArea;  // Slide the frames in the line by the computed delta. This also  // updates the lines Y coordinate and the combined area's Y  // coordinate.  nscoord finalDeltaY = newLineY - aLine->mBounds.y;  mBlock->SlideLine(*this, aLine, finalDeltaY);  // aLine has been slided, but...  // XXX it is not necessary to worry about the ascent of mBlock here, right?  // Indeed, depending on the status of the first line of mBlock, we can either have:  // case first line of mBlock is dirty : it will be reflowed by mBlock and so  // mBlock->mAscent will be recomputed by the block frame, and we will  // never enter into this RecoverStateFrom(aLine) function.  // case first line of mBlock is clean : it is untouched by the incremental reflow.  //      In other words, aLine is never equals to mBlock->mLines in this function.  //      so mBlock->mAscent will remain unchanged.   // Place floaters for this line into the space manager  if (aLine->HasFloaters()) {    // Undo border/padding translation since the nsFloaterCache's    // coordinates are relative to the frame not relative to the    // border/padding.    const nsMargin& bp = BorderPadding();    mSpaceManager->Translate(-bp.left, -bp.top);    // Place the floaters into the space-manager again. Also slide    // them, just like the regular frames on the line.    nsRect r;    nsFloaterCache* fc = aLine->GetFirstFloater();    while (fc) {      fc->mRegion.y += finalDeltaY;      fc->mCombinedArea.y += finalDeltaY;      nsIFrame* floater = fc->mPlaceholder->GetOutOfFlowFrame();      floater->GetRect(r);      floater->MoveTo(mPresContext, r.x, r.y + finalDeltaY);#ifdef DEBUG      if (gNoisyReflow || gNoisySpaceManager) {        nscoord tx, ty;        mSpaceManager->GetTranslation(tx, ty);        nsFrame::IndentBy(stdout, gNoiseIndent);        printf("RecoverState: txy=%d,%d (%d,%d) ",               tx, ty, mSpaceManagerX, mSpaceManagerY);        nsFrame::ListTag(stdout, floater);        printf(" r.y=%d finalDeltaY=%d (sum=%d) region={%d,%d,%d,%d}\n",               r.y, finalDeltaY, r.y + finalDeltaY,               fc->mRegion.x, fc->mRegion.y,               fc->mRegion.width, fc->mRegion.height);      }#endif      mSpaceManager->AddRectRegion(floater, fc->mRegion);      fc = fc->Next();    }#ifdef DEBUG    if (gNoisyReflow || gNoisySpaceManager) {      mSpaceManager->List(stdout);    }#endif    // And then put the translation back again    mSpaceManager->Translate(bp.left, bp.top);  }  // Recover mY  mY = aLine->mBounds.YMost();  // Compute the damage area  if (aDamageRect) {    if (0 == finalDeltaY) {      aDamageRect->Empty();    } else {      aLine->GetCombinedArea(&lineCombinedArea);      aDamageRect->UnionRect(oldCombinedArea, lineCombinedArea);    }  }// XXX Does this do anything?  It doesn't seem to work.... (bug 29413)  // It's possible that the line has clear after semantics  if (!aLine->IsBlock() && aLine->HasBreak()) {    PRUint8 breakType = aLine->GetBreakType();    switch (breakType) {    case NS_STYLE_CLEAR_LEFT:    case NS_STYLE_CLEAR_RIGHT:    case NS_STYLE_CLEAR_LEFT_AND_RIGHT:      ClearFloaters(mY, breakType);      break;    }  }}