Chromium Code Reviews| Index: third_party/WebKit/Source/core/layout/ColumnBalancer.cpp |
| diff --git a/third_party/WebKit/Source/core/layout/ColumnBalancer.cpp b/third_party/WebKit/Source/core/layout/ColumnBalancer.cpp |
| index 92caebf9aa6fb8b0dd83e7c294545f88e9b9fd60..1c07bf8899978955883769dbcbe2bdb2f0824cf8 100644 |
| --- a/third_party/WebKit/Source/core/layout/ColumnBalancer.cpp |
| +++ b/third_party/WebKit/Source/core/layout/ColumnBalancer.cpp |
| @@ -143,10 +143,28 @@ InitialColumnHeightFinder::InitialColumnHeightFinder( |
| } |
| LayoutUnit InitialColumnHeightFinder::initialMinimalBalancedHeight() const { |
| + LayoutUnit rowLogicalTop; |
| + if (m_contentRuns.size() > columnSet().usedColumnCount()) { |
| + // We have not inserted additional fragmentainer groups yet (because we |
| + // aren't able to calculate their constraints yet), but we already know for |
| + // sure that there'll be more than one of them, due to the number of forced |
| + // breaks in a nested multicol container. We will now attempt to take all |
| + // the imaginary rows into account and calculate a minimal balanced logical |
| + // height for everything. |
| + unsigned stride = columnSet().usedColumnCount(); |
| + LayoutUnit rowStartOffset = logicalTopInFlowThread(); |
| + for (unsigned i = 0; i < firstContentRunIndexInLastRow(); i += stride) { |
| + LayoutUnit rowEndOffset = m_contentRuns[i + stride - 1].breakOffset(); |
| + float rowHeight = float(rowEndOffset - rowStartOffset) / float(stride); |
| + rowLogicalTop += LayoutUnit::fromFloatCeil(rowHeight); |
|
eae
2016/11/10 23:37:12
why ceil?
mstensho (USE GERRIT)
2016/11/11 08:47:46
That's what InitialColumnHeightFinder::ContentRun:
|
| + rowStartOffset = rowEndOffset; |
| + } |
| + } |
| unsigned index = contentRunIndexWithTallestColumns(); |
| LayoutUnit startOffset = index > 0 ? m_contentRuns[index - 1].breakOffset() |
| : logicalTopInFlowThread(); |
| - return m_contentRuns[index].columnLogicalHeight(startOffset); |
| + LayoutUnit height = m_contentRuns[index].columnLogicalHeight(startOffset); |
| + return rowLogicalTop + std::max(height, m_tallestUnbreakableLogicalHeight); |
| } |
| void InitialColumnHeightFinder::examineBoxAfterEntering( |
| @@ -255,9 +273,17 @@ void InitialColumnHeightFinder::addContentRun( |
| endOffsetInFlowThread <= m_contentRuns.last().breakOffset()) |
| return; |
| // Append another item as long as we haven't exceeded used column count. What |
| - // ends up in the overflow area shouldn't affect column balancing. |
| - if (m_contentRuns.size() < columnSet().usedColumnCount()) |
| - m_contentRuns.append(ContentRun(endOffsetInFlowThread)); |
| + // ends up in the overflow area shouldn't affect column balancing. However, if |
| + // we're in a nested fragmentation context, we may still need to record all |
| + // runs, since there'll be no overflow area in the inline direction then, but |
| + // rather additional rows of columns in multiple outer fragmentainers. |
| + if (m_contentRuns.size() >= columnSet().usedColumnCount()) { |
| + const auto* flowThread = columnSet().multiColumnFlowThread(); |
| + if (!flowThread->enclosingFragmentationContext() || |
| + columnSet().newFragmentainerGroupsAllowed()) |
| + return; |
| + } |
| + m_contentRuns.append(ContentRun(endOffsetInFlowThread)); |
| } |
| unsigned InitialColumnHeightFinder::contentRunIndexWithTallestColumns() const { |
| @@ -266,7 +292,7 @@ unsigned InitialColumnHeightFinder::contentRunIndexWithTallestColumns() const { |
| LayoutUnit previousOffset = logicalTopInFlowThread(); |
| size_t runCount = m_contentRuns.size(); |
| ASSERT(runCount); |
| - for (size_t i = 0; i < runCount; i++) { |
| + for (size_t i = firstContentRunIndexInLastRow(); i < runCount; i++) { |
| const ContentRun& run = m_contentRuns[i]; |
| LayoutUnit height = run.columnLogicalHeight(previousOffset); |
| if (largestHeight < height) { |
| @@ -291,6 +317,18 @@ void InitialColumnHeightFinder::distributeImplicitBreaks() { |
| // 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. |
| + if (columnCount > columnSet().usedColumnCount()) { |
| + // If we exceed used column-count (which we are allowed to do if we're at |
| + // the initial balancing pass for a multicol that lives inside another |
| + // to-be-balanced outer multicol container), we only care about content that |
| + // could end up in the last row. We need to pad up the number of columns, so |
| + // that all rows will contain as many columns as used column-count dictates. |
| + columnCount %= columnSet().usedColumnCount(); |
| + // If there are just enough explicit breaks to fill all rows with the right |
| + // amount of columns, we won't be needing any implicit breaks. |
| + if (!columnCount) |
| + return; |
| + } |
| while (columnCount < columnSet().usedColumnCount()) { |
| unsigned index = contentRunIndexWithTallestColumns(); |
| m_contentRuns[index].assumeAnotherImplicitBreak(); |