/** * Restore information about floats into the float manager for an * incremental reflow, and simultaneously push the floats 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::RecoverFloats(nsLineList::iterator aLine, nscoord aDeltaY) { if (aLine->HasFloats()) { // Place the floats into the space-manager again. Also slide // them, just like the regular frames on the line. nsFloatCache* fc = aLine->GetFirstFloat(); while (fc) { nsIFrame* floatFrame = fc->mFloat; if (aDeltaY != 0) { nsPoint p = floatFrame->GetPosition(); floatFrame->SetPosition(nsPoint(p.x, p.y + aDeltaY)); nsContainerFrame::PositionFrameView(floatFrame); nsContainerFrame::PositionChildViews(floatFrame); } #ifdef DEBUG if (nsBlockFrame::gNoisyReflow || nsBlockFrame::gNoisyFloatManager) { nscoord tx, ty; mFloatManager->GetTranslation(tx, ty); nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent); printf("RecoverFloats: txy=%d,%d (%d,%d) ", tx, ty, mFloatManagerX, mFloatManagerY); nsFrame::ListTag(stdout, floatFrame); nsRect region = nsFloatManager::GetRegionFor(floatFrame); printf(" aDeltaY=%d region={%d,%d,%d,%d}\n", aDeltaY, region.x, region.y, region.width, region.height); } #endif mFloatManager->AddFloat(floatFrame, nsFloatManager::GetRegionFor(floatFrame)); fc = fc->Next(); } } else if (aLine->IsBlock()) { nsBlockFrame::RecoverFloatsFor(aLine->mFirstChild, *mFloatManager); } }
/** * Restore information about floats into the space manager for an * incremental reflow, and simultaneously push the floats 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::RecoverFloats(nsLineList::iterator aLine, nscoord aDeltaY) { if (aLine->HasFloats()) { // Place the floats into the space-manager again. Also slide // them, just like the regular frames on the line. nsFloatCache* fc = aLine->GetFirstFloat(); while (fc) { nsIFrame* floatFrame = fc->mPlaceholder->GetOutOfFlowFrame(); if (aDeltaY != 0) { fc->mRegion.y += aDeltaY; nsPoint p = floatFrame->GetPosition(); floatFrame->SetPosition(nsPoint(p.x, p.y + aDeltaY)); nsContainerFrame::PositionFrameView(floatFrame); nsContainerFrame::PositionChildViews(floatFrame); } #ifdef DEBUG if (nsBlockFrame::gNoisyReflow || nsBlockFrame::gNoisySpaceManager) { nscoord tx, ty; mSpaceManager->GetTranslation(tx, ty); nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent); printf("RecoverFloats: txy=%d,%d (%d,%d) ", tx, ty, mSpaceManagerX, mSpaceManagerY); nsFrame::ListTag(stdout, floatFrame); printf(" aDeltaY=%d region={%d,%d,%d,%d}\n", aDeltaY, fc->mRegion.x, fc->mRegion.y, fc->mRegion.width, fc->mRegion.height); } #endif mSpaceManager->AddRectRegion(floatFrame, fc->mRegion); fc = fc->Next(); } } else if (aLine->IsBlock()) { nsBlockFrame *kid = nsnull; aLine->mFirstChild->QueryInterface(kBlockFrameCID, (void**)&kid); // don't recover any state inside a block that has its own space // manager (we don't currently have any blocks like this, though, // thanks to our use of extra frames for 'overflow') if (kid && !nsBlockFrame::BlockNeedsSpaceManager(kid)) { nscoord tx = kid->mRect.x, ty = kid->mRect.y; // If the element is relatively positioned, then adjust x and y // accordingly so that we consider relatively positioned frames // at their original position. if (NS_STYLE_POSITION_RELATIVE == kid->GetStyleDisplay()->mPosition) { nsPoint *offsets = static_cast<nsPoint*> (mPresContext->PropertyTable()->GetProperty(kid, nsGkAtoms::computedOffsetProperty)); if (offsets) { tx -= offsets->x; ty -= offsets->y; } } mSpaceManager->Translate(tx, ty); for (nsBlockFrame::line_iterator line = kid->begin_lines(), line_end = kid->end_lines(); line != line_end; ++line) // Pass 0, not the real DeltaY, since these floats aren't // moving relative to their parent block, only relative to // the space manager. RecoverFloats(line, 0); mSpaceManager->Translate(-tx, -ty); } } }