bool MultiColumnFragmentainerGroup::heightIsAuto() const { // Only the last row may have auto height, and thus be balanced. There are no good reasons to // balance the preceding rows, and that could potentially lead to an insane number of layout // passes as well. return isLastGroup() && m_columnSet.heightIsAuto(); }
void MultiColumnFragmentainerGroup::expandToEncompassFlowThreadOverflow() { ASSERT(isLastGroup()); // Get the offset within the flow thread in its block progression direction. Then get the // flow thread's remaining logical height including its overflow and expand our rect // to encompass that remaining height and overflow. The idea is that we will generate // additional columns and pages to hold that overflow, since people do write bad // content like <body style="height:0px"> in multi-column layouts. LayoutMultiColumnFlowThread* flowThread = m_columnSet.multiColumnFlowThread(); LayoutRect layoutRect = flowThread->layoutOverflowRect(); m_logicalBottomInFlowThread = flowThread->isHorizontalWritingMode() ? layoutRect.maxY() : layoutRect.maxX(); }
bool MultiColumnFragmentainerGroup::recalculateColumnHeight( LayoutMultiColumnSet& columnSet) { LayoutUnit oldColumnHeight = m_columnHeight; m_maxColumnHeight = calculateMaxColumnHeight(); // Only the last row may have auto height, and thus be balanced. There are no // good reasons to balance the preceding rows, and that could potentially lead // to an insane number of layout passes as well. if (isLastGroup() && columnSet.heightIsAuto()) { LayoutUnit newColumnHeight; if (!columnSet.isInitialHeightCalculated()) { // Initial balancing: Start with the lowest imaginable column height. Also // calculate the height of the tallest piece of unbreakable content. // Columns should never get any shorter than that (unless constrained by // max-height). Propagate this to our containing column set, in case there // is an outer multicol container that also needs to balance. After having // calculated the initial column height, the multicol container needs // another layout pass with the column height that we just calculated. InitialColumnHeightFinder initialHeightFinder( columnSet, logicalTopInFlowThread(), logicalBottomInFlowThread()); LayoutUnit tallestUnbreakableLogicalHeight = initialHeightFinder.tallestUnbreakableLogicalHeight(); columnSet.propagateTallestUnbreakableLogicalHeight( tallestUnbreakableLogicalHeight); newColumnHeight = std::max(initialHeightFinder.initialMinimalBalancedHeight(), tallestUnbreakableLogicalHeight); } else { // Rebalancing: After having laid out again, we'll need to rebalance if // the height wasn't enough and we're allowed to stretch it, and then // re-lay out. There are further details on the column balancing // machinery in ColumnBalancer and its derivates. newColumnHeight = rebalanceColumnHeightIfNeeded(); } setAndConstrainColumnHeight(newColumnHeight); } else { // The position of the column set may have changed, in which case height // available for columns may have changed as well. setAndConstrainColumnHeight(m_columnHeight); } if (m_columnHeight == oldColumnHeight) return false; // No change. We're done. return true; // Need another pass. }