コード例 #1
0
void RenderMultiColumnBlock::ensureColumnSets()
{
    // This function ensures we have the correct column set information before we get into layout.
    // For a simple multi-column layout in continuous media, only one column set child is required.
    // Once a column is nested inside an enclosing pagination context, the number of column sets
    // required becomes 2n-1, where n is the total number of nested pagination contexts. For example:
    //
    // Column layout with no enclosing pagination model = 2 * 1 - 1 = 1 column set.
    // Columns inside pages = 2 * 2 - 1 = 3 column sets (bottom of first page, all the subsequent pages, then the last page).
    // Columns inside columns inside pages = 2 * 3 - 1 = 5 column sets.
    //
    // In addition, column spans will force a column set to "split" into before/after sets around the spanning region.
    //
    // Finally, we will need to deal with columns inside regions. If regions have variable widths, then there will need
    // to be unique column sets created inside any region whose width is different from its surrounding regions. This is
    // actually pretty similar to the spanning case, in that we break up the column sets whenever the width varies.
    //
    // FIXME: For now just make one column set. This matches the old multi-column code.
    // Right now our goal is just feature parity with the old multi-column code so that we can switch over to the
    // new code as soon as possible.
    if (!flowThread())
        return;

    RenderMultiColumnSet* columnSet = firstChild()->isRenderMultiColumnSet() ? toRenderMultiColumnSet(firstChild()) : 0;
    if (!columnSet) {
        columnSet = RenderMultiColumnSet::createAnonymous(flowThread());
        columnSet->setStyle(RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK));
        RenderBlock::addChild(columnSet, firstChild());
    }
    columnSet->setRequiresBalancing(requiresBalancing());
}
コード例 #2
0
bool RenderMultiColumnBlock::relayoutForPagination(bool, LayoutUnit, LayoutStateMaintainer& statePusher)
{
    if (m_inBalancingPass || !requiresBalancing())
        return false;
    m_inBalancingPass = true; // Prevent re-entering this method (and recursion into layout).

    bool needsRelayout;
    bool neededRelayout = false;
    bool firstPass = true;
    do {
        // Column heights may change here because of balancing. We may have to do multiple layout
        // passes, depending on how the contents is fitted to the changed column heights. In most
        // cases, laying out again twice or even just once will suffice. Sometimes we need more
        // passes than that, though, but the number of retries should not exceed the number of
        // columns, unless we have a bug.
        needsRelayout = false;
        for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox())
            if (childBox != m_flowThread && childBox->isRenderMultiColumnSet()) {
                RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(childBox);
                if (multicolSet->calculateBalancedHeight(firstPass)) {
                    multicolSet->setChildNeedsLayout(MarkOnlyThis);
                    needsRelayout = true;
                }
            }

        if (needsRelayout) {
            // Layout again. Column balancing resulted in a new height.
            neededRelayout = true;
            m_flowThread->setChildNeedsLayout(MarkOnlyThis);
            setChildNeedsLayout(MarkOnlyThis);
            if (firstPass)
                statePusher.pop();
            layoutBlock(false);
        }
        firstPass = false;
    } while (needsRelayout);
    m_inBalancingPass = false;
    return neededRelayout;
}