line_iterator aLine, PRBool* aKeepReflowGoing, PRBool aDamageDirtyArea)
LineData* aLine, nsReflowStatus& aReflowResult)
nsBlockFrame::ReflowLine(nsBlockReflowState& aState,                         line_iterator aLine,                         PRBool* aKeepReflowGoing,                         PRBool aDamageDirtyArea){  nsresult rv = NS_OK;  NS_ABORT_IF_FALSE(aLine->GetChildCount(), "reflowing empty line");  // Setup the line-layout for the new line  aState.mCurrentLine = aLine;  aLine->ClearDirty();  // Now that we know what kind of line we have, reflow it  nsRect oldCombinedArea;  aLine->GetCombinedArea(&oldCombinedArea);  if (aLine->IsBlock()) {    rv = ReflowBlockFrame(aState, aLine, aKeepReflowGoing);    // We expect blocks to damage any area inside their bounds that is    // dirty; however, if the frame changes size or position then we    // need to do some repainting    if (aDamageDirtyArea) {      nsRect lineCombinedArea;      aLine->GetCombinedArea(&lineCombinedArea);      if ((oldCombinedArea.x != lineCombinedArea.x) ||          (oldCombinedArea.y != lineCombinedArea.y)) {        // The block has moved, and so to be safe we need to repaint        // XXX We need to improve on this...        nsRect  dirtyRect;        dirtyRect.UnionRect(oldCombinedArea, lineCombinedArea);#ifdef NOISY_BLOCK_INVALIDATE        printf("%p invalidate 6 (%d, %d, %d, %d)\n",               this, dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height);#endif        if (!dirtyRect.IsEmpty()) {          Invalidate(aState.mPresContext, dirtyRect);        }      } else {        if (oldCombinedArea.width != lineCombinedArea.width) {          nsRect  dirtyRect;          // Just damage the vertical strip that was either added or went          // away          dirtyRect.x = PR_MIN(oldCombinedArea.XMost(),                               lineCombinedArea.XMost());          dirtyRect.y = lineCombinedArea.y;          dirtyRect.width = PR_MAX(oldCombinedArea.XMost(),                                   lineCombinedArea.XMost()) -                            dirtyRect.x;          dirtyRect.height = PR_MAX(oldCombinedArea.height,                                    lineCombinedArea.height);#ifdef NOISY_BLOCK_INVALIDATE          printf("%p invalidate 7 (%d, %d, %d, %d)\n",                 this, dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height);#endif          if (!dirtyRect.IsEmpty()) {            Invalidate(aState.mPresContext, dirtyRect);          }        }        if (oldCombinedArea.height != lineCombinedArea.height) {          nsRect  dirtyRect;                    // Just damage the horizontal strip that was either added or went          // away          dirtyRect.x = lineCombinedArea.x;          dirtyRect.y = PR_MIN(oldCombinedArea.YMost(),                               lineCombinedArea.YMost());          dirtyRect.width = PR_MAX(oldCombinedArea.width,                                   lineCombinedArea.width);          dirtyRect.height = PR_MAX(oldCombinedArea.YMost(),                                    lineCombinedArea.YMost()) -                             dirtyRect.y;#ifdef NOISY_BLOCK_INVALIDATE          printf("%p invalidate 8 (%d, %d, %d, %d)\n",                 this, dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height);#endif          if (!dirtyRect.IsEmpty()) {            Invalidate(aState.mPresContext, dirtyRect);          }        }      }    }  }  else {    aLine->SetLineWrapped(PR_FALSE);    // If we're supposed to update the maximum width, then we'll need to reflow    // the line with an unconstrained width (which will give us the new maximum    // width), then we'll reflow it again with the constrained width.    // We only do this if this is a beginning line, i.e., don't do this for    // lines associated with content that line wrapped (see ReflowDirtyLines()    // for details).    // XXX This approach doesn't work when floaters are involved in which case    // we'll either need to recover the floater state that applies to the    // unconstrained reflow or keep it around in a separate space manager...    PRBool isBeginningLine = aState.mCurrentLine == begin_lines() ||                             !aState.mCurrentLine.prev()->IsLineWrapped();    if (aState.GetFlag(BRS_COMPUTEMAXWIDTH) && isBeginningLine) {      // First reflow the line with an unconstrained width.       nscoord oldY = aState.mY;      nsCollapsingMargin oldPrevBottomMargin(aState.mPrevBottomMargin);      PRBool  oldUnconstrainedWidth = aState.GetFlag(BRS_UNCONSTRAINEDWIDTH);#ifdef DEBUG_waterson      if (oldUnconstrainedWidth)        printf("*** oldUnconstrainedWidth was already set.\n");#endif      // When doing this we need to set the block reflow state's      // "mUnconstrainedWidth" variable to PR_TRUE so if we encounter      // a placeholder and then reflow its associated floater we don't      // end up resetting the line's right edge and have it think the      // width is unconstrained...      aState.SetFlag(BRS_UNCONSTRAINEDWIDTH, PR_TRUE);      ReflowInlineFrames(aState, aLine, aKeepReflowGoing, aDamageDirtyArea, PR_TRUE);      aState.mY = oldY;      aState.mPrevBottomMargin = oldPrevBottomMargin;      aState.SetFlag(BRS_UNCONSTRAINEDWIDTH, oldUnconstrainedWidth);#ifdef DEBUG_waterson      // XXXwaterson if oldUnconstrainedWidth was set, why do we need      // to do the second reflow, below?      if (oldUnconstrainedWidth)        printf("+++ possibly doing an unnecessary second-pass unconstrained reflow\n");#endif      // Update the line's maximum width      aLine->mMaximumWidth = aLine->mBounds.XMost();#ifdef NOISY_MAXIMUM_WIDTH      printf("nsBlockFrame::ReflowLine block %p line %p setting aLine.mMaximumWidth to %d\n",              this, aLine, aLine->mMaximumWidth);#endif      aState.UpdateMaximumWidth(aLine->mMaximumWidth);      // Remove any floaters associated with the line from the space      // manager      aLine->RemoveFloatersFromSpaceManager(aState.mSpaceManager);      // Now reflow the line again this time without having it compute      // the maximum width or max-element-size.      // Note: we need to reset both member variables, because the inline      // code examines mComputeMaxElementSize and if there is a placeholder      // on this line the code to reflow the floater looks at both...      nscoord oldComputeMaxElementSize = aState.GetFlag(BRS_COMPUTEMAXELEMENTSIZE);      nscoord oldComputeMaximumWidth = aState.GetFlag(BRS_COMPUTEMAXWIDTH);      aState.SetFlag(BRS_COMPUTEMAXELEMENTSIZE, PR_FALSE);      aState.SetFlag(BRS_COMPUTEMAXWIDTH, PR_FALSE);      rv = ReflowInlineFrames(aState, aLine, aKeepReflowGoing, aDamageDirtyArea);      aState.SetFlag(BRS_COMPUTEMAXELEMENTSIZE, oldComputeMaxElementSize);      aState.SetFlag(BRS_COMPUTEMAXWIDTH, oldComputeMaximumWidth);    } else {      rv = ReflowInlineFrames(aState, aLine, aKeepReflowGoing, aDamageDirtyArea);      if (NS_SUCCEEDED(rv))      {        if (aState.GetFlag(BRS_COMPUTEMAXWIDTH))        {#ifdef NOISY_MAXIMUM_WIDTH          printf("nsBlockFrame::ReflowLine block %p line %p setting aLine.mMaximumWidth to %d\n",                  this, aLine, aLine->mMaximumWidth);#endif          aState.UpdateMaximumWidth(aLine->mMaximumWidth);        }        if (aState.GetFlag(BRS_COMPUTEMAXELEMENTSIZE))        {#ifdef NOISY_MAX_ELEMENT_SIZE          printf("nsBlockFrame::ReflowLine block %p line %p setting aLine.mMaxElementWidth to %d\n",                  this, aLine, aLine->mMaxElementWidth);#endif          aState.UpdateMaxElementSize(nsSize(aLine->mMaxElementWidth, aLine->mBounds.height));        }      }    }    // We don't really know what changed in the line, so use the union    // of the old and new combined areas    // SEC: added "aLine->IsForceInvalidate()" for bug 45152    if (aDamageDirtyArea || aLine->IsForceInvalidate()) {      aLine->SetForceInvalidate(PR_FALSE);  // doing the invalidate now, force flag to off      nsRect combinedArea;      aLine->GetCombinedArea(&combinedArea);      nsRect dirtyRect;      dirtyRect.UnionRect(oldCombinedArea, combinedArea);#ifdef NOISY_BLOCK_INVALIDATE      printf("%p invalidate because %s is true (%d, %d, %d, %d)\n",             this, aDamageDirtyArea ? "aDamageDirtyArea" : "aLine->IsForceInvalidate",             dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height);      if (aLine->IsForceInvalidate())        printf("  dirty line is %p\n");#endif      if (!dirtyRect.IsEmpty()) {        Invalidate(aState.mPresContext, dirtyRect);      }    }  }  return rv;}