コード例 #1
0
void LayoutMultiColumnFlowThread::appendNewFragmentainerGroupIfNeeded(LayoutUnit bottomOffsetInFlowThread)
{
    if (!isPageLogicalHeightKnown()) {
        // If we have no clue about the height of the multicol container, bail. This situation
        // occurs initially when an auto-height multicol container is nested inside another
        // auto-height multicol container. We need at least an estimated height of the outer
        // multicol container before we can check what an inner fragmentainer group has room for.
        // Its height is indefinite for now.
        return;
    }
    // TODO(mstensho): bottomOffsetInFlowThread is an endpoint-exclusive offset, i.e. the offset
    // just after the bottom of some object. So, ideally, columnSetAtBlockOffset() should be
    // informed about this (i.e. take a PageBoundaryRule argument). This is not the only place with
    // this issue; see also pageRemainingLogicalHeightForOffset().
    LayoutMultiColumnSet* columnSet = columnSetAtBlockOffset(bottomOffsetInFlowThread);
    if (columnSet->isInitialHeightCalculated()) {
        // We only insert additional fragmentainer groups in the initial layout pass. We only want
        // to balance columns in the last fragmentainer group (if we need to balance at all), so we
        // want that last fragmentainer group to be the same one in all layout passes that follow.
        return;
    }

    if (!columnSet->hasFragmentainerGroupForColumnAt(bottomOffsetInFlowThread)) {
        FragmentationContext* enclosingFragmentationContext = this->enclosingFragmentationContext();
        if (!enclosingFragmentationContext)
            return; // Not nested. We'll never need more rows than the one we already have then.
        ASSERT(!isLayoutPagedFlowThread());
        // We have run out of columns here, so we add another row to hold more columns. When we add
        // a new row, it implicitly means that we're inserting another column in our enclosing
        // multicol container. That in turn may mean that we've run out of columns there too.
        const MultiColumnFragmentainerGroup& newRow = columnSet->appendNewFragmentainerGroup();
        if (LayoutMultiColumnFlowThread* enclosingFlowThread = enclosingFragmentationContext->associatedFlowThread())
            enclosingFlowThread->appendNewFragmentainerGroupIfNeeded(newRow.blockOffsetInEnclosingFragmentationContext() + newRow.logicalHeight());
    }
}
コード例 #2
0
void LayoutMultiColumnFlowThread::appendNewFragmentainerGroupIfNeeded(LayoutUnit offsetInFlowThread)
{
    if (!isPageLogicalHeightKnown()) {
        // If we have no clue about the height of the multicol container, bail. This situation
        // occurs initially when an auto-height multicol container is nested inside another
        // auto-height multicol container. We need at least an estimated height of the outer
        // multicol container before we can check what an inner fragmentainer group has room for.
        // Its height is indefinite for now.
        return;
    }
    LayoutMultiColumnSet* columnSet = columnSetAtBlockOffset(offsetInFlowThread);
    if (columnSet->isInitialHeightCalculated()) {
        // We only insert additional fragmentainer groups in the initial layout pass. We only want
        // to balance columns in the last fragmentainer group (if we need to balance at all), so we
        // want that last fragmentainer group to be the same one in all layout passes that follow.
        return;
    }

    if (!columnSet->hasFragmentainerGroupForColumnAt(offsetInFlowThread)) {
        FragmentationContext* enclosingFragmentationContext = this->enclosingFragmentationContext();
        if (!enclosingFragmentationContext)
            return; // Not nested. We'll never need more rows than the one we already have then.
        ASSERT(!isLayoutPagedFlowThread());
        // We have run out of columns here, so we add another row to hold more columns. When we add
        // a new row, it implicitly means that we're inserting another column in our enclosing
        // multicol container. That in turn may mean that we've run out of columns there too.
        const MultiColumnFragmentainerGroup& newRow = columnSet->appendNewFragmentainerGroup();
        if (LayoutMultiColumnFlowThread* enclosingFlowThread = enclosingFragmentationContext->associatedFlowThread())
            enclosingFlowThread->appendNewFragmentainerGroupIfNeeded(newRow.blockOffsetInEnclosingFragmentationContext());
    }
}
コード例 #3
0
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.
}