if (oldCombinedArea.height != lineCombinedArea.height) { nsRect  dirtyRect;    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 Invalidate(dirtyRect); }
frame->GetNextSibling(frame);
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());  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());      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        Invalidate(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          Invalidate(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          Invalidate(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 floats are involved in which case    // we'll either need to recover the float 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();    // XXXldb Add &&!aState.GetFlag(BRS_UNCONSTRAINEDWIDTH)    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);#if defined(DEBUG_waterson) || defined(DEBUG_dbaron)      // XXXwaterson if oldUnconstrainedWidth was set, why do we need      // to do the second reflow, below?      if (oldUnconstrainedWidth)        printf("*** oldUnconstrainedWidth was already set.\n"               "*** This code (%s:%d) could be optimized a lot!\n"               "+++ possibly doing an unnecessary second-pass unconstrained "               "reflow\n",               __FILE__, __LINE__);#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 float we don't      // end up resetting the line's right edge and have it think the      // width is unconstrained...      aState.mSpaceManager->PushState();      aState.SetFlag(BRS_UNCONSTRAINEDWIDTH, PR_TRUE);      ReflowInlineFrames(aState, aLine, aKeepReflowGoing, aDamageDirtyArea, PR_TRUE);      aState.mY = oldY;      aState.mPrevBottomMargin = oldPrevBottomMargin;      aState.SetFlag(BRS_UNCONSTRAINEDWIDTH, oldUnconstrainedWidth);      aState.mSpaceManager->PopState();      // 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, NS_STATIC_CAST(void*, aLine.get()), aLine->mMaximumWidth);#endif      aState.UpdateMaximumWidth(aLine->mMaximumWidth);      // Now reflow the line again this time without having it compute      // the maximum width or max-element-width.      // Note: we need to reset both member variables, because the inline      // code examines mComputeMaxElementWidth and if there is a placeholder      // on this line the code to reflow the float looks at both...      nscoord oldComputeMaxElementWidth = aState.GetFlag(BRS_COMPUTEMAXELEMENTWIDTH);      nscoord oldComputeMaximumWidth = aState.GetFlag(BRS_COMPUTEMAXWIDTH);      aState.SetFlag(BRS_COMPUTEMAXELEMENTWIDTH, PR_FALSE);      aState.SetFlag(BRS_COMPUTEMAXWIDTH, PR_FALSE);      rv = ReflowInlineFrames(aState, aLine, aKeepReflowGoing, aDamageDirtyArea);      aState.SetFlag(BRS_COMPUTEMAXELEMENTWIDTH, oldComputeMaxElementWidth);      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, NS_STATIC_CAST(void*, aLine.get()), aLine->mMaximumWidth);#endif          aState.UpdateMaximumWidth(aLine->mMaximumWidth);        }        if (aState.GetFlag(BRS_COMPUTEMAXELEMENTWIDTH))        {#ifdef DEBUG          if (gNoisyMaxElementWidth) {            IndentBy(stdout, gNoiseIndent);            printf("nsBlockFrame::ReflowLine block %p line %p setting aLine.mMaxElementWidth to %d\n",                    NS_STATIC_CAST(void*, this), NS_STATIC_CAST(void*, aLine.get()),                   aLine->mMaxElementWidth);          }#endif          aState.UpdateMaxElementWidth(aLine->mMaxElementWidth);        }      }    }    // 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 dirtyRect;      dirtyRect.UnionRect(oldCombinedArea, aLine->GetCombinedArea());#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", NS_STATIC_CAST(void*, aLine.get());#endif      Invalidate(dirtyRect);    }  }  return rv;}