Move line grid functionality from RenderBlock into RenderBlockFlow.
[WebKit-https.git] / Source / WebCore / rendering / RenderBlockFlow.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2007 David Smith (catfish.man@gmail.com)
5  * Copyright (C) 2003-2013 Apple Inc. All rights reserved.
6  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23
24 #include "config.h"
25 #include "RenderBlockFlow.h"
26
27 #include "FloatingObjects.h"
28 #include "LayoutRepainter.h"
29 #include "RenderFlowThread.h"
30 #include "RenderLayer.h"
31 #include "RenderView.h"
32 #include "VerticalPositionCache.h"
33
34 using namespace std;
35
36 namespace WebCore {
37
38 struct SameSizeAsMarginInfo {
39     uint32_t bitfields : 16;
40     LayoutUnit margins[2];
41 };
42
43 COMPILE_ASSERT(sizeof(RenderBlockFlow::MarginValues) == sizeof(LayoutUnit[4]), MarginValues_should_stay_small);
44
45 // Our MarginInfo state used when laying out block children.
46 RenderBlockFlow::MarginInfo::MarginInfo(RenderBlockFlow* block, LayoutUnit beforeBorderPadding, LayoutUnit afterBorderPadding)
47     : m_atBeforeSideOfBlock(true)
48     , m_atAfterSideOfBlock(false)
49     , m_hasMarginBeforeQuirk(false)
50     , m_hasMarginAfterQuirk(false)
51     , m_determinedMarginBeforeQuirk(false)
52     , m_discardMargin(false)
53 {
54     RenderStyle* blockStyle = block->style();
55     ASSERT(block->isRenderView() || block->parent());
56     m_canCollapseWithChildren = !block->isRenderView() && !block->isRoot() && !block->isOutOfFlowPositioned()
57         && !block->isFloating() && !block->isTableCell() && !block->hasOverflowClip() && !block->isInlineBlockOrInlineTable()
58         && !block->isRenderFlowThread() && !block->isWritingModeRoot() && !block->parent()->isFlexibleBox()
59         && blockStyle->hasAutoColumnCount() && blockStyle->hasAutoColumnWidth() && !blockStyle->columnSpan();
60
61     m_canCollapseMarginBeforeWithChildren = m_canCollapseWithChildren && !beforeBorderPadding && blockStyle->marginBeforeCollapse() != MSEPARATE;
62
63     // If any height other than auto is specified in CSS, then we don't collapse our bottom
64     // margins with our children's margins. To do otherwise would be to risk odd visual
65     // effects when the children overflow out of the parent block and yet still collapse
66     // with it. We also don't collapse if we have any bottom border/padding.
67     m_canCollapseMarginAfterWithChildren = m_canCollapseWithChildren && !afterBorderPadding
68         && (blockStyle->logicalHeight().isAuto() && !blockStyle->logicalHeight().value()) && blockStyle->marginAfterCollapse() != MSEPARATE;
69     
70     m_quirkContainer = block->isTableCell() || block->isBody();
71
72     m_discardMargin = m_canCollapseMarginBeforeWithChildren && block->mustDiscardMarginBefore();
73
74     m_positiveMargin = (m_canCollapseMarginBeforeWithChildren && !block->mustDiscardMarginBefore()) ? block->maxPositiveMarginBefore() : LayoutUnit();
75     m_negativeMargin = (m_canCollapseMarginBeforeWithChildren && !block->mustDiscardMarginBefore()) ? block->maxNegativeMarginBefore() : LayoutUnit();
76 }
77
78 RenderBlockFlow::RenderBlockFlow(Element* element)
79     : RenderBlock(element)
80 {
81     COMPILE_ASSERT(sizeof(RenderBlockFlow::MarginInfo) == sizeof(SameSizeAsMarginInfo), MarginInfo_should_stay_small);
82 }
83
84 RenderBlockFlow::~RenderBlockFlow()
85 {
86 }
87
88 void RenderBlockFlow::willBeDestroyed()
89 {
90     if (lineGridBox())
91         lineGridBox()->destroy(renderArena());
92
93     RenderBlock::willBeDestroyed();
94 }
95
96 void RenderBlockFlow::clearFloats()
97 {
98     if (m_floatingObjects)
99         m_floatingObjects->setHorizontalWritingMode(isHorizontalWritingMode());
100
101     HashSet<RenderBox*> oldIntrudingFloatSet;
102     if (!childrenInline() && m_floatingObjects) {
103         const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
104         auto end = floatingObjectSet.end();
105         for (auto it = floatingObjectSet.begin(); it != end; ++it) {
106             FloatingObject* floatingObject = it->get();
107             if (!floatingObject->isDescendant())
108                 oldIntrudingFloatSet.add(&floatingObject->renderer());
109         }
110     }
111
112     // Inline blocks are covered by the isReplaced() check in the avoidFloats method.
113     if (avoidsFloats() || isRoot() || isRenderView() || isFloatingOrOutOfFlowPositioned() || isTableCell()) {
114         if (m_floatingObjects) {
115             m_floatingObjects->clear();
116         }
117         if (!oldIntrudingFloatSet.isEmpty())
118             markAllDescendantsWithFloatsForLayout();
119         return;
120     }
121
122     RendererToFloatInfoMap floatMap;
123
124     if (m_floatingObjects) {
125         if (childrenInline())
126             m_floatingObjects->moveAllToFloatInfoMap(floatMap);
127         else
128             m_floatingObjects->clear();
129     }
130
131     // We should not process floats if the parent node is not a RenderBlock. Otherwise, we will add 
132     // floats in an invalid context. This will cause a crash arising from a bad cast on the parent.
133     // See <rdar://problem/8049753>, where float property is applied on a text node in a SVG.
134     if (!parent() || !parent()->isRenderBlock())
135         return;
136
137     // Attempt to locate a previous sibling with overhanging floats. We skip any elements that are
138     // out of flow (like floating/positioned elements), and we also skip over any objects that may have shifted
139     // to avoid floats.
140     RenderBlock* parentBlock = toRenderBlock(parent());
141     bool parentHasFloats = false;
142     RenderObject* prev = previousSibling();
143     while (prev && (prev->isFloatingOrOutOfFlowPositioned() || !prev->isBox() || !prev->isRenderBlock() || toRenderBlock(prev)->avoidsFloats())) {
144         if (prev->isFloating())
145             parentHasFloats = true;
146         prev = prev->previousSibling();
147     }
148
149     // First add in floats from the parent.
150     LayoutUnit logicalTopOffset = logicalTop();
151     if (parentHasFloats)
152         addIntrudingFloats(parentBlock, parentBlock->logicalLeftOffsetForContent(), logicalTopOffset);
153     
154     LayoutUnit logicalLeftOffset = 0;
155     if (prev)
156         logicalTopOffset -= toRenderBox(prev)->logicalTop();
157     else {
158         prev = parentBlock;
159         logicalLeftOffset += parentBlock->logicalLeftOffsetForContent();
160     }
161
162     // Add overhanging floats from the previous RenderBlock, but only if it has a float that intrudes into our space.    
163     RenderBlock* block = toRenderBlock(prev);
164     if (block->m_floatingObjects && block->lowestFloatLogicalBottom() > logicalTopOffset)
165         addIntrudingFloats(block, logicalLeftOffset, logicalTopOffset);
166
167     if (childrenInline()) {
168         LayoutUnit changeLogicalTop = LayoutUnit::max();
169         LayoutUnit changeLogicalBottom = LayoutUnit::min();
170         if (m_floatingObjects) {
171             const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
172             auto end = floatingObjectSet.end();
173             for (auto it = floatingObjectSet.begin(); it != end; ++it) {
174                 FloatingObject* f = it->get();
175                 std::unique_ptr<FloatingObject> oldFloatingObject = floatMap.take(&f->renderer());
176                 LayoutUnit logicalBottom = f->logicalBottom(isHorizontalWritingMode());
177                 if (oldFloatingObject) {
178                     LayoutUnit oldLogicalBottom = oldFloatingObject->logicalBottom(isHorizontalWritingMode());
179                     if (f->logicalWidth(isHorizontalWritingMode()) != oldFloatingObject->logicalWidth(isHorizontalWritingMode()) || f->logicalLeft(isHorizontalWritingMode()) != oldFloatingObject->logicalLeft(isHorizontalWritingMode())) {
180                         changeLogicalTop = 0;
181                         changeLogicalBottom = max(changeLogicalBottom, max(logicalBottom, oldLogicalBottom));
182                     } else {
183                         if (logicalBottom != oldLogicalBottom) {
184                             changeLogicalTop = min(changeLogicalTop, min(logicalBottom, oldLogicalBottom));
185                             changeLogicalBottom = max(changeLogicalBottom, max(logicalBottom, oldLogicalBottom));
186                         }
187                         LayoutUnit logicalTop = f->logicalTop(isHorizontalWritingMode());
188                         LayoutUnit oldLogicalTop = oldFloatingObject->logicalTop(isHorizontalWritingMode());
189                         if (logicalTop != oldLogicalTop) {
190                             changeLogicalTop = min(changeLogicalTop, min(logicalTop, oldLogicalTop));
191                             changeLogicalBottom = max(changeLogicalBottom, max(logicalTop, oldLogicalTop));
192                         }
193                     }
194
195                     if (oldFloatingObject->originatingLine() && !selfNeedsLayout()) {
196                         ASSERT(&oldFloatingObject->originatingLine()->renderer() == this);
197                         oldFloatingObject->originatingLine()->markDirty();
198                     }
199                 } else {
200                     changeLogicalTop = 0;
201                     changeLogicalBottom = max(changeLogicalBottom, logicalBottom);
202                 }
203             }
204         }
205
206         auto end = floatMap.end();
207         for (auto it = floatMap.begin(); it != end; ++it) {
208             FloatingObject* floatingObject = it->value.get();
209             if (!floatingObject->isDescendant()) {
210                 changeLogicalTop = 0;
211                 changeLogicalBottom = max(changeLogicalBottom, floatingObject->logicalBottom(isHorizontalWritingMode()));
212             }
213         }
214
215         markLinesDirtyInBlockRange(changeLogicalTop, changeLogicalBottom);
216     } else if (!oldIntrudingFloatSet.isEmpty()) {
217         // If there are previously intruding floats that no longer intrude, then children with floats
218         // should also get layout because they might need their floating object lists cleared.
219         if (m_floatingObjects->set().size() < oldIntrudingFloatSet.size())
220             markAllDescendantsWithFloatsForLayout();
221         else {
222             const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
223             auto end = floatingObjectSet.end();
224             for (auto it = floatingObjectSet.begin(); it != end && !oldIntrudingFloatSet.isEmpty(); ++it)
225                 oldIntrudingFloatSet.remove(&(*it)->renderer());
226             if (!oldIntrudingFloatSet.isEmpty())
227                 markAllDescendantsWithFloatsForLayout();
228         }
229     }
230 }
231
232 void RenderBlockFlow::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight)
233 {
234     ASSERT(needsLayout());
235
236     if (!relayoutChildren && simplifiedLayout())
237         return;
238
239     LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
240
241     if (updateLogicalWidthAndColumnWidth())
242         relayoutChildren = true;
243
244     clearFloats();
245
246     LayoutUnit previousHeight = logicalHeight();
247     // FIXME: should this start out as borderAndPaddingLogicalHeight() + scrollbarLogicalHeight(),
248     // for consistency with other render classes?
249     setLogicalHeight(0);
250
251     bool pageLogicalHeightChanged = false;
252     bool hasSpecifiedPageLogicalHeight = false;
253     checkForPaginationLogicalHeightChange(pageLogicalHeight, pageLogicalHeightChanged, hasSpecifiedPageLogicalHeight);
254
255     RenderStyle* styleToUse = style();
256     LayoutStateMaintainer statePusher(&view(), this, locationOffset(), hasColumns() || hasTransform() || hasReflection() || styleToUse->isFlippedBlocksWritingMode(), pageLogicalHeight, pageLogicalHeightChanged, columnInfo());
257
258     // Regions changing widths can force us to relayout our children.
259     RenderFlowThread* flowThread = flowThreadContainingBlock();
260     if (logicalWidthChangedInRegions(flowThread))
261         relayoutChildren = true;
262     if (updateShapesBeforeBlockLayout())
263         relayoutChildren = true;
264
265     // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track
266     // our current maximal positive and negative margins. These values are used when we
267     // are collapsed with adjacent blocks, so for example, if you have block A and B
268     // collapsing together, then you'd take the maximal positive margin from both A and B
269     // and subtract it from the maximal negative margin from both A and B to get the
270     // true collapsed margin. This algorithm is recursive, so when we finish layout()
271     // our block knows its current maximal positive/negative values.
272     //
273     // Start out by setting our margin values to our current margins. Table cells have
274     // no margins, so we don't fill in the values for table cells.
275     bool isCell = isTableCell();
276     if (!isCell) {
277         initMaxMarginValues();
278         
279         setHasMarginBeforeQuirk(styleToUse->hasMarginBeforeQuirk());
280         setHasMarginAfterQuirk(styleToUse->hasMarginAfterQuirk());
281         setPaginationStrut(0);
282     }
283
284     LayoutUnit repaintLogicalTop = 0;
285     LayoutUnit repaintLogicalBottom = 0;
286     LayoutUnit maxFloatLogicalBottom = 0;
287     if (!firstChild() && !isAnonymousBlock())
288         setChildrenInline(true);
289     if (childrenInline())
290         layoutInlineChildren(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
291     else
292         layoutBlockChildren(relayoutChildren, maxFloatLogicalBottom);
293
294     // Expand our intrinsic height to encompass floats.
295     LayoutUnit toAdd = borderAndPaddingAfter() + scrollbarLogicalHeight();
296     if (lowestFloatLogicalBottom() > (logicalHeight() - toAdd) && expandsToEncloseOverhangingFloats())
297         setLogicalHeight(lowestFloatLogicalBottom() + toAdd);
298     
299     if (relayoutForPagination(hasSpecifiedPageLogicalHeight, pageLogicalHeight, statePusher) || relayoutToAvoidWidows(statePusher)) {
300         ASSERT(!shouldBreakAtLineToAvoidWidow());
301         return;
302     }
303
304     // Calculate our new height.
305     LayoutUnit oldHeight = logicalHeight();
306     LayoutUnit oldClientAfterEdge = clientLogicalBottom();
307
308     // Before updating the final size of the flow thread make sure a forced break is applied after the content.
309     // This ensures the size information is correctly computed for the last auto-height region receiving content.
310     if (isRenderFlowThread())
311         toRenderFlowThread(this)->applyBreakAfterContent(oldClientAfterEdge);
312
313     updateLogicalHeight();
314     LayoutUnit newHeight = logicalHeight();
315     if (oldHeight != newHeight) {
316         if (oldHeight > newHeight && maxFloatLogicalBottom > newHeight && !childrenInline()) {
317             // One of our children's floats may have become an overhanging float for us. We need to look for it.
318             for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
319                 if (child->isRenderBlockFlow() && !child->isFloatingOrOutOfFlowPositioned()) {
320                     RenderBlock* block = toRenderBlock(child);
321                     if (block->lowestFloatLogicalBottom() + block->logicalTop() > newHeight)
322                         addOverhangingFloats(block, false);
323                 }
324             }
325         }
326     }
327
328     bool heightChanged = (previousHeight != newHeight);
329     if (heightChanged)
330         relayoutChildren = true;
331
332     layoutPositionedObjects(relayoutChildren || isRoot());
333
334     updateShapesAfterBlockLayout(heightChanged);
335
336     // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway).
337     computeOverflow(oldClientAfterEdge);
338     
339     statePusher.pop();
340
341     fitBorderToLinesIfNeeded();
342
343     if (view().layoutState()->m_pageLogicalHeight)
344         setPageLogicalOffset(view().layoutState()->pageLogicalOffset(this, logicalTop()));
345
346     updateLayerTransform();
347
348     // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
349     // we overflow or not.
350     updateScrollInfoAfterLayout();
351
352     // FIXME: This repaint logic should be moved into a separate helper function!
353     // Repaint with our new bounds if they are different from our old bounds.
354     bool didFullRepaint = repainter.repaintAfterLayout();
355     if (!didFullRepaint && repaintLogicalTop != repaintLogicalBottom && (styleToUse->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) {
356         // FIXME: We could tighten up the left and right invalidation points if we let layoutInlineChildren fill them in based off the particular lines
357         // it had to lay out. We wouldn't need the hasOverflowClip() hack in that case either.
358         LayoutUnit repaintLogicalLeft = logicalLeftVisualOverflow();
359         LayoutUnit repaintLogicalRight = logicalRightVisualOverflow();
360         if (hasOverflowClip()) {
361             // If we have clipped overflow, we should use layout overflow as well, since visual overflow from lines didn't propagate to our block's overflow.
362             // Note the old code did this as well but even for overflow:visible. The addition of hasOverflowClip() at least tightens up the hack a bit.
363             // layoutInlineChildren should be patched to compute the entire repaint rect.
364             repaintLogicalLeft = min(repaintLogicalLeft, logicalLeftLayoutOverflow());
365             repaintLogicalRight = max(repaintLogicalRight, logicalRightLayoutOverflow());
366         }
367         
368         LayoutRect repaintRect;
369         if (isHorizontalWritingMode())
370             repaintRect = LayoutRect(repaintLogicalLeft, repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop);
371         else
372             repaintRect = LayoutRect(repaintLogicalTop, repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft);
373
374         // The repaint rect may be split across columns, in which case adjustRectForColumns() will return the union.
375         adjustRectForColumns(repaintRect);
376
377         repaintRect.inflate(maximalOutlineSize(PaintPhaseOutline));
378         
379         if (hasOverflowClip()) {
380             // Adjust repaint rect for scroll offset
381             repaintRect.move(-scrolledContentOffset());
382
383             // Don't allow this rect to spill out of our overflow box.
384             repaintRect.intersect(LayoutRect(LayoutPoint(), size()));
385         }
386
387         // Make sure the rect is still non-empty after intersecting for overflow above
388         if (!repaintRect.isEmpty()) {
389             repaintRectangle(repaintRect); // We need to do a partial repaint of our content.
390             if (hasReflection())
391                 repaintRectangle(reflectedRect(repaintRect));
392         }
393     }
394
395     setNeedsLayout(false);
396 }
397
398 void RenderBlockFlow::layoutBlockChildren(bool relayoutChildren, LayoutUnit& maxFloatLogicalBottom)
399 {
400     dirtyForLayoutFromPercentageHeightDescendants();
401
402     LayoutUnit beforeEdge = borderAndPaddingBefore();
403     LayoutUnit afterEdge = borderAndPaddingAfter() + scrollbarLogicalHeight();
404
405     setLogicalHeight(beforeEdge);
406     
407     // Lay out our hypothetical grid line as though it occurs at the top of the block.
408     if (view().layoutState()->lineGrid() == this)
409         layoutLineGridBox();
410
411     // The margin struct caches all our current margin collapsing state.
412     MarginInfo marginInfo(this, beforeEdge, afterEdge);
413
414     // Fieldsets need to find their legend and position it inside the border of the object.
415     // The legend then gets skipped during normal layout. The same is true for ruby text.
416     // It doesn't get included in the normal layout process but is instead skipped.
417     RenderObject* childToExclude = layoutSpecialExcludedChild(relayoutChildren);
418
419     LayoutUnit previousFloatLogicalBottom = 0;
420     maxFloatLogicalBottom = 0;
421
422     RenderBox* next = firstChildBox();
423
424     while (next) {
425         RenderBox* child = next;
426         next = child->nextSiblingBox();
427
428         if (childToExclude == child)
429             continue; // Skip this child, since it will be positioned by the specialized subclass (fieldsets and ruby runs).
430
431         updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, child);
432
433         if (child->isOutOfFlowPositioned()) {
434             child->containingBlock()->insertPositionedObject(child);
435             adjustPositionedBlock(child, marginInfo);
436             continue;
437         }
438         if (child->isFloating()) {
439             insertFloatingObject(child);
440             adjustFloatingBlock(marginInfo);
441             continue;
442         }
443
444         // Lay out the child.
445         layoutBlockChild(child, marginInfo, previousFloatLogicalBottom, maxFloatLogicalBottom);
446     }
447     
448     // Now do the handling of the bottom of the block, adding in our bottom border/padding and
449     // determining the correct collapsed bottom margin information.
450     handleAfterSideOfBlock(beforeEdge, afterEdge, marginInfo);
451 }
452
453 void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom)
454 {
455     LayoutUnit oldPosMarginBefore = maxPositiveMarginBefore();
456     LayoutUnit oldNegMarginBefore = maxNegativeMarginBefore();
457
458     // The child is a normal flow object. Compute the margins we will use for collapsing now.
459     child->computeAndSetBlockDirectionMargins(this);
460
461     // Try to guess our correct logical top position. In most cases this guess will
462     // be correct. Only if we're wrong (when we compute the real logical top position)
463     // will we have to potentially relayout.
464     LayoutUnit estimateWithoutPagination;
465     LayoutUnit logicalTopEstimate = estimateLogicalTopPosition(child, marginInfo, estimateWithoutPagination);
466
467     // Cache our old rect so that we can dirty the proper repaint rects if the child moves.
468     LayoutRect oldRect = child->frameRect();
469     LayoutUnit oldLogicalTop = logicalTopForChild(child);
470
471 #if !ASSERT_DISABLED
472     LayoutSize oldLayoutDelta = view().layoutDelta();
473 #endif
474     // Go ahead and position the child as though it didn't collapse with the top.
475     setLogicalTopForChild(child, logicalTopEstimate, ApplyLayoutDelta);
476     estimateRegionRangeForBoxChild(child);
477
478     RenderBlockFlow* childBlockFlow = child->isRenderBlockFlow() ? toRenderBlockFlow(child) : 0;
479     bool markDescendantsWithFloats = false;
480     if (logicalTopEstimate != oldLogicalTop && !child->avoidsFloats() && childBlockFlow && childBlockFlow->containsFloats())
481         markDescendantsWithFloats = true;
482 #if ENABLE(SUBPIXEL_LAYOUT)
483     else if (UNLIKELY(logicalTopEstimate.mightBeSaturated()))
484         // logicalTopEstimate, returned by estimateLogicalTopPosition, might be saturated for
485         // very large elements. If it does the comparison with oldLogicalTop might yield a
486         // false negative as adding and removing margins, borders etc from a saturated number
487         // might yield incorrect results. If this is the case always mark for layout.
488         markDescendantsWithFloats = true;
489 #endif
490     else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) {
491         // If an element might be affected by the presence of floats, then always mark it for
492         // layout.
493         LayoutUnit fb = max(previousFloatLogicalBottom, lowestFloatLogicalBottom());
494         if (fb > logicalTopEstimate)
495             markDescendantsWithFloats = true;
496     }
497
498     if (childBlockFlow) {
499         if (markDescendantsWithFloats)
500             childBlockFlow->markAllDescendantsWithFloatsForLayout();
501         if (!child->isWritingModeRoot())
502             previousFloatLogicalBottom = max(previousFloatLogicalBottom, oldLogicalTop + childBlockFlow->lowestFloatLogicalBottom());
503     }
504
505     if (!child->needsLayout())
506         child->markForPaginationRelayoutIfNeeded();
507
508     bool childHadLayout = child->everHadLayout();
509     bool childNeededLayout = child->needsLayout();
510     if (childNeededLayout)
511         child->layout();
512
513     // Cache if we are at the top of the block right now.
514     bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock();
515
516     // Now determine the correct ypos based off examination of collapsing margin
517     // values.
518     LayoutUnit logicalTopBeforeClear = collapseMargins(child, marginInfo);
519
520     // Now check for clear.
521     LayoutUnit logicalTopAfterClear = clearFloatsIfNeeded(child, marginInfo, oldPosMarginBefore, oldNegMarginBefore, logicalTopBeforeClear);
522     
523     bool paginated = view().layoutState()->isPaginated();
524     if (paginated)
525         logicalTopAfterClear = adjustBlockChildForPagination(logicalTopAfterClear, estimateWithoutPagination, child,
526             atBeforeSideOfBlock && logicalTopBeforeClear == logicalTopAfterClear);
527
528     setLogicalTopForChild(child, logicalTopAfterClear, ApplyLayoutDelta);
529
530     // Now we have a final top position. See if it really does end up being different from our estimate.
531     // clearFloatsIfNeeded can also mark the child as needing a layout even though we didn't move. This happens
532     // when collapseMargins dynamically adds overhanging floats because of a child with negative margins.
533     if (logicalTopAfterClear != logicalTopEstimate || child->needsLayout() || (paginated && childBlockFlow && childBlockFlow->shouldBreakAtLineToAvoidWidow())) {
534         if (child->shrinkToAvoidFloats()) {
535             // The child's width depends on the line width.
536             // When the child shifts to clear an item, its width can
537             // change (because it has more available line width).
538             // So go ahead and mark the item as dirty.
539             child->setChildNeedsLayout(true, MarkOnlyThis);
540         }
541         
542         if (childBlockFlow) {
543             if (!child->avoidsFloats() && childBlockFlow->containsFloats())
544                 childBlockFlow->markAllDescendantsWithFloatsForLayout();
545             if (!child->needsLayout())
546                 child->markForPaginationRelayoutIfNeeded();
547         }
548
549         // Our guess was wrong. Make the child lay itself out again.
550         child->layoutIfNeeded();
551     }
552
553     if (updateRegionRangeForBoxChild(child)) {
554         child->setNeedsLayout(true, MarkOnlyThis);
555         child->layoutIfNeeded();
556     }
557
558     // We are no longer at the top of the block if we encounter a non-empty child.  
559     // This has to be done after checking for clear, so that margins can be reset if a clear occurred.
560     if (marginInfo.atBeforeSideOfBlock() && !child->isSelfCollapsingBlock())
561         marginInfo.setAtBeforeSideOfBlock(false);
562
563     // Now place the child in the correct left position
564     determineLogicalLeftPositionForChild(child, ApplyLayoutDelta);
565
566     LayoutSize childOffset = child->location() - oldRect.location();
567 #if ENABLE(CSS_SHAPES)
568     relayoutShapeDescendantIfMoved(child->isRenderBlock() ? toRenderBlock(child) : 0, childOffset);
569 #endif
570
571     // Update our height now that the child has been placed in the correct position.
572     setLogicalHeight(logicalHeight() + logicalHeightForChild(child));
573     if (mustSeparateMarginAfterForChild(child)) {
574         setLogicalHeight(logicalHeight() + marginAfterForChild(child));
575         marginInfo.clearMargin();
576     }
577     // If the child has overhanging floats that intrude into following siblings (or possibly out
578     // of this block), then the parent gets notified of the floats now.
579     if (childBlockFlow && childBlockFlow->containsFloats())
580         maxFloatLogicalBottom = max(maxFloatLogicalBottom, addOverhangingFloats(toRenderBlock(child), !childNeededLayout));
581
582     if (childOffset.width() || childOffset.height()) {
583         view().addLayoutDelta(childOffset);
584
585         // If the child moved, we have to repaint it as well as any floating/positioned
586         // descendants. An exception is if we need a layout. In this case, we know we're going to
587         // repaint ourselves (and the child) anyway.
588         if (childHadLayout && !selfNeedsLayout() && child->checkForRepaintDuringLayout())
589             child->repaintDuringLayoutIfMoved(oldRect);
590     }
591
592     if (!childHadLayout && child->checkForRepaintDuringLayout()) {
593         child->repaint();
594         child->repaintOverhangingFloats(true);
595     }
596
597     if (paginated) {
598         // Check for an after page/column break.
599         LayoutUnit newHeight = applyAfterBreak(child, logicalHeight(), marginInfo);
600         if (newHeight != height())
601             setLogicalHeight(newHeight);
602     }
603
604     ASSERT(view().layoutDeltaMatches(oldLayoutDelta));
605 }
606
607 void RenderBlockFlow::adjustPositionedBlock(RenderBox* child, const MarginInfo& marginInfo)
608 {
609     bool isHorizontal = isHorizontalWritingMode();
610     bool hasStaticBlockPosition = child->style()->hasStaticBlockPosition(isHorizontal);
611     
612     LayoutUnit logicalTop = logicalHeight();
613     updateStaticInlinePositionForChild(child, logicalTop);
614
615     if (!marginInfo.canCollapseWithMarginBefore()) {
616         // Positioned blocks don't collapse margins, so add the margin provided by
617         // the container now. The child's own margin is added later when calculating its logical top.
618         LayoutUnit collapsedBeforePos = marginInfo.positiveMargin();
619         LayoutUnit collapsedBeforeNeg = marginInfo.negativeMargin();
620         logicalTop += collapsedBeforePos - collapsedBeforeNeg;
621     }
622     
623     RenderLayer* childLayer = child->layer();
624     if (childLayer->staticBlockPosition() != logicalTop) {
625         childLayer->setStaticBlockPosition(logicalTop);
626         if (hasStaticBlockPosition)
627             child->setChildNeedsLayout(true, MarkOnlyThis);
628     }
629 }
630
631 void RenderBlockFlow::adjustFloatingBlock(const MarginInfo& marginInfo)
632 {
633     // The float should be positioned taking into account the bottom margin
634     // of the previous flow. We add that margin into the height, get the
635     // float positioned properly, and then subtract the margin out of the
636     // height again. In the case of self-collapsing blocks, we always just
637     // use the top margins, since the self-collapsing block collapsed its
638     // own bottom margin into its top margin.
639     //
640     // Note also that the previous flow may collapse its margin into the top of
641     // our block. If this is the case, then we do not add the margin in to our
642     // height when computing the position of the float. This condition can be tested
643     // for by simply calling canCollapseWithMarginBefore. See
644     // http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html for
645     // an example of this scenario.
646     LayoutUnit marginOffset = marginInfo.canCollapseWithMarginBefore() ? LayoutUnit() : marginInfo.margin();
647     setLogicalHeight(logicalHeight() + marginOffset);
648     positionNewFloats();
649     setLogicalHeight(logicalHeight() - marginOffset);
650 }
651
652 RenderBlockFlow::MarginValues RenderBlockFlow::marginValuesForChild(RenderBox* child) const
653 {
654     LayoutUnit childBeforePositive = 0;
655     LayoutUnit childBeforeNegative = 0;
656     LayoutUnit childAfterPositive = 0;
657     LayoutUnit childAfterNegative = 0;
658
659     LayoutUnit beforeMargin = 0;
660     LayoutUnit afterMargin = 0;
661
662     RenderBlockFlow* childRenderBlock = child->isRenderBlockFlow() ? toRenderBlockFlow(child) : 0;
663     
664     // If the child has the same directionality as we do, then we can just return its
665     // margins in the same direction.
666     if (!child->isWritingModeRoot()) {
667         if (childRenderBlock) {
668             childBeforePositive = childRenderBlock->maxPositiveMarginBefore();
669             childBeforeNegative = childRenderBlock->maxNegativeMarginBefore();
670             childAfterPositive = childRenderBlock->maxPositiveMarginAfter();
671             childAfterNegative = childRenderBlock->maxNegativeMarginAfter();
672         } else {
673             beforeMargin = child->marginBefore();
674             afterMargin = child->marginAfter();
675         }
676     } else if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) {
677         // The child has a different directionality. If the child is parallel, then it's just
678         // flipped relative to us. We can use the margins for the opposite edges.
679         if (childRenderBlock) {
680             childBeforePositive = childRenderBlock->maxPositiveMarginAfter();
681             childBeforeNegative = childRenderBlock->maxNegativeMarginAfter();
682             childAfterPositive = childRenderBlock->maxPositiveMarginBefore();
683             childAfterNegative = childRenderBlock->maxNegativeMarginBefore();
684         } else {
685             beforeMargin = child->marginAfter();
686             afterMargin = child->marginBefore();
687         }
688     } else {
689         // The child is perpendicular to us, which means its margins don't collapse but are on the
690         // "logical left/right" sides of the child box. We can just return the raw margin in this case.
691         beforeMargin = marginBeforeForChild(child);
692         afterMargin = marginAfterForChild(child);
693     }
694
695     // Resolve uncollapsing margins into their positive/negative buckets.
696     if (beforeMargin) {
697         if (beforeMargin > 0)
698             childBeforePositive = beforeMargin;
699         else
700             childBeforeNegative = -beforeMargin;
701     }
702     if (afterMargin) {
703         if (afterMargin > 0)
704             childAfterPositive = afterMargin;
705         else
706             childAfterNegative = -afterMargin;
707     }
708
709     return MarginValues(childBeforePositive, childBeforeNegative, childAfterPositive, childAfterNegative);
710 }
711
712 LayoutUnit RenderBlockFlow::collapseMargins(RenderBox* child, MarginInfo& marginInfo)
713 {
714     bool childDiscardMarginBefore = mustDiscardMarginBeforeForChild(child);
715     bool childDiscardMarginAfter = mustDiscardMarginAfterForChild(child);
716     bool childIsSelfCollapsing = child->isSelfCollapsingBlock();
717
718     // The child discards the before margin when the the after margin has discard in the case of a self collapsing block.
719     childDiscardMarginBefore = childDiscardMarginBefore || (childDiscardMarginAfter && childIsSelfCollapsing);
720
721     // Get the four margin values for the child and cache them.
722     const MarginValues childMargins = marginValuesForChild(child);
723
724     // Get our max pos and neg top margins.
725     LayoutUnit posTop = childMargins.positiveMarginBefore();
726     LayoutUnit negTop = childMargins.negativeMarginBefore();
727
728     // For self-collapsing blocks, collapse our bottom margins into our
729     // top to get new posTop and negTop values.
730     if (childIsSelfCollapsing) {
731         posTop = max(posTop, childMargins.positiveMarginAfter());
732         negTop = max(negTop, childMargins.negativeMarginAfter());
733     }
734     
735     // See if the top margin is quirky. We only care if this child has
736     // margins that will collapse with us.
737     bool topQuirk = hasMarginBeforeQuirk(child);
738
739     if (marginInfo.canCollapseWithMarginBefore()) {
740         if (!childDiscardMarginBefore && !marginInfo.discardMargin()) {
741             // This child is collapsing with the top of the
742             // block. If it has larger margin values, then we need to update
743             // our own maximal values.
744             if (!document().inQuirksMode() || !marginInfo.quirkContainer() || !topQuirk)
745                 setMaxMarginBeforeValues(max(posTop, maxPositiveMarginBefore()), max(negTop, maxNegativeMarginBefore()));
746
747             // The minute any of the margins involved isn't a quirk, don't
748             // collapse it away, even if the margin is smaller (www.webreference.com
749             // has an example of this, a <dt> with 0.8em author-specified inside
750             // a <dl> inside a <td>.
751             if (!marginInfo.determinedMarginBeforeQuirk() && !topQuirk && (posTop - negTop)) {
752                 setHasMarginBeforeQuirk(false);
753                 marginInfo.setDeterminedMarginBeforeQuirk(true);
754             }
755
756             if (!marginInfo.determinedMarginBeforeQuirk() && topQuirk && !marginBefore())
757                 // We have no top margin and our top child has a quirky margin.
758                 // We will pick up this quirky margin and pass it through.
759                 // This deals with the <td><div><p> case.
760                 // Don't do this for a block that split two inlines though. You do
761                 // still apply margins in this case.
762                 setHasMarginBeforeQuirk(true);
763         } else
764             // The before margin of the container will also discard all the margins it is collapsing with.
765             setMustDiscardMarginBefore();
766     }
767
768     // Once we find a child with discardMarginBefore all the margins collapsing with us must also discard. 
769     if (childDiscardMarginBefore) {
770         marginInfo.setDiscardMargin(true);
771         marginInfo.clearMargin();
772     }
773
774     if (marginInfo.quirkContainer() && marginInfo.atBeforeSideOfBlock() && (posTop - negTop))
775         marginInfo.setHasMarginBeforeQuirk(topQuirk);
776
777     LayoutUnit beforeCollapseLogicalTop = logicalHeight();
778     LayoutUnit logicalTop = beforeCollapseLogicalTop;
779     if (childIsSelfCollapsing) {
780         // For a self collapsing block both the before and after margins get discarded. The block doesn't contribute anything to the height of the block.
781         // Also, the child's top position equals the logical height of the container.
782         if (!childDiscardMarginBefore && !marginInfo.discardMargin()) {
783             // This child has no height. We need to compute our
784             // position before we collapse the child's margins together,
785             // so that we can get an accurate position for the zero-height block.
786             LayoutUnit collapsedBeforePos = max(marginInfo.positiveMargin(), childMargins.positiveMarginBefore());
787             LayoutUnit collapsedBeforeNeg = max(marginInfo.negativeMargin(), childMargins.negativeMarginBefore());
788             marginInfo.setMargin(collapsedBeforePos, collapsedBeforeNeg);
789             
790             // Now collapse the child's margins together, which means examining our
791             // bottom margin values as well. 
792             marginInfo.setPositiveMarginIfLarger(childMargins.positiveMarginAfter());
793             marginInfo.setNegativeMarginIfLarger(childMargins.negativeMarginAfter());
794
795             if (!marginInfo.canCollapseWithMarginBefore())
796                 // We need to make sure that the position of the self-collapsing block
797                 // is correct, since it could have overflowing content
798                 // that needs to be positioned correctly (e.g., a block that
799                 // had a specified height of 0 but that actually had subcontent).
800                 logicalTop = logicalHeight() + collapsedBeforePos - collapsedBeforeNeg;
801         }
802     } else {
803         if (mustSeparateMarginBeforeForChild(child)) {
804             ASSERT(!marginInfo.discardMargin() || (marginInfo.discardMargin() && !marginInfo.margin()));
805             // If we are at the before side of the block and we collapse, ignore the computed margin
806             // and just add the child margin to the container height. This will correctly position
807             // the child inside the container.
808             LayoutUnit separateMargin = !marginInfo.canCollapseWithMarginBefore() ? marginInfo.margin() : LayoutUnit(0);
809             setLogicalHeight(logicalHeight() + separateMargin + marginBeforeForChild(child));
810             logicalTop = logicalHeight();
811         } else if (!marginInfo.discardMargin() && (!marginInfo.atBeforeSideOfBlock()
812             || (!marginInfo.canCollapseMarginBeforeWithChildren()
813             && (!document().inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.hasMarginBeforeQuirk())))) {
814             // We're collapsing with a previous sibling's margins and not
815             // with the top of the block.
816             setLogicalHeight(logicalHeight() + max(marginInfo.positiveMargin(), posTop) - max(marginInfo.negativeMargin(), negTop));
817             logicalTop = logicalHeight();
818         }
819
820         marginInfo.setDiscardMargin(childDiscardMarginAfter);
821         
822         if (!marginInfo.discardMargin()) {
823             marginInfo.setPositiveMargin(childMargins.positiveMarginAfter());
824             marginInfo.setNegativeMargin(childMargins.negativeMarginAfter());
825         } else
826             marginInfo.clearMargin();
827
828         if (marginInfo.margin())
829             marginInfo.setHasMarginAfterQuirk(hasMarginAfterQuirk(child));
830     }
831     
832     // If margins would pull us past the top of the next page, then we need to pull back and pretend like the margins
833     // collapsed into the page edge.
834     LayoutState* layoutState = view().layoutState();
835     if (layoutState->isPaginated() && layoutState->pageLogicalHeight() && logicalTop > beforeCollapseLogicalTop
836         && hasNextPage(beforeCollapseLogicalTop)) {
837         LayoutUnit oldLogicalTop = logicalTop;
838         logicalTop = min(logicalTop, nextPageLogicalTop(beforeCollapseLogicalTop));
839         setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop));
840     }
841
842     // If we have collapsed into a previous sibling and so reduced the height of the parent, ensure any floats that now
843     // overhang from the previous sibling are added to our parent. If the child's previous sibling itself is a float the child will avoid
844     // or clear it anyway, so don't worry about any floating children it may contain.
845     LayoutUnit oldLogicalHeight = logicalHeight();
846     setLogicalHeight(logicalTop);
847     RenderObject* prev = child->previousSibling();
848     if (prev && prev->isRenderBlockFlow() && !prev->isFloatingOrOutOfFlowPositioned()) {
849         RenderBlock* block = toRenderBlock(prev);
850         if (block->containsFloats() && !block->avoidsFloats() && (block->logicalTop() + block->lowestFloatLogicalBottom()) > logicalTop) 
851             addOverhangingFloats(block, false);
852     }
853     setLogicalHeight(oldLogicalHeight);
854
855     return logicalTop;
856 }
857
858 LayoutUnit RenderBlockFlow::clearFloatsIfNeeded(RenderBox* child, MarginInfo& marginInfo, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPos)
859 {
860     LayoutUnit heightIncrease = getClearDelta(child, yPos);
861     if (!heightIncrease)
862         return yPos;
863
864     if (child->isSelfCollapsingBlock()) {
865         bool childDiscardMargin = mustDiscardMarginBeforeForChild(child) || mustDiscardMarginAfterForChild(child);
866
867         // For self-collapsing blocks that clear, they can still collapse their
868         // margins with following siblings. Reset the current margins to represent
869         // the self-collapsing block's margins only.
870         // If DISCARD is specified for -webkit-margin-collapse, reset the margin values.
871         if (!childDiscardMargin) {
872             MarginValues childMargins = marginValuesForChild(child);
873             marginInfo.setPositiveMargin(max(childMargins.positiveMarginBefore(), childMargins.positiveMarginAfter()));
874             marginInfo.setNegativeMargin(max(childMargins.negativeMarginBefore(), childMargins.negativeMarginAfter()));
875         } else
876             marginInfo.clearMargin();
877         marginInfo.setDiscardMargin(childDiscardMargin);
878
879         // CSS2.1 states:
880         // "If the top and bottom margins of an element with clearance are adjoining, its margins collapse with 
881         // the adjoining margins of following siblings but that resulting margin does not collapse with the bottom margin of the parent block."
882         // So the parent's bottom margin cannot collapse through this block or any subsequent self-collapsing blocks. Check subsequent siblings
883         // for a block with height - if none is found then don't allow the margins to collapse with the parent.
884         bool wouldCollapseMarginsWithParent = marginInfo.canCollapseMarginAfterWithChildren();
885         for (RenderBox* curr = child->nextSiblingBox(); curr && wouldCollapseMarginsWithParent; curr = curr->nextSiblingBox()) {
886             if (!curr->isFloatingOrOutOfFlowPositioned() && !curr->isSelfCollapsingBlock())
887                 wouldCollapseMarginsWithParent = false;
888         }
889         if (wouldCollapseMarginsWithParent)
890             marginInfo.setCanCollapseMarginAfterWithChildren(false);
891
892         // CSS2.1: "the amount of clearance is set so that clearance + margin-top = [height of float], i.e., clearance = [height of float] - margin-top"
893         // Move the top of the child box to the bottom of the float ignoring the child's top margin.
894         LayoutUnit collapsedMargin = collapsedMarginBeforeForChild(child);
895         setLogicalHeight(child->logicalTop() - collapsedMargin);
896         // A negative collapsed margin-top value cancels itself out as it has already been factored into |yPos| above.
897         heightIncrease -= max(LayoutUnit(), collapsedMargin);
898     } else
899         // Increase our height by the amount we had to clear.
900         setLogicalHeight(logicalHeight() + heightIncrease);
901     
902     if (marginInfo.canCollapseWithMarginBefore()) {
903         // We can no longer collapse with the top of the block since a clear
904         // occurred. The empty blocks collapse into the cleared block.
905         // FIXME: This isn't quite correct. Need clarification for what to do
906         // if the height the cleared block is offset by is smaller than the
907         // margins involved.
908         setMaxMarginBeforeValues(oldTopPosMargin, oldTopNegMargin);
909         marginInfo.setAtBeforeSideOfBlock(false);
910
911         // In case the child discarded the before margin of the block we need to reset the mustDiscardMarginBefore flag to the initial value.
912         setMustDiscardMarginBefore(style()->marginBeforeCollapse() == MDISCARD);
913     }
914
915     LayoutUnit logicalTop = yPos + heightIncrease;
916     // After margin collapsing, one of our floats may now intrude into the child. If the child doesn't contain floats of its own it
917     // won't get picked up for relayout even though the logical top estimate was wrong - so add the newly intruding float now.
918     if (containsFloats() && child->isRenderBlock() && !toRenderBlock(child)->containsFloats() && !child->avoidsFloats() && lowestFloatLogicalBottom() > logicalTop)
919         toRenderBlock(child)->addIntrudingFloats(this, logicalLeftOffsetForContent(), logicalTop);
920
921     return logicalTop;
922 }
923
924 void RenderBlockFlow::marginBeforeEstimateForChild(RenderBox* child, LayoutUnit& positiveMarginBefore, LayoutUnit& negativeMarginBefore, bool& discardMarginBefore) const
925 {
926     // Give up if in quirks mode and we're a body/table cell and the top margin of the child box is quirky.
927     // Give up if the child specified -webkit-margin-collapse: separate that prevents collapsing.
928     // FIXME: Use writing mode independent accessor for marginBeforeCollapse.
929     if ((document().inQuirksMode() && hasMarginAfterQuirk(child) && (isTableCell() || isBody())) || child->style()->marginBeforeCollapse() == MSEPARATE)
930         return;
931
932     // The margins are discarded by a child that specified -webkit-margin-collapse: discard.
933     // FIXME: Use writing mode independent accessor for marginBeforeCollapse.
934     if (child->style()->marginBeforeCollapse() == MDISCARD) {
935         positiveMarginBefore = 0;
936         negativeMarginBefore = 0;
937         discardMarginBefore = true;
938         return;
939     }
940
941     LayoutUnit beforeChildMargin = marginBeforeForChild(child);
942     positiveMarginBefore = max(positiveMarginBefore, beforeChildMargin);
943     negativeMarginBefore = max(negativeMarginBefore, -beforeChildMargin);
944
945     if (!child->isRenderBlockFlow())
946         return;
947     
948     RenderBlockFlow* childBlock = toRenderBlockFlow(child);
949     if (childBlock->childrenInline() || childBlock->isWritingModeRoot())
950         return;
951
952     MarginInfo childMarginInfo(childBlock, childBlock->borderAndPaddingBefore(), childBlock->borderAndPaddingAfter());
953     if (!childMarginInfo.canCollapseMarginBeforeWithChildren())
954         return;
955
956     RenderBox* grandchildBox = childBlock->firstChildBox();
957     for ( ; grandchildBox; grandchildBox = grandchildBox->nextSiblingBox()) {
958         if (!grandchildBox->isFloatingOrOutOfFlowPositioned())
959             break;
960     }
961     
962     // Give up if there is clearance on the box, since it probably won't collapse into us.
963     if (!grandchildBox || grandchildBox->style()->clear() != CNONE)
964         return;
965
966     // Make sure to update the block margins now for the grandchild box so that we're looking at current values.
967     if (grandchildBox->needsLayout()) {
968         grandchildBox->computeAndSetBlockDirectionMargins(this);
969         if (grandchildBox->isRenderBlock()) {
970             RenderBlock* grandchildBlock = toRenderBlock(grandchildBox);
971             grandchildBlock->setHasMarginBeforeQuirk(grandchildBox->style()->hasMarginBeforeQuirk());
972             grandchildBlock->setHasMarginAfterQuirk(grandchildBox->style()->hasMarginAfterQuirk());
973         }
974     }
975
976     // Collapse the margin of the grandchild box with our own to produce an estimate.
977     childBlock->marginBeforeEstimateForChild(grandchildBox, positiveMarginBefore, negativeMarginBefore, discardMarginBefore);
978 }
979
980 LayoutUnit RenderBlockFlow::estimateLogicalTopPosition(RenderBox* child, const MarginInfo& marginInfo, LayoutUnit& estimateWithoutPagination)
981 {
982     // FIXME: We need to eliminate the estimation of vertical position, because when it's wrong we sometimes trigger a pathological
983     // relayout if there are intruding floats.
984     LayoutUnit logicalTopEstimate = logicalHeight();
985     if (!marginInfo.canCollapseWithMarginBefore()) {
986         LayoutUnit positiveMarginBefore = 0;
987         LayoutUnit negativeMarginBefore = 0;
988         bool discardMarginBefore = false;
989         if (child->selfNeedsLayout()) {
990             // Try to do a basic estimation of how the collapse is going to go.
991             marginBeforeEstimateForChild(child, positiveMarginBefore, negativeMarginBefore, discardMarginBefore);
992         } else {
993             // Use the cached collapsed margin values from a previous layout. Most of the time they
994             // will be right.
995             MarginValues marginValues = marginValuesForChild(child);
996             positiveMarginBefore = max(positiveMarginBefore, marginValues.positiveMarginBefore());
997             negativeMarginBefore = max(negativeMarginBefore, marginValues.negativeMarginBefore());
998             discardMarginBefore = mustDiscardMarginBeforeForChild(child);
999         }
1000
1001         // Collapse the result with our current margins.
1002         if (!discardMarginBefore)
1003             logicalTopEstimate += max(marginInfo.positiveMargin(), positiveMarginBefore) - max(marginInfo.negativeMargin(), negativeMarginBefore);
1004     }
1005
1006     // Adjust logicalTopEstimate down to the next page if the margins are so large that we don't fit on the current
1007     // page.
1008     LayoutState* layoutState = view().layoutState();
1009     if (layoutState->isPaginated() && layoutState->pageLogicalHeight() && logicalTopEstimate > logicalHeight()
1010         && hasNextPage(logicalHeight()))
1011         logicalTopEstimate = min(logicalTopEstimate, nextPageLogicalTop(logicalHeight()));
1012
1013     logicalTopEstimate += getClearDelta(child, logicalTopEstimate);
1014     
1015     estimateWithoutPagination = logicalTopEstimate;
1016
1017     if (layoutState->isPaginated()) {
1018         // If the object has a page or column break value of "before", then we should shift to the top of the next page.
1019         logicalTopEstimate = applyBeforeBreak(child, logicalTopEstimate);
1020     
1021         // For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one.
1022         logicalTopEstimate = adjustForUnsplittableChild(child, logicalTopEstimate);
1023         
1024         if (!child->selfNeedsLayout() && child->isRenderBlock())
1025             logicalTopEstimate += toRenderBlock(child)->paginationStrut();
1026     }
1027
1028     return logicalTopEstimate;
1029 }
1030
1031 void RenderBlockFlow::setCollapsedBottomMargin(const MarginInfo& marginInfo)
1032 {
1033     if (marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()) {
1034         // Update the after side margin of the container to discard if the after margin of the last child also discards and we collapse with it.
1035         // Don't update the max margin values because we won't need them anyway.
1036         if (marginInfo.discardMargin()) {
1037             setMustDiscardMarginAfter();
1038             return;
1039         }
1040
1041         // Update our max pos/neg bottom margins, since we collapsed our bottom margins
1042         // with our children.
1043         setMaxMarginAfterValues(max(maxPositiveMarginAfter(), marginInfo.positiveMargin()), max(maxNegativeMarginAfter(), marginInfo.negativeMargin()));
1044
1045         if (!marginInfo.hasMarginAfterQuirk())
1046             setHasMarginAfterQuirk(false);
1047
1048         if (marginInfo.hasMarginAfterQuirk() && !marginAfter())
1049             // We have no bottom margin and our last child has a quirky margin.
1050             // We will pick up this quirky margin and pass it through.
1051             // This deals with the <td><div><p> case.
1052             setHasMarginAfterQuirk(true);
1053     }
1054 }
1055
1056 void RenderBlockFlow::handleAfterSideOfBlock(LayoutUnit beforeSide, LayoutUnit afterSide, MarginInfo& marginInfo)
1057 {
1058     marginInfo.setAtAfterSideOfBlock(true);
1059
1060     // If we can't collapse with children then go ahead and add in the bottom margin.
1061     if (!marginInfo.discardMargin() && (!marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()
1062         && (!document().inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.hasMarginAfterQuirk())))
1063         setLogicalHeight(logicalHeight() + marginInfo.margin());
1064         
1065     // Now add in our bottom border/padding.
1066     setLogicalHeight(logicalHeight() + afterSide);
1067
1068     // Negative margins can cause our height to shrink below our minimal height (border/padding).
1069     // If this happens, ensure that the computed height is increased to the minimal height.
1070     setLogicalHeight(max(logicalHeight(), beforeSide + afterSide));
1071
1072     // Update our bottom collapsed margin info.
1073     setCollapsedBottomMargin(marginInfo);
1074 }
1075
1076 void RenderBlockFlow::setMaxMarginBeforeValues(LayoutUnit pos, LayoutUnit neg)
1077 {
1078     if (!m_rareData) {
1079         if (pos == RenderBlockFlowRareData::positiveMarginBeforeDefault(this) && neg == RenderBlockFlowRareData::negativeMarginBeforeDefault(this))
1080             return;
1081         m_rareData = adoptPtr(new RenderBlockFlowRareData(this));
1082     }
1083     m_rareData->m_margins.setPositiveMarginBefore(pos);
1084     m_rareData->m_margins.setNegativeMarginBefore(neg);
1085 }
1086
1087 void RenderBlockFlow::setMaxMarginAfterValues(LayoutUnit pos, LayoutUnit neg)
1088 {
1089     if (!m_rareData) {
1090         if (pos == RenderBlockFlowRareData::positiveMarginAfterDefault(this) && neg == RenderBlockFlowRareData::negativeMarginAfterDefault(this))
1091             return;
1092         m_rareData = adoptPtr(new RenderBlockFlowRareData(this));
1093     }
1094     m_rareData->m_margins.setPositiveMarginAfter(pos);
1095     m_rareData->m_margins.setNegativeMarginAfter(neg);
1096 }
1097
1098 void RenderBlockFlow::setMustDiscardMarginBefore(bool value)
1099 {
1100     if (style()->marginBeforeCollapse() == MDISCARD) {
1101         ASSERT(value);
1102         return;
1103     }
1104     
1105     if (!m_rareData && !value)
1106         return;
1107
1108     if (!m_rareData)
1109         m_rareData = adoptPtr(new RenderBlockFlowRareData(this));
1110
1111     m_rareData->m_discardMarginBefore = value;
1112 }
1113
1114 void RenderBlockFlow::setMustDiscardMarginAfter(bool value)
1115 {
1116     if (style()->marginAfterCollapse() == MDISCARD) {
1117         ASSERT(value);
1118         return;
1119     }
1120
1121     if (!m_rareData && !value)
1122         return;
1123
1124     if (!m_rareData)
1125         m_rareData = adoptPtr(new RenderBlockFlowRareData(this));
1126
1127     m_rareData->m_discardMarginAfter = value;
1128 }
1129
1130 bool RenderBlockFlow::mustDiscardMarginBefore() const
1131 {
1132     return style()->marginBeforeCollapse() == MDISCARD || (m_rareData && m_rareData->m_discardMarginBefore);
1133 }
1134
1135 bool RenderBlockFlow::mustDiscardMarginAfter() const
1136 {
1137     return style()->marginAfterCollapse() == MDISCARD || (m_rareData && m_rareData->m_discardMarginAfter);
1138 }
1139
1140 bool RenderBlockFlow::mustDiscardMarginBeforeForChild(const RenderBox* child) const
1141 {
1142     ASSERT(!child->selfNeedsLayout());
1143     if (!child->isWritingModeRoot())
1144         return child->isRenderBlockFlow() ? toRenderBlockFlow(child)->mustDiscardMarginBefore() : (child->style()->marginBeforeCollapse() == MDISCARD);
1145     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
1146         return child->isRenderBlockFlow() ? toRenderBlockFlow(child)->mustDiscardMarginAfter() : (child->style()->marginAfterCollapse() == MDISCARD);
1147
1148     // FIXME: We return false here because the implementation is not geometrically complete. We have values only for before/after, not start/end.
1149     // In case the boxes are perpendicular we assume the property is not specified.
1150     return false;
1151 }
1152
1153 bool RenderBlockFlow::mustDiscardMarginAfterForChild(const RenderBox* child) const
1154 {
1155     ASSERT(!child->selfNeedsLayout());
1156     if (!child->isWritingModeRoot())
1157         return child->isRenderBlockFlow() ? toRenderBlockFlow(child)->mustDiscardMarginAfter() : (child->style()->marginAfterCollapse() == MDISCARD);
1158     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
1159         return child->isRenderBlockFlow() ? toRenderBlockFlow(child)->mustDiscardMarginBefore() : (child->style()->marginBeforeCollapse() == MDISCARD);
1160
1161     // FIXME: See |mustDiscardMarginBeforeForChild| above.
1162     return false;
1163 }
1164
1165 bool RenderBlockFlow::mustSeparateMarginBeforeForChild(const RenderBox* child) const
1166 {
1167     ASSERT(!child->selfNeedsLayout());
1168     const RenderStyle* childStyle = child->style();
1169     if (!child->isWritingModeRoot())
1170         return childStyle->marginBeforeCollapse() == MSEPARATE;
1171     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
1172         return childStyle->marginAfterCollapse() == MSEPARATE;
1173
1174     // FIXME: See |mustDiscardMarginBeforeForChild| above.
1175     return false;
1176 }
1177
1178 bool RenderBlockFlow::mustSeparateMarginAfterForChild(const RenderBox* child) const
1179 {
1180     ASSERT(!child->selfNeedsLayout());
1181     const RenderStyle* childStyle = child->style();
1182     if (!child->isWritingModeRoot())
1183         return childStyle->marginAfterCollapse() == MSEPARATE;
1184     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
1185         return childStyle->marginBeforeCollapse() == MSEPARATE;
1186
1187     // FIXME: See |mustDiscardMarginBeforeForChild| above.
1188     return false;
1189 }
1190
1191 static bool inNormalFlow(RenderBox* child)
1192 {
1193     RenderBlock* curr = child->containingBlock();
1194     while (curr && curr != &child->view()) {
1195         if (curr->hasColumns() || curr->isRenderFlowThread())
1196             return true;
1197         if (curr->isFloatingOrOutOfFlowPositioned())
1198             return false;
1199         curr = curr->containingBlock();
1200     }
1201     return true;
1202 }
1203
1204 LayoutUnit RenderBlockFlow::applyBeforeBreak(RenderBox* child, LayoutUnit logicalOffset)
1205 {
1206     // FIXME: Add page break checking here when we support printing.
1207     bool checkColumnBreaks = view().layoutState()->isPaginatingColumns();
1208     bool checkPageBreaks = !checkColumnBreaks && view().layoutState()->m_pageLogicalHeight; // FIXME: Once columns can print we have to check this.
1209     RenderFlowThread* flowThread = flowThreadContainingBlock();
1210     bool checkRegionBreaks = flowThread && flowThread->isRenderNamedFlowThread();
1211     bool checkBeforeAlways = (checkColumnBreaks && child->style()->columnBreakBefore() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakBefore() == PBALWAYS)
1212         || (checkRegionBreaks && child->style()->regionBreakBefore() == PBALWAYS);
1213     if (checkBeforeAlways && inNormalFlow(child) && hasNextPage(logicalOffset, IncludePageBoundary)) {
1214         if (checkColumnBreaks)
1215             view().layoutState()->addForcedColumnBreak(child, logicalOffset);
1216         if (checkRegionBreaks) {
1217             LayoutUnit offsetBreakAdjustment = 0;
1218             if (flowThread->addForcedRegionBreak(this, offsetFromLogicalTopOfFirstPage() + logicalOffset, child, true, &offsetBreakAdjustment))
1219                 return logicalOffset + offsetBreakAdjustment;
1220         }
1221         return nextPageLogicalTop(logicalOffset, IncludePageBoundary);
1222     }
1223     return logicalOffset;
1224 }
1225
1226 LayoutUnit RenderBlockFlow::applyAfterBreak(RenderBox* child, LayoutUnit logicalOffset, MarginInfo& marginInfo)
1227 {
1228     // FIXME: Add page break checking here when we support printing.
1229     bool checkColumnBreaks = view().layoutState()->isPaginatingColumns();
1230     bool checkPageBreaks = !checkColumnBreaks && view().layoutState()->m_pageLogicalHeight; // FIXME: Once columns can print we have to check this.
1231     RenderFlowThread* flowThread = flowThreadContainingBlock();
1232     bool checkRegionBreaks = flowThread && flowThread->isRenderNamedFlowThread();
1233     bool checkAfterAlways = (checkColumnBreaks && child->style()->columnBreakAfter() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakAfter() == PBALWAYS)
1234         || (checkRegionBreaks && child->style()->regionBreakAfter() == PBALWAYS);
1235     if (checkAfterAlways && inNormalFlow(child) && hasNextPage(logicalOffset, IncludePageBoundary)) {
1236         LayoutUnit marginOffset = marginInfo.canCollapseWithMarginBefore() ? LayoutUnit() : marginInfo.margin();
1237
1238         // So our margin doesn't participate in the next collapsing steps.
1239         marginInfo.clearMargin();
1240
1241         if (checkColumnBreaks)
1242             view().layoutState()->addForcedColumnBreak(child, logicalOffset);
1243         if (checkRegionBreaks) {
1244             LayoutUnit offsetBreakAdjustment = 0;
1245             if (flowThread->addForcedRegionBreak(this, offsetFromLogicalTopOfFirstPage() + logicalOffset + marginOffset, child, false, &offsetBreakAdjustment))
1246                 return logicalOffset + marginOffset + offsetBreakAdjustment;
1247         }
1248         return nextPageLogicalTop(logicalOffset, IncludePageBoundary);
1249     }
1250     return logicalOffset;
1251 }
1252
1253 LayoutUnit RenderBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTopAfterClear, LayoutUnit estimateWithoutPagination, RenderBox* child, bool atBeforeSideOfBlock)
1254 {
1255     RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0;
1256
1257     if (estimateWithoutPagination != logicalTopAfterClear) {
1258         // Our guess prior to pagination movement was wrong. Before we attempt to paginate, let's try again at the new
1259         // position.
1260         setLogicalHeight(logicalTopAfterClear);
1261         setLogicalTopForChild(child, logicalTopAfterClear, ApplyLayoutDelta);
1262
1263         if (child->shrinkToAvoidFloats()) {
1264             // The child's width depends on the line width.
1265             // When the child shifts to clear an item, its width can
1266             // change (because it has more available line width).
1267             // So go ahead and mark the item as dirty.
1268             child->setChildNeedsLayout(true, MarkOnlyThis);
1269         }
1270         
1271         if (childRenderBlock) {
1272             if (!child->avoidsFloats() && childRenderBlock->containsFloats())
1273                 childRenderBlock->markAllDescendantsWithFloatsForLayout();
1274             if (!child->needsLayout())
1275                 child->markForPaginationRelayoutIfNeeded();
1276         }
1277
1278         // Our guess was wrong. Make the child lay itself out again.
1279         child->layoutIfNeeded();
1280     }
1281
1282     LayoutUnit oldTop = logicalTopAfterClear;
1283
1284     // If the object has a page or column break value of "before", then we should shift to the top of the next page.
1285     LayoutUnit result = applyBeforeBreak(child, logicalTopAfterClear);
1286
1287     if (pageLogicalHeightForOffset(result)) {
1288         LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(result, ExcludePageBoundary);
1289         LayoutUnit spaceShortage = child->logicalHeight() - remainingLogicalHeight;
1290         if (spaceShortage > 0) {
1291             // If the child crosses a column boundary, report a break, in case nothing inside it has already
1292             // done so. The column balancer needs to know how much it has to stretch the columns to make more
1293             // content fit. If no breaks are reported (but do occur), the balancer will have no clue. FIXME:
1294             // This should be improved, though, because here we just pretend that the child is
1295             // unsplittable. A splittable child, on the other hand, has break opportunities at every position
1296             // where there's no child content, border or padding. In other words, we risk stretching more
1297             // than necessary.
1298             setPageBreak(result, spaceShortage);
1299         }
1300     }
1301
1302     // For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one.
1303     LayoutUnit logicalTopBeforeUnsplittableAdjustment = result;
1304     LayoutUnit logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChild(child, result);
1305     
1306     LayoutUnit paginationStrut = 0;
1307     LayoutUnit unsplittableAdjustmentDelta = logicalTopAfterUnsplittableAdjustment - logicalTopBeforeUnsplittableAdjustment;
1308     if (unsplittableAdjustmentDelta)
1309         paginationStrut = unsplittableAdjustmentDelta;
1310     else if (childRenderBlock && childRenderBlock->paginationStrut())
1311         paginationStrut = childRenderBlock->paginationStrut();
1312
1313     if (paginationStrut) {
1314         // We are willing to propagate out to our parent block as long as we were at the top of the block prior
1315         // to collapsing our margins, and as long as we didn't clear or move as a result of other pagination.
1316         if (atBeforeSideOfBlock && oldTop == result && !isOutOfFlowPositioned() && !isTableCell()) {
1317             // FIXME: Should really check if we're exceeding the page height before propagating the strut, but we don't
1318             // have all the information to do so (the strut only has the remaining amount to push). Gecko gets this wrong too
1319             // and pushes to the next page anyway, so not too concerned about it.
1320             setPaginationStrut(result + paginationStrut);
1321             if (childRenderBlock)
1322                 childRenderBlock->setPaginationStrut(0);
1323         } else
1324             result += paginationStrut;
1325     }
1326
1327     // Similar to how we apply clearance. Go ahead and boost height() to be the place where we're going to position the child.
1328     setLogicalHeight(logicalHeight() + (result - oldTop));
1329     
1330     // Return the final adjusted logical top.
1331     return result;
1332 }
1333
1334 static inline LayoutUnit calculateMinimumPageHeight(RenderStyle* renderStyle, RootInlineBox* lastLine, LayoutUnit lineTop, LayoutUnit lineBottom)
1335 {
1336     // We may require a certain minimum number of lines per page in order to satisfy
1337     // orphans and widows, and that may affect the minimum page height.
1338     unsigned lineCount = max<unsigned>(renderStyle->hasAutoOrphans() ? 1 : renderStyle->orphans(), renderStyle->hasAutoWidows() ? 1 : renderStyle->widows());
1339     if (lineCount > 1) {
1340         RootInlineBox* line = lastLine;
1341         for (unsigned i = 1; i < lineCount && line->prevRootBox(); i++)
1342             line = line->prevRootBox();
1343
1344         // FIXME: Paginating using line overflow isn't all fine. See FIXME in
1345         // adjustLinePositionForPagination() for more details.
1346         LayoutRect overflow = line->logicalVisualOverflowRect(line->lineTop(), line->lineBottom());
1347         lineTop = min(line->lineTopWithLeading(), overflow.y());
1348     }
1349     return lineBottom - lineTop;
1350 }
1351
1352 void RenderBlockFlow::adjustLinePositionForPagination(RootInlineBox* lineBox, LayoutUnit& delta, RenderFlowThread* flowThread)
1353 {
1354     // FIXME: For now we paginate using line overflow. This ensures that lines don't overlap at all when we
1355     // put a strut between them for pagination purposes. However, this really isn't the desired rendering, since
1356     // the line on the top of the next page will appear too far down relative to the same kind of line at the top
1357     // of the first column.
1358     //
1359     // The rendering we would like to see is one where the lineTopWithLeading is at the top of the column, and any line overflow
1360     // simply spills out above the top of the column. This effect would match what happens at the top of the first column.
1361     // We can't achieve this rendering, however, until we stop columns from clipping to the column bounds (thus allowing
1362     // for overflow to occur), and then cache visible overflow for each column rect.
1363     //
1364     // Furthermore, the paint we have to do when a column has overflow has to be special. We need to exclude
1365     // content that paints in a previous column (and content that paints in the following column).
1366     //
1367     // For now we'll at least honor the lineTopWithLeading when paginating if it is above the logical top overflow. This will
1368     // at least make positive leading work in typical cases.
1369     //
1370     // FIXME: Another problem with simply moving lines is that the available line width may change (because of floats).
1371     // Technically if the location we move the line to has a different line width than our old position, then we need to dirty the
1372     // line and all following lines.
1373     LayoutRect logicalVisualOverflow = lineBox->logicalVisualOverflowRect(lineBox->lineTop(), lineBox->lineBottom());
1374     LayoutUnit logicalOffset = min(lineBox->lineTopWithLeading(), logicalVisualOverflow.y());
1375     LayoutUnit logicalBottom = max(lineBox->lineBottomWithLeading(), logicalVisualOverflow.maxY());
1376     LayoutUnit lineHeight = logicalBottom - logicalOffset;
1377     updateMinimumPageHeight(logicalOffset, calculateMinimumPageHeight(style(), lineBox, logicalOffset, logicalBottom));
1378     logicalOffset += delta;
1379     lineBox->setPaginationStrut(0);
1380     lineBox->setIsFirstAfterPageBreak(false);
1381     LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
1382     bool hasUniformPageLogicalHeight = !flowThread || flowThread->regionsHaveUniformLogicalHeight();
1383     // If lineHeight is greater than pageLogicalHeight, but logicalVisualOverflow.height() still fits, we are
1384     // still going to add a strut, so that the visible overflow fits on a single page.
1385     if (!pageLogicalHeight || (hasUniformPageLogicalHeight && logicalVisualOverflow.height() > pageLogicalHeight)
1386         || !hasNextPage(logicalOffset))
1387         return;
1388     LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset, ExcludePageBoundary);
1389
1390     int lineIndex = lineCount(lineBox);
1391     if (remainingLogicalHeight < lineHeight || (shouldBreakAtLineToAvoidWidow() && lineBreakToAvoidWidow() == lineIndex)) {
1392         if (shouldBreakAtLineToAvoidWidow() && lineBreakToAvoidWidow() == lineIndex)
1393             clearShouldBreakAtLineToAvoidWidow();
1394         // If we have a non-uniform page height, then we have to shift further possibly.
1395         if (!hasUniformPageLogicalHeight && !pushToNextPageWithMinimumLogicalHeight(remainingLogicalHeight, logicalOffset, lineHeight))
1396             return;
1397         if (lineHeight > pageLogicalHeight) {
1398             // Split the top margin in order to avoid splitting the visible part of the line.
1399             remainingLogicalHeight -= min(lineHeight - pageLogicalHeight, max<LayoutUnit>(0, logicalVisualOverflow.y() - lineBox->lineTopWithLeading()));
1400         }
1401         LayoutUnit totalLogicalHeight = lineHeight + max<LayoutUnit>(0, logicalOffset);
1402         LayoutUnit pageLogicalHeightAtNewOffset = hasUniformPageLogicalHeight ? pageLogicalHeight : pageLogicalHeightForOffset(logicalOffset + remainingLogicalHeight);
1403         setPageBreak(logicalOffset, lineHeight - remainingLogicalHeight);
1404         if (((lineBox == firstRootBox() && totalLogicalHeight < pageLogicalHeightAtNewOffset) || (!style()->hasAutoOrphans() && style()->orphans() >= lineIndex))
1405             && !isOutOfFlowPositioned() && !isTableCell())
1406             setPaginationStrut(remainingLogicalHeight + max<LayoutUnit>(0, logicalOffset));
1407         else {
1408             delta += remainingLogicalHeight;
1409             lineBox->setPaginationStrut(remainingLogicalHeight);
1410             lineBox->setIsFirstAfterPageBreak(true);
1411         }
1412     } else if (remainingLogicalHeight == pageLogicalHeight && lineBox != firstRootBox())
1413         lineBox->setIsFirstAfterPageBreak(true);
1414 }
1415
1416 void RenderBlockFlow::setBreakAtLineToAvoidWidow(int lineToBreak)
1417 {
1418     ASSERT(lineToBreak);
1419     if (!m_rareData)
1420         m_rareData = adoptPtr(new RenderBlockFlowRareData(this));
1421     m_rareData->m_shouldBreakAtLineToAvoidWidow = true;
1422     m_rareData->m_lineBreakToAvoidWidow = lineToBreak;
1423 }
1424
1425 void RenderBlockFlow::clearShouldBreakAtLineToAvoidWidow() const
1426 {
1427     if (!m_rareData)
1428         return;
1429     m_rareData->m_shouldBreakAtLineToAvoidWidow = false;
1430     m_rareData->m_lineBreakToAvoidWidow = -1;
1431 }
1432
1433 bool RenderBlockFlow::relayoutToAvoidWidows(LayoutStateMaintainer& statePusher)
1434 {
1435     if (!shouldBreakAtLineToAvoidWidow())
1436         return false;
1437
1438     statePusher.pop();
1439     setEverHadLayout(true);
1440     layoutBlock(false);
1441     return true;
1442 }
1443
1444 void RenderBlockFlow::layoutLineGridBox()
1445 {
1446     if (style()->lineGrid() == RenderStyle::initialLineGrid()) {
1447         setLineGridBox(0);
1448         return;
1449     }
1450     
1451     setLineGridBox(0);
1452
1453     RootInlineBox* lineGridBox = new (renderArena()) RootInlineBox(*this);
1454     lineGridBox->setHasTextChildren(); // Needed to make the line ascent/descent actually be honored in quirks mode.
1455     lineGridBox->setConstructed();
1456     GlyphOverflowAndFallbackFontsMap textBoxDataMap;
1457     VerticalPositionCache verticalPositionCache;
1458     lineGridBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, verticalPositionCache);
1459     
1460     setLineGridBox(lineGridBox);
1461     
1462     // FIXME: If any of the characteristics of the box change compared to the old one, then we need to do a deep dirtying
1463     // (similar to what happens when the page height changes). Ideally, though, we only do this if someone is actually snapping
1464     // to this grid.
1465 }
1466
1467 } // namespace WebCore