LayoutUnit RenderFlowThread::pageRemainingLogicalHeightForOffset(LayoutUnit offset, PageBoundaryRule pageBoundaryRule) { RenderMultiColumnSet* columnSet = columnSetAtBlockOffset(offset); if (!columnSet) return 0; LayoutUnit pageLogicalTop = columnSet->pageLogicalTopForOffset(offset); LayoutUnit pageLogicalHeight = columnSet->pageLogicalHeight(); LayoutUnit pageLogicalBottom = pageLogicalTop + pageLogicalHeight; LayoutUnit remainingHeight = pageLogicalBottom - offset; if (pageBoundaryRule == IncludePageBoundary) { // If IncludePageBoundary is set, the line exactly on the top edge of a // columnSet will act as being part of the previous columnSet. remainingHeight = intMod(remainingHeight, pageLogicalHeight); } return remainingHeight; }
LayoutUnit RenderFlowThread::pageLogicalTopForOffset(LayoutUnit offset) { RenderMultiColumnSet* columnSet = columnSetAtBlockOffset(offset); return columnSet ? columnSet->pageLogicalTopForOffset(offset) : LayoutUnit(); }
LayoutPoint RenderFlowThread::adjustedPositionRelativeToOffsetParent(const RenderBoxModelObject& boxModelObject, const LayoutPoint& startPoint) { LayoutPoint referencePoint = startPoint; // FIXME: This needs to be adapted for different writing modes inside the flow thread. RenderMultiColumnSet* startColumnSet = columnSetAtBlockOffset(referencePoint.y()); if (startColumnSet) { // Take into account the offset coordinates of the columnSet. RenderObject* currObject = startColumnSet; RenderObject* currOffsetParentRenderer; Element* currOffsetParentElement; while ((currOffsetParentElement = currObject->offsetParent()) && (currOffsetParentRenderer = currOffsetParentElement->renderer())) { if (currObject->isBoxModelObject()) referencePoint.move(toRenderBoxModelObject(currObject)->offsetLeft(), toRenderBoxModelObject(currObject)->offsetTop()); // Since we're looking for the offset relative to the body, we must also // take into consideration the borders of the columnSet's offsetParent. if (currOffsetParentRenderer->isBox() && !currOffsetParentRenderer->isBody()) referencePoint.move(toRenderBox(currOffsetParentRenderer)->borderLeft(), toRenderBox(currOffsetParentRenderer)->borderTop()); currObject = currOffsetParentRenderer; } // We need to check if any of this box's containing blocks start in a different columnSet // and if so, drop the object's top position (which was computed relative to its containing block // and is no longer valid) and recompute it using the columnSet in which it flows as reference. bool wasComputedRelativeToOtherRegion = false; const RenderBlock* objContainingBlock = boxModelObject.containingBlock(); while (objContainingBlock) { // Check if this object is in a different columnSet. RenderMultiColumnSet* parentStartRegion = 0; RenderMultiColumnSet* parentEndRegion = 0; getRegionRangeForBox(objContainingBlock, parentStartRegion, parentEndRegion); if (parentStartRegion && parentStartRegion != startColumnSet) { wasComputedRelativeToOtherRegion = true; break; } objContainingBlock = objContainingBlock->containingBlock(); } if (wasComputedRelativeToOtherRegion) { // Get the logical top coordinate of the current object. LayoutUnit top = 0; if (boxModelObject.isRenderBlock()) { top = toRenderBlock(&boxModelObject)->offsetFromLogicalTopOfFirstPage(); } else { if (boxModelObject.containingBlock()) top = boxModelObject.containingBlock()->offsetFromLogicalTopOfFirstPage(); if (boxModelObject.isBox()) top += toRenderBox(&boxModelObject)->topLeftLocation().y(); else if (boxModelObject.isRenderInline()) top -= toRenderInline(&boxModelObject)->borderTop(); } // Get the logical top of the columnSet this object starts in // and compute the object's top, relative to the columnSet's top. LayoutUnit regionLogicalTop = startColumnSet->pageLogicalTopForOffset(top); LayoutUnit topRelativeToRegion = top - regionLogicalTop; referencePoint.setY(startColumnSet->offsetTop() + topRelativeToRegion); // Since the top has been overriden, check if the // relative positioning must be reconsidered. if (boxModelObject.isRelPositioned()) referencePoint.move(0, boxModelObject.relativePositionOffset().height()); } // Since we're looking for the offset relative to the body, we must also // take into consideration the borders of the columnSet. referencePoint.move(startColumnSet->borderLeft(), startColumnSet->borderTop()); } return referencePoint; }