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

Unified Diff: Source/core/rendering/RenderMultiColumnFlowThread.cpp

Issue 246403015: [New Multicolumn] Create RenderMultiColumnSet during renderer creation, not during layout. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebase master Created 6 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
« no previous file with comments | « Source/core/rendering/RenderMultiColumnFlowThread.h ('k') | Source/core/rendering/RenderMultiColumnSet.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/rendering/RenderMultiColumnFlowThread.cpp
diff --git a/Source/core/rendering/RenderMultiColumnFlowThread.cpp b/Source/core/rendering/RenderMultiColumnFlowThread.cpp
index e44bfdb6a500ff6f43c2c01e83f19428b9aba1ea..f5c8ab08213f7691ebc6c824d189992227c17135 100644
--- a/Source/core/rendering/RenderMultiColumnFlowThread.cpp
+++ b/Source/core/rendering/RenderMultiColumnFlowThread.cpp
@@ -52,6 +52,41 @@ RenderMultiColumnFlowThread* RenderMultiColumnFlowThread::createAnonymous(Docume
return renderer;
}
+RenderMultiColumnSet* RenderMultiColumnFlowThread::firstMultiColumnSet() const
+{
+ for (RenderObject* sibling = nextSibling(); sibling; sibling = sibling->nextSibling()) {
+ if (sibling->isRenderMultiColumnSet())
+ return toRenderMultiColumnSet(sibling);
+ }
+ return 0;
+}
+
+RenderMultiColumnSet* RenderMultiColumnFlowThread::lastMultiColumnSet() const
+{
+ for (RenderObject* sibling = multiColumnBlockFlow()->lastChild(); sibling; sibling = sibling->previousSibling()) {
+ if (sibling->isRenderMultiColumnSet())
+ return toRenderMultiColumnSet(sibling);
+ }
+ return 0;
+}
+
+void RenderMultiColumnFlowThread::addChild(RenderObject* newChild, RenderObject* beforeChild)
+{
+ RenderBlockFlow::addChild(newChild, beforeChild);
+ if (firstMultiColumnSet())
+ return;
+
+ // For now we only create one column set. It's created as soon as the multicol container gets
+ // any content at all.
+ RenderMultiColumnSet* newSet = RenderMultiColumnSet::createAnonymous(this, multiColumnBlockFlow()->style());
+
+ // Need to skip RenderBlockFlow's implementation of addChild(), or we'd get redirected right
+ // back here.
+ multiColumnBlockFlow()->RenderBlock::addChild(newSet);
+
+ invalidateRegions();
+}
+
void RenderMultiColumnFlowThread::populate()
{
RenderBlockFlow* multicolContainer = multiColumnBlockFlow();
@@ -67,12 +102,8 @@ void RenderMultiColumnFlowThread::evacuateAndDestroy()
RenderBlockFlow* multicolContainer = multiColumnBlockFlow();
// Remove all sets.
- for (RenderBox* sibling = nextSiblingBox(); sibling;) {
- RenderBox* nextSibling = sibling->nextSiblingBox();
- if (sibling->isRenderMultiColumnSet())
- sibling->destroy();
- sibling = nextSibling;
- }
+ while (RenderMultiColumnSet* columnSet = firstMultiColumnSet())
+ columnSet->destroy();
ASSERT(!previousSibling());
ASSERT(!nextSibling());
@@ -97,15 +128,11 @@ void RenderMultiColumnFlowThread::layoutColumns(bool relayoutChildren, SubtreeLa
// Update the dimensions of our regions before we lay out the flow thread.
// FIXME: Eventually this is going to get way more complicated, and we will be destroying regions
// instead of trying to keep them around.
- RenderBlockFlow* container = multiColumnBlockFlow();
bool shouldInvalidateRegions = false;
- for (RenderBox* childBox = container->firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
- if (childBox == this)
- continue;
-
- if (relayoutChildren || childBox->needsLayout()) {
- if (!m_inBalancingPass && childBox->isRenderMultiColumnSet())
- toRenderMultiColumnSet(childBox)->prepareForLayout();
+ for (RenderMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; columnSet = columnSet->nextSiblingMultiColumnSet()) {
+ if (relayoutChildren || columnSet->needsLayout()) {
+ if (!m_inBalancingPass)
+ columnSet->prepareForLayout();
shouldInvalidateRegions = true;
}
}
@@ -173,13 +200,10 @@ bool RenderMultiColumnFlowThread::recalculateColumnHeights()
// passes than that, though, but the number of retries should not exceed the number of
// columns, unless we have a bug.
bool needsRelayout = false;
- for (RenderBox* childBox = multiColumnBlockFlow()->firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
- if (childBox != this && childBox->isRenderMultiColumnSet()) {
- RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(childBox);
- if (multicolSet->recalculateBalancedHeight(!m_inBalancingPass)) {
- multicolSet->setChildNeedsLayout(MarkOnlyThis);
- needsRelayout = true;
- }
+ for (RenderMultiColumnSet* multicolSet = firstMultiColumnSet(); multicolSet; multicolSet = multicolSet->nextSiblingMultiColumnSet()) {
+ if (multicolSet->recalculateBalancedHeight(!m_inBalancingPass)) {
+ multicolSet->setChildNeedsLayout(MarkOnlyThis);
+ needsRelayout = true;
}
}
@@ -195,6 +219,30 @@ const char* RenderMultiColumnFlowThread::renderName() const
return "RenderMultiColumnFlowThread";
}
+void RenderMultiColumnFlowThread::addRegionToThread(RenderRegion* renderRegion)
+{
+ RenderMultiColumnSet* columnSet = toRenderMultiColumnSet(renderRegion);
+ if (RenderMultiColumnSet* nextSet = columnSet->nextSiblingMultiColumnSet()) {
+ RenderRegionList::iterator it = m_regionList.find(nextSet);
+ ASSERT(it != m_regionList.end());
+ m_regionList.insertBefore(it, columnSet);
+ } else {
+ m_regionList.add(columnSet);
+ }
+ renderRegion->setIsValid(true);
+}
+
+void RenderMultiColumnFlowThread::willBeRemovedFromTree()
+{
+ // Detach all column sets from the flow thread. Cannot destroy them at this point, since they
+ // are siblings of this object, and there may be pointers to this object's sibling somewhere
+ // further up on the call stack.
+ for (RenderMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; columnSet = columnSet->nextSiblingMultiColumnSet())
+ columnSet->detachRegion();
+ multiColumnBlockFlow()->resetMultiColumnFlowThread();
+ RenderFlowThread::willBeRemovedFromTree();
+}
+
void RenderMultiColumnFlowThread::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const
{
// We simply remain at our intrinsic height.
@@ -207,45 +255,6 @@ LayoutUnit RenderMultiColumnFlowThread::initialLogicalWidth() const
return columnWidth();
}
-void RenderMultiColumnFlowThread::autoGenerateRegionsToBlockOffset(LayoutUnit /*offset*/)
-{
- // This function ensures we have the correct column set information at all times.
- // For a simple multi-column layout in continuous media, only one column set child is required.
- // Once a column is nested inside an enclosing pagination context, the number of column sets
- // required becomes 2n-1, where n is the total number of nested pagination contexts. For example:
- //
- // Column layout with no enclosing pagination model = 2 * 1 - 1 = 1 column set.
- // Columns inside pages = 2 * 2 - 1 = 3 column sets (bottom of first page, all the subsequent pages, then the last page).
- // Columns inside columns inside pages = 2 * 3 - 1 = 5 column sets.
- //
- // In addition, column spans will force a column set to "split" into before/after sets around the spanning element.
- //
- // Finally, we will need to deal with columns inside regions. If regions have variable widths, then there will need
- // to be unique column sets created inside any region whose width is different from its surrounding regions. This is
- // actually pretty similar to the spanning case, in that we break up the column sets whenever the width varies.
- //
- // FIXME: For now just make one column set. This matches the old multi-column code.
- // Right now our goal is just feature parity with the old multi-column code so that we can switch over to the
- // new code as soon as possible.
- RenderMultiColumnSet* firstSet = toRenderMultiColumnSet(firstRegion());
- if (firstSet)
- return;
-
- invalidateRegions();
-
- RenderBlockFlow* parentBlock = multiColumnBlockFlow();
- firstSet = RenderMultiColumnSet::createAnonymous(this);
- firstSet->setStyle(RenderStyle::createAnonymousStyleWithDisplay(parentBlock->style(), BLOCK));
- parentBlock->RenderBlock::addChild(firstSet);
-
- // Even though we aren't placed yet, we can go ahead and set up our size. At this point we're
- // typically in the middle of laying out the thread, attempting to paginate, and we need to do
- // some rudimentary "layout" of the set now, so that pagination will work.
- firstSet->prepareForLayout();
-
- validateRegions();
-}
-
void RenderMultiColumnFlowThread::setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage)
{
if (RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(regionAtBlockOffset(offset)))
@@ -258,6 +267,12 @@ void RenderMultiColumnFlowThread::updateMinimumPageHeight(LayoutUnit offset, Lay
multicolSet->updateMinimumColumnHeight(minHeight);
}
+RenderRegion* RenderMultiColumnFlowThread::regionAtBlockOffset(LayoutUnit /*offset*/) const
+{
+ // For now there's only one column set, so this is easy:
+ return firstMultiColumnSet();
+}
+
bool RenderMultiColumnFlowThread::addForcedRegionBreak(LayoutUnit offset, RenderObject* /*breakChild*/, bool /*isBefore*/, LayoutUnit* offsetBreakAdjustment)
{
if (RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(regionAtBlockOffset(offset))) {
@@ -271,12 +286,9 @@ bool RenderMultiColumnFlowThread::addForcedRegionBreak(LayoutUnit offset, Render
bool RenderMultiColumnFlowThread::isPageLogicalHeightKnown() const
{
- for (RenderBox* renderer = parentBox()->lastChildBox(); renderer; renderer = renderer->previousSiblingBox()) {
- if (renderer->isRenderMultiColumnSet())
- return toRenderMultiColumnSet(renderer)->computedColumnHeight();
- }
- // A column set hasn't been created yet. Height may already be known if column-fill is 'auto', though.
- return !requiresBalancing();
+ if (RenderMultiColumnSet* columnSet = lastMultiColumnSet())
+ return columnSet->computedColumnHeight();
+ return false;
}
}
« no previous file with comments | « Source/core/rendering/RenderMultiColumnFlowThread.h ('k') | Source/core/rendering/RenderMultiColumnSet.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698