void RenderView::pushLayoutState(LayoutState& layoutState) { if (m_flowThreadController) { RenderFlowThread* currentFlowThread = m_flowThreadController->currentRenderFlowThread(); if (currentFlowThread) currentFlowThread->pushFlowThreadLayoutState(layoutState.renderer()); } m_layoutState = &layoutState; }
void RenderFlowThread::pushFlowThreadLayoutState(const RenderObject& object) { if (const RenderBox* currentBoxDescendant = currentStatePusherRenderBox()) { LayoutState* layoutState = currentBoxDescendant->view()->layoutState(); if (layoutState && layoutState->isPaginated()) { ASSERT(layoutState->renderer() == currentBoxDescendant); LayoutSize offsetDelta = layoutState->layoutOffset() - layoutState->pageOffset(); setOffsetFromLogicalTopOfFirstRegion(currentBoxDescendant, currentBoxDescendant->isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.width()); } } m_statePusherObjectsStack.add(&object); }
LayoutUnit RenderFlowThread::offsetFromLogicalTopOfFirstRegion(const RenderBlock* currentBlock) const { // First check if we cached the offset for the block if it's an ancestor containing block of the box // being currently laid out. LayoutUnit offset; if (cachedOffsetFromLogicalTopOfFirstRegion(currentBlock, offset)) return offset; // If it's the current box being laid out, use the layout state. const RenderBox* currentBoxDescendant = currentStatePusherRenderBox(); if (currentBlock == currentBoxDescendant) { LayoutState* layoutState = view()->layoutState(); ASSERT(layoutState->renderer() == currentBlock); ASSERT(layoutState && layoutState->isPaginated()); LayoutSize offsetDelta = layoutState->layoutOffset() - layoutState->pageOffset(); return currentBoxDescendant->isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.width(); } // As a last resort, take the slow path. LayoutRect blockRect(0, 0, currentBlock->width(), currentBlock->height()); while (currentBlock && !currentBlock->isRenderFlowThread()) { RenderBlock* containerBlock = currentBlock->containingBlock(); ASSERT(containerBlock); if (!containerBlock) return 0; LayoutPoint currentBlockLocation = currentBlock->location(); if (containerBlock->style()->writingMode() != currentBlock->style()->writingMode()) { // We have to put the block rect in container coordinates // and we have to take into account both the container and current block flipping modes if (containerBlock->style()->isFlippedBlocksWritingMode()) { if (containerBlock->isHorizontalWritingMode()) blockRect.setY(currentBlock->height() - blockRect.maxY()); else blockRect.setX(currentBlock->width() - blockRect.maxX()); } currentBlock->flipForWritingMode(blockRect); } blockRect.moveBy(currentBlockLocation); currentBlock = containerBlock; } return currentBlock->isHorizontalWritingMode() ? blockRect.y() : blockRect.x(); }