void RenderMultiColumnSet::distributeImplicitBreaks() { unsigned breakCount = forcedBreaksCount(); #ifndef NDEBUG // There should be no implicit breaks assumed at this point. for (unsigned i = 0; i < breakCount; i++) ASSERT(!m_contentRuns[i].assumedImplicitBreaks()); #endif // NDEBUG // There will always be at least one break, since the flow thread reports a "forced break" at // end of content. ASSERT(breakCount >= 1); // If there is room for more breaks (to reach the used value of column-count), imagine that we // insert implicit breaks at suitable locations. At any given time, the content run with the // currently tallest columns will get another implicit break "inserted", which will increase its // column count by one and shrink its columns' height. Repeat until we have the desired total // number of breaks. The largest column height among the runs will then be the initial column // height for the balancer to use. while (breakCount < m_computedColumnCount) { unsigned index = findRunWithTallestColumns(); m_contentRuns[index].assumeAnotherImplicitBreak(); breakCount++; } }
void MultiColumnFragmentainerGroup::distributeImplicitBreaks() { #if ENABLE(ASSERT) // There should be no implicit breaks assumed at this point. for (unsigned i = 0; i < m_contentRuns.size(); i++) ASSERT(!m_contentRuns[i].assumedImplicitBreaks()); #endif // ENABLE(ASSERT) // Insert a final content run to encompass all content. This will include overflow if this is // the last set. addContentRun(m_logicalBottomInFlowThread); unsigned columnCount = m_contentRuns.size(); // If there is room for more breaks (to reach the used value of column-count), imagine that we // insert implicit breaks at suitable locations. At any given time, the content run with the // currently tallest columns will get another implicit break "inserted", which will increase its // column count by one and shrink its columns' height. Repeat until we have the desired total // number of breaks. The largest column height among the runs will then be the initial column // height for the balancer to use. while (columnCount < m_columnSet.usedColumnCount()) { unsigned index = findRunWithTallestColumns(); m_contentRuns[index].assumeAnotherImplicitBreak(); columnCount++; } }
LayoutUnit RenderMultiColumnSet::calculateBalancedHeight(bool initial) const { if (initial) { // Start with the lowest imaginable column height. unsigned index = findRunWithTallestColumns(); LayoutUnit startOffset = index > 0 ? m_contentRuns[index - 1].breakOffset() : LayoutUnit(); return std::max<LayoutUnit>(m_contentRuns[index].columnLogicalHeight(startOffset), m_minimumColumnHeight); } if (columnCount() <= computedColumnCount()) { // With the current column height, the content fits without creating overflowing columns. We're done. return m_computedColumnHeight; } if (forcedBreaksCount() > 1 && forcedBreaksCount() >= computedColumnCount()) { // Too many forced breaks to allow any implicit breaks. Initial balancing should already // have set a good height. There's nothing more we should do. return m_computedColumnHeight; } // If the initial guessed column height wasn't enough, stretch it now. Stretch by the lowest // amount of space shortage found during layout. ASSERT(m_minSpaceShortage > 0); // We should never _shrink_ the height! ASSERT(m_minSpaceShortage != RenderFlowThread::maxLogicalHeight()); // If this happens, we probably have a bug. if (m_minSpaceShortage == RenderFlowThread::maxLogicalHeight()) return m_computedColumnHeight; // So bail out rather than looping infinitely. return m_computedColumnHeight + m_minSpaceShortage; }
LayoutUnit RenderMultiColumnSet::calculateColumnHeight(BalancedHeightCalculation calculationMode) const { if (calculationMode == GuessFromFlowThreadPortion) { // Initial balancing. Start with the lowest imaginable column height. We use the tallest // content run (after having "inserted" implicit breaks), and find its start offset (by // looking at the previous run's end offset, or, if there's no previous run, the set's start // offset in the flow thread). unsigned index = findRunWithTallestColumns(); LayoutUnit startOffset = index > 0 ? m_contentRuns[index - 1].breakOffset() : logicalTopInFlowThread(); return std::max<LayoutUnit>(m_contentRuns[index].columnLogicalHeight(startOffset), m_minimumColumnHeight); } if (actualColumnCount() <= usedColumnCount()) { // With the current column height, the content fits without creating overflowing columns. We're done. return m_columnHeight; } if (m_contentRuns.size() >= usedColumnCount()) { // Too many forced breaks to allow any implicit breaks. Initial balancing should already // have set a good height. There's nothing more we should do. return m_columnHeight; } // If the initial guessed column height wasn't enough, stretch it now. Stretch by the lowest // amount of space shortage found during layout. ASSERT(m_minSpaceShortage > 0); // We should never _shrink_ the height! ASSERT(m_minSpaceShortage != RenderFlowThread::maxLogicalHeight()); // If this happens, we probably have a bug. if (m_minSpaceShortage == RenderFlowThread::maxLogicalHeight()) return m_columnHeight; // So bail out rather than looping infinitely. return m_columnHeight + m_minSpaceShortage; }