Bug 117374: nsBlockFrame::UpdateSpaceManager is no longer needed since nsBlockReflowState::RecoverFloaters does the same work.

Bug 113895:  Pass |aDeltaY| as 0 for recursive calls to RecoverFloaters.
b=117374  r=attinasi  sr=waterson
This commit is contained in:
dbaron%fas.harvard.edu 2002-01-06 18:14:00 +00:00
Родитель 6f658a8b68
Коммит a293c9dc19
6 изменённых файлов: 66 добавлений и 200 удалений

Просмотреть файл

@ -2828,48 +2828,28 @@ nsBlockFrame::SlideLine(nsBlockReflowState& aState,
}
if (aLine->IsBlock()) {
nsRect r;
kid->GetRect(r);
if (aDY) {
r.y += aDY;
kid->SetRect(aState.mPresContext, r);
nsPoint p;
kid->GetOrigin(p);
p.y += aDY;
kid->MoveTo(aState.mPresContext, p.x, p.y);
}
// Make sure the frame's view and any child views are updated
::PlaceFrameView(aState.mPresContext, kid);
// If the child has any floaters that impact the space-manager,
// place them now so that they are present in the space-manager
// again (they were removed by the space-manager's frame when
// the reflow began).
nsBlockFrame* bf;
nsresult rv = kid->QueryInterface(kBlockFrameCID, (void**) &bf);
if (NS_SUCCEEDED(rv)) {
// Translate spacemanager to the child blocks upper-left corner
// so that when it places its floaters (which are relative to
// it) the right coordinates are used. Note that we have already
// been translated by our border+padding so factor that in to
// get the right translation.
const nsMargin& bp = aState.BorderPadding();
nscoord dx = r.x - bp.left;
nscoord dy = r.y - bp.top;
aState.mSpaceManager->Translate(dx, dy);
bf->UpdateSpaceManager(aState.mPresContext, aState.mSpaceManager);
aState.mSpaceManager->Translate(-dx, -dy);
}
}
else {
// Adjust the Y coordinate of the frames in the line.
// Note: we need to re-position views even if aDY is 0, because
// one of our parent frames may have moved and so the view's position
// relative to its parent may have changed
nsRect r;
PRInt32 n = aLine->GetChildCount();
while (--n >= 0) {
if (aDY) {
kid->GetRect(r);
r.y += aDY;
kid->SetRect(aState.mPresContext, r);
nsPoint p;
kid->GetOrigin(p);
p.y += aDY;
kid->MoveTo(aState.mPresContext, p.x, p.y);
}
// Make sure the frame's view and any child views are updated
::PlaceFrameView(aState.mPresContext, kid);
@ -2878,58 +2858,6 @@ nsBlockFrame::SlideLine(nsBlockReflowState& aState,
}
}
nsresult
nsBlockFrame::UpdateSpaceManager(nsIPresContext* aPresContext,
nsSpaceManager* aSpaceManager)
{
for (line_iterator line = begin_lines(), line_end = end_lines();
line != line_end;
++line) {
// Place the floaters in the spacemanager
if (line->HasFloaters()) {
nsFloaterCache* fc = line->GetFirstFloater();
while (fc) {
nsIFrame* floater = fc->mPlaceholder->GetOutOfFlowFrame();
aSpaceManager->AddRectRegion(floater, fc->mRegion);
#ifdef NOISY_SPACEMANAGER
nscoord tx, ty;
aSpaceManager->GetTranslation(tx, ty);
nsFrame::ListTag(stdout, this);
printf(": UpdateSpaceManager: AddRectRegion: txy=%d,%d {%d,%d,%d,%d}\n",
tx, ty,
fc->mRegion.x, fc->mRegion.y,
fc->mRegion.width, fc->mRegion.height);
#endif
fc = fc->Next();
}
}
// Tell kids about the move too
if (line->mFirstChild && line->IsBlock()) {
// If the child has any floaters that impact the space-manager,
// place them now so that they are present in the space-manager
// again (they were removed by the space-manager's frame when
// the reflow began).
nsBlockFrame* bf;
nsresult rv = line->mFirstChild->QueryInterface(kBlockFrameCID,
NS_REINTERPRET_CAST(void**, &bf));
if (NS_SUCCEEDED(rv)) {
nsPoint origin;
bf->GetOrigin(origin);
// Translate spacemanager to the child blocks upper-left
// corner so that when it places its floaters (which are
// relative to it) the right coordinates are used.
aSpaceManager->Translate(origin.x, origin.y);
bf->UpdateSpaceManager(aPresContext, aSpaceManager);
aSpaceManager->Translate(-origin.x, -origin.y);
}
}
}
return NS_OK;
}
NS_IMETHODIMP
nsBlockFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,

Просмотреть файл

@ -188,12 +188,6 @@ public:
*/
nsIFrame* GetTopBlockChild();
/** Place the floaters in the spacemanager for all lines in this block.
* recursively adds floaters in child blocks of this frame.
*/
nsresult UpdateSpaceManager(nsIPresContext* aPresContext,
nsSpaceManager* aSpaceManager);
// returns true on success and false if aFoundLine is set to end_lines()
PRBool FindLineFor(nsIFrame* aFrame,
PRBool* aIsFloaterResult,

Просмотреть файл

@ -474,6 +474,14 @@ nsBlockReflowState::ReconstructMarginAbove(nsLineList::iterator aLine)
}
}
/**
* Restore information about floaters into the space manager for an
* incremental reflow, and simultaneously push the floaters by
* |aDeltaY|, which is the amount |aLine| was pushed relative to its
* parent. The recovery of state is one of the things that makes
* incremental reflow O(N^2) and this state should really be kept
* around, attached to the frame tree.
*/
void
nsBlockReflowState::RecoverFloaters(nsLineList::iterator aLine,
nscoord aDeltaY)
@ -481,25 +489,26 @@ nsBlockReflowState::RecoverFloaters(nsLineList::iterator aLine,
if (aLine->HasFloaters()) {
// Place the floaters into the space-manager again. Also slide
// them, just like the regular frames on the line.
nsRect r;
nsFloaterCache* fc = aLine->GetFirstFloater();
while (fc) {
fc->mRegion.y += aDeltaY;
fc->mCombinedArea.y += aDeltaY;
nsIFrame* floater = fc->mPlaceholder->GetOutOfFlowFrame();
floater->GetRect(r);
floater->MoveTo(mPresContext, r.x, r.y + aDeltaY);
if (aDeltaY != 0) {
fc->mRegion.y += aDeltaY;
fc->mCombinedArea.y += aDeltaY;
nsPoint p;
floater->GetOrigin(p);
floater->MoveTo(mPresContext, p.x, p.y + aDeltaY);
}
#ifdef DEBUG
if (nsBlockFrame::gNoisyReflow || nsBlockFrame::gNoisySpaceManager) {
nscoord tx, ty;
mSpaceManager->GetTranslation(tx, ty);
nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
printf("RecoverState: txy=%d,%d (%d,%d) ",
printf("RecoverFloaters: txy=%d,%d (%d,%d) ",
tx, ty, mSpaceManagerX, mSpaceManagerY);
nsFrame::ListTag(stdout, floater);
printf(" r.y=%d aDeltaY=%d (sum=%d) region={%d,%d,%d,%d}\n",
r.y, aDeltaY, r.y + aDeltaY,
fc->mRegion.x, fc->mRegion.y,
printf(" aDeltaY=%d region={%d,%d,%d,%d}\n",
aDeltaY, fc->mRegion.x, fc->mRegion.y,
fc->mRegion.width, fc->mRegion.height);
}
#endif
@ -511,15 +520,17 @@ nsBlockReflowState::RecoverFloaters(nsLineList::iterator aLine,
nsBlockFrame *kid = nsnull;
aLine->mFirstChild->QueryInterface(kBlockFrameCID, (void**)&kid);
if (kid) {
nsRect kidRect;
kid->GetRect(kidRect);
mSpaceManager->Translate(kidRect.x, kidRect.y);
nscoord kidx = kid->mRect.x, kidy = kid->mRect.y;
mSpaceManager->Translate(kidx, kidy);
for (nsBlockFrame::line_iterator line = kid->begin_lines(),
line_end = kid->end_lines();
line != line_end;
++line)
RecoverFloaters(line, aDeltaY);
mSpaceManager->Translate(-kidRect.x, -kidRect.y);
// Pass 0, not the real DeltaY, since these floaters aren't
// moving relative to their parent block, only relative to
// the space manager.
RecoverFloaters(line, 0);
mSpaceManager->Translate(-kidx, -kidy);
}
}
}

Просмотреть файл

@ -2828,48 +2828,28 @@ nsBlockFrame::SlideLine(nsBlockReflowState& aState,
}
if (aLine->IsBlock()) {
nsRect r;
kid->GetRect(r);
if (aDY) {
r.y += aDY;
kid->SetRect(aState.mPresContext, r);
nsPoint p;
kid->GetOrigin(p);
p.y += aDY;
kid->MoveTo(aState.mPresContext, p.x, p.y);
}
// Make sure the frame's view and any child views are updated
::PlaceFrameView(aState.mPresContext, kid);
// If the child has any floaters that impact the space-manager,
// place them now so that they are present in the space-manager
// again (they were removed by the space-manager's frame when
// the reflow began).
nsBlockFrame* bf;
nsresult rv = kid->QueryInterface(kBlockFrameCID, (void**) &bf);
if (NS_SUCCEEDED(rv)) {
// Translate spacemanager to the child blocks upper-left corner
// so that when it places its floaters (which are relative to
// it) the right coordinates are used. Note that we have already
// been translated by our border+padding so factor that in to
// get the right translation.
const nsMargin& bp = aState.BorderPadding();
nscoord dx = r.x - bp.left;
nscoord dy = r.y - bp.top;
aState.mSpaceManager->Translate(dx, dy);
bf->UpdateSpaceManager(aState.mPresContext, aState.mSpaceManager);
aState.mSpaceManager->Translate(-dx, -dy);
}
}
else {
// Adjust the Y coordinate of the frames in the line.
// Note: we need to re-position views even if aDY is 0, because
// one of our parent frames may have moved and so the view's position
// relative to its parent may have changed
nsRect r;
PRInt32 n = aLine->GetChildCount();
while (--n >= 0) {
if (aDY) {
kid->GetRect(r);
r.y += aDY;
kid->SetRect(aState.mPresContext, r);
nsPoint p;
kid->GetOrigin(p);
p.y += aDY;
kid->MoveTo(aState.mPresContext, p.x, p.y);
}
// Make sure the frame's view and any child views are updated
::PlaceFrameView(aState.mPresContext, kid);
@ -2878,58 +2858,6 @@ nsBlockFrame::SlideLine(nsBlockReflowState& aState,
}
}
nsresult
nsBlockFrame::UpdateSpaceManager(nsIPresContext* aPresContext,
nsSpaceManager* aSpaceManager)
{
for (line_iterator line = begin_lines(), line_end = end_lines();
line != line_end;
++line) {
// Place the floaters in the spacemanager
if (line->HasFloaters()) {
nsFloaterCache* fc = line->GetFirstFloater();
while (fc) {
nsIFrame* floater = fc->mPlaceholder->GetOutOfFlowFrame();
aSpaceManager->AddRectRegion(floater, fc->mRegion);
#ifdef NOISY_SPACEMANAGER
nscoord tx, ty;
aSpaceManager->GetTranslation(tx, ty);
nsFrame::ListTag(stdout, this);
printf(": UpdateSpaceManager: AddRectRegion: txy=%d,%d {%d,%d,%d,%d}\n",
tx, ty,
fc->mRegion.x, fc->mRegion.y,
fc->mRegion.width, fc->mRegion.height);
#endif
fc = fc->Next();
}
}
// Tell kids about the move too
if (line->mFirstChild && line->IsBlock()) {
// If the child has any floaters that impact the space-manager,
// place them now so that they are present in the space-manager
// again (they were removed by the space-manager's frame when
// the reflow began).
nsBlockFrame* bf;
nsresult rv = line->mFirstChild->QueryInterface(kBlockFrameCID,
NS_REINTERPRET_CAST(void**, &bf));
if (NS_SUCCEEDED(rv)) {
nsPoint origin;
bf->GetOrigin(origin);
// Translate spacemanager to the child blocks upper-left
// corner so that when it places its floaters (which are
// relative to it) the right coordinates are used.
aSpaceManager->Translate(origin.x, origin.y);
bf->UpdateSpaceManager(aPresContext, aSpaceManager);
aSpaceManager->Translate(-origin.x, -origin.y);
}
}
}
return NS_OK;
}
NS_IMETHODIMP
nsBlockFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,

Просмотреть файл

@ -188,12 +188,6 @@ public:
*/
nsIFrame* GetTopBlockChild();
/** Place the floaters in the spacemanager for all lines in this block.
* recursively adds floaters in child blocks of this frame.
*/
nsresult UpdateSpaceManager(nsIPresContext* aPresContext,
nsSpaceManager* aSpaceManager);
// returns true on success and false if aFoundLine is set to end_lines()
PRBool FindLineFor(nsIFrame* aFrame,
PRBool* aIsFloaterResult,

Просмотреть файл

@ -474,6 +474,14 @@ nsBlockReflowState::ReconstructMarginAbove(nsLineList::iterator aLine)
}
}
/**
* Restore information about floaters into the space manager for an
* incremental reflow, and simultaneously push the floaters by
* |aDeltaY|, which is the amount |aLine| was pushed relative to its
* parent. The recovery of state is one of the things that makes
* incremental reflow O(N^2) and this state should really be kept
* around, attached to the frame tree.
*/
void
nsBlockReflowState::RecoverFloaters(nsLineList::iterator aLine,
nscoord aDeltaY)
@ -481,25 +489,26 @@ nsBlockReflowState::RecoverFloaters(nsLineList::iterator aLine,
if (aLine->HasFloaters()) {
// Place the floaters into the space-manager again. Also slide
// them, just like the regular frames on the line.
nsRect r;
nsFloaterCache* fc = aLine->GetFirstFloater();
while (fc) {
fc->mRegion.y += aDeltaY;
fc->mCombinedArea.y += aDeltaY;
nsIFrame* floater = fc->mPlaceholder->GetOutOfFlowFrame();
floater->GetRect(r);
floater->MoveTo(mPresContext, r.x, r.y + aDeltaY);
if (aDeltaY != 0) {
fc->mRegion.y += aDeltaY;
fc->mCombinedArea.y += aDeltaY;
nsPoint p;
floater->GetOrigin(p);
floater->MoveTo(mPresContext, p.x, p.y + aDeltaY);
}
#ifdef DEBUG
if (nsBlockFrame::gNoisyReflow || nsBlockFrame::gNoisySpaceManager) {
nscoord tx, ty;
mSpaceManager->GetTranslation(tx, ty);
nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
printf("RecoverState: txy=%d,%d (%d,%d) ",
printf("RecoverFloaters: txy=%d,%d (%d,%d) ",
tx, ty, mSpaceManagerX, mSpaceManagerY);
nsFrame::ListTag(stdout, floater);
printf(" r.y=%d aDeltaY=%d (sum=%d) region={%d,%d,%d,%d}\n",
r.y, aDeltaY, r.y + aDeltaY,
fc->mRegion.x, fc->mRegion.y,
printf(" aDeltaY=%d region={%d,%d,%d,%d}\n",
aDeltaY, fc->mRegion.x, fc->mRegion.y,
fc->mRegion.width, fc->mRegion.height);
}
#endif
@ -511,15 +520,17 @@ nsBlockReflowState::RecoverFloaters(nsLineList::iterator aLine,
nsBlockFrame *kid = nsnull;
aLine->mFirstChild->QueryInterface(kBlockFrameCID, (void**)&kid);
if (kid) {
nsRect kidRect;
kid->GetRect(kidRect);
mSpaceManager->Translate(kidRect.x, kidRect.y);
nscoord kidx = kid->mRect.x, kidy = kid->mRect.y;
mSpaceManager->Translate(kidx, kidy);
for (nsBlockFrame::line_iterator line = kid->begin_lines(),
line_end = kid->end_lines();
line != line_end;
++line)
RecoverFloaters(line, aDeltaY);
mSpaceManager->Translate(-kidRect.x, -kidRect.y);
// Pass 0, not the real DeltaY, since these floaters aren't
// moving relative to their parent block, only relative to
// the space manager.
RecoverFloaters(line, 0);
mSpaceManager->Translate(-kidx, -kidy);
}
}
}