2008-11-07 Simon Fraser <simon.fraser@apple.com>

        Reviewed by Dan Bernstein

        https://bugs.webkit.org/show_bug.cgi?id=22122

        Use a stack-based object to simplify the pushLayoutState/popLayoutState
        code. LayoutStateMaintainer either pushes in the constructor, or allows
        an explicit push() later. Both cases require an explicit pop().

        * rendering/RenderBlock.cpp:
        (WebCore::RenderBlock::layoutBlock):
        (WebCore::RenderBlock::layoutOnlyPositionedObjects):
        * rendering/RenderContainer.cpp:
        (WebCore::RenderContainer::layout):
        * rendering/RenderFlexibleBox.cpp:
        (WebCore::RenderFlexibleBox::layoutBlock):
        * rendering/RenderTable.cpp:
        (WebCore::RenderTable::layout):
        * rendering/RenderTableRow.cpp:
        (WebCore::RenderTableRow::layout):
        * rendering/RenderTableSection.cpp:
        (WebCore::RenderTableSection::setCellWidths):
        (WebCore::RenderTableSection::calcRowHeight):
        (WebCore::RenderTableSection::layoutRows):
        * rendering/RenderView.h:
        (WebCore::LayoutStateMaintainer::LayoutStateMaintainer):
        (WebCore::LayoutStateMaintainer::~LayoutStateMaintainer):
        (WebCore::LayoutStateMaintainer::pop):
        (WebCore::LayoutStateMaintainer::push):
        (WebCore::LayoutStateMaintainer::didPush):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@38227 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 87861c80
