summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/RenderMultiColumnBlock.cpp
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@digia.com>2013-09-13 12:51:20 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-19 20:50:05 +0200
commitd441d6f39bb846989d95bcf5caf387b42414718d (patch)
treee367e64a75991c554930278175d403c072de6bb8 /Source/WebCore/rendering/RenderMultiColumnBlock.cpp
parent0060b2994c07842f4c59de64b5e3e430525c4b90 (diff)
downloadqtwebkit-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.cpp138
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())