LayoutUnit MultiColumnFragmentainerGroup::calculateMaxColumnHeight() const { LayoutBlockFlow* multicolBlock = m_columnSet.multiColumnBlockFlow(); const ComputedStyle& multicolStyle = multicolBlock->styleRef(); LayoutMultiColumnFlowThread* flowThread = m_columnSet.multiColumnFlowThread(); LayoutUnit availableHeight = flowThread->columnHeightAvailable(); LayoutUnit maxColumnHeight = availableHeight ? availableHeight : LayoutUnit::max(); if (!multicolStyle.logicalMaxHeight().isMaxSizeNone()) { LayoutUnit logicalMaxHeight = multicolBlock->computeContentLogicalHeight(MaxSize, multicolStyle.logicalMaxHeight(), -1); if (logicalMaxHeight != -1 && maxColumnHeight > logicalMaxHeight) maxColumnHeight = logicalMaxHeight; } LayoutUnit maxHeight = heightAdjustedForRowOffset(maxColumnHeight); if (LayoutMultiColumnFlowThread* enclosingFlowThread = flowThread->enclosingFlowThread()) { if (enclosingFlowThread->isPageLogicalHeightKnown()) { // We're nested inside another fragmentation context whose fragmentainer heights are // known. This constrains the max height. LayoutUnit remainingOuterLogicalHeight = enclosingFlowThread->pageRemainingLogicalHeightForOffset(blockOffsetInEnclosingFlowThread(), LayoutBlock::AssociateWithLatterPage); ASSERT(remainingOuterLogicalHeight > 0); if (maxHeight > remainingOuterLogicalHeight) maxHeight = remainingOuterLogicalHeight; } } return maxHeight; }
void MultiColumnFragmentainerGroup::resetColumnHeight() { m_maxColumnHeight = calculateMaxColumnHeight(); LayoutMultiColumnFlowThread* flowThread = m_columnSet.multiColumnFlowThread(); if (m_columnSet.heightIsAuto()) { FragmentationContext* enclosingFragmentationContext = flowThread->enclosingFragmentationContext(); if (enclosingFragmentationContext && enclosingFragmentationContext->isFragmentainerLogicalHeightKnown()) { // Even if height is auto, we set an initial height, in order to tell how much content // this MultiColumnFragmentainerGroup can hold, and when we need to append a new one. m_columnHeight = m_maxColumnHeight; } else { m_columnHeight = LayoutUnit(); } } else { setAndConstrainColumnHeight(heightAdjustedForRowOffset(flowThread->columnHeightAvailable())); } }
void MultiColumnFragmentainerGroup::resetColumnHeight() { // Nuke previously stored minimum column height. Contents may have changed for all we know. m_minimumColumnHeight = 0; m_maxColumnHeight = calculateMaxColumnHeight(); LayoutMultiColumnFlowThread* flowThread = m_columnSet.multiColumnFlowThread(); LayoutMultiColumnFlowThread* enclosingFlowThread = flowThread->enclosingFlowThread(); if (enclosingFlowThread && enclosingFlowThread->isPageLogicalHeightKnown()) { // TODO(mstensho): Do this better. If height is auto here, we shouldn't set a // height, or forced breaks and pagination struts might mess up column balancing. LayoutUnit columnHeight = heightIsAuto() ? m_maxColumnHeight : heightAdjustedForRowOffset(flowThread->columnHeightAvailable()); setAndConstrainColumnHeight(columnHeight); } else if (heightIsAuto()) { m_columnHeight = LayoutUnit(); } else { setAndConstrainColumnHeight(heightAdjustedForRowOffset(flowThread->columnHeightAvailable())); } }
bool LayoutMultiColumnSet::heightIsAuto() const { LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread(); if (!flowThread->isLayoutPagedFlowThread()) { // If support for the column-fill property isn't enabled, we want to behave as if // column-fill were auto, so that multicol containers with specified height don't get their // columns balanced (auto-height multicol containers will still get their columns balanced, // even if column-fill isn't 'balance' - in accordance with the spec). Pretending that // column-fill is auto also matches the old multicol implementation, which has no support // for this property. if (multiColumnBlockFlow()->style()->getColumnFill() == ColumnFillBalance) return true; if (LayoutBox* next = nextSiblingBox()) { if (next->isLayoutMultiColumnSpannerPlaceholder()) { // If we're followed by a spanner, we need to balance. return true; } } } return !flowThread->columnHeightAvailable(); }