LayoutUnit LayoutMultiColumnSet::nextLogicalTopForUnbreakableContent(LayoutUnit flowThreadOffset, LayoutUnit contentLogicalHeight) const { ASSERT(flowThreadOffset.mightBeSaturated() || pageLogicalTopForOffset(flowThreadOffset) == flowThreadOffset); FragmentationContext* enclosingFragmentationContext = multiColumnFlowThread()->enclosingFragmentationContext(); if (!enclosingFragmentationContext) { // If there's no enclosing fragmentation context, there'll ever be only one row, and all // columns there will have the same height. return flowThreadOffset; } // Assert the problematic situation. If we have no problem with the column height, why are we // even here? ASSERT(pageLogicalHeightForOffset(flowThreadOffset) < contentLogicalHeight); // There's a likelihood for subsequent rows to be taller than the first one. // TODO(mstensho): if we're doubly nested (e.g. multicol in multicol in multicol), we need to // look beyond the first row here. const MultiColumnFragmentainerGroup& firstRow = firstFragmentainerGroup(); LayoutUnit firstRowLogicalBottomInFlowThread = firstRow.logicalTopInFlowThread() + fragmentainerGroupCapacity(firstRow); if (flowThreadOffset >= firstRowLogicalBottomInFlowThread) return flowThreadOffset; // We're not in the first row. Give up. LayoutUnit newLogicalHeight = enclosingFragmentationContext->fragmentainerLogicalHeightAt(firstRow.blockOffsetInEnclosingFragmentationContext() + firstRow.logicalHeight()); if (contentLogicalHeight > newLogicalHeight) { // The next outer column or page doesn't have enough space either. Give up and stay where // we are. return flowThreadOffset; } return firstRowLogicalBottomInFlowThread; }
LayoutUnit LayoutMultiColumnSet::pageRemainingLogicalHeightForOffset(LayoutUnit offsetInFlowThread, PageBoundaryRule pageBoundaryRule) const { const MultiColumnFragmentainerGroup& row = fragmentainerGroupAtFlowThreadOffset(offsetInFlowThread); LayoutUnit pageLogicalHeight = row.logicalHeight(); ASSERT(pageLogicalHeight); // It's not allowed to call this method if the height is unknown. LayoutUnit pageLogicalBottom = row.columnLogicalTopForOffset(offsetInFlowThread) + pageLogicalHeight; LayoutUnit remainingLogicalHeight = pageLogicalBottom - offsetInFlowThread; if (pageBoundaryRule == AssociateWithFormerPage) { // An offset exactly at a column boundary will act as being part of the former column in // question (i.e. no remaining space), rather than being part of the latter (i.e. one whole // column length of remaining space). remainingLogicalHeight = intMod(remainingLogicalHeight, pageLogicalHeight); } else if (!remainingLogicalHeight) { // When pageBoundaryRule is AssociateWithLatterPage, we should never return 0, because if // there's no space left, it means that we should be at a column boundary, in which case we // should return the amount of space remaining in the *next* column. But this is not true if // the offset is "infinite" (saturated), so allow this to happen in that case. ASSERT(offsetInFlowThread.mightBeSaturated()); remainingLogicalHeight = pageLogicalHeight; } return remainingLogicalHeight; }