Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(939)

Unified Diff: Source/core/layout/MultiColumnFragmentainerGroup.cpp

Issue 1292163002: Initial support for nested multicol layout. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: code review Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/layout/MultiColumnFragmentainerGroup.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/layout/MultiColumnFragmentainerGroup.cpp
diff --git a/Source/core/layout/MultiColumnFragmentainerGroup.cpp b/Source/core/layout/MultiColumnFragmentainerGroup.cpp
index f72aed8e9ff4c97c425ad51281d6576fad697006..b67612d7a9ae65f8f537fac9f7397576837d8c7e 100644
--- a/Source/core/layout/MultiColumnFragmentainerGroup.cpp
+++ b/Source/core/layout/MultiColumnFragmentainerGroup.cpp
@@ -28,6 +28,11 @@ LayoutSize MultiColumnFragmentainerGroup::offsetFromColumnSet() const
return offset;
}
+LayoutUnit MultiColumnFragmentainerGroup::blockOffsetInEnclosingFlowThread() const
+{
+ return logicalTop() + m_columnSet.logicalTop() + m_columnSet.multiColumnFlowThread()->blockOffsetInEnclosingFlowThread();
+}
+
bool MultiColumnFragmentainerGroup::heightIsAuto() const
{
// Only the last row may have auto height, and thus be balanced. There are no good reasons to
@@ -45,10 +50,18 @@ void MultiColumnFragmentainerGroup::resetColumnHeight()
LayoutUnit oldColumnHeight = m_columnHeight;
- if (heightIsAuto())
+ 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(m_columnSet.multiColumnFlowThread()->columnHeightAvailable()));
+ } else {
+ setAndConstrainColumnHeight(heightAdjustedForRowOffset(flowThread->columnHeightAvailable()));
+ }
if (m_columnHeight != oldColumnHeight)
m_columnSet.setChildNeedsLayout(MarkOnlyThis);
@@ -119,14 +132,35 @@ bool MultiColumnFragmentainerGroup::recalculateColumnHeight(BalancedColumnHeight
LayoutSize MultiColumnFragmentainerGroup::flowThreadTranslationAtOffset(LayoutUnit offsetInFlowThread) const
{
- LayoutFlowThread* flowThread = m_columnSet.flowThread();
+ LayoutMultiColumnFlowThread* flowThread = m_columnSet.multiColumnFlowThread();
unsigned columnIndex = columnIndexAtOffset(offsetInFlowThread);
LayoutRect portionRect(flowThreadPortionRectAt(columnIndex));
flowThread->flipForWritingMode(portionRect);
LayoutRect columnRect(columnRectAt(columnIndex));
m_columnSet.flipForWritingMode(columnRect);
LayoutSize translationRelativeToGroup = columnRect.location() - portionRect.location();
- return translationRelativeToGroup + offsetFromColumnSet() + m_columnSet.topLeftLocationOffset() - flowThread->topLeftLocationOffset();
+
+ LayoutSize enclosingTranslation;
+ if (LayoutMultiColumnFlowThread* enclosingFlowThread = flowThread->enclosingFlowThread()) {
+ // Translation that would map points in the coordinate space of the outermost flow thread to
+ // visual points in the first column in the first fragmentainer group (row) in our multicol
+ // container.
+ LayoutSize enclosingTranslationOrigin = enclosingFlowThread->flowThreadTranslationAtOffset(flowThread->blockOffsetInEnclosingFlowThread());
+
+ // Translation that would map points in the coordinate space of the outermost flow thread to
+ // visual points in the first column in this fragmentainer group.
+ enclosingTranslation = enclosingFlowThread->flowThreadTranslationAtOffset(blockOffsetInEnclosingFlowThread());
+
+ // What we ultimately return from this method is a translation that maps points in the
+ // coordinate space of our flow thread to a visual point in a certain column in this
+ // fragmentainer group. We had to go all the way up to the outermost flow thread, since this
+ // fragmentainer group may be in a different outer column than the first outer column that
+ // this multicol container lives in. It's the visual distance between the first
+ // fragmentainer group and this fragmentainer group that we need to add to the translation.
+ enclosingTranslation -= enclosingTranslationOrigin;
+ }
+
+ return enclosingTranslation + translationRelativeToGroup + offsetFromColumnSet() + m_columnSet.topLeftLocationOffset() - flowThread->topLeftLocationOffset();
}
LayoutUnit MultiColumnFragmentainerGroup::columnLogicalTopForOffset(LayoutUnit offsetInFlowThread) const
@@ -308,14 +342,26 @@ LayoutUnit MultiColumnFragmentainerGroup::calculateMaxColumnHeight() const
{
LayoutBlockFlow* multicolBlock = m_columnSet.multiColumnBlockFlow();
const ComputedStyle& multicolStyle = multicolBlock->styleRef();
- LayoutUnit availableHeight = m_columnSet.multiColumnFlowThread()->columnHeightAvailable();
+ 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;
}
- return heightAdjustedForRowOffset(maxColumnHeight);
+ 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::setAndConstrainColumnHeight(LayoutUnit newHeight)
@@ -323,7 +369,6 @@ void MultiColumnFragmentainerGroup::setAndConstrainColumnHeight(LayoutUnit newHe
m_columnHeight = newHeight;
if (m_columnHeight > m_maxColumnHeight)
m_columnHeight = m_maxColumnHeight;
- // FIXME: the height may also be affected by the enclosing pagination context, if any.
}
unsigned MultiColumnFragmentainerGroup::findRunWithTallestColumns() const
@@ -469,16 +514,18 @@ LayoutRect MultiColumnFragmentainerGroup::flowThreadPortionOverflowRectAt(unsign
//
// FIXME: Eventually we will know overflow on a per-column basis, but we can't do this until we have a painting
// mode that understands not to paint contents from a previous column in the overflow area of a following column.
- bool isFirstColumn = !columnIndex;
- bool isLastColumn = columnIndex == actualColumnCount() - 1;
+ bool isFirstColumnInRow = !columnIndex;
+ bool isLastColumnInRow = columnIndex == actualColumnCount() - 1;
bool isLTR = m_columnSet.style()->isLeftToRightDirection();
- bool isLeftmostColumn = isLTR ? isFirstColumn : isLastColumn;
- bool isRightmostColumn = isLTR ? isLastColumn : isFirstColumn;
+ bool isLeftmostColumn = isLTR ? isFirstColumnInRow : isLastColumnInRow;
+ bool isRightmostColumn = isLTR ? isLastColumnInRow : isFirstColumnInRow;
LayoutRect portionRect = flowThreadPortionRectAt(columnIndex);
+ bool isFirstColumnInMulticolContainer = isFirstColumnInRow && this == &m_columnSet.firstFragmentainerGroup() && !m_columnSet.previousSiblingMultiColumnSet();
+ bool isLastColumnInMulticolContainer = isLastColumnInRow && this == &m_columnSet.lastFragmentainerGroup() && !m_columnSet.nextSiblingMultiColumnSet();
// Calculate the overflow rectangle, based on the flow thread's, clipped at column logical
// top/bottom unless it's the first/last column.
- LayoutRect overflowRect = m_columnSet.overflowRectForFlowThreadPortion(portionRect, isFirstColumn && !m_columnSet.previousSiblingMultiColumnSet(), isLastColumn && !m_columnSet.nextSiblingMultiColumnSet());
+ LayoutRect overflowRect = m_columnSet.overflowRectForFlowThreadPortion(portionRect, isFirstColumnInMulticolContainer, isLastColumnInMulticolContainer);
// Avoid overflowing into neighboring columns, by clipping in the middle of adjacent column
// gaps. Also make sure that we avoid rounding errors.
« no previous file with comments | « Source/core/layout/MultiColumnFragmentainerGroup.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698