| Index: Source/core/rendering/RenderMultiColumnBlock.cpp
|
| diff --git a/Source/core/rendering/RenderMultiColumnBlock.cpp b/Source/core/rendering/RenderMultiColumnBlock.cpp
|
| index e4418294368262a56d2b6d0321e096ee391a754e..434fccd5b863f4eb007033a6c1ad26a8eea93018 100644
|
| --- a/Source/core/rendering/RenderMultiColumnBlock.cpp
|
| +++ b/Source/core/rendering/RenderMultiColumnBlock.cpp
|
| @@ -27,6 +27,8 @@
|
| #include "core/rendering/RenderMultiColumnBlock.h"
|
|
|
| #include "core/rendering/RenderMultiColumnFlowThread.h"
|
| +#include "core/rendering/RenderMultiColumnSet.h"
|
| +#include "core/rendering/RenderView.h"
|
|
|
| using namespace std;
|
|
|
| @@ -37,8 +39,8 @@ RenderMultiColumnBlock::RenderMultiColumnBlock(Element* element)
|
| , m_flowThread(0)
|
| , m_columnCount(1)
|
| , m_columnWidth(0)
|
| - , m_columnHeight(0)
|
| - , m_requiresBalancing(false)
|
| + , m_columnHeightAvailable(0)
|
| + , m_inBalancingPass(false)
|
| {
|
| }
|
|
|
| @@ -89,21 +91,49 @@ void RenderMultiColumnBlock::checkForPaginationLogicalHeightChange(LayoutUnit& /
|
| {
|
| // We don't actually update any of the variables. We just subclassed to adjust our column height.
|
| updateLogicalHeight();
|
| - LayoutUnit newContentLogicalHeight = contentLogicalHeight();
|
| - m_requiresBalancing = !newContentLogicalHeight;
|
| - if (!m_requiresBalancing) {
|
| - // The regions will be invalidated when we lay them out and they change size to
|
| - // the new column height.
|
| - if (columnHeight() != newContentLogicalHeight)
|
| - setColumnHeight(newContentLogicalHeight);
|
| - }
|
| + m_columnHeightAvailable = max<LayoutUnit>(contentLogicalHeight(), 0);
|
| setLogicalHeight(0);
|
| }
|
|
|
| -bool RenderMultiColumnBlock::relayoutForPagination(bool, LayoutUnit, LayoutStateMaintainer&)
|
| +bool RenderMultiColumnBlock::relayoutForPagination(bool, LayoutUnit, LayoutStateMaintainer& statePusher)
|
| {
|
| - // FIXME: Implement.
|
| - return false;
|
| + if (m_inBalancingPass || !requiresBalancing())
|
| + return false;
|
| + m_inBalancingPass = true; // Prevent re-entering this method (and recursion into layout).
|
| +
|
| + bool needsRelayout;
|
| + bool neededRelayout = false;
|
| + bool firstPass = true;
|
| + do {
|
| + // Column heights may change here because of balancing. We may have to do multiple layout
|
| + // passes, depending on how the contents is fitted to the changed column heights. In most
|
| + // cases, laying out again twice or even just once will suffice. Sometimes we need more
|
| + // passes than that, though, but the number of retries should not exceed the number of
|
| + // columns, unless we have a bug.
|
| + needsRelayout = false;
|
| + for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
|
| + if (childBox != m_flowThread && childBox->isRenderMultiColumnSet()) {
|
| + RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(childBox);
|
| + if (multicolSet->calculateBalancedHeight(firstPass)) {
|
| + multicolSet->setChildNeedsLayout(true, MarkOnlyThis);
|
| + needsRelayout = true;
|
| + }
|
| + }
|
| + }
|
| +
|
| + if (needsRelayout) {
|
| + // Layout again. Column balancing resulted in a new height.
|
| + neededRelayout = true;
|
| + m_flowThread->setChildNeedsLayout(true, MarkOnlyThis);
|
| + setChildNeedsLayout(true, MarkOnlyThis);
|
| + if (firstPass)
|
| + statePusher.pop();
|
| + layoutBlock(false);
|
| + }
|
| + firstPass = false;
|
| + } while (needsRelayout);
|
| + m_inBalancingPass = false;
|
| + return neededRelayout;
|
| }
|
|
|
| void RenderMultiColumnBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
|
| @@ -121,17 +151,17 @@ RenderObject* RenderMultiColumnBlock::layoutSpecialExcludedChild(bool relayoutCh
|
| if (!m_flowThread)
|
| return 0;
|
|
|
| - // Update the sizes of our regions (but not the placement) before we lay out the flow thread.
|
| + // 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.
|
| bool shouldInvalidateRegions = false;
|
| for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
|
| if (childBox == m_flowThread)
|
| continue;
|
| -
|
| +
|
| if (relayoutChildren || childBox->needsLayout()) {
|
| - childBox->updateLogicalWidth();
|
| - childBox->updateLogicalHeight();
|
| + if (!m_inBalancingPass && childBox->isRenderMultiColumnSet())
|
| + toRenderMultiColumnSet(childBox)->prepareForLayout();
|
| shouldInvalidateRegions = true;
|
| }
|
| }
|
|
|