| Index: third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.cpp
|
| diff --git a/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.cpp b/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.cpp
|
| index 9305698260901b2baec3e3f1c3c8ae25b0c29ac4..72000539f6d00ba8935a318a64f18ee079697b88 100644
|
| --- a/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.cpp
|
| +++ b/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.cpp
|
| @@ -98,10 +98,16 @@ bool MultiColumnFragmentainerGroup::recalculateColumnHeight(LayoutMultiColumnSet
|
| return true; // Need another pass.
|
| }
|
|
|
| -LayoutSize MultiColumnFragmentainerGroup::flowThreadTranslationAtOffset(LayoutUnit offsetInFlowThread, CoordinateSpaceConversion mode) const
|
| +LayoutSize MultiColumnFragmentainerGroup::flowThreadTranslationAtOffset(LayoutUnit offsetInFlowThread, LayoutBox::PageBoundaryRule rule, CoordinateSpaceConversion mode) const
|
| {
|
| LayoutMultiColumnFlowThread* flowThread = m_columnSet.multiColumnFlowThread();
|
| - unsigned columnIndex = columnIndexAtOffset(offsetInFlowThread);
|
| +
|
| + // A column out of range doesn't have a flow thread portion, so we need to clamp to make sure
|
| + // that we stay within the actual columns. This means that content in the overflow area will be
|
| + // mapped to the last actual column, instead of being mapped to an imaginary column further
|
| + // ahead.
|
| + unsigned columnIndex = offsetInFlowThread >= logicalBottomInFlowThread() ? actualColumnCount() - 1 : columnIndexAtOffset(offsetInFlowThread, rule);
|
| +
|
| LayoutRect portionRect(flowThreadPortionRectAt(columnIndex));
|
| flowThread->flipForWritingMode(portionRect);
|
| LayoutRect columnRect(columnRectAt(columnIndex));
|
| @@ -117,11 +123,11 @@ LayoutSize MultiColumnFragmentainerGroup::flowThreadTranslationAtOffset(LayoutUn
|
| // 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(firstRow.blockOffsetInEnclosingFragmentationContext(), mode);
|
| + LayoutSize enclosingTranslationOrigin = enclosingFlowThread->flowThreadTranslationAtOffset(firstRow.blockOffsetInEnclosingFragmentationContext(), LayoutBox::AssociateWithLatterPage, mode);
|
|
|
| // 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(blockOffsetInEnclosingFragmentationContext(), mode);
|
| + enclosingTranslation = enclosingFlowThread->flowThreadTranslationAtOffset(blockOffsetInEnclosingFragmentationContext(), LayoutBox::AssociateWithLatterPage, mode);
|
|
|
| // 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
|
| @@ -137,7 +143,7 @@ LayoutSize MultiColumnFragmentainerGroup::flowThreadTranslationAtOffset(LayoutUn
|
|
|
| LayoutUnit MultiColumnFragmentainerGroup::columnLogicalTopForOffset(LayoutUnit offsetInFlowThread) const
|
| {
|
| - unsigned columnIndex = columnIndexAtOffset(offsetInFlowThread, AssumeNewColumns);
|
| + unsigned columnIndex = columnIndexAtOffset(offsetInFlowThread, LayoutBox::AssociateWithLatterPage);
|
| return logicalTopInFlowThreadAt(columnIndex);
|
| }
|
|
|
| @@ -187,7 +193,7 @@ LayoutRect MultiColumnFragmentainerGroup::fragmentsBoundingBox(const LayoutRect&
|
| flowThread->flipForWritingMode(startColumnFlowThreadOverflowPortion);
|
| LayoutRect startColumnRect(boundingBoxInFlowThread);
|
| startColumnRect.intersect(startColumnFlowThreadOverflowPortion);
|
| - startColumnRect.move(flowThreadTranslationAtOffset(logicalTopInFlowThreadAt(startColumn), CoordinateSpaceConversion::Containing));
|
| + startColumnRect.move(flowThreadTranslationAtOffset(logicalTopInFlowThreadAt(startColumn), LayoutBox::AssociateWithLatterPage, CoordinateSpaceConversion::Containing));
|
| if (startColumn == endColumn)
|
| return startColumnRect; // It all takes place in one column. We're done.
|
|
|
| @@ -195,7 +201,7 @@ LayoutRect MultiColumnFragmentainerGroup::fragmentsBoundingBox(const LayoutRect&
|
| flowThread->flipForWritingMode(endColumnFlowThreadOverflowPortion);
|
| LayoutRect endColumnRect(boundingBoxInFlowThread);
|
| endColumnRect.intersect(endColumnFlowThreadOverflowPortion);
|
| - endColumnRect.move(flowThreadTranslationAtOffset(logicalTopInFlowThreadAt(endColumn), CoordinateSpaceConversion::Containing));
|
| + endColumnRect.move(flowThreadTranslationAtOffset(logicalTopInFlowThreadAt(endColumn), LayoutBox::AssociateWithLatterPage, CoordinateSpaceConversion::Containing));
|
| return unionRect(startColumnRect, endColumnRect);
|
| }
|
|
|
| @@ -385,21 +391,22 @@ LayoutRect MultiColumnFragmentainerGroup::flowThreadPortionOverflowRectAt(unsign
|
| return overflowRect;
|
| }
|
|
|
| -unsigned MultiColumnFragmentainerGroup::columnIndexAtOffset(LayoutUnit offsetInFlowThread, ColumnIndexCalculationMode mode) const
|
| +unsigned MultiColumnFragmentainerGroup::columnIndexAtOffset(LayoutUnit offsetInFlowThread, LayoutBox::PageBoundaryRule pageBoundaryRule) const
|
| {
|
| // Handle the offset being out of range.
|
| if (offsetInFlowThread < m_logicalTopInFlowThread)
|
| return 0;
|
| - // If we're laying out right now, we cannot constrain against some logical bottom, since it
|
| - // isn't known yet. Otherwise, just return the last column if we're past the logical bottom.
|
| - if (mode == ClampToExistingColumns) {
|
| - if (offsetInFlowThread >= m_logicalBottomInFlowThread)
|
| - return actualColumnCount() - 1;
|
| - }
|
|
|
| - if (m_columnHeight)
|
| - return ((offsetInFlowThread - m_logicalTopInFlowThread) / m_columnHeight).floor();
|
| - return 0;
|
| + if (!m_columnHeight)
|
| + return 0;
|
| + unsigned columnIndex = ((offsetInFlowThread - m_logicalTopInFlowThread) / m_columnHeight).floor();
|
| + if (pageBoundaryRule == LayoutBox::AssociateWithFormerPage
|
| + && columnIndex > 0 && logicalTopInFlowThreadAt(columnIndex) == offsetInFlowThread) {
|
| + // We are exactly at a column boundary, and we've been told to associate offsets at column
|
| + // boundaries with the former column, not the latter.
|
| + columnIndex--;
|
| + }
|
| + return columnIndex;
|
| }
|
|
|
| unsigned MultiColumnFragmentainerGroup::columnIndexAtVisualPoint(const LayoutPoint& visualPoint) const
|
| @@ -422,12 +429,11 @@ unsigned MultiColumnFragmentainerGroup::columnIndexAtVisualPoint(const LayoutPoi
|
|
|
| void MultiColumnFragmentainerGroup::columnIntervalForBlockRangeInFlowThread(LayoutUnit logicalTopInFlowThread, LayoutUnit logicalBottomInFlowThread, unsigned& firstColumn, unsigned& lastColumn) const
|
| {
|
| + logicalTopInFlowThread = std::max(logicalTopInFlowThread, this->logicalTopInFlowThread());
|
| + logicalBottomInFlowThread = std::min(logicalBottomInFlowThread, this->logicalBottomInFlowThread());
|
| ASSERT(logicalTopInFlowThread <= logicalBottomInFlowThread);
|
| - firstColumn = columnIndexAtOffset(logicalTopInFlowThread);
|
| - lastColumn = columnIndexAtOffset(logicalBottomInFlowThread);
|
| - // logicalBottomInFlowThread is an exclusive endpoint, so some additional adjustments may be necessary.
|
| - if (lastColumn > firstColumn && logicalTopInFlowThreadAt(lastColumn) == logicalBottomInFlowThread)
|
| - lastColumn--;
|
| + firstColumn = columnIndexAtOffset(logicalTopInFlowThread, LayoutBox::AssociateWithLatterPage);
|
| + lastColumn = columnIndexAtOffset(logicalBottomInFlowThread, LayoutBox::AssociateWithFormerPage);
|
| }
|
|
|
| void MultiColumnFragmentainerGroup::columnIntervalForVisualRect(const LayoutRect& rect, unsigned& firstColumn, unsigned& lastColumn) const
|
|
|