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

Unified Diff: third_party/WebKit/Source/core/layout/ColumnBalancer.cpp

Issue 1891783002: Support multiple fragmentainer groups per ColumnBalancer run. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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
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 45607bdde8b166eb4b9092b18e8d059939e91489..1ba071994ee615703c926bdedf4bb874cca748d3 100644
--- a/third_party/WebKit/Source/core/layout/ColumnBalancer.cpp
+++ b/third_party/WebKit/Source/core/layout/ColumnBalancer.cpp
@@ -10,15 +10,17 @@
namespace blink {
-ColumnBalancer::ColumnBalancer(const MultiColumnFragmentainerGroup& group)
- : m_group(group)
+ColumnBalancer::ColumnBalancer(const LayoutMultiColumnSet& columnSet, LayoutUnit logicalTopInFlowThread, LayoutUnit logicalBottomInFlowThread)
+ : m_columnSet(columnSet)
+ , m_logicalTopInFlowThread(logicalTopInFlowThread)
+ , m_logicalBottomInFlowThread(logicalBottomInFlowThread)
, m_previousBreakAfterValue(BreakAuto)
{
}
void ColumnBalancer::traverse()
{
- traverseSubtree(*m_group.columnSet().flowThread());
+ traverseSubtree(*columnSet().flowThread());
ASSERT(!flowThreadOffset());
}
@@ -28,15 +30,15 @@ void ColumnBalancer::traverseSubtree(const LayoutBox& box)
// Look for breaks between lines.
for (const RootInlineBox* line = toLayoutBlockFlow(box).firstRootBox(); line; line = line->nextRootBox()) {
LayoutUnit lineTopInFlowThread = m_flowThreadOffset + line->lineTopWithLeading();
- if (lineTopInFlowThread < group().logicalTopInFlowThread())
+ if (lineTopInFlowThread < logicalTopInFlowThread())
continue;
- if (lineTopInFlowThread >= group().logicalBottomInFlowThread())
+ if (lineTopInFlowThread >= logicalBottomInFlowThread())
break;
examineLine(*line);
}
}
- const LayoutFlowThread* flowThread = group().columnSet().flowThread();
+ const LayoutFlowThread* flowThread = columnSet().flowThread();
bool isHorizontalWritingMode = flowThread->isHorizontalWritingMode();
// Look for breaks between and inside block-level children. Even if this is a block flow with
@@ -47,13 +49,13 @@ void ColumnBalancer::traverseSubtree(const LayoutBox& box)
const LayoutBox& childBox = toLayoutBox(*child);
LayoutRect overflowRect = childBox.layoutOverflowRect();
LayoutUnit childLogicalBottomWithOverflow = childBox.logicalTop() + (isHorizontalWritingMode ? overflowRect.maxY() : overflowRect.maxX());
- if (m_flowThreadOffset + childLogicalBottomWithOverflow <= group().logicalTopInFlowThread()) {
- // This child is fully above the fragmentainer group we're examining.
+ if (m_flowThreadOffset + childLogicalBottomWithOverflow <= logicalTopInFlowThread()) {
+ // This child is fully above the flow thread portion we're examining.
continue;
}
LayoutUnit childLogicalTopWithOverflow = childBox.logicalTop() + (isHorizontalWritingMode ? overflowRect.y() : overflowRect.x());
- if (m_flowThreadOffset + childLogicalTopWithOverflow >= group().logicalBottomInFlowThread()) {
- // This child is fully below the fragmentainer group we're examining. We cannot just
+ if (m_flowThreadOffset + childLogicalTopWithOverflow >= logicalBottomInFlowThread()) {
+ // This child is fully below the flow thread portion we're examining. We cannot just
// stop here, though, thanks to negative margins. So keep looking.
continue;
}
@@ -77,10 +79,10 @@ void ColumnBalancer::traverseSubtree(const LayoutBox& box)
}
}
-InitialColumnHeightFinder::InitialColumnHeightFinder(const MultiColumnFragmentainerGroup& group)
- : ColumnBalancer(group)
+InitialColumnHeightFinder::InitialColumnHeightFinder(const LayoutMultiColumnSet& columnSet, LayoutUnit logicalTopInFlowThread, LayoutUnit logicalBottomInFlowThread)
+ : ColumnBalancer(columnSet, logicalTopInFlowThread, logicalBottomInFlowThread)
{
- m_shortestStruts.resize(group.columnSet().usedColumnCount());
+ m_shortestStruts.resize(columnSet.usedColumnCount());
for (auto& strut : m_shortestStruts)
strut = LayoutUnit::max();
traverse();
@@ -93,7 +95,7 @@ InitialColumnHeightFinder::InitialColumnHeightFinder(const MultiColumnFragmentai
LayoutUnit InitialColumnHeightFinder::initialMinimalBalancedHeight() const
{
unsigned index = contentRunIndexWithTallestColumns();
- LayoutUnit startOffset = index > 0 ? m_contentRuns[index - 1].breakOffset() : group().logicalTopInFlowThread();
+ LayoutUnit startOffset = index > 0 ? m_contentRuns[index - 1].breakOffset() : logicalTopInFlowThread();
return m_contentRuns[index].columnLogicalHeight(startOffset);
}
@@ -157,11 +159,10 @@ void InitialColumnHeightFinder::examineLine(const RootInlineBox& line)
void InitialColumnHeightFinder::recordStrutBeforeOffset(LayoutUnit offsetInFlowThread, LayoutUnit strut)
{
- const LayoutMultiColumnSet& columnSet = group().columnSet();
- ASSERT(columnSet.usedColumnCount() >= 1);
- unsigned columnCount = columnSet.usedColumnCount();
+ ASSERT(columnSet().usedColumnCount() >= 1);
+ unsigned columnCount = columnSet().usedColumnCount();
ASSERT(m_shortestStruts.size() == columnCount);
- unsigned index = group().columnIndexAtOffset(offsetInFlowThread - strut, MultiColumnFragmentainerGroup::AssumeNewColumns);
+ unsigned index = groupAtOffset(offsetInFlowThread).columnIndexAtOffset(offsetInFlowThread - strut, MultiColumnFragmentainerGroup::AssumeNewColumns);
if (index >= columnCount)
return;
m_shortestStruts[index] = std::min(m_shortestStruts[index], strut);
@@ -169,8 +170,8 @@ void InitialColumnHeightFinder::recordStrutBeforeOffset(LayoutUnit offsetInFlowT
LayoutUnit InitialColumnHeightFinder::spaceUsedByStrutsAt(LayoutUnit offsetInFlowThread) const
{
- unsigned stopBeforeColumn = group().columnIndexAtOffset(offsetInFlowThread, MultiColumnFragmentainerGroup::AssumeNewColumns) + 1;
- stopBeforeColumn = std::min(stopBeforeColumn, group().columnSet().usedColumnCount());
+ unsigned stopBeforeColumn = groupAtOffset(offsetInFlowThread).columnIndexAtOffset(offsetInFlowThread, MultiColumnFragmentainerGroup::AssumeNewColumns) + 1;
+ stopBeforeColumn = std::min(stopBeforeColumn, columnSet().usedColumnCount());
ASSERT(stopBeforeColumn <= m_shortestStruts.size());
LayoutUnit totalStrutSpace;
for (unsigned i = 0; i < stopBeforeColumn; i++) {
@@ -187,7 +188,7 @@ void InitialColumnHeightFinder::addContentRun(LayoutUnit endOffsetInFlowThread)
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() < group().columnSet().usedColumnCount())
+ if (m_contentRuns.size() < columnSet().usedColumnCount())
m_contentRuns.append(ContentRun(endOffsetInFlowThread));
}
@@ -195,7 +196,7 @@ unsigned InitialColumnHeightFinder::contentRunIndexWithTallestColumns() const
{
unsigned indexWithLargestHeight = 0;
LayoutUnit largestHeight;
- LayoutUnit previousOffset = group().logicalTopInFlowThread();
+ LayoutUnit previousOffset = logicalTopInFlowThread();
size_t runCount = m_contentRuns.size();
ASSERT(runCount);
for (size_t i = 0; i < runCount; i++) {
@@ -212,9 +213,9 @@ unsigned InitialColumnHeightFinder::contentRunIndexWithTallestColumns() const
void InitialColumnHeightFinder::distributeImplicitBreaks()
{
- // Insert a final content run to encompass all content. This will include overflow if this is
- // the last group in the multicol container.
- addContentRun(group().logicalBottomInFlowThread());
+ // Insert a final content run to encompass all content. This will include overflow if we're at
+ // the end of the multicol container.
+ addContentRun(logicalBottomInFlowThread());
unsigned columnCount = m_contentRuns.size();
// If there is room for more breaks (to reach the used value of column-count), imagine that we
@@ -223,15 +224,15 @@ void InitialColumnHeightFinder::distributeImplicitBreaks()
// column count by one and 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.
- while (columnCount < group().columnSet().usedColumnCount()) {
+ while (columnCount < columnSet().usedColumnCount()) {
unsigned index = contentRunIndexWithTallestColumns();
m_contentRuns[index].assumeAnotherImplicitBreak();
columnCount++;
}
}
-MinimumSpaceShortageFinder::MinimumSpaceShortageFinder(const MultiColumnFragmentainerGroup& group)
- : ColumnBalancer(group)
+MinimumSpaceShortageFinder::MinimumSpaceShortageFinder(const LayoutMultiColumnSet& columnSet, LayoutUnit logicalTopInFlowThread, LayoutUnit logicalBottomInFlowThread)
+ : ColumnBalancer(columnSet, logicalTopInFlowThread, logicalBottomInFlowThread)
, m_minimumSpaceShortage(LayoutUnit::max())
, m_pendingStrut(LayoutUnit::min())
, m_forcedBreaksCount(0)
@@ -269,14 +270,15 @@ void MinimumSpaceShortageFinder::examineBoxAfterEntering(const LayoutBox& box)
if (breakability != LayoutBox::ForbidBreaks) {
// See if this breakable box crosses column boundaries.
LayoutUnit bottomInFlowThread = flowThreadOffset() + box.logicalHeight();
+ const MultiColumnFragmentainerGroup& group = groupAtOffset(flowThreadOffset());
if (isFirstAfterBreak(flowThreadOffset())
- || group().columnLogicalTopForOffset(flowThreadOffset()) != group().columnLogicalTopForOffset(bottomInFlowThread)) {
+ || group.columnLogicalTopForOffset(flowThreadOffset()) != group.columnLogicalTopForOffset(bottomInFlowThread)) {
// If the child crosses a column boundary, record space shortage, in case nothing
// inside it has already done so. The column balancer needs to know by how much it
// has to stretch the columns to make more content fit. If no breaks are reported
// (but do occur), the balancer will have no clue. Only measure the space after the
// last column boundary, in case it crosses more than one.
- LayoutUnit spaceUsedInLastColumn = bottomInFlowThread - group().columnLogicalTopForOffset(bottomInFlowThread);
+ LayoutUnit spaceUsedInLastColumn = bottomInFlowThread - group.columnLogicalTopForOffset(bottomInFlowThread);
recordSpaceShortage(spaceUsedInLastColumn);
}
}
@@ -288,10 +290,12 @@ void MinimumSpaceShortageFinder::examineBoxAfterEntering(const LayoutBox& box)
if (!flowThread || flowThread->isLayoutPagedFlowThread())
return;
for (const LayoutMultiColumnSet* columnSet = flowThread->firstMultiColumnSet(); columnSet; columnSet = columnSet->nextSiblingMultiColumnSet()) {
- for (const MultiColumnFragmentainerGroup& row : columnSet->fragmentainerGroups()) {
- MinimumSpaceShortageFinder innerFinder(row);
- recordSpaceShortage(innerFinder.minimumSpaceShortage());
- }
+ // Establish an inner shortage finder for this column set in the inner multicol
+ // container. We need to let it walk through all fragmentainer groups in one go, or we'd
+ // miss the column boundaries between each fragmentainer group. We need to record space
+ // shortage there too.
+ MinimumSpaceShortageFinder innerFinder(*columnSet, columnSet->logicalTopInFlowThread(), columnSet->logicalBottomInFlowThread());
+ recordSpaceShortage(innerFinder.minimumSpaceShortage());
}
}
@@ -303,7 +307,7 @@ void MinimumSpaceShortageFinder::examineBoxBeforeLeaving(const LayoutBox& box)
// The previous break was before a breakable block. Here's the first piece of unbreakable
// content after / inside that block. We want to record the distance from the top of the column
// to the bottom of this box as space shortage.
- LayoutUnit logicalOffsetFromCurrentColumn = flowThreadOffset() - group().columnLogicalTopForOffset(flowThreadOffset());
+ LayoutUnit logicalOffsetFromCurrentColumn = offsetFromColumnLogicalTop(flowThreadOffset());
recordSpaceShortage(logicalOffsetFromCurrentColumn + box.logicalHeight() - m_pendingStrut);
m_pendingStrut = LayoutUnit::min();
}
@@ -317,7 +321,7 @@ void MinimumSpaceShortageFinder::examineLine(const RootInlineBox& line)
// The previous break was before a breakable block. Here's the first line after / inside
// that block. We want to record the distance from the top of the column to the bottom of
// this box as space shortage.
- LayoutUnit logicalOffsetFromCurrentColumn = lineTopInFlowThread - group().columnLogicalTopForOffset(lineTopInFlowThread);
+ LayoutUnit logicalOffsetFromCurrentColumn = offsetFromColumnLogicalTop(lineTopInFlowThread);
recordSpaceShortage(logicalOffsetFromCurrentColumn + lineHeight - m_pendingStrut);
m_pendingStrut = LayoutUnit::min();
return;
@@ -329,9 +333,10 @@ void MinimumSpaceShortageFinder::examineLine(const RootInlineBox& line)
// Even if the line box itself fits fine inside a column, some content may overflow the line
// box bottom (due to restrictive line-height, for instance). We should check if some portion
// of said overflow ends up in the next column. That counts as space shortage.
+ const MultiColumnFragmentainerGroup& group = groupAtOffset(lineTopInFlowThread);
LayoutUnit lineBottomWithOverflow = lineTopInFlowThread + line.lineBottom() - lineTop;
- if (group().columnLogicalTopForOffset(lineTopInFlowThread) != group().columnLogicalTopForOffset(lineBottomWithOverflow)) {
- LayoutUnit shortage = lineBottomWithOverflow - group().columnLogicalTopForOffset(lineBottomWithOverflow);
+ if (group.columnLogicalTopForOffset(lineTopInFlowThread) != group.columnLogicalTopForOffset(lineBottomWithOverflow)) {
+ LayoutUnit shortage = lineBottomWithOverflow - group.columnLogicalTopForOffset(lineBottomWithOverflow);
recordSpaceShortage(shortage);
}
}

Powered by Google App Engine
This is Rietveld 408576698