From 311d2c39744d289aa36469b5693ecaa14f7d01b3 Mon Sep 17 00:00:00 2001 From: "kipp%netscape.com" Date: Fri, 10 Sep 1999 18:52:56 +0000 Subject: [PATCH] Fixed two incremental reflow bugs (12890) --- layout/generic/nsBlockFrame.cpp | 50 ++++++++++++++----- layout/generic/nsBlockReflowContext.cpp | 14 ++++-- layout/generic/nsBlockReflowState.cpp | 50 ++++++++++++++----- layout/generic/nsBlockReflowState.h | 50 ++++++++++++++----- layout/html/base/src/nsBlockFrame.cpp | 50 ++++++++++++++----- layout/html/base/src/nsBlockReflowContext.cpp | 14 ++++-- layout/html/base/src/nsBlockReflowState.cpp | 50 ++++++++++++++----- layout/html/base/src/nsBlockReflowState.h | 50 ++++++++++++++----- 8 files changed, 248 insertions(+), 80 deletions(-) diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index b64bc4b88d3..e5c6f294dde 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -758,7 +758,7 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, } } else { - // Recover the top and bottom marings for this line + // Recover the top and bottom margins for this line nscoord topMargin, bottomMargin; RecoverVerticalMargins(aLine, aApplyTopMargin, &topMargin, &bottomMargin); @@ -2844,10 +2844,32 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, // flow block. Since we just continued the child block frame, // we know that line->mFirstChild is not the last flow block // therefore zero out the running margin value. +#ifdef NOISY_VERTICAL_MARGINS + ListTag(stdout); + printf(": reflow incomplete, frame="); + nsFrame::ListTag(stdout, frame); + printf(" prevBottomMargin=%d, setting to zero\n", + aState.mPrevBottomMargin); +#endif aState.mPrevBottomMargin = 0; } else { - aState.mPrevBottomMargin = collapsedBottomMargin; +#ifdef NOISY_VERTICAL_MARGINS + ListTag(stdout); + printf(": reflow complete for "); + nsFrame::ListTag(stdout, frame); + printf(" prevBottomMargin=%d collapsedBottomMargin=%d\n", + aState.mPrevBottomMargin, collapsedBottomMargin); +#endif + if (collapsedBottomMargin >= 0) { + aState.mPrevBottomMargin = collapsedBottomMargin; + } + else { + // Leave margin alone: it was a collapsed paragraph that + // must not interfere with the running margin calculations + // (in other words it should act like an empty line of + // whitespace). + } } #ifdef NOISY_VERTICAL_MARGINS ListTag(stdout); @@ -4620,6 +4642,9 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState, nsMargin& aMarginResult, nsMargin& aComputedOffsetsResult) { + // XXX update this just + aState.GetAvailableSpace(); + // Reflow the floater. Since floaters are continued we given them an // unbounded height. Floaters with an auto width are sized to zero // according to the css2 spec. @@ -4690,23 +4715,24 @@ nsBlockReflowState::AddFloater(nsLineLayout& aLineLayout, // Now place the floater immediately if possible. Otherwise stash it // away in mPendingFloaters and place it later. if (aLineLayout.CanPlaceFloaterNow()) { + // Because we are in the middle of reflowing a placeholder frame + // within a line (and possibly nested in an inline frame or two + // that's a child of our block) we need to restore the space + // manager's translation to the space that the block resides in + // before placing the floater. + nscoord ox, oy; + mSpaceManager->GetTranslation(ox, oy); + nscoord dx = ox - mSpaceManagerX; + nscoord dy = oy - mSpaceManagerY; + mSpaceManager->Translate(-dx, -dy); + nsRect combinedArea; nsMargin floaterMargins; nsMargin floaterOffsets; mBlock->ReflowFloater(*this, aPlaceholder, combinedArea, floaterMargins, floaterOffsets); - // Because we are in the middle of reflowing a placeholder frame - // within a line (and possibly nested in an inline frame or two - // that's a child of our block) we need to restore the space - // manager's translation to the space that the block resides in - // before placing the floater. PRBool isLeftFloater; - nscoord ox, oy; - mSpaceManager->GetTranslation(ox, oy); - nscoord dx = ox - mSpaceManagerX; - nscoord dy = oy - mSpaceManagerY; - mSpaceManager->Translate(-dx, -dy); nsPoint origin; PlaceFloater(aPlaceholder, floaterMargins, floaterOffsets, &isLeftFloater, &origin); diff --git a/layout/generic/nsBlockReflowContext.cpp b/layout/generic/nsBlockReflowContext.cpp index 1e5896e90be..ff01ad6cfec 100644 --- a/layout/generic/nsBlockReflowContext.cpp +++ b/layout/generic/nsBlockReflowContext.cpp @@ -159,11 +159,16 @@ nsBlockReflowContext::ReflowBlock(nsIFrame* aFrame, if (aApplyTopMargin) { // Compute the childs collapsed top margin (its margin collpased // with its first childs top-margin -- recursively). + topMargin = ComputeCollapsedTopMargin(mPresContext, reflowState); + #ifdef NOISY_VERTICAL_MARGINS nsFrame::ListTag(stdout, mOuterReflowState.frame); - printf(": prevBottomMargin=%d\n", aPrevBottomMargin); + printf(": reflowing "); + nsFrame::ListTag(stdout, aFrame); + printf(" prevBottomMargin=%d, collapsedTopMargin=%d => %d\n", + aPrevBottomMargin, topMargin, + MaxMargin(topMargin, aPrevBottomMargin)); #endif - topMargin = ComputeCollapsedTopMargin(mPresContext, reflowState); // Collapse that value with the previous bottom margin to perform // the sibling to sibling collaspe. @@ -345,8 +350,9 @@ nsBlockReflowContext::PlaceBlock(PRBool aForceFit, if ((0 == mMetrics.height) && (0 == mMetrics.mCombinedArea.height)) { if (IsHTMLParagraph(mFrame)) { // Special "feature" for HTML compatability - empty paragraphs - // collapse into nothingness, including their margins. - *aBottomMarginResult = 0; + // collapse into nothingness, including their margins. Signal + // the special nature here by returning -1. + *aBottomMarginResult = -1; #ifdef NOISY_VERTICAL_MARGINS printf(" "); nsFrame::ListTag(stdout, mOuterReflowState.frame); diff --git a/layout/generic/nsBlockReflowState.cpp b/layout/generic/nsBlockReflowState.cpp index b64bc4b88d3..e5c6f294dde 100644 --- a/layout/generic/nsBlockReflowState.cpp +++ b/layout/generic/nsBlockReflowState.cpp @@ -758,7 +758,7 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, } } else { - // Recover the top and bottom marings for this line + // Recover the top and bottom margins for this line nscoord topMargin, bottomMargin; RecoverVerticalMargins(aLine, aApplyTopMargin, &topMargin, &bottomMargin); @@ -2844,10 +2844,32 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, // flow block. Since we just continued the child block frame, // we know that line->mFirstChild is not the last flow block // therefore zero out the running margin value. +#ifdef NOISY_VERTICAL_MARGINS + ListTag(stdout); + printf(": reflow incomplete, frame="); + nsFrame::ListTag(stdout, frame); + printf(" prevBottomMargin=%d, setting to zero\n", + aState.mPrevBottomMargin); +#endif aState.mPrevBottomMargin = 0; } else { - aState.mPrevBottomMargin = collapsedBottomMargin; +#ifdef NOISY_VERTICAL_MARGINS + ListTag(stdout); + printf(": reflow complete for "); + nsFrame::ListTag(stdout, frame); + printf(" prevBottomMargin=%d collapsedBottomMargin=%d\n", + aState.mPrevBottomMargin, collapsedBottomMargin); +#endif + if (collapsedBottomMargin >= 0) { + aState.mPrevBottomMargin = collapsedBottomMargin; + } + else { + // Leave margin alone: it was a collapsed paragraph that + // must not interfere with the running margin calculations + // (in other words it should act like an empty line of + // whitespace). + } } #ifdef NOISY_VERTICAL_MARGINS ListTag(stdout); @@ -4620,6 +4642,9 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState, nsMargin& aMarginResult, nsMargin& aComputedOffsetsResult) { + // XXX update this just + aState.GetAvailableSpace(); + // Reflow the floater. Since floaters are continued we given them an // unbounded height. Floaters with an auto width are sized to zero // according to the css2 spec. @@ -4690,23 +4715,24 @@ nsBlockReflowState::AddFloater(nsLineLayout& aLineLayout, // Now place the floater immediately if possible. Otherwise stash it // away in mPendingFloaters and place it later. if (aLineLayout.CanPlaceFloaterNow()) { + // Because we are in the middle of reflowing a placeholder frame + // within a line (and possibly nested in an inline frame or two + // that's a child of our block) we need to restore the space + // manager's translation to the space that the block resides in + // before placing the floater. + nscoord ox, oy; + mSpaceManager->GetTranslation(ox, oy); + nscoord dx = ox - mSpaceManagerX; + nscoord dy = oy - mSpaceManagerY; + mSpaceManager->Translate(-dx, -dy); + nsRect combinedArea; nsMargin floaterMargins; nsMargin floaterOffsets; mBlock->ReflowFloater(*this, aPlaceholder, combinedArea, floaterMargins, floaterOffsets); - // Because we are in the middle of reflowing a placeholder frame - // within a line (and possibly nested in an inline frame or two - // that's a child of our block) we need to restore the space - // manager's translation to the space that the block resides in - // before placing the floater. PRBool isLeftFloater; - nscoord ox, oy; - mSpaceManager->GetTranslation(ox, oy); - nscoord dx = ox - mSpaceManagerX; - nscoord dy = oy - mSpaceManagerY; - mSpaceManager->Translate(-dx, -dy); nsPoint origin; PlaceFloater(aPlaceholder, floaterMargins, floaterOffsets, &isLeftFloater, &origin); diff --git a/layout/generic/nsBlockReflowState.h b/layout/generic/nsBlockReflowState.h index b64bc4b88d3..e5c6f294dde 100644 --- a/layout/generic/nsBlockReflowState.h +++ b/layout/generic/nsBlockReflowState.h @@ -758,7 +758,7 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, } } else { - // Recover the top and bottom marings for this line + // Recover the top and bottom margins for this line nscoord topMargin, bottomMargin; RecoverVerticalMargins(aLine, aApplyTopMargin, &topMargin, &bottomMargin); @@ -2844,10 +2844,32 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, // flow block. Since we just continued the child block frame, // we know that line->mFirstChild is not the last flow block // therefore zero out the running margin value. +#ifdef NOISY_VERTICAL_MARGINS + ListTag(stdout); + printf(": reflow incomplete, frame="); + nsFrame::ListTag(stdout, frame); + printf(" prevBottomMargin=%d, setting to zero\n", + aState.mPrevBottomMargin); +#endif aState.mPrevBottomMargin = 0; } else { - aState.mPrevBottomMargin = collapsedBottomMargin; +#ifdef NOISY_VERTICAL_MARGINS + ListTag(stdout); + printf(": reflow complete for "); + nsFrame::ListTag(stdout, frame); + printf(" prevBottomMargin=%d collapsedBottomMargin=%d\n", + aState.mPrevBottomMargin, collapsedBottomMargin); +#endif + if (collapsedBottomMargin >= 0) { + aState.mPrevBottomMargin = collapsedBottomMargin; + } + else { + // Leave margin alone: it was a collapsed paragraph that + // must not interfere with the running margin calculations + // (in other words it should act like an empty line of + // whitespace). + } } #ifdef NOISY_VERTICAL_MARGINS ListTag(stdout); @@ -4620,6 +4642,9 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState, nsMargin& aMarginResult, nsMargin& aComputedOffsetsResult) { + // XXX update this just + aState.GetAvailableSpace(); + // Reflow the floater. Since floaters are continued we given them an // unbounded height. Floaters with an auto width are sized to zero // according to the css2 spec. @@ -4690,23 +4715,24 @@ nsBlockReflowState::AddFloater(nsLineLayout& aLineLayout, // Now place the floater immediately if possible. Otherwise stash it // away in mPendingFloaters and place it later. if (aLineLayout.CanPlaceFloaterNow()) { + // Because we are in the middle of reflowing a placeholder frame + // within a line (and possibly nested in an inline frame or two + // that's a child of our block) we need to restore the space + // manager's translation to the space that the block resides in + // before placing the floater. + nscoord ox, oy; + mSpaceManager->GetTranslation(ox, oy); + nscoord dx = ox - mSpaceManagerX; + nscoord dy = oy - mSpaceManagerY; + mSpaceManager->Translate(-dx, -dy); + nsRect combinedArea; nsMargin floaterMargins; nsMargin floaterOffsets; mBlock->ReflowFloater(*this, aPlaceholder, combinedArea, floaterMargins, floaterOffsets); - // Because we are in the middle of reflowing a placeholder frame - // within a line (and possibly nested in an inline frame or two - // that's a child of our block) we need to restore the space - // manager's translation to the space that the block resides in - // before placing the floater. PRBool isLeftFloater; - nscoord ox, oy; - mSpaceManager->GetTranslation(ox, oy); - nscoord dx = ox - mSpaceManagerX; - nscoord dy = oy - mSpaceManagerY; - mSpaceManager->Translate(-dx, -dy); nsPoint origin; PlaceFloater(aPlaceholder, floaterMargins, floaterOffsets, &isLeftFloater, &origin); diff --git a/layout/html/base/src/nsBlockFrame.cpp b/layout/html/base/src/nsBlockFrame.cpp index b64bc4b88d3..e5c6f294dde 100644 --- a/layout/html/base/src/nsBlockFrame.cpp +++ b/layout/html/base/src/nsBlockFrame.cpp @@ -758,7 +758,7 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, } } else { - // Recover the top and bottom marings for this line + // Recover the top and bottom margins for this line nscoord topMargin, bottomMargin; RecoverVerticalMargins(aLine, aApplyTopMargin, &topMargin, &bottomMargin); @@ -2844,10 +2844,32 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, // flow block. Since we just continued the child block frame, // we know that line->mFirstChild is not the last flow block // therefore zero out the running margin value. +#ifdef NOISY_VERTICAL_MARGINS + ListTag(stdout); + printf(": reflow incomplete, frame="); + nsFrame::ListTag(stdout, frame); + printf(" prevBottomMargin=%d, setting to zero\n", + aState.mPrevBottomMargin); +#endif aState.mPrevBottomMargin = 0; } else { - aState.mPrevBottomMargin = collapsedBottomMargin; +#ifdef NOISY_VERTICAL_MARGINS + ListTag(stdout); + printf(": reflow complete for "); + nsFrame::ListTag(stdout, frame); + printf(" prevBottomMargin=%d collapsedBottomMargin=%d\n", + aState.mPrevBottomMargin, collapsedBottomMargin); +#endif + if (collapsedBottomMargin >= 0) { + aState.mPrevBottomMargin = collapsedBottomMargin; + } + else { + // Leave margin alone: it was a collapsed paragraph that + // must not interfere with the running margin calculations + // (in other words it should act like an empty line of + // whitespace). + } } #ifdef NOISY_VERTICAL_MARGINS ListTag(stdout); @@ -4620,6 +4642,9 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState, nsMargin& aMarginResult, nsMargin& aComputedOffsetsResult) { + // XXX update this just + aState.GetAvailableSpace(); + // Reflow the floater. Since floaters are continued we given them an // unbounded height. Floaters with an auto width are sized to zero // according to the css2 spec. @@ -4690,23 +4715,24 @@ nsBlockReflowState::AddFloater(nsLineLayout& aLineLayout, // Now place the floater immediately if possible. Otherwise stash it // away in mPendingFloaters and place it later. if (aLineLayout.CanPlaceFloaterNow()) { + // Because we are in the middle of reflowing a placeholder frame + // within a line (and possibly nested in an inline frame or two + // that's a child of our block) we need to restore the space + // manager's translation to the space that the block resides in + // before placing the floater. + nscoord ox, oy; + mSpaceManager->GetTranslation(ox, oy); + nscoord dx = ox - mSpaceManagerX; + nscoord dy = oy - mSpaceManagerY; + mSpaceManager->Translate(-dx, -dy); + nsRect combinedArea; nsMargin floaterMargins; nsMargin floaterOffsets; mBlock->ReflowFloater(*this, aPlaceholder, combinedArea, floaterMargins, floaterOffsets); - // Because we are in the middle of reflowing a placeholder frame - // within a line (and possibly nested in an inline frame or two - // that's a child of our block) we need to restore the space - // manager's translation to the space that the block resides in - // before placing the floater. PRBool isLeftFloater; - nscoord ox, oy; - mSpaceManager->GetTranslation(ox, oy); - nscoord dx = ox - mSpaceManagerX; - nscoord dy = oy - mSpaceManagerY; - mSpaceManager->Translate(-dx, -dy); nsPoint origin; PlaceFloater(aPlaceholder, floaterMargins, floaterOffsets, &isLeftFloater, &origin); diff --git a/layout/html/base/src/nsBlockReflowContext.cpp b/layout/html/base/src/nsBlockReflowContext.cpp index 1e5896e90be..ff01ad6cfec 100644 --- a/layout/html/base/src/nsBlockReflowContext.cpp +++ b/layout/html/base/src/nsBlockReflowContext.cpp @@ -159,11 +159,16 @@ nsBlockReflowContext::ReflowBlock(nsIFrame* aFrame, if (aApplyTopMargin) { // Compute the childs collapsed top margin (its margin collpased // with its first childs top-margin -- recursively). + topMargin = ComputeCollapsedTopMargin(mPresContext, reflowState); + #ifdef NOISY_VERTICAL_MARGINS nsFrame::ListTag(stdout, mOuterReflowState.frame); - printf(": prevBottomMargin=%d\n", aPrevBottomMargin); + printf(": reflowing "); + nsFrame::ListTag(stdout, aFrame); + printf(" prevBottomMargin=%d, collapsedTopMargin=%d => %d\n", + aPrevBottomMargin, topMargin, + MaxMargin(topMargin, aPrevBottomMargin)); #endif - topMargin = ComputeCollapsedTopMargin(mPresContext, reflowState); // Collapse that value with the previous bottom margin to perform // the sibling to sibling collaspe. @@ -345,8 +350,9 @@ nsBlockReflowContext::PlaceBlock(PRBool aForceFit, if ((0 == mMetrics.height) && (0 == mMetrics.mCombinedArea.height)) { if (IsHTMLParagraph(mFrame)) { // Special "feature" for HTML compatability - empty paragraphs - // collapse into nothingness, including their margins. - *aBottomMarginResult = 0; + // collapse into nothingness, including their margins. Signal + // the special nature here by returning -1. + *aBottomMarginResult = -1; #ifdef NOISY_VERTICAL_MARGINS printf(" "); nsFrame::ListTag(stdout, mOuterReflowState.frame); diff --git a/layout/html/base/src/nsBlockReflowState.cpp b/layout/html/base/src/nsBlockReflowState.cpp index b64bc4b88d3..e5c6f294dde 100644 --- a/layout/html/base/src/nsBlockReflowState.cpp +++ b/layout/html/base/src/nsBlockReflowState.cpp @@ -758,7 +758,7 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, } } else { - // Recover the top and bottom marings for this line + // Recover the top and bottom margins for this line nscoord topMargin, bottomMargin; RecoverVerticalMargins(aLine, aApplyTopMargin, &topMargin, &bottomMargin); @@ -2844,10 +2844,32 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, // flow block. Since we just continued the child block frame, // we know that line->mFirstChild is not the last flow block // therefore zero out the running margin value. +#ifdef NOISY_VERTICAL_MARGINS + ListTag(stdout); + printf(": reflow incomplete, frame="); + nsFrame::ListTag(stdout, frame); + printf(" prevBottomMargin=%d, setting to zero\n", + aState.mPrevBottomMargin); +#endif aState.mPrevBottomMargin = 0; } else { - aState.mPrevBottomMargin = collapsedBottomMargin; +#ifdef NOISY_VERTICAL_MARGINS + ListTag(stdout); + printf(": reflow complete for "); + nsFrame::ListTag(stdout, frame); + printf(" prevBottomMargin=%d collapsedBottomMargin=%d\n", + aState.mPrevBottomMargin, collapsedBottomMargin); +#endif + if (collapsedBottomMargin >= 0) { + aState.mPrevBottomMargin = collapsedBottomMargin; + } + else { + // Leave margin alone: it was a collapsed paragraph that + // must not interfere with the running margin calculations + // (in other words it should act like an empty line of + // whitespace). + } } #ifdef NOISY_VERTICAL_MARGINS ListTag(stdout); @@ -4620,6 +4642,9 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState, nsMargin& aMarginResult, nsMargin& aComputedOffsetsResult) { + // XXX update this just + aState.GetAvailableSpace(); + // Reflow the floater. Since floaters are continued we given them an // unbounded height. Floaters with an auto width are sized to zero // according to the css2 spec. @@ -4690,23 +4715,24 @@ nsBlockReflowState::AddFloater(nsLineLayout& aLineLayout, // Now place the floater immediately if possible. Otherwise stash it // away in mPendingFloaters and place it later. if (aLineLayout.CanPlaceFloaterNow()) { + // Because we are in the middle of reflowing a placeholder frame + // within a line (and possibly nested in an inline frame or two + // that's a child of our block) we need to restore the space + // manager's translation to the space that the block resides in + // before placing the floater. + nscoord ox, oy; + mSpaceManager->GetTranslation(ox, oy); + nscoord dx = ox - mSpaceManagerX; + nscoord dy = oy - mSpaceManagerY; + mSpaceManager->Translate(-dx, -dy); + nsRect combinedArea; nsMargin floaterMargins; nsMargin floaterOffsets; mBlock->ReflowFloater(*this, aPlaceholder, combinedArea, floaterMargins, floaterOffsets); - // Because we are in the middle of reflowing a placeholder frame - // within a line (and possibly nested in an inline frame or two - // that's a child of our block) we need to restore the space - // manager's translation to the space that the block resides in - // before placing the floater. PRBool isLeftFloater; - nscoord ox, oy; - mSpaceManager->GetTranslation(ox, oy); - nscoord dx = ox - mSpaceManagerX; - nscoord dy = oy - mSpaceManagerY; - mSpaceManager->Translate(-dx, -dy); nsPoint origin; PlaceFloater(aPlaceholder, floaterMargins, floaterOffsets, &isLeftFloater, &origin); diff --git a/layout/html/base/src/nsBlockReflowState.h b/layout/html/base/src/nsBlockReflowState.h index b64bc4b88d3..e5c6f294dde 100644 --- a/layout/html/base/src/nsBlockReflowState.h +++ b/layout/html/base/src/nsBlockReflowState.h @@ -758,7 +758,7 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, } } else { - // Recover the top and bottom marings for this line + // Recover the top and bottom margins for this line nscoord topMargin, bottomMargin; RecoverVerticalMargins(aLine, aApplyTopMargin, &topMargin, &bottomMargin); @@ -2844,10 +2844,32 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, // flow block. Since we just continued the child block frame, // we know that line->mFirstChild is not the last flow block // therefore zero out the running margin value. +#ifdef NOISY_VERTICAL_MARGINS + ListTag(stdout); + printf(": reflow incomplete, frame="); + nsFrame::ListTag(stdout, frame); + printf(" prevBottomMargin=%d, setting to zero\n", + aState.mPrevBottomMargin); +#endif aState.mPrevBottomMargin = 0; } else { - aState.mPrevBottomMargin = collapsedBottomMargin; +#ifdef NOISY_VERTICAL_MARGINS + ListTag(stdout); + printf(": reflow complete for "); + nsFrame::ListTag(stdout, frame); + printf(" prevBottomMargin=%d collapsedBottomMargin=%d\n", + aState.mPrevBottomMargin, collapsedBottomMargin); +#endif + if (collapsedBottomMargin >= 0) { + aState.mPrevBottomMargin = collapsedBottomMargin; + } + else { + // Leave margin alone: it was a collapsed paragraph that + // must not interfere with the running margin calculations + // (in other words it should act like an empty line of + // whitespace). + } } #ifdef NOISY_VERTICAL_MARGINS ListTag(stdout); @@ -4620,6 +4642,9 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState, nsMargin& aMarginResult, nsMargin& aComputedOffsetsResult) { + // XXX update this just + aState.GetAvailableSpace(); + // Reflow the floater. Since floaters are continued we given them an // unbounded height. Floaters with an auto width are sized to zero // according to the css2 spec. @@ -4690,23 +4715,24 @@ nsBlockReflowState::AddFloater(nsLineLayout& aLineLayout, // Now place the floater immediately if possible. Otherwise stash it // away in mPendingFloaters and place it later. if (aLineLayout.CanPlaceFloaterNow()) { + // Because we are in the middle of reflowing a placeholder frame + // within a line (and possibly nested in an inline frame or two + // that's a child of our block) we need to restore the space + // manager's translation to the space that the block resides in + // before placing the floater. + nscoord ox, oy; + mSpaceManager->GetTranslation(ox, oy); + nscoord dx = ox - mSpaceManagerX; + nscoord dy = oy - mSpaceManagerY; + mSpaceManager->Translate(-dx, -dy); + nsRect combinedArea; nsMargin floaterMargins; nsMargin floaterOffsets; mBlock->ReflowFloater(*this, aPlaceholder, combinedArea, floaterMargins, floaterOffsets); - // Because we are in the middle of reflowing a placeholder frame - // within a line (and possibly nested in an inline frame or two - // that's a child of our block) we need to restore the space - // manager's translation to the space that the block resides in - // before placing the floater. PRBool isLeftFloater; - nscoord ox, oy; - mSpaceManager->GetTranslation(ox, oy); - nscoord dx = ox - mSpaceManagerX; - nscoord dy = oy - mSpaceManagerY; - mSpaceManager->Translate(-dx, -dy); nsPoint origin; PlaceFloater(aPlaceholder, floaterMargins, floaterOffsets, &isLeftFloater, &origin);