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

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

Issue 147233002: Remove internal recursion for RenderBlockFlow and RenderMultiColumnBlock layout (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebase to apply on latest trunk Created 6 years, 11 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/RenderBlockFlow.h ('k') | Source/core/rendering/RenderMultiColumnBlock.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/rendering/RenderBlockFlow.cpp
diff --git a/Source/core/rendering/RenderBlockFlow.cpp b/Source/core/rendering/RenderBlockFlow.cpp
index 0f3b3fee6997603689ee58c369c66c8cf0a0ca94..bc24ebc7121b36e2f0b03bda1f9a346a7723c706 100644
--- a/Source/core/rendering/RenderBlockFlow.cpp
+++ b/Source/core/rendering/RenderBlockFlow.cpp
@@ -38,6 +38,7 @@
#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/LayoutRepainter.h"
#include "core/rendering/RenderLayer.h"
+#include "core/rendering/RenderMultiColumnBlock.h"
#include "core/rendering/RenderNamedFlowFragment.h"
#include "core/rendering/RenderNamedFlowThread.h"
#include "core/rendering/RenderText.h"
@@ -219,57 +220,45 @@ void RenderBlockFlow::checkForPaginationLogicalHeightChange(LayoutUnit& pageLogi
}
}
-bool RenderBlockFlow::relayoutForPagination(bool hasSpecifiedPageLogicalHeight, LayoutUnit pageLogicalHeight, LayoutStateMaintainer& statePusher)
+bool RenderBlockFlow::shouldRelayoutForPagination(LayoutUnit& pageLogicalHeight, LayoutUnit layoutOverflowLogicalBottom) const
{
- if (!hasColumns())
- return false;
-
- OwnPtr<RenderOverflow> savedOverflow = m_overflow.release();
- if (childrenInline())
- addOverflowFromInlineChildren();
- else
- addOverflowFromBlockChildren();
- LayoutUnit layoutOverflowLogicalBottom = (isHorizontalWritingMode() ? layoutOverflowRect().maxY() : layoutOverflowRect().maxX()) - borderBefore() - paddingBefore();
-
// FIXME: We don't balance properly at all in the presence of forced page breaks. We need to understand what
// the distance between forced page breaks is so that we can avoid making the minimum column height too tall.
ColumnInfo* colInfo = columnInfo();
- if (!hasSpecifiedPageLogicalHeight) {
- LayoutUnit columnHeight = pageLogicalHeight;
- int minColumnCount = colInfo->forcedBreaks() + 1;
- int desiredColumnCount = colInfo->desiredColumnCount();
- if (minColumnCount >= desiredColumnCount) {
- // The forced page breaks are in control of the balancing. Just set the column height to the
- // maximum page break distance.
- if (!pageLogicalHeight) {
- LayoutUnit distanceBetweenBreaks = max<LayoutUnit>(colInfo->maximumDistanceBetweenForcedBreaks(),
- view()->layoutState()->pageLogicalOffset(this, borderBefore() + paddingBefore() + layoutOverflowLogicalBottom) - colInfo->forcedBreakOffset());
- columnHeight = max(colInfo->minimumColumnHeight(), distanceBetweenBreaks);
- }
- } else if (layoutOverflowLogicalBottom > boundedMultiply(pageLogicalHeight, desiredColumnCount)) {
- // Now that we know the intrinsic height of the columns, we have to rebalance them.
- columnHeight = max<LayoutUnit>(colInfo->minimumColumnHeight(), ceilf((float)layoutOverflowLogicalBottom / desiredColumnCount));
+ LayoutUnit columnHeight = pageLogicalHeight;
+ const int minColumnCount = colInfo->forcedBreaks() + 1;
+ const int desiredColumnCount = colInfo->desiredColumnCount();
+ if (minColumnCount >= desiredColumnCount) {
+ // The forced page breaks are in control of the balancing. Just set the column height to the
+ // maximum page break distance.
+ if (!pageLogicalHeight) {
+ LayoutUnit distanceBetweenBreaks = max<LayoutUnit>(colInfo->maximumDistanceBetweenForcedBreaks(),
+ view()->layoutState()->pageLogicalOffset(this, borderBefore() + paddingBefore() + layoutOverflowLogicalBottom) - colInfo->forcedBreakOffset());
+ columnHeight = max(colInfo->minimumColumnHeight(), distanceBetweenBreaks);
}
+ } else if (layoutOverflowLogicalBottom > boundedMultiply(pageLogicalHeight, desiredColumnCount)) {
+ // Now that we know the intrinsic height of the columns, we have to rebalance them.
+ columnHeight = max<LayoutUnit>(colInfo->minimumColumnHeight(), ceilf((float)layoutOverflowLogicalBottom / desiredColumnCount));
+ }
- if (columnHeight && columnHeight != pageLogicalHeight) {
- statePusher.pop();
- setEverHadLayout(true);
- layoutBlockFlow(false, columnHeight);
- return true;
- }
+ if (columnHeight && columnHeight != pageLogicalHeight) {
+ pageLogicalHeight = columnHeight;
+ return true;
}
+ return false;
+}
+
+void RenderBlockFlow::setColumnCountAndHeight(unsigned count, LayoutUnit pageLogicalHeight)
+{
+ ColumnInfo* colInfo = columnInfo();
if (pageLogicalHeight)
- colInfo->setColumnCountAndHeight(ceilf((float)layoutOverflowLogicalBottom / pageLogicalHeight), pageLogicalHeight);
+ colInfo->setColumnCountAndHeight(count, pageLogicalHeight);
if (columnCount(colInfo)) {
setLogicalHeight(borderBefore() + paddingBefore() + colInfo->columnHeight() + borderAfter() + paddingAfter() + scrollbarLogicalHeight());
m_overflow.clear();
- } else {
- m_overflow = savedOverflow.release();
}
-
- return false;
}
bool RenderBlockFlow::isSelfCollapsingBlock() const
@@ -280,11 +269,6 @@ bool RenderBlockFlow::isSelfCollapsingBlock() const
void RenderBlockFlow::layoutBlock(bool relayoutChildren)
{
- layoutBlockFlow(relayoutChildren);
-}
-
-inline void RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit pageLogicalHeight)
-{
ASSERT(needsLayout());
ASSERT(isInlineBlockOrInlineTable() || !isInline());
@@ -296,6 +280,20 @@ inline void RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit p
if (!relayoutChildren && simplifiedLayout())
return;
+ SubtreeLayoutScope layoutScope(this);
+
+ // Multiple passes might be required for column and pagination based layout
+ // In the case of the old column code the number of passes will only be two
+ // however, in the newer column code the number of passes could equal the
+ // number of columns.
+ bool done = false;
+ LayoutUnit pageLogicalHeight = 0;
+ while (!done)
+ done = layoutBlockFlow(relayoutChildren, pageLogicalHeight, layoutScope);
+}
+
+inline bool RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit &pageLogicalHeight, SubtreeLayoutScope& layoutScope)
+{
LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
if (updateLogicalWidthAndColumnWidth())
@@ -336,8 +334,6 @@ inline void RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit p
setPaginationStrut(0);
}
- SubtreeLayoutScope layoutScope(this);
-
LayoutUnit beforeEdge = borderBefore() + paddingBefore();
LayoutUnit afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeight();
LayoutUnit previousHeight = logicalHeight();
@@ -363,16 +359,41 @@ inline void RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit p
if (frameView()->partialLayout().isStopping()) {
statePusher.pop();
- return;
+ return true;
}
// Expand our intrinsic height to encompass floats.
if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) && createsBlockFormattingContext())
setLogicalHeight(lowestFloatLogicalBottom() + afterEdge);
- if (relayoutForPagination(hasSpecifiedPageLogicalHeight, pageLogicalHeight, statePusher) || relayoutToAvoidWidows(statePusher)) {
- ASSERT(!shouldBreakAtLineToAvoidWidow());
- return;
+ if (isRenderMultiColumnBlock()) {
+ if (toRenderMultiColumnBlock(this)->shouldRelayoutMultiColumnBlock()) {
+ setChildNeedsLayout(MarkOnlyThis);
+ statePusher.pop();
+ return false;
+ }
+ } else if (hasColumns()) {
+ OwnPtr<RenderOverflow> savedOverflow = m_overflow.release();
+ if (childrenInline())
+ addOverflowFromInlineChildren();
+ else
+ addOverflowFromBlockChildren();
+ LayoutUnit layoutOverflowLogicalBottom = (isHorizontalWritingMode() ? layoutOverflowRect().maxY() : layoutOverflowRect().maxX()) - borderBefore() - paddingBefore();
+ m_overflow = savedOverflow.release();
+
+ if (!hasSpecifiedPageLogicalHeight && shouldRelayoutForPagination(pageLogicalHeight, layoutOverflowLogicalBottom)) {
+ statePusher.pop();
+ setEverHadLayout(true);
+ return false;
+ }
+
+ setColumnCountAndHeight(ceilf((float)layoutOverflowLogicalBottom / pageLogicalHeight), pageLogicalHeight);
+ }
+
+ if (shouldBreakAtLineToAvoidWidow()) {
+ statePusher.pop();
+ setEverHadLayout(true);
+ return false;
}
// Calculate our new height.
@@ -415,7 +436,7 @@ inline void RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit p
fitBorderToLinesIfNeeded();
if (frameView()->partialLayout().isStopping())
- return;
+ return true;
if (renderView->layoutState()->m_pageLogicalHeight)
setPageLogicalOffset(renderView->layoutState()->pageLogicalOffset(this, logicalTop()));
@@ -436,6 +457,7 @@ inline void RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit p
}
clearNeedsLayout();
+ return true;
}
void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom)
« no previous file with comments | « Source/core/rendering/RenderBlockFlow.h ('k') | Source/core/rendering/RenderMultiColumnBlock.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698