зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
6f658a8b68
Коммит
a293c9dc19
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче