Chromium Code Reviews| Index: Source/core/rendering/RenderBlockFlow.cpp |
| diff --git a/Source/core/rendering/RenderBlockFlow.cpp b/Source/core/rendering/RenderBlockFlow.cpp |
| index d67b5e39511905f6578f1a1c47e99d281444d520..e19de90fd0e4219a169366984ed35cd83458d6e8 100644 |
| --- a/Source/core/rendering/RenderBlockFlow.cpp |
| +++ b/Source/core/rendering/RenderBlockFlow.cpp |
| @@ -282,40 +282,64 @@ void RenderBlockFlow::layoutBlock(bool relayoutChildren) |
| SubtreeLayoutScope layoutScope(this); |
| + m_layoutScope = &layoutScope; |
| + m_pageLogicalHeight = 0; |
| + |
| + preLayoutBlock(relayoutChildren, true); |
| + |
| // 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); |
| + bool done = postLayoutBlock(); |
| + while (!done) { |
| + preLayoutBlock(relayoutChildren, true); |
| + done = postLayoutBlock(); |
| + } |
| + m_layoutScope = 0; |
| } |
| -inline bool RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit &pageLogicalHeight, SubtreeLayoutScope& layoutScope) |
| +void RenderBlockFlow::preLayoutBlock(bool relayoutChildren, bool traverseChildren) |
| { |
| - LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); |
| + m_relayoutChildren = relayoutChildren; |
| + preLayoutBlockFlow(traverseChildren); |
| +} |
| + |
| +bool RenderBlockFlow::postLayoutBlock() |
| +{ |
| + return postLayoutBlockFlow(); |
| +} |
| + |
| +void RenderBlockFlow::preLayoutBlockFlow(bool traverseChildren) |
| +{ |
| + m_checkForRepaint = checkForRepaintDuringLayout(); |
| + m_oldBounds = LayoutRect(); |
| + m_oldOutlineBox = LayoutRect(); |
| + if (m_checkForRepaint) { |
| + m_oldBounds = clippedOverflowRectForRepaint(containerForRepaint()); |
| + m_oldOutlineBox = outlineBoundsForRepaint(containerForRepaint(), 0); |
| + } |
| if (updateLogicalWidthAndColumnWidth()) |
| - relayoutChildren = true; |
| + m_relayoutChildren = true; |
| rebuildFloatsFromIntruding(); |
| bool pageLogicalHeightChanged = false; |
| - bool hasSpecifiedPageLogicalHeight = false; |
| - checkForPaginationLogicalHeightChange(pageLogicalHeight, pageLogicalHeightChanged, hasSpecifiedPageLogicalHeight); |
| + m_hasSpecifiedPageLogicalHeight = false; |
| + checkForPaginationLogicalHeightChange(m_pageLogicalHeight, pageLogicalHeightChanged, m_hasSpecifiedPageLogicalHeight); |
| RenderView* renderView = view(); |
| - LayoutStateMaintainer statePusher(renderView, this, locationOffset(), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode(), pageLogicalHeight, pageLogicalHeightChanged, columnInfo()); |
| + m_statePusher = new LayoutStateMaintainer(renderView, this, locationOffset(), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode(), m_pageLogicalHeight, pageLogicalHeightChanged, columnInfo()); |
| // Regions changing widths can force us to relayout our children. |
| RenderFlowThread* flowThread = flowThreadContainingBlock(); |
| if (logicalWidthChangedInRegions(flowThread)) |
| - relayoutChildren = true; |
| + m_relayoutChildren = true; |
| if (updateRegionsAndShapesLogicalSize(flowThread)) |
| - relayoutChildren = true; |
| - if (!relayoutChildren && isRenderNamedFlowFragmentContainer()) |
| - relayoutChildren = true; |
| + m_relayoutChildren = true; |
| + if (!m_relayoutChildren && isRenderNamedFlowFragmentContainer()) |
| + m_relayoutChildren = true; |
| // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track |
| // our current maximal positive and negative margins. These values are used when we |
| @@ -336,12 +360,12 @@ inline bool RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit & |
| LayoutUnit beforeEdge = borderBefore() + paddingBefore(); |
| LayoutUnit afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeight(); |
| - LayoutUnit previousHeight = logicalHeight(); |
| + m_heightBeforeLayout = logicalHeight(); |
| setLogicalHeight(beforeEdge); |
| m_repaintLogicalTop = 0; |
| m_repaintLogicalBottom = 0; |
| - LayoutUnit maxFloatLogicalBottom = 0; |
| + m_maxFloatLogicalBottom = 0; |
| if (!firstChild() && !isAnonymousBlock()) |
| setChildrenInline(true); |
| @@ -350,15 +374,42 @@ inline bool RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit & |
| textAutosizer->beginLayout(this); |
| if (childrenInline()) |
| - layoutInlineChildren(relayoutChildren, m_repaintLogicalTop, m_repaintLogicalBottom, afterEdge); |
| - else |
| - layoutBlockChildren(relayoutChildren, maxFloatLogicalBottom, layoutScope, beforeEdge, afterEdge); |
| + layoutInlineChildren(m_relayoutChildren, m_repaintLogicalTop, m_repaintLogicalBottom, afterEdge); |
| + else { |
| + dirtyForLayoutFromPercentageHeightDescendants(*m_layoutScope); |
| + |
| + // Lay out our hypothetical grid line as though it occurs at the top of the block. |
| + if (view()->layoutState()->lineGrid() == this) |
| + layoutLineGridBox(); |
| + |
| + layoutBlockChildren(beforeEdge, afterEdge, traverseChildren); |
| + } |
| +} |
| + |
| +bool RenderBlockFlow::postLayoutBlockFlow() |
| +{ |
| + if (!m_statePusher) // simple layout |
| + return true; |
| if (frameView()->partialLayout().isStopping()) { |
| - statePusher.pop(); |
| + m_statePusher->pop(); |
| + delete m_statePusher; |
| + m_statePusher = 0; |
| return true; |
| } |
| + LayoutRepainter repainter(*this, m_checkForRepaint, m_oldBounds, m_oldOutlineBox); |
| + LayoutUnit beforeEdge = borderBefore() + paddingBefore(); |
| + LayoutUnit afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeight(); |
| + |
| + if (!childrenInline()) { |
| + // Now do the handling of the bottom of the block, adding in our bottom border/padding and |
| + // determining the correct collapsed bottom margin information. |
| + handleAfterSideOfBlock(m_lastNormalFlowChild, beforeEdge, afterEdge, *m_marginInfo); |
| + delete m_marginInfo; |
| + m_marginInfo = 0; |
| + } |
| + |
| // Expand our intrinsic height to encompass floats. |
| if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) && createsBlockFormattingContext()) |
| setLogicalHeight(lowestFloatLogicalBottom() + afterEdge); |
| @@ -366,7 +417,9 @@ inline bool RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit & |
| if (isRenderMultiColumnBlock()) { |
| if (toRenderMultiColumnBlock(this)->shouldRelayoutMultiColumnBlock()) { |
| setChildNeedsLayout(MarkOnlyThis); |
| - statePusher.pop(); |
| + m_statePusher->pop(); |
| + delete m_statePusher; |
| + m_statePusher = 0; |
| return false; |
| } |
| } else if (hasColumns()) { |
| @@ -378,17 +431,21 @@ inline bool RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit & |
| LayoutUnit layoutOverflowLogicalBottom = (isHorizontalWritingMode() ? layoutOverflowRect().maxY() : layoutOverflowRect().maxX()) - borderBefore() - paddingBefore(); |
| m_overflow = savedOverflow.release(); |
| - if (!hasSpecifiedPageLogicalHeight && shouldRelayoutForPagination(pageLogicalHeight, layoutOverflowLogicalBottom)) { |
| - statePusher.pop(); |
| + if (!m_hasSpecifiedPageLogicalHeight && shouldRelayoutForPagination(m_pageLogicalHeight, layoutOverflowLogicalBottom)) { |
| + m_statePusher->pop(); |
| + delete m_statePusher; |
| + m_statePusher = 0; |
| setEverHadLayout(true); |
| return false; |
| } |
| - setColumnCountAndHeight(ceilf((float)layoutOverflowLogicalBottom / pageLogicalHeight), pageLogicalHeight); |
| + setColumnCountAndHeight(ceilf((float)layoutOverflowLogicalBottom / m_pageLogicalHeight), m_pageLogicalHeight); |
| } |
| if (shouldBreakAtLineToAvoidWidow()) { |
| - statePusher.pop(); |
| + m_statePusher->pop(); |
| + delete m_statePusher; |
| + m_statePusher = 0; |
| setEverHadLayout(true); |
| return false; |
| } |
| @@ -405,7 +462,7 @@ inline bool RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit & |
| updateLogicalHeight(); |
| LayoutUnit newHeight = logicalHeight(); |
| if (oldHeight != newHeight) { |
| - if (oldHeight > newHeight && maxFloatLogicalBottom > newHeight && !childrenInline()) { |
| + if (oldHeight > newHeight && m_maxFloatLogicalBottom > newHeight && !childrenInline()) { |
| // One of our children's floats may have become an overhanging float for us. We need to look for it. |
| for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { |
| if (child->isRenderBlockFlow() && !child->isFloatingOrOutOfFlowPositioned()) { |
| @@ -417,26 +474,29 @@ inline bool RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit & |
| } |
| } |
| - bool heightChanged = (previousHeight != newHeight); |
| + bool heightChanged = (m_heightBeforeLayout != newHeight); |
| if (heightChanged) |
| - relayoutChildren = true; |
| + m_relayoutChildren = true; |
| - layoutPositionedObjects(relayoutChildren || isRoot()); |
| + layoutPositionedObjects(m_relayoutChildren || isRoot()); |
| - updateRegionsAndShapesAfterChildLayout(flowThread, heightChanged); |
| + updateRegionsAndShapesAfterChildLayout(flowThreadContainingBlock(), heightChanged); |
| // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway). |
| computeOverflow(oldClientAfterEdge); |
| - statePusher.pop(); |
| + m_statePusher->pop(); |
| fitBorderToLinesIfNeeded(); |
| - if (frameView()->partialLayout().isStopping()) |
| + if (frameView()->partialLayout().isStopping()) { |
| + delete m_statePusher; |
| + m_statePusher = 0; |
| return true; |
| + } |
| - if (renderView->layoutState()->m_pageLogicalHeight) |
| - setPageLogicalOffset(renderView->layoutState()->pageLogicalOffset(this, logicalTop())); |
| + if (view()->layoutState()->m_pageLogicalHeight) |
| + setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(this, logicalTop())); |
| updateLayerTransform(); |
| @@ -453,17 +513,36 @@ inline bool RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit & |
| repaintOverflow(); |
| } |
| + FastTextAutosizer* textAutosizer = document().fastTextAutosizer(); |
| if (textAutosizer) |
| textAutosizer->endLayout(this); |
| clearNeedsLayout(); |
| + delete m_statePusher; |
| + m_statePusher = 0; |
|
esprehn
2014/02/15 00:35:43
This should be an OwnPtr you just clear.
|
| return true; |
| } |
| -void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom) |
| +bool RenderBlockFlow::preLayoutBlockChild(RenderBox* child, bool& skipChildren) |
| { |
| - LayoutUnit oldPosMarginBefore = maxPositiveMarginBefore(); |
| - LayoutUnit oldNegMarginBefore = maxNegativeMarginBefore(); |
| + updateBlockChildDirtyBitsBeforeLayout(m_relayoutChildren, child); |
| + |
| + if (child->isOutOfFlowPositioned()) { |
| + child->containingBlock()->insertPositionedObject(child); |
| + adjustPositionedBlock(child, *m_marginInfo); |
| + skipChildren = true; |
| + return false; |
| + } |
| + |
| + if (child->isFloating()) { |
| + insertFloatingObject(child); |
| + adjustFloatingBlock(*m_marginInfo); |
| + skipChildren = true; |
| + return false; |
| + } |
| + |
| + m_oldPosMarginBefore = maxPositiveMarginBefore(); |
| + m_oldNegMarginBefore = maxNegativeMarginBefore(); |
| // The child is a normal flow object. Compute the margins we will use for collapsing now. |
| child->computeAndSetBlockDirectionMargins(this); |
| @@ -471,25 +550,25 @@ void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, |
| // Try to guess our correct logical top position. In most cases this guess will |
| // be correct. Only if we're wrong (when we compute the real logical top position) |
| // will we have to potentially relayout. |
| - LayoutUnit estimateWithoutPagination; |
| - LayoutUnit logicalTopEstimate = estimateLogicalTopPosition(child, marginInfo, estimateWithoutPagination); |
| + m_estimateWithoutPagination = 0; |
| + m_logicalTopEstimate = estimateLogicalTopPosition(child, *m_marginInfo, m_estimateWithoutPagination); |
| // Cache our old rect so that we can dirty the proper repaint rects if the child moves. |
| - LayoutRect oldRect = child->frameRect(); |
| + m_oldRect = child->frameRect(); |
| LayoutUnit oldLogicalTop = logicalTopForChild(child); |
| #if !ASSERT_DISABLED |
| - LayoutSize oldLayoutDelta = RuntimeEnabledFeatures::repaintAfterLayoutEnabled() ? LayoutSize() : view()->layoutDelta(); |
| + m_oldLayoutDelta = RuntimeEnabledFeatures::repaintAfterLayoutEnabled() ? LayoutSize() : view()->layoutDelta(); |
| #endif |
| // Go ahead and position the child as though it didn't collapse with the top. |
| - setLogicalTopForChild(child, logicalTopEstimate, ApplyLayoutDelta); |
| + setLogicalTopForChild(child, m_logicalTopEstimate, ApplyLayoutDelta); |
| RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0; |
| RenderBlockFlow* childRenderBlockFlow = (childRenderBlock && child->isRenderBlockFlow()) ? toRenderBlockFlow(child) : 0; |
| bool markDescendantsWithFloats = false; |
| - if (logicalTopEstimate != oldLogicalTop && !child->avoidsFloats() && childRenderBlock && childRenderBlock->containsFloats()) { |
| + if (m_logicalTopEstimate != oldLogicalTop && !child->avoidsFloats() && childRenderBlock && childRenderBlock->containsFloats()) { |
| markDescendantsWithFloats = true; |
| - } else if (UNLIKELY(logicalTopEstimate.mightBeSaturated())) { |
| + } else if (UNLIKELY(m_logicalTopEstimate.mightBeSaturated())) { |
| // logicalTopEstimate, returned by estimateLogicalTopPosition, might be saturated for |
| // very large elements. If it does the comparison with oldLogicalTop might yield a |
| // false negative as adding and removing margins, borders etc from a saturated number |
| @@ -498,8 +577,8 @@ void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, |
| } else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) { |
| // If an element might be affected by the presence of floats, then always mark it for |
| // layout. |
| - LayoutUnit fb = max(previousFloatLogicalBottom, lowestFloatLogicalBottom()); |
| - if (fb > logicalTopEstimate) |
| + LayoutUnit fb = max(m_previousFloatLogicalBottom, lowestFloatLogicalBottom()); |
| + if (fb > m_logicalTopEstimate) |
| markDescendantsWithFloats = true; |
| } |
| @@ -507,43 +586,58 @@ void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, |
| if (markDescendantsWithFloats) |
| childRenderBlockFlow->markAllDescendantsWithFloatsForLayout(); |
| if (!child->isWritingModeRoot()) |
| - previousFloatLogicalBottom = max(previousFloatLogicalBottom, oldLogicalTop + childRenderBlockFlow->lowestFloatLogicalBottom()); |
| + m_previousFloatLogicalBottom = max(m_previousFloatLogicalBottom, oldLogicalTop + childRenderBlockFlow->lowestFloatLogicalBottom()); |
| } |
| - SubtreeLayoutScope layoutScope(child); |
| + m_childLayoutScope = new SubtreeLayoutScope(child); |
| if (!child->needsLayout()) |
| - child->markForPaginationRelayoutIfNeeded(layoutScope); |
| - |
| - bool childHadLayout = child->everHadLayout(); |
| - bool childNeededLayout = child->needsLayout(); |
| - if (childNeededLayout) |
| - child->layout(); |
| + child->markForPaginationRelayoutIfNeeded(*m_childLayoutScope); |
| + |
| + m_childHadLayout = child->everHadLayout(); |
| + m_childNeededLayout = child->needsLayout(); |
|
esprehn
2014/02/15 00:35:43
This doesn't feel right. Storing so much state in
atreat
2014/02/18 16:03:57
Right, see the comment in the header file. We'll
|
| + skipChildren |= !m_childNeededLayout; |
| + if (m_childNeededLayout) { |
| + if (child->isNonRecursiveLayout()) |
| + child->preLayout(); |
| + else |
| + child->layout(); |
| + } |
| + return true; |
| +} |
| - if (frameView()->partialLayout().isStopping()) |
| +void RenderBlockFlow::postLayoutBlockChild(RenderBox* child) |
| +{ |
| + if (child->isOutOfFlowPositioned() || child->isFloating()) |
| return; |
| + if (m_childNeededLayout && child->isNonRecursiveLayout()) |
| + child->postLayout(); |
| + |
| // Cache if we are at the top of the block right now. |
| - bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock(); |
| + bool atBeforeSideOfBlock = m_marginInfo->atBeforeSideOfBlock(); |
| // Now determine the correct ypos based off examination of collapsing margin |
| // values. |
| - LayoutUnit logicalTopBeforeClear = collapseMargins(child, marginInfo); |
| + LayoutUnit logicalTopBeforeClear = collapseMargins(child, *m_marginInfo); |
| // Now check for clear. |
| - LayoutUnit logicalTopAfterClear = clearFloatsIfNeeded(child, marginInfo, oldPosMarginBefore, oldNegMarginBefore, logicalTopBeforeClear); |
| + LayoutUnit logicalTopAfterClear = clearFloatsIfNeeded(child, *m_marginInfo, m_oldPosMarginBefore, m_oldNegMarginBefore, logicalTopBeforeClear); |
| bool paginated = view()->layoutState()->isPaginated(); |
| if (paginated) { |
| - logicalTopAfterClear = adjustBlockChildForPagination(logicalTopAfterClear, estimateWithoutPagination, child, |
| + logicalTopAfterClear = adjustBlockChildForPagination(logicalTopAfterClear, m_estimateWithoutPagination, child, |
| atBeforeSideOfBlock && logicalTopBeforeClear == logicalTopAfterClear); |
| } |
| setLogicalTopForChild(child, logicalTopAfterClear, ApplyLayoutDelta); |
| + RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0; |
| + RenderBlockFlow* childRenderBlockFlow = (childRenderBlock && child->isRenderBlockFlow()) ? toRenderBlockFlow(child) : 0; |
| + |
| // Now we have a final top position. See if it really does end up being different from our estimate. |
| // clearFloatsIfNeeded can also mark the child as needing a layout even though we didn't move. This happens |
| // when collapseMargins dynamically adds overhanging floats because of a child with negative margins. |
| - if (logicalTopAfterClear != logicalTopEstimate || child->needsLayout() || (paginated && childRenderBlock && childRenderBlock->shouldBreakAtLineToAvoidWidow())) { |
| + if (logicalTopAfterClear != m_logicalTopEstimate || child->needsLayout() || (paginated && childRenderBlock && childRenderBlock->shouldBreakAtLineToAvoidWidow())) { |
| SubtreeLayoutScope layoutScope(child); |
| if (child->shrinkToAvoidFloats()) { |
| // The child's width depends on the line width. |
| @@ -568,30 +662,30 @@ void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, |
| // we set this bit to ensure we would not collapse the child's margins, and those of any subsequent |
| // self-collapsing siblings, with our parent. If this child is not self-collapsing then it can |
| // collapse its margins with the parent so reset the bit. |
| - if (!marginInfo.canCollapseMarginAfterWithLastChild() && !child->isSelfCollapsingBlock()) |
| - marginInfo.setCanCollapseMarginAfterWithLastChild(true); |
| + if (!m_marginInfo->canCollapseMarginAfterWithLastChild() && !child->isSelfCollapsingBlock()) |
| + m_marginInfo->setCanCollapseMarginAfterWithLastChild(true); |
| // We are no longer at the top of the block if we encounter a non-empty child. |
| // This has to be done after checking for clear, so that margins can be reset if a clear occurred. |
| - if (marginInfo.atBeforeSideOfBlock() && !child->isSelfCollapsingBlock()) |
| - marginInfo.setAtBeforeSideOfBlock(false); |
| + if (m_marginInfo->atBeforeSideOfBlock() && !child->isSelfCollapsingBlock()) |
| + m_marginInfo->setAtBeforeSideOfBlock(false); |
| // Now place the child in the correct left position |
| determineLogicalLeftPositionForChild(child, ApplyLayoutDelta); |
| - LayoutSize childOffset = child->location() - oldRect.location(); |
| + LayoutSize childOffset = child->location() - m_oldRect.location(); |
| relayoutShapeDescendantIfMoved(childRenderBlock, childOffset); |
| // Update our height now that the child has been placed in the correct position. |
| setLogicalHeight(logicalHeight() + logicalHeightForChild(child)); |
| if (mustSeparateMarginAfterForChild(child)) { |
| setLogicalHeight(logicalHeight() + marginAfterForChild(child)); |
| - marginInfo.clearMargin(); |
| + m_marginInfo->clearMargin(); |
| } |
| // If the child has overhanging floats that intrude into following siblings (or possibly out |
| // of this block), then the parent gets notified of the floats now. |
| if (childRenderBlockFlow && childRenderBlockFlow->containsFloats()) |
| - maxFloatLogicalBottom = max(maxFloatLogicalBottom, addOverhangingFloats(childRenderBlockFlow, !childNeededLayout)); |
| + m_maxFloatLogicalBottom = max(m_maxFloatLogicalBottom, addOverhangingFloats(childRenderBlockFlow, !m_childNeededLayout)); |
| if (childOffset.width() || childOffset.height()) { |
| if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) |
| @@ -600,13 +694,13 @@ void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, |
| // If the child moved, we have to repaint it as well as any floating/positioned |
| // descendants. An exception is if we need a layout. In this case, we know we're going to |
| // repaint ourselves (and the child) anyway. |
| - if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && childHadLayout && !selfNeedsLayout()) |
| + if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && m_childHadLayout && !selfNeedsLayout()) |
| child->repaintOverhangingFloats(true); |
| - else if (childHadLayout && !selfNeedsLayout() && child->checkForRepaintDuringLayout()) |
| - child->repaintDuringLayoutIfMoved(oldRect); |
| + else if (m_childHadLayout && !selfNeedsLayout() && child->checkForRepaintDuringLayout()) |
| + child->repaintDuringLayoutIfMoved(m_oldRect); |
| } |
| - if (!childHadLayout && child->checkForRepaint()) { |
| + if (!m_childHadLayout && child->checkForRepaint()) { |
| if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) |
| child->repaint(); |
| child->repaintOverhangingFloats(true); |
| @@ -614,14 +708,18 @@ void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, |
| if (paginated) { |
| // Check for an after page/column break. |
| - LayoutUnit newHeight = applyAfterBreak(child, logicalHeight(), marginInfo); |
| + LayoutUnit newHeight = applyAfterBreak(child, logicalHeight(), *m_marginInfo); |
| if (newHeight != height()) |
| setLogicalHeight(newHeight); |
| } |
| if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) { |
| - ASSERT(view()->layoutDeltaMatches(oldLayoutDelta)); |
| + ASSERT(view()->layoutDeltaMatches(m_oldLayoutDelta)); |
| } |
| + |
| + m_lastNormalFlowChild = child; |
| + delete m_childLayoutScope; |
| + m_childLayoutScope = 0; |
| } |
| LayoutUnit RenderBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTopAfterClear, LayoutUnit estimateWithoutPagination, RenderBox* child, bool atBeforeSideOfBlock) |
| @@ -848,63 +946,67 @@ void RenderBlockFlow::rebuildFloatsFromIntruding() |
| } |
| } |
| -void RenderBlockFlow::layoutBlockChildren(bool relayoutChildren, LayoutUnit& maxFloatLogicalBottom, SubtreeLayoutScope& layoutScope, LayoutUnit beforeEdge, LayoutUnit afterEdge) |
| +void RenderBlockFlow::layoutBlockChildren(LayoutUnit beforeEdge, LayoutUnit afterEdge, bool traverseChildren) |
| { |
| - dirtyForLayoutFromPercentageHeightDescendants(layoutScope); |
| - |
| - // Lay out our hypothetical grid line as though it occurs at the top of the block. |
| - if (view()->layoutState()->lineGrid() == this) |
| - layoutLineGridBox(); |
| - |
| // The margin struct caches all our current margin collapsing state. The compact struct caches state when we encounter compacts, |
| - MarginInfo marginInfo(this, beforeEdge, afterEdge); |
| + m_marginInfo = new MarginInfo(this, beforeEdge, afterEdge); |
|
esprehn
2014/02/15 00:35:43
Adding more mallocs doesn't seem like the right wa
|
| // Fieldsets need to find their legend and position it inside the border of the object. |
| // The legend then gets skipped during normal layout. The same is true for ruby text. |
| // It doesn't get included in the normal layout process but is instead skipped. |
| - RenderObject* childToExclude = layoutSpecialExcludedChild(relayoutChildren, layoutScope); |
| + m_childToExclude = layoutSpecialExcludedChild(m_relayoutChildren, *m_layoutScope); |
| + m_previousFloatLogicalBottom = 0; |
| + m_maxFloatLogicalBottom = 0; |
| + m_lastNormalFlowChild = 0; |
| - LayoutUnit previousFloatLogicalBottom = 0; |
| - maxFloatLogicalBottom = 0; |
| + if (!traverseChildren) |
| + return; |
| - RenderBox* next = firstChildBox(); |
| - RenderBox* lastNormalFlowChild = 0; |
| + bool skippingChildren = false; |
| +#if NON_RECURSIVE |
| + Order order = Pre; |
| + RenderObject* childObject = nextForLayout(order, this, skippingChildren); |
| + for (; childObject && childObject != this; childObject = childObject->nextForLayout(order, this, skippingChildren)) { |
| + if (!childObject->isBox()) |
| + continue; |
| + RenderBox *child = toRenderBox(childObject); |
| + skippingChildren = child->childrenInline(); |
| +#else |
| + (void)skippingChildren; |
| + for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) { |
| +#endif |
| - while (next) { |
| - RenderBox* child = next; |
| - next = child->nextSiblingBox(); |
| + ASSERT(child->parent()->isRenderBlockFlow()); |
| + RenderBlockFlow* directParent = toRenderBlockFlow(child->parent()); |
| LayoutRectRecorder recorder(*child); |
| - |
| - if (childToExclude == child) |
| + if (directParent->m_childToExclude == child) { |
| + skippingChildren = true; |
| continue; // Skip this child, since it will be positioned by the specialized subclass (fieldsets and ruby runs). |
| + } |
| - updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, child); |
| +#if NON_RECURSIVE |
| + if (order == Pre) { |
| +#endif |
| - if (child->isOutOfFlowPositioned()) { |
| - child->containingBlock()->insertPositionedObject(child); |
| - adjustPositionedBlock(child, marginInfo); |
| - continue; |
| - } |
| - if (child->isFloating()) { |
| - insertFloatingObject(child); |
| - adjustFloatingBlock(marginInfo); |
| + // Lay out the child. |
| + if (!directParent->preLayoutBlockChild(child, skippingChildren)) |
| continue; |
| - } |
| - // Lay out the child. |
| - layoutBlockChild(child, marginInfo, previousFloatLogicalBottom, maxFloatLogicalBottom); |
| - lastNormalFlowChild = child; |
| +#if NON_RECURSIVE |
| + } else { |
| +#endif |
| + |
| + directParent->postLayoutBlockChild(child); |
| + |
| +#if NON_RECURSIVE |
| + } |
| +#endif |
| // If doing a partial layout and the child was the target renderer, early exit here. |
| if (frameView()->partialLayout().checkPartialLayoutComplete(child)) |
| return; |
| - |
| } |
| - |
| - // Now do the handling of the bottom of the block, adding in our bottom border/padding and |
| - // determining the correct collapsed bottom margin information. |
| - handleAfterSideOfBlock(lastNormalFlowChild, beforeEdge, afterEdge, marginInfo); |
| } |
| // Our MarginInfo state used when laying out block children. |