diff options
author | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2013-09-13 12:51:20 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-19 20:50:05 +0200 |
commit | d441d6f39bb846989d95bcf5caf387b42414718d (patch) | |
tree | e367e64a75991c554930278175d403c072de6bb8 /Source/WebCore/rendering/RenderMultiColumnBlock.cpp | |
parent | 0060b2994c07842f4c59de64b5e3e430525c4b90 (diff) | |
download | qtwebkit-d441d6f39bb846989d95bcf5caf387b42414718d.tar.gz |
Import Qt5x2 branch of QtWebkit for Qt 5.2
Importing a new snapshot of webkit.
Change-Id: I2d01ad12cdc8af8cb015387641120a9d7ea5f10c
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'Source/WebCore/rendering/RenderMultiColumnBlock.cpp')
-rw-r--r-- | Source/WebCore/rendering/RenderMultiColumnBlock.cpp | 138 |
1 files changed, 88 insertions, 50 deletions
diff --git a/Source/WebCore/rendering/RenderMultiColumnBlock.cpp b/Source/WebCore/rendering/RenderMultiColumnBlock.cpp index ba3ccd9b2..33d5c873b 100644 --- a/Source/WebCore/rendering/RenderMultiColumnBlock.cpp +++ b/Source/WebCore/rendering/RenderMultiColumnBlock.cpp @@ -25,21 +25,31 @@ #include "config.h" #include "RenderMultiColumnBlock.h" + #include "RenderMultiColumnFlowThread.h" #include "RenderMultiColumnSet.h" +#include "RenderView.h" #include "StyleInheritedData.h" using namespace std; namespace WebCore { -RenderMultiColumnBlock::RenderMultiColumnBlock(Node* node) - : RenderBlock(node) +RenderMultiColumnBlock::RenderMultiColumnBlock(Element* element) + : RenderBlock(element) , m_flowThread(0) , m_columnCount(1) , m_columnWidth(0) - , m_columnHeight(0) + , m_columnHeightAvailable(0) + , m_inBalancingPass(false) +{ +} + +void RenderMultiColumnBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) { + RenderBlock::styleDidChange(diff, oldStyle); + for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) + child->setStyle(RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK)); } void RenderMultiColumnBlock::computeColumnCountAndWidth() @@ -82,76 +92,104 @@ 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(); - if (newContentLogicalHeight > 0) { - // 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); - - // Set up our column sets. - ensureColumnSets(); } -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) { if (!m_flowThread) { - m_flowThread = new (renderArena()) RenderMultiColumnFlowThread(document()); + m_flowThread = RenderMultiColumnFlowThread::createAnonymous(document()); m_flowThread->setStyle(RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK)); - RenderBlock::addChild(m_flowThread); // Always put the flow thread at the end. + RenderBlock::addChild(m_flowThread); } - - // Column sets are siblings of the flow thread. All children designed to be in the columns, however, are part - // of the flow thread itself. - if (newChild->isRenderMultiColumnSet()) - RenderBlock::addChild(newChild, beforeChild); - else - m_flowThread->addChild(newChild, beforeChild); + m_flowThread->addChild(newChild, beforeChild); } - -void RenderMultiColumnBlock::ensureColumnSets() + +RenderObject* RenderMultiColumnBlock::layoutSpecialExcludedChild(bool relayoutChildren) { - // This function ensures we have the correct column set information before we get into layout. - // 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 region. - // - // 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. - if (flowThread() && !firstChild()->isRenderMultiColumnSet()) { - RenderMultiColumnSet* columnSet = new (renderArena()) RenderMultiColumnSet(document(), flowThread()); - columnSet->setStyle(RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK)); - RenderBlock::addChild(columnSet, firstChild()); + if (!m_flowThread) + return 0; + + // 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()) { + if (!m_inBalancingPass && childBox->isRenderMultiColumnSet()) + toRenderMultiColumnSet(childBox)->prepareForLayout(); + shouldInvalidateRegions = true; + } } + + if (shouldInvalidateRegions) + m_flowThread->invalidateRegions(); + + if (relayoutChildren) + m_flowThread->setChildNeedsLayout(true, MarkOnlyThis); + + setLogicalTopForChild(m_flowThread, borderAndPaddingBefore()); + m_flowThread->layoutIfNeeded(); + determineLogicalLeftPositionForChild(m_flowThread); + + return m_flowThread; } const char* RenderMultiColumnBlock::renderName() const -{ +{ if (isFloating()) return "RenderMultiColumnBlock (floating)"; if (isOutOfFlowPositioned()) return "RenderMultiColumnBlock (positioned)"; if (isAnonymousBlock()) return "RenderMultiColumnBlock (anonymous)"; + // FIXME: Temporary hack while the new generated content system is being implemented. + if (isPseudoElement()) + return "RenderMultiColumnBlock (generated)"; if (isAnonymous()) return "RenderMultiColumnBlock (generated)"; if (isRelPositioned()) |