2008-11-07 Simon Fraser <simon.fraser@apple.com>
Reviewed by Dan Bernstein
https://bugs.webkit.org/show_bug.cgi?id=22122
Use a stack-based object to simplify the pushLayoutState/popLayoutState
code. LayoutStateMaintainer either pushes in the constructor, or allows
an explicit push() later. Both cases require an explicit pop().
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::layoutBlock):
(WebCore::RenderBlock::layoutOnlyPositionedObjects):
* rendering/RenderContainer.cpp:
(WebCore::RenderContainer::layout):
* rendering/RenderFlexibleBox.cpp:
(WebCore::RenderFlexibleBox::layoutBlock):
* rendering/RenderTable.cpp:
(WebCore::RenderTable::layout):
* rendering/RenderTableRow.cpp:
(WebCore::RenderTableRow::layout):
* rendering/RenderTableSection.cpp:
(WebCore::RenderTableSection::setCellWidths):
(WebCore::RenderTableSection::calcRowHeight):
(WebCore::RenderTableSection::layoutRows):
* rendering/RenderView.h:
(WebCore::LayoutStateMaintainer::LayoutStateMaintainer):
(WebCore::LayoutStateMaintainer::~LayoutStateMaintainer):
(WebCore::LayoutStateMaintainer::pop):
(WebCore::LayoutStateMaintainer::push):
(WebCore::LayoutStateMaintainer::didPush):
2008-11-07 Tor Arne Vestbø <tavestbo@trolltech.com> 2008-11-07 Tor Arne Vestbø <tavestbo@trolltech.com>
Fix the QtWebKit build on Mac Fix the QtWebKit build on Mac
...@@ -592,11 +592,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren) ...@@ -592,11 +592,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren)
oldOutlineBox = absoluteOutlineBox(); oldOutlineBox = absoluteOutlineBox();
} }
bool hadColumns = m_hasColumns; LayoutStateMaintainer statePusher(view(), this, IntSize(xPos(), yPos()), !m_hasColumns && !hasReflection());
if (!hadColumns && !hasReflection())
view()->pushLayoutState(this, IntSize(xPos(), yPos()));
else
view()->disableLayoutState();
int oldWidth = m_width; int oldWidth = m_width;
int oldColumnWidth = desiredColumnWidth(); int oldColumnWidth = desiredColumnWidth();
...@@ -725,10 +721,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren) ...@@ -725,10 +721,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren)
} }
} }
if (!hadColumns && !hasReflection()) statePusher.pop();
view()->popLayoutState();
else
view()->enableLayoutState();
// Update our scroll information if we're overflow:auto/scroll/hidden now that we know if // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
// we overflow or not. // we overflow or not.
...@@ -1394,10 +1387,7 @@ bool RenderBlock::layoutOnlyPositionedObjects() ...@@ -1394,10 +1387,7 @@ bool RenderBlock::layoutOnlyPositionedObjects()
if (!posChildNeedsLayout() || normalChildNeedsLayout() || selfNeedsLayout()) if (!posChildNeedsLayout() || normalChildNeedsLayout() || selfNeedsLayout())
return false; return false;
if (!m_hasColumns) LayoutStateMaintainer statePusher(view(), this, IntSize(xPos(), yPos()), !m_hasColumns);
view()->pushLayoutState(this, IntSize(xPos(), yPos()));
else
view()->disableLayoutState();
if (needsPositionedMovementLayout()) { if (needsPositionedMovementLayout()) {
tryLayoutDoingPositionedMovementOnly(); tryLayoutDoingPositionedMovementOnly();
...@@ -1408,10 +1398,7 @@ bool RenderBlock::layoutOnlyPositionedObjects() ...@@ -1408,10 +1398,7 @@ bool RenderBlock::layoutOnlyPositionedObjects()
// All we have to is lay out our positioned objects. // All we have to is lay out our positioned objects.
layoutPositionedObjects(false); layoutPositionedObjects(false);
if (!m_hasColumns) statePusher.pop();
view()->popLayoutState();
else
view()->enableLayoutState();
if (hasOverflowClip()) if (hasOverflowClip())
m_layer->updateScrollInfoAfterLayout(); m_layer->updateScrollInfoAfterLayout();
......
...@@ -520,7 +520,7 @@ void RenderContainer::layout() ...@@ -520,7 +520,7 @@ void RenderContainer::layout()
{ {
ASSERT(needsLayout()); ASSERT(needsLayout());
view()->pushLayoutState(this, IntSize(m_x, m_y)); LayoutStateMaintainer statePusher(view(), this, IntSize(m_x, m_y));
RenderObject* child = m_firstChild; RenderObject* child = m_firstChild;
while (child) { while (child) {
...@@ -529,7 +529,7 @@ void RenderContainer::layout() ...@@ -529,7 +529,7 @@ void RenderContainer::layout()
child = child->nextSibling(); child = child->nextSibling();
} }
view()->popLayoutState(); statePusher.pop();
setNeedsLayout(false); setNeedsLayout(false);
} }
......
...@@ -219,10 +219,7 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren) ...@@ -219,10 +219,7 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren)
oldOutlineBox = absoluteOutlineBox(); oldOutlineBox = absoluteOutlineBox();
} }
if (!hasReflection()) LayoutStateMaintainer statePusher(view(), this, IntSize(m_x, m_y), !hasReflection());
view()->pushLayoutState(this, IntSize(m_x, m_y));
else
view()->disableLayoutState();
int previousWidth = m_width; int previousWidth = m_width;
int previousHeight = m_height; int previousHeight = m_height;
...@@ -308,10 +305,7 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren) ...@@ -308,10 +305,7 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren)
} }
} }
if (!hasReflection()) statePusher.pop();
view()->popLayoutState();
else
view()->enableLayoutState();
// Update our scrollbars if we're overflow:auto/scroll/hidden now that we know if // Update our scrollbars if we're overflow:auto/scroll/hidden now that we know if
// we overflow or not. // we overflow or not.
......
...@@ -265,7 +265,7 @@ void RenderTable::layout() ...@@ -265,7 +265,7 @@ void RenderTable::layout()
oldOutlineBox = absoluteOutlineBox(); oldOutlineBox = absoluteOutlineBox();
} }
view()->pushLayoutState(this, IntSize(m_x, m_y)); LayoutStateMaintainer statePusher(view(), this, IntSize(m_x, m_y));
m_height = 0; m_height = 0;
m_overflowHeight = 0; m_overflowHeight = 0;
...@@ -425,7 +425,7 @@ void RenderTable::layout() ...@@ -425,7 +425,7 @@ void RenderTable::layout()
} }
} }
view()->popLayoutState(); statePusher.pop();
bool didFullRepaint = true; bool didFullRepaint = true;
// Repaint with our new bounds if they are different from our old bounds. // Repaint with our new bounds if they are different from our old bounds.
......
...@@ -124,7 +124,7 @@ void RenderTableRow::layout() ...@@ -124,7 +124,7 @@ void RenderTableRow::layout()
ASSERT(needsLayout()); ASSERT(needsLayout());
// Table rows do not add translation. // Table rows do not add translation.
view()->pushLayoutState(this, IntSize()); LayoutStateMaintainer statePusher(view(), this, IntSize());
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
if (child->isTableCell()) { if (child->isTableCell()) {
...@@ -148,7 +148,7 @@ void RenderTableRow::layout() ...@@ -148,7 +148,7 @@ void RenderTableRow::layout()
} }
} }
view()->popLayoutState(); statePusher.pop();
setNeedsLayout(false); setNeedsLayout(false);
} }
......
...@@ -257,8 +257,9 @@ void RenderTableSection::addCell(RenderTableCell* cell, RenderObject* row) ...@@ -257,8 +257,9 @@ void RenderTableSection::addCell(RenderTableCell* cell, RenderObject* row)
void RenderTableSection::setCellWidths() void RenderTableSection::setCellWidths()
{ {
Vector<int>& columnPos = table()->columnPositions(); Vector<int>& columnPos = table()->columnPositions();
bool pushedLayoutState = false;
LayoutStateMaintainer statePusher(view());
for (int i = 0; i < m_gridRows; i++) { for (int i = 0; i < m_gridRows; i++) {
Row& row = *m_grid[i].row; Row& row = *m_grid[i].row;
int cols = row.size(); int cols = row.size();
...@@ -279,11 +280,10 @@ void RenderTableSection::setCellWidths() ...@@ -279,11 +280,10 @@ void RenderTableSection::setCellWidths()
if (w != oldWidth) { if (w != oldWidth) {
cell->setNeedsLayout(true); cell->setNeedsLayout(true);
if (!table()->selfNeedsLayout() && cell->checkForRepaintDuringLayout()) { if (!table()->selfNeedsLayout() && cell->checkForRepaintDuringLayout()) {
if (!pushedLayoutState) { if (!statePusher.didPush()) {
// Technically, we should also push state for the row, but since // Technically, we should also push state for the row, but since
// rows don't push a coordinate transform, that's not necessary. // rows don't push a coordinate transform, that's not necessary.
view()->pushLayoutState(this, IntSize(m_x, m_y)); statePusher.push(this, IntSize(m_x, m_y));
pushedLayoutState = true;
} }
cell->repaint(); cell->repaint();
} }
...@@ -292,8 +292,7 @@ void RenderTableSection::setCellWidths() ...@@ -292,8 +292,7 @@ void RenderTableSection::setCellWidths()
} }
} }
if (pushedLayoutState) statePusher.pop(); // only pops if we pushed
view()->popLayoutState();
} }
int RenderTableSection::calcRowHeight() int RenderTableSection::calcRowHeight()
...@@ -301,7 +300,8 @@ int RenderTableSection::calcRowHeight() ...@@ -301,7 +300,8 @@ int RenderTableSection::calcRowHeight()
RenderTableCell* cell; RenderTableCell* cell;
int spacing = table()->vBorderSpacing(); int spacing = table()->vBorderSpacing();
bool pushedLayoutState = false;
LayoutStateMaintainer statePusher(view());
m_rowPos.resize(m_gridRows + 1); m_rowPos.resize(m_gridRows + 1);
m_rowPos[0] = spacing; m_rowPos[0] = spacing;
...@@ -330,11 +330,10 @@ int RenderTableSection::calcRowHeight() ...@@ -330,11 +330,10 @@ int RenderTableSection::calcRowHeight()
int indx = max(r - cell->rowSpan() + 1, 0); int indx = max(r - cell->rowSpan() + 1, 0);
if (cell->overrideSize() != -1) { if (cell->overrideSize() != -1) {
if (!pushedLayoutState) { if (!statePusher.didPush()) {
// Technically, we should also push state for the row, but since // Technically, we should also push state for the row, but since
// rows don't push a coordinate transform, that's not necessary. // rows don't push a coordinate transform, that's not necessary.
view()->pushLayoutState(this, IntSize(m_x, m_y)); statePusher.push(this, IntSize(m_x, m_y));
pushedLayoutState = true;
} }
cell->setOverrideSize(-1); cell->setOverrideSize(-1);
cell->setChildNeedsLayout(true, false); cell->setChildNeedsLayout(true, false);
...@@ -373,8 +372,7 @@ int RenderTableSection::calcRowHeight() ...@@ -373,8 +372,7 @@ int RenderTableSection::calcRowHeight()
m_rowPos[r + 1] = max(m_rowPos[r + 1], m_rowPos[r]); m_rowPos[r + 1] = max(m_rowPos[r + 1], m_rowPos[r]);
} }
if (pushedLayoutState) statePusher.pop();
view()->popLayoutState();
return m_rowPos[m_gridRows]; return m_rowPos[m_gridRows];
} }
...@@ -456,7 +454,7 @@ int RenderTableSection::layoutRows(int toAdd) ...@@ -456,7 +454,7 @@ int RenderTableSection::layoutRows(int toAdd)
int vspacing = table()->vBorderSpacing(); int vspacing = table()->vBorderSpacing();
int nEffCols = table()->numEffCols(); int nEffCols = table()->numEffCols();
view()->pushLayoutState(this, IntSize(m_x, m_y)); LayoutStateMaintainer statePusher(view(), this, IntSize(m_x, m_y));
for (int r = 0; r < totalRows; r++) { for (int r = 0; r < totalRows; r++) {
// Set the row's x/y position and width/height. // Set the row's x/y position and width/height.
...@@ -575,7 +573,7 @@ int RenderTableSection::layoutRows(int toAdd) ...@@ -575,7 +573,7 @@ int RenderTableSection::layoutRows(int toAdd)
} }
} }
view()->popLayoutState(); statePusher.pop();
m_height = m_rowPos[totalRows]; m_height = m_rowPos[totalRows];
m_overflowHeight = max(m_overflowHeight, m_height); m_overflowHeight = max(m_overflowHeight, m_height);
......
...@@ -157,6 +157,64 @@ private: ...@@ -157,6 +157,64 @@ private:
unsigned m_layoutStateDisableCount; unsigned m_layoutStateDisableCount;
}; };
// Stack-based class to assist with LayoutState push/pop
class LayoutStateMaintainer : Noncopyable {
public:
// ctor to push now
LayoutStateMaintainer(RenderView* view, RenderBox* root, IntSize offset, bool shouldPush = true)
: m_view(view)
, m_shouldPushPop(shouldPush)
, m_didStart(false)
, m_didEnd(false)
{
push(root, offset);
}
// ctor to maybe push later
LayoutStateMaintainer(RenderView* view)
: m_view(view)
, m_shouldPushPop(true)
, m_didStart(false)
, m_didEnd(false)
{
}
~LayoutStateMaintainer()
{
ASSERT(m_didStart == m_didEnd); // if this fires, it means that someone did a push(), but forgot to pop().
}
void pop()
{
if (m_didStart) {
ASSERT(!m_didEnd);
if (m_shouldPushPop)
m_view->popLayoutState();
else
m_view->enableLayoutState();
m_didEnd = true;
}
}
void push(RenderBox* root, IntSize offset)
{
ASSERT(!m_didStart);
if (m_shouldPushPop)
m_view->pushLayoutState(root, offset);
else
m_view->disableLayoutState();
m_didStart = true;
}
bool didPush() const { return m_didStart; }
private:
RenderView* m_view;
bool m_shouldPushPop : 1; // true if we should push/pop, rather than disable/enable
bool m_didStart : 1; // true if we did a push or disable
bool m_didEnd : 1; // true if we popped or re-enabled
};
} // namespace WebCore } // namespace WebCore
#endif // RenderView_h #endif // RenderView_h
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment