fixed bug 25510 and 28084
r=troy a=jar
This commit is contained in:
@@ -451,6 +451,7 @@ public:
|
|||||||
PRPackedBool mUnconstrainedHeight;
|
PRPackedBool mUnconstrainedHeight;
|
||||||
PRPackedBool mShrinkWrapWidth;
|
PRPackedBool mShrinkWrapWidth;
|
||||||
PRPackedBool mNeedResizeReflow;
|
PRPackedBool mNeedResizeReflow;
|
||||||
|
PRPackedBool mIsInlineIncrReflow;
|
||||||
|
|
||||||
// The content area to reflow child frames within. The x/y
|
// The content area to reflow child frames within. The x/y
|
||||||
// coordinates are known to be mBorderPadding.left and
|
// coordinates are known to be mBorderPadding.left and
|
||||||
@@ -579,7 +580,8 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
|
|||||||
mPrevBottomMargin(0),
|
mPrevBottomMargin(0),
|
||||||
mFreeLineList(nsnull),
|
mFreeLineList(nsnull),
|
||||||
mLineNumber(0),
|
mLineNumber(0),
|
||||||
mNeedResizeReflow(PR_FALSE)
|
mNeedResizeReflow(PR_FALSE),
|
||||||
|
mIsInlineIncrReflow(PR_FALSE)
|
||||||
{
|
{
|
||||||
const nsMargin& borderPadding = BorderPadding();
|
const nsMargin& borderPadding = BorderPadding();
|
||||||
|
|
||||||
@@ -1463,6 +1465,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
|
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
PRBool isStyleChange = PR_FALSE;
|
PRBool isStyleChange = PR_FALSE;
|
||||||
|
state.mIsInlineIncrReflow = PR_FALSE;
|
||||||
nsIFrame* target;
|
nsIFrame* target;
|
||||||
switch (aReflowState.reason) {
|
switch (aReflowState.reason) {
|
||||||
case eReflowReason_Initial:
|
case eReflowReason_Initial:
|
||||||
@@ -1518,6 +1521,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
// in the normal case, this just marks the line dirty
|
// in the normal case, this just marks the line dirty
|
||||||
// but, it causes an incremental reflow targeted at a frame
|
// but, it causes an incremental reflow targeted at a frame
|
||||||
// inside a continued span to get dropped on the floor. see bug 25510
|
// inside a continued span to get dropped on the floor. see bug 25510
|
||||||
|
// This will be yanked as soon as we have high confidence in the enabled code below
|
||||||
rv = PrepareChildIncrementalReflow(state);
|
rv = PrepareChildIncrementalReflow(state);
|
||||||
#else
|
#else
|
||||||
// this code does a correct job of propogating incremental reflows (bug 25510)
|
// this code does a correct job of propogating incremental reflows (bug 25510)
|
||||||
@@ -1531,21 +1535,35 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
{
|
{
|
||||||
if (!isFloater) // punt if isFloater!
|
if (!isFloater) // punt if isFloater!
|
||||||
{
|
{
|
||||||
nsBlockReflowState incrState(aReflowState, aPresContext, this, aMetrics,
|
// reflow the line containing the target of the incr. reflow
|
||||||
NS_BLOCK_MARGIN_ROOT & mState);
|
// first mark the line dirty and set up the state object
|
||||||
incrState.mNextRCFrame = state.mNextRCFrame;
|
rv = PrepareChildIncrementalReflow(state);
|
||||||
PRBool keepGoing;
|
state.mIsInlineIncrReflow = PR_TRUE;
|
||||||
rv = ReflowLine(incrState, line, &keepGoing, PR_TRUE);
|
state.mPrevLine = prevLine;
|
||||||
line->RemoveFloatersFromSpaceManager(aReflowState.mSpaceManager);
|
state.mCurrentLine = line;
|
||||||
state.mNextRCFrame = nsnull;
|
state.mNextRCFrame = state.mNextRCFrame;
|
||||||
|
// let ReflowDirtyLines do all the work
|
||||||
|
rv = ReflowDirtyLines(state);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_ASSERTION(0, "Reflow failed\n");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
// compute the final size
|
||||||
|
ComputeFinalSize(aReflowState, state, aMetrics);
|
||||||
|
|
||||||
|
// finally, mark this block frame as having a dirty child and return
|
||||||
|
// XXX: we should be able to optimize this so we only call ReflowDirtyChild
|
||||||
|
// if it's absolutely necessary: something on the line changed size.
|
||||||
|
nsCOMPtr<nsIPresShell> shell;
|
||||||
|
aPresContext->GetShell(getter_AddRefs(shell));
|
||||||
|
rv = ReflowDirtyChild(shell, state.mNextRCFrame);
|
||||||
|
//XXX: it's possible we need to do some work regarding incremental painting
|
||||||
|
// here, see code below "ReflowDirtyLines() after this switch statement.
|
||||||
|
// It might be right to factor the tail end of this method into a new method
|
||||||
|
// and call that here before calling ReflowDirtyChild().
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// XXX To Do: we need to check some metrics here to see if anything changed
|
|
||||||
// if nothing changed, we're done
|
|
||||||
// otherwise, we should mark the line and the previous line both dirty
|
|
||||||
// and do a resize reflow
|
|
||||||
// Now just mark the line dirty every time. We call PrepareChildIncrementalReflow
|
|
||||||
// because it includes a hack for floaters that we don't want to duplicate here.
|
|
||||||
rv = PrepareChildIncrementalReflow(state);
|
rv = PrepareChildIncrementalReflow(state);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -1562,8 +1580,17 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_ASSERTION(0, "setting up reflow failed.\n");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
// Now reflow...
|
// Now reflow...
|
||||||
rv = ReflowDirtyLines(state);
|
rv = ReflowDirtyLines(state);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_ASSERTION(0, "reflow dirty lines failed.\n");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
aStatus = state.mReflowStatus;
|
aStatus = state.mReflowStatus;
|
||||||
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
|
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
|
||||||
if (NS_STYLE_OVERFLOW_HIDDEN == aReflowState.mStyleDisplay->mOverflow) {
|
if (NS_STYLE_OVERFLOW_HIDDEN == aReflowState.mStyleDisplay->mOverflow) {
|
||||||
@@ -2567,8 +2594,9 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
aState.mReflowState.reflowCommand->GetType(type);
|
aState.mReflowState.reflowCommand->GetType(type);
|
||||||
IndentBy(stdout, gNoiseIndent);
|
IndentBy(stdout, gNoiseIndent);
|
||||||
ListTag(stdout);
|
ListTag(stdout);
|
||||||
printf(": incrementally reflowing dirty lines: type=%s(%d)",
|
printf(": incrementally reflowing dirty lines: type=%s(%d) isInline=%s",
|
||||||
kReflowCommandType[type], type);
|
kReflowCommandType[type], type,
|
||||||
|
aState.mIsInlineIncrReflow ? "true" : "false");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
IndentBy(stdout, gNoiseIndent);
|
IndentBy(stdout, gNoiseIndent);
|
||||||
@@ -2586,10 +2614,30 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
aState.mReflowState.reason ==
|
aState.mReflowState.reason ==
|
||||||
eReflowReason_Dirty;
|
eReflowReason_Dirty;
|
||||||
|
|
||||||
|
nscoord deltaY = 0;
|
||||||
|
|
||||||
// Reflow the lines that are already ours
|
// Reflow the lines that are already ours
|
||||||
aState.mPrevLine = nsnull;
|
aState.mPrevLine = nsnull;
|
||||||
nsLineBox* line = mLines;
|
nsLineBox* line = mLines;
|
||||||
nscoord deltaY = 0;
|
if (aState.mIsInlineIncrReflow && aState.mNextRCFrame)
|
||||||
|
{
|
||||||
|
const nsLineBox* incrTargetLine = aState.mCurrentLine;
|
||||||
|
aState.mCurrentLine = line;
|
||||||
|
aState.mPrevLine = nsnull;
|
||||||
|
while (line && (line != incrTargetLine))
|
||||||
|
{
|
||||||
|
nsRect damageRect;
|
||||||
|
RecoverStateFrom(aState, line, deltaY, incrementalReflow ?
|
||||||
|
&damageRect : 0);
|
||||||
|
if (incrementalReflow && !damageRect.IsEmpty()) {
|
||||||
|
Invalidate(aState.mPresContext, damageRect);
|
||||||
|
}
|
||||||
|
aState.mPrevLine = line;
|
||||||
|
line = line->mNext;
|
||||||
|
aState.AdvanceToNextLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (nsnull != line) {
|
while (nsnull != line) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisyReflow) {
|
if (gNoisyReflow) {
|
||||||
@@ -2623,6 +2671,10 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
if (!(NS_FRAME_IS_COMPLETE(aState.mReflowStatus)))
|
||||||
|
{
|
||||||
|
printf("line %p is not complete\n", line);
|
||||||
|
}
|
||||||
if (!keepGoing) {
|
if (!keepGoing) {
|
||||||
if (0 == line->GetChildCount()) {
|
if (0 == line->GetChildCount()) {
|
||||||
DeleteLine(aState, line);
|
DeleteLine(aState, line);
|
||||||
@@ -3522,7 +3574,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
|||||||
// Try to place the child block
|
// Try to place the child block
|
||||||
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
|
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
|
||||||
nscoord collapsedBottomMargin;
|
nscoord collapsedBottomMargin;
|
||||||
nsRect combinedArea;
|
nsRect combinedArea(0,0,0,0);
|
||||||
*aKeepReflowGoing = brc.PlaceBlock(isAdjacentWithTop, computedOffsets,
|
*aKeepReflowGoing = brc.PlaceBlock(isAdjacentWithTop, computedOffsets,
|
||||||
&collapsedBottomMargin,
|
&collapsedBottomMargin,
|
||||||
aLine->mBounds, combinedArea);
|
aLine->mBounds, combinedArea);
|
||||||
@@ -4356,7 +4408,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||||||
// Stop reflow and whack the reflow status if reflow hasn't
|
// Stop reflow and whack the reflow status if reflow hasn't
|
||||||
// already been stopped.
|
// already been stopped.
|
||||||
if (*aKeepReflowGoing) {
|
if (*aKeepReflowGoing) {
|
||||||
NS_ASSERTION(NS_FRAME_COMPLETE == aState.mReflowStatus,
|
NS_ASSERTION(NS_FRAME_COMPLETE == aState.mReflowStatus,
|
||||||
"lost reflow status");
|
"lost reflow status");
|
||||||
aState.mReflowStatus = NS_FRAME_NOT_COMPLETE;
|
aState.mReflowStatus = NS_FRAME_NOT_COMPLETE;
|
||||||
*aKeepReflowGoing = PR_FALSE;
|
*aKeepReflowGoing = PR_FALSE;
|
||||||
|
|||||||
@@ -451,6 +451,7 @@ public:
|
|||||||
PRPackedBool mUnconstrainedHeight;
|
PRPackedBool mUnconstrainedHeight;
|
||||||
PRPackedBool mShrinkWrapWidth;
|
PRPackedBool mShrinkWrapWidth;
|
||||||
PRPackedBool mNeedResizeReflow;
|
PRPackedBool mNeedResizeReflow;
|
||||||
|
PRPackedBool mIsInlineIncrReflow;
|
||||||
|
|
||||||
// The content area to reflow child frames within. The x/y
|
// The content area to reflow child frames within. The x/y
|
||||||
// coordinates are known to be mBorderPadding.left and
|
// coordinates are known to be mBorderPadding.left and
|
||||||
@@ -579,7 +580,8 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
|
|||||||
mPrevBottomMargin(0),
|
mPrevBottomMargin(0),
|
||||||
mFreeLineList(nsnull),
|
mFreeLineList(nsnull),
|
||||||
mLineNumber(0),
|
mLineNumber(0),
|
||||||
mNeedResizeReflow(PR_FALSE)
|
mNeedResizeReflow(PR_FALSE),
|
||||||
|
mIsInlineIncrReflow(PR_FALSE)
|
||||||
{
|
{
|
||||||
const nsMargin& borderPadding = BorderPadding();
|
const nsMargin& borderPadding = BorderPadding();
|
||||||
|
|
||||||
@@ -1463,6 +1465,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
|
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
PRBool isStyleChange = PR_FALSE;
|
PRBool isStyleChange = PR_FALSE;
|
||||||
|
state.mIsInlineIncrReflow = PR_FALSE;
|
||||||
nsIFrame* target;
|
nsIFrame* target;
|
||||||
switch (aReflowState.reason) {
|
switch (aReflowState.reason) {
|
||||||
case eReflowReason_Initial:
|
case eReflowReason_Initial:
|
||||||
@@ -1518,6 +1521,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
// in the normal case, this just marks the line dirty
|
// in the normal case, this just marks the line dirty
|
||||||
// but, it causes an incremental reflow targeted at a frame
|
// but, it causes an incremental reflow targeted at a frame
|
||||||
// inside a continued span to get dropped on the floor. see bug 25510
|
// inside a continued span to get dropped on the floor. see bug 25510
|
||||||
|
// This will be yanked as soon as we have high confidence in the enabled code below
|
||||||
rv = PrepareChildIncrementalReflow(state);
|
rv = PrepareChildIncrementalReflow(state);
|
||||||
#else
|
#else
|
||||||
// this code does a correct job of propogating incremental reflows (bug 25510)
|
// this code does a correct job of propogating incremental reflows (bug 25510)
|
||||||
@@ -1531,21 +1535,35 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
{
|
{
|
||||||
if (!isFloater) // punt if isFloater!
|
if (!isFloater) // punt if isFloater!
|
||||||
{
|
{
|
||||||
nsBlockReflowState incrState(aReflowState, aPresContext, this, aMetrics,
|
// reflow the line containing the target of the incr. reflow
|
||||||
NS_BLOCK_MARGIN_ROOT & mState);
|
// first mark the line dirty and set up the state object
|
||||||
incrState.mNextRCFrame = state.mNextRCFrame;
|
rv = PrepareChildIncrementalReflow(state);
|
||||||
PRBool keepGoing;
|
state.mIsInlineIncrReflow = PR_TRUE;
|
||||||
rv = ReflowLine(incrState, line, &keepGoing, PR_TRUE);
|
state.mPrevLine = prevLine;
|
||||||
line->RemoveFloatersFromSpaceManager(aReflowState.mSpaceManager);
|
state.mCurrentLine = line;
|
||||||
state.mNextRCFrame = nsnull;
|
state.mNextRCFrame = state.mNextRCFrame;
|
||||||
|
// let ReflowDirtyLines do all the work
|
||||||
|
rv = ReflowDirtyLines(state);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_ASSERTION(0, "Reflow failed\n");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
// compute the final size
|
||||||
|
ComputeFinalSize(aReflowState, state, aMetrics);
|
||||||
|
|
||||||
|
// finally, mark this block frame as having a dirty child and return
|
||||||
|
// XXX: we should be able to optimize this so we only call ReflowDirtyChild
|
||||||
|
// if it's absolutely necessary: something on the line changed size.
|
||||||
|
nsCOMPtr<nsIPresShell> shell;
|
||||||
|
aPresContext->GetShell(getter_AddRefs(shell));
|
||||||
|
rv = ReflowDirtyChild(shell, state.mNextRCFrame);
|
||||||
|
//XXX: it's possible we need to do some work regarding incremental painting
|
||||||
|
// here, see code below "ReflowDirtyLines() after this switch statement.
|
||||||
|
// It might be right to factor the tail end of this method into a new method
|
||||||
|
// and call that here before calling ReflowDirtyChild().
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// XXX To Do: we need to check some metrics here to see if anything changed
|
|
||||||
// if nothing changed, we're done
|
|
||||||
// otherwise, we should mark the line and the previous line both dirty
|
|
||||||
// and do a resize reflow
|
|
||||||
// Now just mark the line dirty every time. We call PrepareChildIncrementalReflow
|
|
||||||
// because it includes a hack for floaters that we don't want to duplicate here.
|
|
||||||
rv = PrepareChildIncrementalReflow(state);
|
rv = PrepareChildIncrementalReflow(state);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -1562,8 +1580,17 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_ASSERTION(0, "setting up reflow failed.\n");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
// Now reflow...
|
// Now reflow...
|
||||||
rv = ReflowDirtyLines(state);
|
rv = ReflowDirtyLines(state);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_ASSERTION(0, "reflow dirty lines failed.\n");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
aStatus = state.mReflowStatus;
|
aStatus = state.mReflowStatus;
|
||||||
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
|
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
|
||||||
if (NS_STYLE_OVERFLOW_HIDDEN == aReflowState.mStyleDisplay->mOverflow) {
|
if (NS_STYLE_OVERFLOW_HIDDEN == aReflowState.mStyleDisplay->mOverflow) {
|
||||||
@@ -2567,8 +2594,9 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
aState.mReflowState.reflowCommand->GetType(type);
|
aState.mReflowState.reflowCommand->GetType(type);
|
||||||
IndentBy(stdout, gNoiseIndent);
|
IndentBy(stdout, gNoiseIndent);
|
||||||
ListTag(stdout);
|
ListTag(stdout);
|
||||||
printf(": incrementally reflowing dirty lines: type=%s(%d)",
|
printf(": incrementally reflowing dirty lines: type=%s(%d) isInline=%s",
|
||||||
kReflowCommandType[type], type);
|
kReflowCommandType[type], type,
|
||||||
|
aState.mIsInlineIncrReflow ? "true" : "false");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
IndentBy(stdout, gNoiseIndent);
|
IndentBy(stdout, gNoiseIndent);
|
||||||
@@ -2586,10 +2614,30 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
aState.mReflowState.reason ==
|
aState.mReflowState.reason ==
|
||||||
eReflowReason_Dirty;
|
eReflowReason_Dirty;
|
||||||
|
|
||||||
|
nscoord deltaY = 0;
|
||||||
|
|
||||||
// Reflow the lines that are already ours
|
// Reflow the lines that are already ours
|
||||||
aState.mPrevLine = nsnull;
|
aState.mPrevLine = nsnull;
|
||||||
nsLineBox* line = mLines;
|
nsLineBox* line = mLines;
|
||||||
nscoord deltaY = 0;
|
if (aState.mIsInlineIncrReflow && aState.mNextRCFrame)
|
||||||
|
{
|
||||||
|
const nsLineBox* incrTargetLine = aState.mCurrentLine;
|
||||||
|
aState.mCurrentLine = line;
|
||||||
|
aState.mPrevLine = nsnull;
|
||||||
|
while (line && (line != incrTargetLine))
|
||||||
|
{
|
||||||
|
nsRect damageRect;
|
||||||
|
RecoverStateFrom(aState, line, deltaY, incrementalReflow ?
|
||||||
|
&damageRect : 0);
|
||||||
|
if (incrementalReflow && !damageRect.IsEmpty()) {
|
||||||
|
Invalidate(aState.mPresContext, damageRect);
|
||||||
|
}
|
||||||
|
aState.mPrevLine = line;
|
||||||
|
line = line->mNext;
|
||||||
|
aState.AdvanceToNextLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (nsnull != line) {
|
while (nsnull != line) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisyReflow) {
|
if (gNoisyReflow) {
|
||||||
@@ -2623,6 +2671,10 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
if (!(NS_FRAME_IS_COMPLETE(aState.mReflowStatus)))
|
||||||
|
{
|
||||||
|
printf("line %p is not complete\n", line);
|
||||||
|
}
|
||||||
if (!keepGoing) {
|
if (!keepGoing) {
|
||||||
if (0 == line->GetChildCount()) {
|
if (0 == line->GetChildCount()) {
|
||||||
DeleteLine(aState, line);
|
DeleteLine(aState, line);
|
||||||
@@ -3522,7 +3574,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
|||||||
// Try to place the child block
|
// Try to place the child block
|
||||||
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
|
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
|
||||||
nscoord collapsedBottomMargin;
|
nscoord collapsedBottomMargin;
|
||||||
nsRect combinedArea;
|
nsRect combinedArea(0,0,0,0);
|
||||||
*aKeepReflowGoing = brc.PlaceBlock(isAdjacentWithTop, computedOffsets,
|
*aKeepReflowGoing = brc.PlaceBlock(isAdjacentWithTop, computedOffsets,
|
||||||
&collapsedBottomMargin,
|
&collapsedBottomMargin,
|
||||||
aLine->mBounds, combinedArea);
|
aLine->mBounds, combinedArea);
|
||||||
@@ -4356,7 +4408,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||||||
// Stop reflow and whack the reflow status if reflow hasn't
|
// Stop reflow and whack the reflow status if reflow hasn't
|
||||||
// already been stopped.
|
// already been stopped.
|
||||||
if (*aKeepReflowGoing) {
|
if (*aKeepReflowGoing) {
|
||||||
NS_ASSERTION(NS_FRAME_COMPLETE == aState.mReflowStatus,
|
NS_ASSERTION(NS_FRAME_COMPLETE == aState.mReflowStatus,
|
||||||
"lost reflow status");
|
"lost reflow status");
|
||||||
aState.mReflowStatus = NS_FRAME_NOT_COMPLETE;
|
aState.mReflowStatus = NS_FRAME_NOT_COMPLETE;
|
||||||
*aKeepReflowGoing = PR_FALSE;
|
*aKeepReflowGoing = PR_FALSE;
|
||||||
|
|||||||
@@ -451,6 +451,7 @@ public:
|
|||||||
PRPackedBool mUnconstrainedHeight;
|
PRPackedBool mUnconstrainedHeight;
|
||||||
PRPackedBool mShrinkWrapWidth;
|
PRPackedBool mShrinkWrapWidth;
|
||||||
PRPackedBool mNeedResizeReflow;
|
PRPackedBool mNeedResizeReflow;
|
||||||
|
PRPackedBool mIsInlineIncrReflow;
|
||||||
|
|
||||||
// The content area to reflow child frames within. The x/y
|
// The content area to reflow child frames within. The x/y
|
||||||
// coordinates are known to be mBorderPadding.left and
|
// coordinates are known to be mBorderPadding.left and
|
||||||
@@ -579,7 +580,8 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
|
|||||||
mPrevBottomMargin(0),
|
mPrevBottomMargin(0),
|
||||||
mFreeLineList(nsnull),
|
mFreeLineList(nsnull),
|
||||||
mLineNumber(0),
|
mLineNumber(0),
|
||||||
mNeedResizeReflow(PR_FALSE)
|
mNeedResizeReflow(PR_FALSE),
|
||||||
|
mIsInlineIncrReflow(PR_FALSE)
|
||||||
{
|
{
|
||||||
const nsMargin& borderPadding = BorderPadding();
|
const nsMargin& borderPadding = BorderPadding();
|
||||||
|
|
||||||
@@ -1463,6 +1465,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
|
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
PRBool isStyleChange = PR_FALSE;
|
PRBool isStyleChange = PR_FALSE;
|
||||||
|
state.mIsInlineIncrReflow = PR_FALSE;
|
||||||
nsIFrame* target;
|
nsIFrame* target;
|
||||||
switch (aReflowState.reason) {
|
switch (aReflowState.reason) {
|
||||||
case eReflowReason_Initial:
|
case eReflowReason_Initial:
|
||||||
@@ -1518,6 +1521,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
// in the normal case, this just marks the line dirty
|
// in the normal case, this just marks the line dirty
|
||||||
// but, it causes an incremental reflow targeted at a frame
|
// but, it causes an incremental reflow targeted at a frame
|
||||||
// inside a continued span to get dropped on the floor. see bug 25510
|
// inside a continued span to get dropped on the floor. see bug 25510
|
||||||
|
// This will be yanked as soon as we have high confidence in the enabled code below
|
||||||
rv = PrepareChildIncrementalReflow(state);
|
rv = PrepareChildIncrementalReflow(state);
|
||||||
#else
|
#else
|
||||||
// this code does a correct job of propogating incremental reflows (bug 25510)
|
// this code does a correct job of propogating incremental reflows (bug 25510)
|
||||||
@@ -1531,21 +1535,35 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
{
|
{
|
||||||
if (!isFloater) // punt if isFloater!
|
if (!isFloater) // punt if isFloater!
|
||||||
{
|
{
|
||||||
nsBlockReflowState incrState(aReflowState, aPresContext, this, aMetrics,
|
// reflow the line containing the target of the incr. reflow
|
||||||
NS_BLOCK_MARGIN_ROOT & mState);
|
// first mark the line dirty and set up the state object
|
||||||
incrState.mNextRCFrame = state.mNextRCFrame;
|
rv = PrepareChildIncrementalReflow(state);
|
||||||
PRBool keepGoing;
|
state.mIsInlineIncrReflow = PR_TRUE;
|
||||||
rv = ReflowLine(incrState, line, &keepGoing, PR_TRUE);
|
state.mPrevLine = prevLine;
|
||||||
line->RemoveFloatersFromSpaceManager(aReflowState.mSpaceManager);
|
state.mCurrentLine = line;
|
||||||
state.mNextRCFrame = nsnull;
|
state.mNextRCFrame = state.mNextRCFrame;
|
||||||
|
// let ReflowDirtyLines do all the work
|
||||||
|
rv = ReflowDirtyLines(state);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_ASSERTION(0, "Reflow failed\n");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
// compute the final size
|
||||||
|
ComputeFinalSize(aReflowState, state, aMetrics);
|
||||||
|
|
||||||
|
// finally, mark this block frame as having a dirty child and return
|
||||||
|
// XXX: we should be able to optimize this so we only call ReflowDirtyChild
|
||||||
|
// if it's absolutely necessary: something on the line changed size.
|
||||||
|
nsCOMPtr<nsIPresShell> shell;
|
||||||
|
aPresContext->GetShell(getter_AddRefs(shell));
|
||||||
|
rv = ReflowDirtyChild(shell, state.mNextRCFrame);
|
||||||
|
//XXX: it's possible we need to do some work regarding incremental painting
|
||||||
|
// here, see code below "ReflowDirtyLines() after this switch statement.
|
||||||
|
// It might be right to factor the tail end of this method into a new method
|
||||||
|
// and call that here before calling ReflowDirtyChild().
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// XXX To Do: we need to check some metrics here to see if anything changed
|
|
||||||
// if nothing changed, we're done
|
|
||||||
// otherwise, we should mark the line and the previous line both dirty
|
|
||||||
// and do a resize reflow
|
|
||||||
// Now just mark the line dirty every time. We call PrepareChildIncrementalReflow
|
|
||||||
// because it includes a hack for floaters that we don't want to duplicate here.
|
|
||||||
rv = PrepareChildIncrementalReflow(state);
|
rv = PrepareChildIncrementalReflow(state);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -1562,8 +1580,17 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_ASSERTION(0, "setting up reflow failed.\n");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
// Now reflow...
|
// Now reflow...
|
||||||
rv = ReflowDirtyLines(state);
|
rv = ReflowDirtyLines(state);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_ASSERTION(0, "reflow dirty lines failed.\n");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
aStatus = state.mReflowStatus;
|
aStatus = state.mReflowStatus;
|
||||||
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
|
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
|
||||||
if (NS_STYLE_OVERFLOW_HIDDEN == aReflowState.mStyleDisplay->mOverflow) {
|
if (NS_STYLE_OVERFLOW_HIDDEN == aReflowState.mStyleDisplay->mOverflow) {
|
||||||
@@ -2567,8 +2594,9 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
aState.mReflowState.reflowCommand->GetType(type);
|
aState.mReflowState.reflowCommand->GetType(type);
|
||||||
IndentBy(stdout, gNoiseIndent);
|
IndentBy(stdout, gNoiseIndent);
|
||||||
ListTag(stdout);
|
ListTag(stdout);
|
||||||
printf(": incrementally reflowing dirty lines: type=%s(%d)",
|
printf(": incrementally reflowing dirty lines: type=%s(%d) isInline=%s",
|
||||||
kReflowCommandType[type], type);
|
kReflowCommandType[type], type,
|
||||||
|
aState.mIsInlineIncrReflow ? "true" : "false");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
IndentBy(stdout, gNoiseIndent);
|
IndentBy(stdout, gNoiseIndent);
|
||||||
@@ -2586,10 +2614,30 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
aState.mReflowState.reason ==
|
aState.mReflowState.reason ==
|
||||||
eReflowReason_Dirty;
|
eReflowReason_Dirty;
|
||||||
|
|
||||||
|
nscoord deltaY = 0;
|
||||||
|
|
||||||
// Reflow the lines that are already ours
|
// Reflow the lines that are already ours
|
||||||
aState.mPrevLine = nsnull;
|
aState.mPrevLine = nsnull;
|
||||||
nsLineBox* line = mLines;
|
nsLineBox* line = mLines;
|
||||||
nscoord deltaY = 0;
|
if (aState.mIsInlineIncrReflow && aState.mNextRCFrame)
|
||||||
|
{
|
||||||
|
const nsLineBox* incrTargetLine = aState.mCurrentLine;
|
||||||
|
aState.mCurrentLine = line;
|
||||||
|
aState.mPrevLine = nsnull;
|
||||||
|
while (line && (line != incrTargetLine))
|
||||||
|
{
|
||||||
|
nsRect damageRect;
|
||||||
|
RecoverStateFrom(aState, line, deltaY, incrementalReflow ?
|
||||||
|
&damageRect : 0);
|
||||||
|
if (incrementalReflow && !damageRect.IsEmpty()) {
|
||||||
|
Invalidate(aState.mPresContext, damageRect);
|
||||||
|
}
|
||||||
|
aState.mPrevLine = line;
|
||||||
|
line = line->mNext;
|
||||||
|
aState.AdvanceToNextLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (nsnull != line) {
|
while (nsnull != line) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisyReflow) {
|
if (gNoisyReflow) {
|
||||||
@@ -2623,6 +2671,10 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
if (!(NS_FRAME_IS_COMPLETE(aState.mReflowStatus)))
|
||||||
|
{
|
||||||
|
printf("line %p is not complete\n", line);
|
||||||
|
}
|
||||||
if (!keepGoing) {
|
if (!keepGoing) {
|
||||||
if (0 == line->GetChildCount()) {
|
if (0 == line->GetChildCount()) {
|
||||||
DeleteLine(aState, line);
|
DeleteLine(aState, line);
|
||||||
@@ -3522,7 +3574,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
|||||||
// Try to place the child block
|
// Try to place the child block
|
||||||
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
|
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
|
||||||
nscoord collapsedBottomMargin;
|
nscoord collapsedBottomMargin;
|
||||||
nsRect combinedArea;
|
nsRect combinedArea(0,0,0,0);
|
||||||
*aKeepReflowGoing = brc.PlaceBlock(isAdjacentWithTop, computedOffsets,
|
*aKeepReflowGoing = brc.PlaceBlock(isAdjacentWithTop, computedOffsets,
|
||||||
&collapsedBottomMargin,
|
&collapsedBottomMargin,
|
||||||
aLine->mBounds, combinedArea);
|
aLine->mBounds, combinedArea);
|
||||||
@@ -4356,7 +4408,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||||||
// Stop reflow and whack the reflow status if reflow hasn't
|
// Stop reflow and whack the reflow status if reflow hasn't
|
||||||
// already been stopped.
|
// already been stopped.
|
||||||
if (*aKeepReflowGoing) {
|
if (*aKeepReflowGoing) {
|
||||||
NS_ASSERTION(NS_FRAME_COMPLETE == aState.mReflowStatus,
|
NS_ASSERTION(NS_FRAME_COMPLETE == aState.mReflowStatus,
|
||||||
"lost reflow status");
|
"lost reflow status");
|
||||||
aState.mReflowStatus = NS_FRAME_NOT_COMPLETE;
|
aState.mReflowStatus = NS_FRAME_NOT_COMPLETE;
|
||||||
*aKeepReflowGoing = PR_FALSE;
|
*aKeepReflowGoing = PR_FALSE;
|
||||||
|
|||||||
@@ -451,6 +451,7 @@ public:
|
|||||||
PRPackedBool mUnconstrainedHeight;
|
PRPackedBool mUnconstrainedHeight;
|
||||||
PRPackedBool mShrinkWrapWidth;
|
PRPackedBool mShrinkWrapWidth;
|
||||||
PRPackedBool mNeedResizeReflow;
|
PRPackedBool mNeedResizeReflow;
|
||||||
|
PRPackedBool mIsInlineIncrReflow;
|
||||||
|
|
||||||
// The content area to reflow child frames within. The x/y
|
// The content area to reflow child frames within. The x/y
|
||||||
// coordinates are known to be mBorderPadding.left and
|
// coordinates are known to be mBorderPadding.left and
|
||||||
@@ -579,7 +580,8 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
|
|||||||
mPrevBottomMargin(0),
|
mPrevBottomMargin(0),
|
||||||
mFreeLineList(nsnull),
|
mFreeLineList(nsnull),
|
||||||
mLineNumber(0),
|
mLineNumber(0),
|
||||||
mNeedResizeReflow(PR_FALSE)
|
mNeedResizeReflow(PR_FALSE),
|
||||||
|
mIsInlineIncrReflow(PR_FALSE)
|
||||||
{
|
{
|
||||||
const nsMargin& borderPadding = BorderPadding();
|
const nsMargin& borderPadding = BorderPadding();
|
||||||
|
|
||||||
@@ -1463,6 +1465,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
|
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
PRBool isStyleChange = PR_FALSE;
|
PRBool isStyleChange = PR_FALSE;
|
||||||
|
state.mIsInlineIncrReflow = PR_FALSE;
|
||||||
nsIFrame* target;
|
nsIFrame* target;
|
||||||
switch (aReflowState.reason) {
|
switch (aReflowState.reason) {
|
||||||
case eReflowReason_Initial:
|
case eReflowReason_Initial:
|
||||||
@@ -1518,6 +1521,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
// in the normal case, this just marks the line dirty
|
// in the normal case, this just marks the line dirty
|
||||||
// but, it causes an incremental reflow targeted at a frame
|
// but, it causes an incremental reflow targeted at a frame
|
||||||
// inside a continued span to get dropped on the floor. see bug 25510
|
// inside a continued span to get dropped on the floor. see bug 25510
|
||||||
|
// This will be yanked as soon as we have high confidence in the enabled code below
|
||||||
rv = PrepareChildIncrementalReflow(state);
|
rv = PrepareChildIncrementalReflow(state);
|
||||||
#else
|
#else
|
||||||
// this code does a correct job of propogating incremental reflows (bug 25510)
|
// this code does a correct job of propogating incremental reflows (bug 25510)
|
||||||
@@ -1531,21 +1535,35 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
{
|
{
|
||||||
if (!isFloater) // punt if isFloater!
|
if (!isFloater) // punt if isFloater!
|
||||||
{
|
{
|
||||||
nsBlockReflowState incrState(aReflowState, aPresContext, this, aMetrics,
|
// reflow the line containing the target of the incr. reflow
|
||||||
NS_BLOCK_MARGIN_ROOT & mState);
|
// first mark the line dirty and set up the state object
|
||||||
incrState.mNextRCFrame = state.mNextRCFrame;
|
rv = PrepareChildIncrementalReflow(state);
|
||||||
PRBool keepGoing;
|
state.mIsInlineIncrReflow = PR_TRUE;
|
||||||
rv = ReflowLine(incrState, line, &keepGoing, PR_TRUE);
|
state.mPrevLine = prevLine;
|
||||||
line->RemoveFloatersFromSpaceManager(aReflowState.mSpaceManager);
|
state.mCurrentLine = line;
|
||||||
state.mNextRCFrame = nsnull;
|
state.mNextRCFrame = state.mNextRCFrame;
|
||||||
|
// let ReflowDirtyLines do all the work
|
||||||
|
rv = ReflowDirtyLines(state);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_ASSERTION(0, "Reflow failed\n");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
// compute the final size
|
||||||
|
ComputeFinalSize(aReflowState, state, aMetrics);
|
||||||
|
|
||||||
|
// finally, mark this block frame as having a dirty child and return
|
||||||
|
// XXX: we should be able to optimize this so we only call ReflowDirtyChild
|
||||||
|
// if it's absolutely necessary: something on the line changed size.
|
||||||
|
nsCOMPtr<nsIPresShell> shell;
|
||||||
|
aPresContext->GetShell(getter_AddRefs(shell));
|
||||||
|
rv = ReflowDirtyChild(shell, state.mNextRCFrame);
|
||||||
|
//XXX: it's possible we need to do some work regarding incremental painting
|
||||||
|
// here, see code below "ReflowDirtyLines() after this switch statement.
|
||||||
|
// It might be right to factor the tail end of this method into a new method
|
||||||
|
// and call that here before calling ReflowDirtyChild().
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// XXX To Do: we need to check some metrics here to see if anything changed
|
|
||||||
// if nothing changed, we're done
|
|
||||||
// otherwise, we should mark the line and the previous line both dirty
|
|
||||||
// and do a resize reflow
|
|
||||||
// Now just mark the line dirty every time. We call PrepareChildIncrementalReflow
|
|
||||||
// because it includes a hack for floaters that we don't want to duplicate here.
|
|
||||||
rv = PrepareChildIncrementalReflow(state);
|
rv = PrepareChildIncrementalReflow(state);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -1562,8 +1580,17 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_ASSERTION(0, "setting up reflow failed.\n");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
// Now reflow...
|
// Now reflow...
|
||||||
rv = ReflowDirtyLines(state);
|
rv = ReflowDirtyLines(state);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_ASSERTION(0, "reflow dirty lines failed.\n");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
aStatus = state.mReflowStatus;
|
aStatus = state.mReflowStatus;
|
||||||
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
|
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
|
||||||
if (NS_STYLE_OVERFLOW_HIDDEN == aReflowState.mStyleDisplay->mOverflow) {
|
if (NS_STYLE_OVERFLOW_HIDDEN == aReflowState.mStyleDisplay->mOverflow) {
|
||||||
@@ -2567,8 +2594,9 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
aState.mReflowState.reflowCommand->GetType(type);
|
aState.mReflowState.reflowCommand->GetType(type);
|
||||||
IndentBy(stdout, gNoiseIndent);
|
IndentBy(stdout, gNoiseIndent);
|
||||||
ListTag(stdout);
|
ListTag(stdout);
|
||||||
printf(": incrementally reflowing dirty lines: type=%s(%d)",
|
printf(": incrementally reflowing dirty lines: type=%s(%d) isInline=%s",
|
||||||
kReflowCommandType[type], type);
|
kReflowCommandType[type], type,
|
||||||
|
aState.mIsInlineIncrReflow ? "true" : "false");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
IndentBy(stdout, gNoiseIndent);
|
IndentBy(stdout, gNoiseIndent);
|
||||||
@@ -2586,10 +2614,30 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
aState.mReflowState.reason ==
|
aState.mReflowState.reason ==
|
||||||
eReflowReason_Dirty;
|
eReflowReason_Dirty;
|
||||||
|
|
||||||
|
nscoord deltaY = 0;
|
||||||
|
|
||||||
// Reflow the lines that are already ours
|
// Reflow the lines that are already ours
|
||||||
aState.mPrevLine = nsnull;
|
aState.mPrevLine = nsnull;
|
||||||
nsLineBox* line = mLines;
|
nsLineBox* line = mLines;
|
||||||
nscoord deltaY = 0;
|
if (aState.mIsInlineIncrReflow && aState.mNextRCFrame)
|
||||||
|
{
|
||||||
|
const nsLineBox* incrTargetLine = aState.mCurrentLine;
|
||||||
|
aState.mCurrentLine = line;
|
||||||
|
aState.mPrevLine = nsnull;
|
||||||
|
while (line && (line != incrTargetLine))
|
||||||
|
{
|
||||||
|
nsRect damageRect;
|
||||||
|
RecoverStateFrom(aState, line, deltaY, incrementalReflow ?
|
||||||
|
&damageRect : 0);
|
||||||
|
if (incrementalReflow && !damageRect.IsEmpty()) {
|
||||||
|
Invalidate(aState.mPresContext, damageRect);
|
||||||
|
}
|
||||||
|
aState.mPrevLine = line;
|
||||||
|
line = line->mNext;
|
||||||
|
aState.AdvanceToNextLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (nsnull != line) {
|
while (nsnull != line) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisyReflow) {
|
if (gNoisyReflow) {
|
||||||
@@ -2623,6 +2671,10 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
if (!(NS_FRAME_IS_COMPLETE(aState.mReflowStatus)))
|
||||||
|
{
|
||||||
|
printf("line %p is not complete\n", line);
|
||||||
|
}
|
||||||
if (!keepGoing) {
|
if (!keepGoing) {
|
||||||
if (0 == line->GetChildCount()) {
|
if (0 == line->GetChildCount()) {
|
||||||
DeleteLine(aState, line);
|
DeleteLine(aState, line);
|
||||||
@@ -3522,7 +3574,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
|||||||
// Try to place the child block
|
// Try to place the child block
|
||||||
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
|
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
|
||||||
nscoord collapsedBottomMargin;
|
nscoord collapsedBottomMargin;
|
||||||
nsRect combinedArea;
|
nsRect combinedArea(0,0,0,0);
|
||||||
*aKeepReflowGoing = brc.PlaceBlock(isAdjacentWithTop, computedOffsets,
|
*aKeepReflowGoing = brc.PlaceBlock(isAdjacentWithTop, computedOffsets,
|
||||||
&collapsedBottomMargin,
|
&collapsedBottomMargin,
|
||||||
aLine->mBounds, combinedArea);
|
aLine->mBounds, combinedArea);
|
||||||
@@ -4356,7 +4408,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||||||
// Stop reflow and whack the reflow status if reflow hasn't
|
// Stop reflow and whack the reflow status if reflow hasn't
|
||||||
// already been stopped.
|
// already been stopped.
|
||||||
if (*aKeepReflowGoing) {
|
if (*aKeepReflowGoing) {
|
||||||
NS_ASSERTION(NS_FRAME_COMPLETE == aState.mReflowStatus,
|
NS_ASSERTION(NS_FRAME_COMPLETE == aState.mReflowStatus,
|
||||||
"lost reflow status");
|
"lost reflow status");
|
||||||
aState.mReflowStatus = NS_FRAME_NOT_COMPLETE;
|
aState.mReflowStatus = NS_FRAME_NOT_COMPLETE;
|
||||||
*aKeepReflowGoing = PR_FALSE;
|
*aKeepReflowGoing = PR_FALSE;
|
||||||
|
|||||||
@@ -451,6 +451,7 @@ public:
|
|||||||
PRPackedBool mUnconstrainedHeight;
|
PRPackedBool mUnconstrainedHeight;
|
||||||
PRPackedBool mShrinkWrapWidth;
|
PRPackedBool mShrinkWrapWidth;
|
||||||
PRPackedBool mNeedResizeReflow;
|
PRPackedBool mNeedResizeReflow;
|
||||||
|
PRPackedBool mIsInlineIncrReflow;
|
||||||
|
|
||||||
// The content area to reflow child frames within. The x/y
|
// The content area to reflow child frames within. The x/y
|
||||||
// coordinates are known to be mBorderPadding.left and
|
// coordinates are known to be mBorderPadding.left and
|
||||||
@@ -579,7 +580,8 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
|
|||||||
mPrevBottomMargin(0),
|
mPrevBottomMargin(0),
|
||||||
mFreeLineList(nsnull),
|
mFreeLineList(nsnull),
|
||||||
mLineNumber(0),
|
mLineNumber(0),
|
||||||
mNeedResizeReflow(PR_FALSE)
|
mNeedResizeReflow(PR_FALSE),
|
||||||
|
mIsInlineIncrReflow(PR_FALSE)
|
||||||
{
|
{
|
||||||
const nsMargin& borderPadding = BorderPadding();
|
const nsMargin& borderPadding = BorderPadding();
|
||||||
|
|
||||||
@@ -1463,6 +1465,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
|
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
PRBool isStyleChange = PR_FALSE;
|
PRBool isStyleChange = PR_FALSE;
|
||||||
|
state.mIsInlineIncrReflow = PR_FALSE;
|
||||||
nsIFrame* target;
|
nsIFrame* target;
|
||||||
switch (aReflowState.reason) {
|
switch (aReflowState.reason) {
|
||||||
case eReflowReason_Initial:
|
case eReflowReason_Initial:
|
||||||
@@ -1518,6 +1521,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
// in the normal case, this just marks the line dirty
|
// in the normal case, this just marks the line dirty
|
||||||
// but, it causes an incremental reflow targeted at a frame
|
// but, it causes an incremental reflow targeted at a frame
|
||||||
// inside a continued span to get dropped on the floor. see bug 25510
|
// inside a continued span to get dropped on the floor. see bug 25510
|
||||||
|
// This will be yanked as soon as we have high confidence in the enabled code below
|
||||||
rv = PrepareChildIncrementalReflow(state);
|
rv = PrepareChildIncrementalReflow(state);
|
||||||
#else
|
#else
|
||||||
// this code does a correct job of propogating incremental reflows (bug 25510)
|
// this code does a correct job of propogating incremental reflows (bug 25510)
|
||||||
@@ -1531,21 +1535,35 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
{
|
{
|
||||||
if (!isFloater) // punt if isFloater!
|
if (!isFloater) // punt if isFloater!
|
||||||
{
|
{
|
||||||
nsBlockReflowState incrState(aReflowState, aPresContext, this, aMetrics,
|
// reflow the line containing the target of the incr. reflow
|
||||||
NS_BLOCK_MARGIN_ROOT & mState);
|
// first mark the line dirty and set up the state object
|
||||||
incrState.mNextRCFrame = state.mNextRCFrame;
|
rv = PrepareChildIncrementalReflow(state);
|
||||||
PRBool keepGoing;
|
state.mIsInlineIncrReflow = PR_TRUE;
|
||||||
rv = ReflowLine(incrState, line, &keepGoing, PR_TRUE);
|
state.mPrevLine = prevLine;
|
||||||
line->RemoveFloatersFromSpaceManager(aReflowState.mSpaceManager);
|
state.mCurrentLine = line;
|
||||||
state.mNextRCFrame = nsnull;
|
state.mNextRCFrame = state.mNextRCFrame;
|
||||||
|
// let ReflowDirtyLines do all the work
|
||||||
|
rv = ReflowDirtyLines(state);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_ASSERTION(0, "Reflow failed\n");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
// compute the final size
|
||||||
|
ComputeFinalSize(aReflowState, state, aMetrics);
|
||||||
|
|
||||||
|
// finally, mark this block frame as having a dirty child and return
|
||||||
|
// XXX: we should be able to optimize this so we only call ReflowDirtyChild
|
||||||
|
// if it's absolutely necessary: something on the line changed size.
|
||||||
|
nsCOMPtr<nsIPresShell> shell;
|
||||||
|
aPresContext->GetShell(getter_AddRefs(shell));
|
||||||
|
rv = ReflowDirtyChild(shell, state.mNextRCFrame);
|
||||||
|
//XXX: it's possible we need to do some work regarding incremental painting
|
||||||
|
// here, see code below "ReflowDirtyLines() after this switch statement.
|
||||||
|
// It might be right to factor the tail end of this method into a new method
|
||||||
|
// and call that here before calling ReflowDirtyChild().
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// XXX To Do: we need to check some metrics here to see if anything changed
|
|
||||||
// if nothing changed, we're done
|
|
||||||
// otherwise, we should mark the line and the previous line both dirty
|
|
||||||
// and do a resize reflow
|
|
||||||
// Now just mark the line dirty every time. We call PrepareChildIncrementalReflow
|
|
||||||
// because it includes a hack for floaters that we don't want to duplicate here.
|
|
||||||
rv = PrepareChildIncrementalReflow(state);
|
rv = PrepareChildIncrementalReflow(state);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -1562,8 +1580,17 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_ASSERTION(0, "setting up reflow failed.\n");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
// Now reflow...
|
// Now reflow...
|
||||||
rv = ReflowDirtyLines(state);
|
rv = ReflowDirtyLines(state);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_ASSERTION(0, "reflow dirty lines failed.\n");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
aStatus = state.mReflowStatus;
|
aStatus = state.mReflowStatus;
|
||||||
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
|
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
|
||||||
if (NS_STYLE_OVERFLOW_HIDDEN == aReflowState.mStyleDisplay->mOverflow) {
|
if (NS_STYLE_OVERFLOW_HIDDEN == aReflowState.mStyleDisplay->mOverflow) {
|
||||||
@@ -2567,8 +2594,9 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
aState.mReflowState.reflowCommand->GetType(type);
|
aState.mReflowState.reflowCommand->GetType(type);
|
||||||
IndentBy(stdout, gNoiseIndent);
|
IndentBy(stdout, gNoiseIndent);
|
||||||
ListTag(stdout);
|
ListTag(stdout);
|
||||||
printf(": incrementally reflowing dirty lines: type=%s(%d)",
|
printf(": incrementally reflowing dirty lines: type=%s(%d) isInline=%s",
|
||||||
kReflowCommandType[type], type);
|
kReflowCommandType[type], type,
|
||||||
|
aState.mIsInlineIncrReflow ? "true" : "false");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
IndentBy(stdout, gNoiseIndent);
|
IndentBy(stdout, gNoiseIndent);
|
||||||
@@ -2586,10 +2614,30 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
aState.mReflowState.reason ==
|
aState.mReflowState.reason ==
|
||||||
eReflowReason_Dirty;
|
eReflowReason_Dirty;
|
||||||
|
|
||||||
|
nscoord deltaY = 0;
|
||||||
|
|
||||||
// Reflow the lines that are already ours
|
// Reflow the lines that are already ours
|
||||||
aState.mPrevLine = nsnull;
|
aState.mPrevLine = nsnull;
|
||||||
nsLineBox* line = mLines;
|
nsLineBox* line = mLines;
|
||||||
nscoord deltaY = 0;
|
if (aState.mIsInlineIncrReflow && aState.mNextRCFrame)
|
||||||
|
{
|
||||||
|
const nsLineBox* incrTargetLine = aState.mCurrentLine;
|
||||||
|
aState.mCurrentLine = line;
|
||||||
|
aState.mPrevLine = nsnull;
|
||||||
|
while (line && (line != incrTargetLine))
|
||||||
|
{
|
||||||
|
nsRect damageRect;
|
||||||
|
RecoverStateFrom(aState, line, deltaY, incrementalReflow ?
|
||||||
|
&damageRect : 0);
|
||||||
|
if (incrementalReflow && !damageRect.IsEmpty()) {
|
||||||
|
Invalidate(aState.mPresContext, damageRect);
|
||||||
|
}
|
||||||
|
aState.mPrevLine = line;
|
||||||
|
line = line->mNext;
|
||||||
|
aState.AdvanceToNextLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (nsnull != line) {
|
while (nsnull != line) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisyReflow) {
|
if (gNoisyReflow) {
|
||||||
@@ -2623,6 +2671,10 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
if (!(NS_FRAME_IS_COMPLETE(aState.mReflowStatus)))
|
||||||
|
{
|
||||||
|
printf("line %p is not complete\n", line);
|
||||||
|
}
|
||||||
if (!keepGoing) {
|
if (!keepGoing) {
|
||||||
if (0 == line->GetChildCount()) {
|
if (0 == line->GetChildCount()) {
|
||||||
DeleteLine(aState, line);
|
DeleteLine(aState, line);
|
||||||
@@ -3522,7 +3574,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
|||||||
// Try to place the child block
|
// Try to place the child block
|
||||||
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
|
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
|
||||||
nscoord collapsedBottomMargin;
|
nscoord collapsedBottomMargin;
|
||||||
nsRect combinedArea;
|
nsRect combinedArea(0,0,0,0);
|
||||||
*aKeepReflowGoing = brc.PlaceBlock(isAdjacentWithTop, computedOffsets,
|
*aKeepReflowGoing = brc.PlaceBlock(isAdjacentWithTop, computedOffsets,
|
||||||
&collapsedBottomMargin,
|
&collapsedBottomMargin,
|
||||||
aLine->mBounds, combinedArea);
|
aLine->mBounds, combinedArea);
|
||||||
@@ -4356,7 +4408,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||||||
// Stop reflow and whack the reflow status if reflow hasn't
|
// Stop reflow and whack the reflow status if reflow hasn't
|
||||||
// already been stopped.
|
// already been stopped.
|
||||||
if (*aKeepReflowGoing) {
|
if (*aKeepReflowGoing) {
|
||||||
NS_ASSERTION(NS_FRAME_COMPLETE == aState.mReflowStatus,
|
NS_ASSERTION(NS_FRAME_COMPLETE == aState.mReflowStatus,
|
||||||
"lost reflow status");
|
"lost reflow status");
|
||||||
aState.mReflowStatus = NS_FRAME_NOT_COMPLETE;
|
aState.mReflowStatus = NS_FRAME_NOT_COMPLETE;
|
||||||
*aKeepReflowGoing = PR_FALSE;
|
*aKeepReflowGoing = PR_FALSE;
|
||||||
|
|||||||
@@ -451,6 +451,7 @@ public:
|
|||||||
PRPackedBool mUnconstrainedHeight;
|
PRPackedBool mUnconstrainedHeight;
|
||||||
PRPackedBool mShrinkWrapWidth;
|
PRPackedBool mShrinkWrapWidth;
|
||||||
PRPackedBool mNeedResizeReflow;
|
PRPackedBool mNeedResizeReflow;
|
||||||
|
PRPackedBool mIsInlineIncrReflow;
|
||||||
|
|
||||||
// The content area to reflow child frames within. The x/y
|
// The content area to reflow child frames within. The x/y
|
||||||
// coordinates are known to be mBorderPadding.left and
|
// coordinates are known to be mBorderPadding.left and
|
||||||
@@ -579,7 +580,8 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
|
|||||||
mPrevBottomMargin(0),
|
mPrevBottomMargin(0),
|
||||||
mFreeLineList(nsnull),
|
mFreeLineList(nsnull),
|
||||||
mLineNumber(0),
|
mLineNumber(0),
|
||||||
mNeedResizeReflow(PR_FALSE)
|
mNeedResizeReflow(PR_FALSE),
|
||||||
|
mIsInlineIncrReflow(PR_FALSE)
|
||||||
{
|
{
|
||||||
const nsMargin& borderPadding = BorderPadding();
|
const nsMargin& borderPadding = BorderPadding();
|
||||||
|
|
||||||
@@ -1463,6 +1465,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
|
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
PRBool isStyleChange = PR_FALSE;
|
PRBool isStyleChange = PR_FALSE;
|
||||||
|
state.mIsInlineIncrReflow = PR_FALSE;
|
||||||
nsIFrame* target;
|
nsIFrame* target;
|
||||||
switch (aReflowState.reason) {
|
switch (aReflowState.reason) {
|
||||||
case eReflowReason_Initial:
|
case eReflowReason_Initial:
|
||||||
@@ -1518,6 +1521,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
// in the normal case, this just marks the line dirty
|
// in the normal case, this just marks the line dirty
|
||||||
// but, it causes an incremental reflow targeted at a frame
|
// but, it causes an incremental reflow targeted at a frame
|
||||||
// inside a continued span to get dropped on the floor. see bug 25510
|
// inside a continued span to get dropped on the floor. see bug 25510
|
||||||
|
// This will be yanked as soon as we have high confidence in the enabled code below
|
||||||
rv = PrepareChildIncrementalReflow(state);
|
rv = PrepareChildIncrementalReflow(state);
|
||||||
#else
|
#else
|
||||||
// this code does a correct job of propogating incremental reflows (bug 25510)
|
// this code does a correct job of propogating incremental reflows (bug 25510)
|
||||||
@@ -1531,21 +1535,35 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
{
|
{
|
||||||
if (!isFloater) // punt if isFloater!
|
if (!isFloater) // punt if isFloater!
|
||||||
{
|
{
|
||||||
nsBlockReflowState incrState(aReflowState, aPresContext, this, aMetrics,
|
// reflow the line containing the target of the incr. reflow
|
||||||
NS_BLOCK_MARGIN_ROOT & mState);
|
// first mark the line dirty and set up the state object
|
||||||
incrState.mNextRCFrame = state.mNextRCFrame;
|
rv = PrepareChildIncrementalReflow(state);
|
||||||
PRBool keepGoing;
|
state.mIsInlineIncrReflow = PR_TRUE;
|
||||||
rv = ReflowLine(incrState, line, &keepGoing, PR_TRUE);
|
state.mPrevLine = prevLine;
|
||||||
line->RemoveFloatersFromSpaceManager(aReflowState.mSpaceManager);
|
state.mCurrentLine = line;
|
||||||
state.mNextRCFrame = nsnull;
|
state.mNextRCFrame = state.mNextRCFrame;
|
||||||
|
// let ReflowDirtyLines do all the work
|
||||||
|
rv = ReflowDirtyLines(state);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_ASSERTION(0, "Reflow failed\n");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
// compute the final size
|
||||||
|
ComputeFinalSize(aReflowState, state, aMetrics);
|
||||||
|
|
||||||
|
// finally, mark this block frame as having a dirty child and return
|
||||||
|
// XXX: we should be able to optimize this so we only call ReflowDirtyChild
|
||||||
|
// if it's absolutely necessary: something on the line changed size.
|
||||||
|
nsCOMPtr<nsIPresShell> shell;
|
||||||
|
aPresContext->GetShell(getter_AddRefs(shell));
|
||||||
|
rv = ReflowDirtyChild(shell, state.mNextRCFrame);
|
||||||
|
//XXX: it's possible we need to do some work regarding incremental painting
|
||||||
|
// here, see code below "ReflowDirtyLines() after this switch statement.
|
||||||
|
// It might be right to factor the tail end of this method into a new method
|
||||||
|
// and call that here before calling ReflowDirtyChild().
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// XXX To Do: we need to check some metrics here to see if anything changed
|
|
||||||
// if nothing changed, we're done
|
|
||||||
// otherwise, we should mark the line and the previous line both dirty
|
|
||||||
// and do a resize reflow
|
|
||||||
// Now just mark the line dirty every time. We call PrepareChildIncrementalReflow
|
|
||||||
// because it includes a hack for floaters that we don't want to duplicate here.
|
|
||||||
rv = PrepareChildIncrementalReflow(state);
|
rv = PrepareChildIncrementalReflow(state);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -1562,8 +1580,17 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_ASSERTION(0, "setting up reflow failed.\n");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
// Now reflow...
|
// Now reflow...
|
||||||
rv = ReflowDirtyLines(state);
|
rv = ReflowDirtyLines(state);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
NS_ASSERTION(0, "reflow dirty lines failed.\n");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
aStatus = state.mReflowStatus;
|
aStatus = state.mReflowStatus;
|
||||||
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
|
if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
|
||||||
if (NS_STYLE_OVERFLOW_HIDDEN == aReflowState.mStyleDisplay->mOverflow) {
|
if (NS_STYLE_OVERFLOW_HIDDEN == aReflowState.mStyleDisplay->mOverflow) {
|
||||||
@@ -2567,8 +2594,9 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
aState.mReflowState.reflowCommand->GetType(type);
|
aState.mReflowState.reflowCommand->GetType(type);
|
||||||
IndentBy(stdout, gNoiseIndent);
|
IndentBy(stdout, gNoiseIndent);
|
||||||
ListTag(stdout);
|
ListTag(stdout);
|
||||||
printf(": incrementally reflowing dirty lines: type=%s(%d)",
|
printf(": incrementally reflowing dirty lines: type=%s(%d) isInline=%s",
|
||||||
kReflowCommandType[type], type);
|
kReflowCommandType[type], type,
|
||||||
|
aState.mIsInlineIncrReflow ? "true" : "false");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
IndentBy(stdout, gNoiseIndent);
|
IndentBy(stdout, gNoiseIndent);
|
||||||
@@ -2586,10 +2614,30 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
aState.mReflowState.reason ==
|
aState.mReflowState.reason ==
|
||||||
eReflowReason_Dirty;
|
eReflowReason_Dirty;
|
||||||
|
|
||||||
|
nscoord deltaY = 0;
|
||||||
|
|
||||||
// Reflow the lines that are already ours
|
// Reflow the lines that are already ours
|
||||||
aState.mPrevLine = nsnull;
|
aState.mPrevLine = nsnull;
|
||||||
nsLineBox* line = mLines;
|
nsLineBox* line = mLines;
|
||||||
nscoord deltaY = 0;
|
if (aState.mIsInlineIncrReflow && aState.mNextRCFrame)
|
||||||
|
{
|
||||||
|
const nsLineBox* incrTargetLine = aState.mCurrentLine;
|
||||||
|
aState.mCurrentLine = line;
|
||||||
|
aState.mPrevLine = nsnull;
|
||||||
|
while (line && (line != incrTargetLine))
|
||||||
|
{
|
||||||
|
nsRect damageRect;
|
||||||
|
RecoverStateFrom(aState, line, deltaY, incrementalReflow ?
|
||||||
|
&damageRect : 0);
|
||||||
|
if (incrementalReflow && !damageRect.IsEmpty()) {
|
||||||
|
Invalidate(aState.mPresContext, damageRect);
|
||||||
|
}
|
||||||
|
aState.mPrevLine = line;
|
||||||
|
line = line->mNext;
|
||||||
|
aState.AdvanceToNextLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (nsnull != line) {
|
while (nsnull != line) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisyReflow) {
|
if (gNoisyReflow) {
|
||||||
@@ -2623,6 +2671,10 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
if (!(NS_FRAME_IS_COMPLETE(aState.mReflowStatus)))
|
||||||
|
{
|
||||||
|
printf("line %p is not complete\n", line);
|
||||||
|
}
|
||||||
if (!keepGoing) {
|
if (!keepGoing) {
|
||||||
if (0 == line->GetChildCount()) {
|
if (0 == line->GetChildCount()) {
|
||||||
DeleteLine(aState, line);
|
DeleteLine(aState, line);
|
||||||
@@ -3522,7 +3574,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
|||||||
// Try to place the child block
|
// Try to place the child block
|
||||||
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
|
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
|
||||||
nscoord collapsedBottomMargin;
|
nscoord collapsedBottomMargin;
|
||||||
nsRect combinedArea;
|
nsRect combinedArea(0,0,0,0);
|
||||||
*aKeepReflowGoing = brc.PlaceBlock(isAdjacentWithTop, computedOffsets,
|
*aKeepReflowGoing = brc.PlaceBlock(isAdjacentWithTop, computedOffsets,
|
||||||
&collapsedBottomMargin,
|
&collapsedBottomMargin,
|
||||||
aLine->mBounds, combinedArea);
|
aLine->mBounds, combinedArea);
|
||||||
@@ -4356,7 +4408,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||||||
// Stop reflow and whack the reflow status if reflow hasn't
|
// Stop reflow and whack the reflow status if reflow hasn't
|
||||||
// already been stopped.
|
// already been stopped.
|
||||||
if (*aKeepReflowGoing) {
|
if (*aKeepReflowGoing) {
|
||||||
NS_ASSERTION(NS_FRAME_COMPLETE == aState.mReflowStatus,
|
NS_ASSERTION(NS_FRAME_COMPLETE == aState.mReflowStatus,
|
||||||
"lost reflow status");
|
"lost reflow status");
|
||||||
aState.mReflowStatus = NS_FRAME_NOT_COMPLETE;
|
aState.mReflowStatus = NS_FRAME_NOT_COMPLETE;
|
||||||
*aKeepReflowGoing = PR_FALSE;
|
*aKeepReflowGoing = PR_FALSE;
|
||||||
|
|||||||
Reference in New Issue
Block a user