4c71440de697b239524d2b2b8768bbbae2144b66
[WebKit-https.git] / Source / WebCore / rendering / RenderBlock.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, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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 "RenderBlock.h"
26
27 #include "ColumnInfo.h"
28 #include "Document.h"
29 #include "Element.h"
30 #include "FloatQuad.h"
31 #include "Frame.h"
32 #include "FrameSelection.h"
33 #include "FrameView.h"
34 #include "GraphicsContext.h"
35 #include "HTMLFormElement.h"
36 #include "HTMLNames.h"
37 #include "HitTestResult.h"
38 #include "InlineIterator.h"
39 #include "InlineTextBox.h"
40 #include "LayoutRepainter.h"
41 #include "Page.h"
42 #include "PaintInfo.h"
43 #include "RenderBoxRegionInfo.h"
44 #include "RenderCombineText.h"
45 #include "RenderDeprecatedFlexibleBox.h"
46 #include "RenderFlowThread.h"
47 #include "RenderImage.h"
48 #include "RenderInline.h"
49 #include "RenderLayer.h"
50 #include "RenderMarquee.h"
51 #include "RenderRegion.h"
52 #include "RenderReplica.h"
53 #include "RenderTableCell.h"
54 #include "RenderTextFragment.h"
55 #include "RenderTheme.h"
56 #include "RenderView.h"
57 #include "Settings.h"
58 #include "SVGTextRunRenderingContext.h"
59 #include "TransformState.h"
60 #include <wtf/StdLibExtras.h>
61
62 using namespace std;
63 using namespace WTF;
64 using namespace Unicode;
65
66 namespace WebCore {
67
68 using namespace HTMLNames;
69
70 typedef WTF::HashMap<const RenderBox*, ColumnInfo*> ColumnInfoMap;
71 static ColumnInfoMap* gColumnInfoMap = 0;
72
73 typedef WTF::HashMap<const RenderBlock*, HashSet<RenderBox*>*> PercentHeightDescendantsMap;
74 static PercentHeightDescendantsMap* gPercentHeightDescendantsMap = 0;
75
76 typedef WTF::HashMap<const RenderBox*, HashSet<RenderBlock*>*> PercentHeightContainerMap;
77 static PercentHeightContainerMap* gPercentHeightContainerMap = 0;
78     
79 typedef WTF::HashMap<RenderBlock*, ListHashSet<RenderInline*>*> ContinuationOutlineTableMap;
80
81 typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet;
82 static int gDelayUpdateScrollInfo = 0;
83 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0;
84
85 bool RenderBlock::s_canPropagateFloatIntoSibling = false;
86
87 // Our MarginInfo state used when laying out block children.
88 RenderBlock::MarginInfo::MarginInfo(RenderBlock* block, LayoutUnit beforeBorderPadding, LayoutUnit afterBorderPadding)
89     : m_atBeforeSideOfBlock(true)
90     , m_atAfterSideOfBlock(false)
91     , m_marginBeforeQuirk(false)
92     , m_marginAfterQuirk(false)
93     , m_determinedMarginBeforeQuirk(false)
94 {
95     // Whether or not we can collapse our own margins with our children.  We don't do this
96     // if we had any border/padding (obviously), if we're the root or HTML elements, or if
97     // we're positioned, floating, a table cell.
98     m_canCollapseWithChildren = !block->isRenderView() && !block->isRoot() && !block->isPositioned()
99         && !block->isFloating() && !block->isTableCell() && !block->hasOverflowClip() && !block->isInlineBlockOrInlineTable()
100         && !block->isWritingModeRoot() && block->style()->hasAutoColumnCount() && block->style()->hasAutoColumnWidth()
101         && !block->style()->columnSpan();
102
103     m_canCollapseMarginBeforeWithChildren = m_canCollapseWithChildren && (beforeBorderPadding == 0) && block->style()->marginBeforeCollapse() != MSEPARATE;
104
105     // If any height other than auto is specified in CSS, then we don't collapse our bottom
106     // margins with our children's margins.  To do otherwise would be to risk odd visual
107     // effects when the children overflow out of the parent block and yet still collapse
108     // with it.  We also don't collapse if we have any bottom border/padding.
109     m_canCollapseMarginAfterWithChildren = m_canCollapseWithChildren && (afterBorderPadding == 0) &&
110         (block->style()->logicalHeight().isAuto() && block->style()->logicalHeight().value() == 0) && block->style()->marginAfterCollapse() != MSEPARATE;
111     
112     m_quirkContainer = block->isTableCell() || block->isBody() || block->style()->marginBeforeCollapse() == MDISCARD || 
113         block->style()->marginAfterCollapse() == MDISCARD;
114
115     m_positiveMargin = m_canCollapseMarginBeforeWithChildren ? block->maxPositiveMarginBefore() : 0;
116     m_negativeMargin = m_canCollapseMarginBeforeWithChildren ? block->maxNegativeMarginBefore() : 0;
117 }
118
119 // -------------------------------------------------------------------------------------------------------
120
121 RenderBlock::RenderBlock(Node* node)
122       : RenderBox(node)
123       , m_lineHeight(-1)
124       , m_beingDestroyed(false)
125       , m_hasPositionedFloats(false)
126 {
127     setChildrenInline(true);
128 }
129
130 RenderBlock::~RenderBlock()
131 {
132     if (m_floatingObjects)
133         deleteAllValues(m_floatingObjects->set());
134     
135     if (hasColumns())
136         delete gColumnInfoMap->take(this);
137
138     if (gPercentHeightDescendantsMap) {
139         if (HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->take(this)) {
140             HashSet<RenderBox*>::iterator end = descendantSet->end();
141             for (HashSet<RenderBox*>::iterator descendant = descendantSet->begin(); descendant != end; ++descendant) {
142                 HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->get(*descendant);
143                 ASSERT(containerSet);
144                 if (!containerSet)
145                     continue;
146                 ASSERT(containerSet->contains(this));
147                 containerSet->remove(this);
148                 if (containerSet->isEmpty()) {
149                     gPercentHeightContainerMap->remove(*descendant);
150                     delete containerSet;
151                 }
152             }
153             delete descendantSet;
154         }
155     }
156 }
157
158 void RenderBlock::willBeDestroyed()
159 {
160     // Mark as being destroyed to avoid trouble with merges in removeChild().
161     m_beingDestroyed = true;
162
163     // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
164     // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
165     children()->destroyLeftoverChildren();
166
167     // Destroy our continuation before anything other than anonymous children.
168     // The reason we don't destroy it before anonymous children is that they may
169     // have continuations of their own that are anonymous children of our continuation.
170     RenderBoxModelObject* continuation = this->continuation();
171     if (continuation) {
172         continuation->destroy();
173         setContinuation(0);
174     }
175     
176     if (!documentBeingDestroyed()) {
177         if (firstLineBox()) {
178             // We can't wait for RenderBox::destroy to clear the selection,
179             // because by then we will have nuked the line boxes.
180             // FIXME: The FrameSelection should be responsible for this when it
181             // is notified of DOM mutations.
182             if (isSelectionBorder())
183                 view()->clearSelection();
184
185             // If we are an anonymous block, then our line boxes might have children
186             // that will outlast this block. In the non-anonymous block case those
187             // children will be destroyed by the time we return from this function.
188             if (isAnonymousBlock()) {
189                 for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox()) {
190                     while (InlineBox* childBox = box->firstChild())
191                         childBox->remove();
192                 }
193             }
194         } else if (parent())
195             parent()->dirtyLinesFromChangedChild(this);
196     }
197
198     m_lineBoxes.deleteLineBoxes(renderArena());
199
200     if (UNLIKELY(gDelayedUpdateScrollInfoSet != 0))
201         gDelayedUpdateScrollInfoSet->remove(this);
202
203     RenderBox::willBeDestroyed();
204 }
205
206 void RenderBlock::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
207 {
208     s_canPropagateFloatIntoSibling = style() ? !isFloatingOrPositioned() && !avoidsFloats() : false;
209
210     setReplaced(newStyle->isDisplayInlineType());
211     
212     if (style() && parent() && diff == StyleDifferenceLayout && style()->position() != newStyle->position()) {
213         if (newStyle->position() == StaticPosition)
214             // Clear our positioned objects list. Our absolutely positioned descendants will be
215             // inserted into our containing block's positioned objects list during layout.
216             removePositionedObjects(0);
217         else if (style()->position() == StaticPosition) {
218             // Remove our absolutely positioned descendants from their current containing block.
219             // They will be inserted into our positioned objects list during layout.
220             RenderObject* cb = parent();
221             while (cb && (cb->style()->position() == StaticPosition || (cb->isInline() && !cb->isReplaced())) && !cb->isRenderView()) {
222                 if (cb->style()->position() == RelativePosition && cb->isInline() && !cb->isReplaced()) {
223                     cb = cb->containingBlock();
224                     break;
225                 }
226                 cb = cb->parent();
227             }
228             
229             if (cb->isRenderBlock())
230                 toRenderBlock(cb)->removePositionedObjects(this);
231         }
232
233         if (containsFloats() && !isFloating() && !isPositioned() && (newStyle->position() == AbsolutePosition || newStyle->position() == FixedPosition))
234             markAllDescendantsWithFloatsForLayout();
235     }
236
237     RenderBox::styleWillChange(diff, newStyle);
238 }
239
240 void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
241 {
242     RenderBox::styleDidChange(diff, oldStyle);
243
244     if (!isAnonymousBlock()) {
245         // Ensure that all of our continuation blocks pick up the new style.
246         for (RenderBlock* currCont = blockElementContinuation(); currCont; currCont = currCont->blockElementContinuation()) {
247             RenderBoxModelObject* nextCont = currCont->continuation();
248             currCont->setContinuation(0);
249             currCont->setStyle(style());
250             currCont->setContinuation(nextCont);
251         }
252     }
253
254     propagateStyleToAnonymousChildren(true);    
255     m_lineHeight = -1;
256
257     // Update pseudos for :before and :after now.
258     if (!isAnonymous() && document()->usesBeforeAfterRules() && canHaveChildren()) {
259         updateBeforeAfterContent(BEFORE);
260         updateBeforeAfterContent(AFTER);
261     }
262
263     // After our style changed, if we lose our ability to propagate floats into next sibling
264     // blocks, then we need to find the top most parent containing that overhanging float and
265     // then mark its descendants with floats for layout and clear all floats from its next
266     // sibling blocks that exist in our floating objects list. See bug 56299 and 62875.
267     bool canPropagateFloatIntoSibling = !isFloatingOrPositioned() && !avoidsFloats();
268     if (diff == StyleDifferenceLayout && s_canPropagateFloatIntoSibling && !canPropagateFloatIntoSibling && hasOverhangingFloats()) {
269         RenderBlock* parentBlock = this;
270         const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
271         FloatingObjectSetIterator end = floatingObjectSet.end();
272
273         for (RenderObject* curr = parent(); curr && !curr->isRenderView(); curr = curr->parent()) {
274             if (curr->isRenderBlock()) {
275                 RenderBlock* currBlock = toRenderBlock(curr);
276
277                 if (currBlock->hasOverhangingFloats()) {
278                     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
279                         RenderBox* renderer = (*it)->renderer();
280                         if (currBlock->hasOverhangingFloat(renderer)) {
281                             parentBlock = currBlock;
282                             break;
283                         }
284                     }
285                 }
286             }
287         }
288               
289         parentBlock->markAllDescendantsWithFloatsForLayout();
290         parentBlock->markSiblingsWithFloatsForLayout();
291     }
292 }
293
294 void RenderBlock::updateBeforeAfterContent(PseudoId pseudoId)
295 {
296     // If this is an anonymous wrapper, then the parent applies its own pseudo-element style to it.
297     if (parent() && parent()->createsAnonymousWrapper())
298         return;
299     children()->updateBeforeAfterContent(this, pseudoId);
300 }
301
302 RenderBlock* RenderBlock::continuationBefore(RenderObject* beforeChild)
303 {
304     if (beforeChild && beforeChild->parent() == this)
305         return this;
306
307     RenderBlock* curr = toRenderBlock(continuation());
308     RenderBlock* nextToLast = this;
309     RenderBlock* last = this;
310     while (curr) {
311         if (beforeChild && beforeChild->parent() == curr) {
312             if (curr->firstChild() == beforeChild)
313                 return last;
314             return curr;
315         }
316
317         nextToLast = last;
318         last = curr;
319         curr = toRenderBlock(curr->continuation());
320     }
321
322     if (!beforeChild && !last->firstChild())
323         return nextToLast;
324     return last;
325 }
326
327 void RenderBlock::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild)
328 {
329     RenderBlock* flow = continuationBefore(beforeChild);
330     ASSERT(!beforeChild || beforeChild->parent()->isAnonymousColumnSpanBlock() || beforeChild->parent()->isRenderBlock());
331     RenderBoxModelObject* beforeChildParent = 0;
332     if (beforeChild)
333         beforeChildParent = toRenderBoxModelObject(beforeChild->parent());
334     else {
335         RenderBoxModelObject* cont = flow->continuation();
336         if (cont)
337             beforeChildParent = cont;
338         else
339             beforeChildParent = flow;
340     }
341
342     if (newChild->isFloatingOrPositioned()) {
343         beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
344         return;
345     }
346
347     // A continuation always consists of two potential candidates: a block or an anonymous
348     // column span box holding column span children.
349     bool childIsNormal = newChild->isInline() || !newChild->style()->columnSpan();
350     bool bcpIsNormal = beforeChildParent->isInline() || !beforeChildParent->style()->columnSpan();
351     bool flowIsNormal = flow->isInline() || !flow->style()->columnSpan();
352
353     if (flow == beforeChildParent) {
354         flow->addChildIgnoringContinuation(newChild, beforeChild);
355         return;
356     }
357     
358     // The goal here is to match up if we can, so that we can coalesce and create the
359     // minimal # of continuations needed for the inline.
360     if (childIsNormal == bcpIsNormal) {
361         beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
362         return;
363     }
364     if (flowIsNormal == childIsNormal) {
365         flow->addChildIgnoringContinuation(newChild, 0); // Just treat like an append.
366         return;
367     }
368     beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
369 }
370
371
372 void RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
373 {
374     ASSERT(!continuation()); // We don't yet support column spans that aren't immediate children of the multi-column block.
375         
376     // The goal is to locate a suitable box in which to place our child.
377     RenderBlock* beforeChildParent = toRenderBlock(beforeChild && beforeChild->parent()->isRenderBlock() ? beforeChild->parent() : lastChild());
378     
379     // If the new child is floating or positioned it can just go in that block.
380     if (newChild->isFloatingOrPositioned()) {
381         beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
382         return;
383     }
384
385     // See if the child can be placed in the box.
386     bool newChildHasColumnSpan = newChild->style()->columnSpan() && !newChild->isInline();
387     bool beforeChildParentHoldsColumnSpans = beforeChildParent->isAnonymousColumnSpanBlock();
388
389     if (newChildHasColumnSpan == beforeChildParentHoldsColumnSpans) {
390         beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
391         return;
392     }
393
394     if (!beforeChild) {
395         // Create a new block of the correct type.
396         RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
397         children()->appendChildNode(this, newBox);
398         newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
399         return;
400     }
401
402     RenderObject* immediateChild = beforeChild;
403     bool isPreviousBlockViable = true;
404     while (immediateChild->parent() != this) {
405         if (isPreviousBlockViable)
406             isPreviousBlockViable = !immediateChild->previousSibling();
407         immediateChild = immediateChild->parent();
408     }
409     if (isPreviousBlockViable && immediateChild->previousSibling()) {
410         toRenderBlock(immediateChild->previousSibling())->addChildIgnoringAnonymousColumnBlocks(newChild, 0); // Treat like an append.
411         return;
412     }
413         
414     // Split our anonymous blocks.
415     RenderObject* newBeforeChild = splitAnonymousBlocksAroundChild(beforeChild);
416     
417     // Create a new anonymous box of the appropriate type.
418     RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
419     children()->insertChildNode(this, newBox, newBeforeChild);
420     newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
421     return;
422 }
423
424 RenderBlock* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBlock)
425 {
426     for (RenderObject* curr = this; curr; curr = curr->parent()) {
427         if (!curr->isRenderBlock() || curr->isFloatingOrPositioned() || curr->isTableCell() || curr->isRoot() || curr->isRenderView() || curr->hasOverflowClip()
428             || curr->isInlineBlockOrInlineTable())
429             return 0;
430         
431         RenderBlock* currBlock = toRenderBlock(curr);
432         if (currBlock->style()->specifiesColumns() && (allowAnonymousColumnBlock || !currBlock->isAnonymousColumnsBlock()))
433             return currBlock;
434             
435         if (currBlock->isAnonymousColumnSpanBlock())
436             return 0;
437     }
438     return 0;
439 }
440
441 RenderBlock* RenderBlock::clone() const
442 {
443     RenderBlock* cloneBlock;
444     if (isAnonymousBlock())
445         cloneBlock = createAnonymousBlock();
446     else {
447         cloneBlock = new (renderArena()) RenderBlock(node());
448         cloneBlock->setStyle(style());
449     }
450     cloneBlock->setChildrenInline(childrenInline());
451     return cloneBlock;
452 }
453
454 void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
455                               RenderBlock* middleBlock,
456                               RenderObject* beforeChild, RenderBoxModelObject* oldCont)
457 {
458     // Create a clone of this inline.
459     RenderBlock* cloneBlock = clone();
460     if (!isAnonymousBlock())
461         cloneBlock->setContinuation(oldCont);
462
463     // Now take all of the children from beforeChild to the end and remove
464     // them from |this| and place them in the clone.
465     if (!beforeChild && isAfterContent(lastChild()))
466         beforeChild = lastChild();
467     moveChildrenTo(cloneBlock, beforeChild, 0);
468     
469     // Hook |clone| up as the continuation of the middle block.
470     if (!cloneBlock->isAnonymousBlock())
471         middleBlock->setContinuation(cloneBlock);
472
473     // We have been reparented and are now under the fromBlock.  We need
474     // to walk up our block parent chain until we hit the containing anonymous columns block.
475     // Once we hit the anonymous columns block we're done.
476     RenderBoxModelObject* curr = toRenderBoxModelObject(parent());
477     RenderBoxModelObject* currChild = this;
478     
479     while (curr && curr != fromBlock) {
480         ASSERT(curr->isRenderBlock());
481         
482         RenderBlock* blockCurr = toRenderBlock(curr);
483         
484         // Create a new clone.
485         RenderBlock* cloneChild = cloneBlock;
486         cloneBlock = blockCurr->clone();
487
488         // Insert our child clone as the first child.
489         cloneBlock->children()->appendChildNode(cloneBlock, cloneChild);
490
491         // Hook the clone up as a continuation of |curr|.  Note we do encounter
492         // anonymous blocks possibly as we walk up the block chain.  When we split an
493         // anonymous block, there's no need to do any continuation hookup, since we haven't
494         // actually split a real element.
495         if (!blockCurr->isAnonymousBlock()) {
496             oldCont = blockCurr->continuation();
497             blockCurr->setContinuation(cloneBlock);
498             cloneBlock->setContinuation(oldCont);
499         }
500
501         // Someone may have indirectly caused a <q> to split.  When this happens, the :after content
502         // has to move into the inline continuation.  Call updateBeforeAfterContent to ensure that the inline's :after
503         // content gets properly destroyed.
504         if (document()->usesBeforeAfterRules())
505             blockCurr->children()->updateBeforeAfterContent(blockCurr, AFTER);
506
507         // Now we need to take all of the children starting from the first child
508         // *after* currChild and append them all to the clone.
509         RenderObject* afterContent = isAfterContent(cloneBlock->lastChild()) ? cloneBlock->lastChild() : 0;
510         blockCurr->moveChildrenTo(cloneBlock, currChild->nextSibling(), 0, afterContent);
511
512         // Keep walking up the chain.
513         currChild = curr;
514         curr = toRenderBoxModelObject(curr->parent());
515     }
516
517     // Now we are at the columns block level. We need to put the clone into the toBlock.
518     toBlock->children()->appendChildNode(toBlock, cloneBlock);
519
520     // Now take all the children after currChild and remove them from the fromBlock
521     // and put them in the toBlock.
522     fromBlock->moveChildrenTo(toBlock, currChild->nextSibling(), 0);
523 }
524
525 void RenderBlock::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
526                             RenderObject* newChild, RenderBoxModelObject* oldCont)
527 {
528     RenderBlock* pre = 0;
529     RenderBlock* block = containingColumnsBlock();
530     
531     // Delete our line boxes before we do the inline split into continuations.
532     block->deleteLineBoxTree();
533     
534     bool madeNewBeforeBlock = false;
535     if (block->isAnonymousColumnsBlock()) {
536         // We can reuse this block and make it the preBlock of the next continuation.
537         pre = block;
538         pre->removePositionedObjects(0);
539         block = toRenderBlock(block->parent());
540     } else {
541         // No anonymous block available for use.  Make one.
542         pre = block->createAnonymousColumnsBlock();
543         pre->setChildrenInline(false);
544         madeNewBeforeBlock = true;
545     }
546
547     RenderBlock* post = block->createAnonymousColumnsBlock();
548     post->setChildrenInline(false);
549
550     RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
551     if (madeNewBeforeBlock)
552         block->children()->insertChildNode(block, pre, boxFirst);
553     block->children()->insertChildNode(block, newBlockBox, boxFirst);
554     block->children()->insertChildNode(block, post, boxFirst);
555     block->setChildrenInline(false);
556     
557     if (madeNewBeforeBlock)
558         block->moveChildrenTo(pre, boxFirst, 0);
559
560     splitBlocks(pre, post, newBlockBox, beforeChild, oldCont);
561
562     // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
563     // time in makeChildrenNonInline by just setting this explicitly up front.
564     newBlockBox->setChildrenInline(false);
565
566     // We delayed adding the newChild until now so that the |newBlockBox| would be fully
567     // connected, thus allowing newChild access to a renderArena should it need
568     // to wrap itself in additional boxes (e.g., table construction).
569     newBlockBox->addChild(newChild);
570
571     // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
572     // get deleted properly.  Because objects moves from the pre block into the post block, we want to
573     // make new line boxes instead of leaving the old line boxes around.
574     pre->setNeedsLayoutAndPrefWidthsRecalc();
575     block->setNeedsLayoutAndPrefWidthsRecalc();
576     post->setNeedsLayoutAndPrefWidthsRecalc();
577 }
578
579 RenderObject* RenderBlock::splitAnonymousBlocksAroundChild(RenderObject* beforeChild)
580 {
581     while (beforeChild->parent() != this) {
582         RenderBlock* blockToSplit = toRenderBlock(beforeChild->parent());
583         if (blockToSplit->firstChild() != beforeChild) {
584             // We have to split the parentBlock into two blocks.
585             RenderBlock* post = createAnonymousBlockWithSameTypeAs(blockToSplit);
586             post->setChildrenInline(blockToSplit->childrenInline());
587             RenderBlock* parentBlock = toRenderBlock(blockToSplit->parent());
588             parentBlock->children()->insertChildNode(parentBlock, post, blockToSplit->nextSibling());
589             blockToSplit->moveChildrenTo(post, beforeChild, 0, blockToSplit->hasLayer());
590             post->setNeedsLayoutAndPrefWidthsRecalc();
591             blockToSplit->setNeedsLayoutAndPrefWidthsRecalc();
592             beforeChild = post;
593         } else
594             beforeChild = blockToSplit;
595     }
596     return beforeChild;
597 }
598
599 void RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlock* newBlockBox, RenderObject* newChild)
600 {
601     RenderBlock* pre = 0;
602     RenderBlock* post = 0;
603     RenderBlock* block = this; // Eventually block will not just be |this|, but will also be a block nested inside |this|.  Assign to a variable
604                                // so that we don't have to patch all of the rest of the code later on.
605     
606     // Delete the block's line boxes before we do the split.
607     block->deleteLineBoxTree();
608
609     if (beforeChild && beforeChild->parent() != this)
610         beforeChild = splitAnonymousBlocksAroundChild(beforeChild);
611
612     if (beforeChild != firstChild()) {
613         pre = block->createAnonymousColumnsBlock();
614         pre->setChildrenInline(block->childrenInline());
615     }
616
617     if (beforeChild) {
618         post = block->createAnonymousColumnsBlock();
619         post->setChildrenInline(block->childrenInline());
620     }
621
622     RenderObject* boxFirst = block->firstChild();
623     if (pre)
624         block->children()->insertChildNode(block, pre, boxFirst);
625     block->children()->insertChildNode(block, newBlockBox, boxFirst);
626     if (post)
627         block->children()->insertChildNode(block, post, boxFirst);
628     block->setChildrenInline(false);
629     
630     // The pre/post blocks always have layers, so we know to always do a full insert/remove (so we pass true as the last argument).
631     block->moveChildrenTo(pre, boxFirst, beforeChild, true);
632     block->moveChildrenTo(post, beforeChild, 0, true);
633
634     // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
635     // time in makeChildrenNonInline by just setting this explicitly up front.
636     newBlockBox->setChildrenInline(false);
637
638     // We delayed adding the newChild until now so that the |newBlockBox| would be fully
639     // connected, thus allowing newChild access to a renderArena should it need
640     // to wrap itself in additional boxes (e.g., table construction).
641     newBlockBox->addChild(newChild);
642
643     // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
644     // get deleted properly.  Because objects moved from the pre block into the post block, we want to
645     // make new line boxes instead of leaving the old line boxes around.
646     if (pre)
647         pre->setNeedsLayoutAndPrefWidthsRecalc();
648     block->setNeedsLayoutAndPrefWidthsRecalc();
649     if (post)
650         post->setNeedsLayoutAndPrefWidthsRecalc();
651 }
652
653 RenderBlock* RenderBlock::columnsBlockForSpanningElement(RenderObject* newChild)
654 {
655     // FIXME: This function is the gateway for the addition of column-span support.  It will
656     // be added to in three stages:
657     // (1) Immediate children of a multi-column block can span.
658     // (2) Nested block-level children with only block-level ancestors between them and the multi-column block can span.
659     // (3) Nested children with block or inline ancestors between them and the multi-column block can span (this is when we
660     // cross the streams and have to cope with both types of continuations mixed together).
661     // This function currently supports (1) and (2).
662     RenderBlock* columnsBlockAncestor = 0;
663     if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isFloatingOrPositioned()
664         && !newChild->isInline() && !isAnonymousColumnSpanBlock()) {
665         if (style()->specifiesColumns())
666             columnsBlockAncestor = this;
667         else if (!isInline() && parent() && parent()->isRenderBlock()) {
668             columnsBlockAncestor = toRenderBlock(parent())->containingColumnsBlock(false);
669             
670             if (columnsBlockAncestor) {
671                 // Make sure that none of the parent ancestors have a continuation.
672                 // If yes, we do not want split the block into continuations.
673                 RenderObject* curr = this;
674                 while (curr && curr != columnsBlockAncestor) {
675                     if (curr->isRenderBlock() && toRenderBlock(curr)->continuation()) {
676                         columnsBlockAncestor = 0;
677                         break;
678                     }
679                     curr = curr->parent();
680                 }
681             }
682         }
683     }
684     return columnsBlockAncestor;
685 }
686
687 void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
688 {
689     // Make sure we don't append things after :after-generated content if we have it.
690     if (!beforeChild)
691         beforeChild = afterPseudoElementRenderer();
692
693     // If the requested beforeChild is not one of our children, then this is because
694     // there is an anonymous container within this object that contains the beforeChild.
695     if (beforeChild && beforeChild->parent() != this) {
696         RenderObject* beforeChildAnonymousContainer = anonymousContainer(beforeChild);
697         ASSERT(beforeChildAnonymousContainer);
698         ASSERT(beforeChildAnonymousContainer->isAnonymous());
699
700         if (beforeChildAnonymousContainer->isAnonymousBlock()) {
701             // Insert the child into the anonymous block box instead of here.
702             if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)
703                 beforeChild->parent()->addChild(newChild, beforeChild);
704             else
705                 addChild(newChild, beforeChild->parent());
706             return;
707         }
708
709         ASSERT(beforeChildAnonymousContainer->isTable());
710         if ((newChild->isTableCol() && newChild->style()->display() == TABLE_COLUMN_GROUP)
711                 || (newChild->isRenderBlock() && newChild->style()->display() == TABLE_CAPTION)
712                 || newChild->isTableSection()
713                 || newChild->isTableRow()
714                 || newChild->isTableCell()) {
715             // Insert into the anonymous table.
716             beforeChildAnonymousContainer->addChild(newChild, beforeChild);
717             return;
718         }
719
720         // Go on to insert before the anonymous table.
721         beforeChild = beforeChildAnonymousContainer;
722     }
723
724     // Check for a spanning element in columns.
725     RenderBlock* columnsBlockAncestor = columnsBlockForSpanningElement(newChild);
726     if (columnsBlockAncestor) {
727         // We are placing a column-span element inside a block. 
728         RenderBlock* newBox = createAnonymousColumnSpanBlock();
729         
730         if (columnsBlockAncestor != this) {
731             // We are nested inside a multi-column element and are being split by the span.  We have to break up
732             // our block into continuations.
733             RenderBoxModelObject* oldContinuation = continuation();
734             setContinuation(newBox);
735
736             // Someone may have put a <p> inside a <q>, causing a split.  When this happens, the :after content
737             // has to move into the inline continuation.  Call updateBeforeAfterContent to ensure that our :after
738             // content gets properly destroyed.
739             bool isLastChild = (beforeChild == lastChild());
740             if (document()->usesBeforeAfterRules())
741                 children()->updateBeforeAfterContent(this, AFTER);
742             if (isLastChild && beforeChild != lastChild())
743                 beforeChild = 0; // We destroyed the last child, so now we need to update our insertion
744                                  // point to be 0.  It's just a straight append now.
745
746             splitFlow(beforeChild, newBox, newChild, oldContinuation);
747             return;
748         }
749
750         // We have to perform a split of this block's children.  This involves creating an anonymous block box to hold
751         // the column-spanning |newChild|.  We take all of the children from before |newChild| and put them into
752         // one anonymous columns block, and all of the children after |newChild| go into another anonymous block.
753         makeChildrenAnonymousColumnBlocks(beforeChild, newBox, newChild);
754         return;
755     }
756
757     bool madeBoxesNonInline = false;
758
759     // A block has to either have all of its children inline, or all of its children as blocks.
760     // So, if our children are currently inline and a block child has to be inserted, we move all our
761     // inline children into anonymous block boxes.
762     if (childrenInline() && !newChild->isInline() && !newChild->isFloatingOrPositioned()) {
763         // This is a block with inline content. Wrap the inline content in anonymous blocks.
764         makeChildrenNonInline(beforeChild);
765         madeBoxesNonInline = true;
766
767         if (beforeChild && beforeChild->parent() != this) {
768             beforeChild = beforeChild->parent();
769             ASSERT(beforeChild->isAnonymousBlock());
770             ASSERT(beforeChild->parent() == this);
771         }
772     } else if (!childrenInline() && (newChild->isFloatingOrPositioned() || newChild->isInline())) {
773         // If we're inserting an inline child but all of our children are blocks, then we have to make sure
774         // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise
775         // a new one is created and inserted into our list of children in the appropriate position.
776         RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();
777
778         if (afterChild && afterChild->isAnonymousBlock()) {
779             afterChild->addChild(newChild);
780             return;
781         }
782
783         if (newChild->isInline()) {
784             // No suitable existing anonymous box - create a new one.
785             RenderBlock* newBox = createAnonymousBlock();
786             RenderBox::addChild(newBox, beforeChild);
787             newBox->addChild(newChild);
788             return;
789         }
790     }
791
792     RenderBox::addChild(newChild, beforeChild);
793
794     if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRenderBlock())
795         toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
796     // this object may be dead here
797 }
798
799 void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
800 {
801     if (continuation() && !isAnonymousBlock())
802         addChildToContinuation(newChild, beforeChild);
803     else
804         addChildIgnoringContinuation(newChild, beforeChild);
805 }
806
807 void RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild)
808 {
809     if (!isAnonymousBlock() && firstChild() && (firstChild()->isAnonymousColumnsBlock() || firstChild()->isAnonymousColumnSpanBlock()))
810         addChildToAnonymousColumnBlocks(newChild, beforeChild);
811     else
812         addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
813 }
814
815 static void getInlineRun(RenderObject* start, RenderObject* boundary,
816                          RenderObject*& inlineRunStart,
817                          RenderObject*& inlineRunEnd)
818 {
819     // Beginning at |start| we find the largest contiguous run of inlines that
820     // we can.  We denote the run with start and end points, |inlineRunStart|
821     // and |inlineRunEnd|.  Note that these two values may be the same if
822     // we encounter only one inline.
823     //
824     // We skip any non-inlines we encounter as long as we haven't found any
825     // inlines yet.
826     //
827     // |boundary| indicates a non-inclusive boundary point.  Regardless of whether |boundary|
828     // is inline or not, we will not include it in a run with inlines before it.  It's as though we encountered
829     // a non-inline.
830     
831     // Start by skipping as many non-inlines as we can.
832     RenderObject * curr = start;
833     bool sawInline;
834     do {
835         while (curr && !(curr->isInline() || curr->isFloatingOrPositioned()))
836             curr = curr->nextSibling();
837         
838         inlineRunStart = inlineRunEnd = curr;
839         
840         if (!curr)
841             return; // No more inline children to be found.
842         
843         sawInline = curr->isInline();
844         
845         curr = curr->nextSibling();
846         while (curr && (curr->isInline() || curr->isFloatingOrPositioned()) && (curr != boundary)) {
847             inlineRunEnd = curr;
848             if (curr->isInline())
849                 sawInline = true;
850             curr = curr->nextSibling();
851         }
852     } while (!sawInline);
853 }
854
855 void RenderBlock::deleteLineBoxTree()
856 {
857     if (containsFloats()) {
858         // Clear references to originating lines, since the lines are being deleted
859         const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
860         FloatingObjectSetIterator end = floatingObjectSet.end();
861         for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
862             ASSERT(!((*it)->m_originatingLine) || (*it)->m_originatingLine->renderer() == this);
863             (*it)->m_originatingLine = 0;
864         }
865     }
866     m_lineBoxes.deleteLineBoxTree(renderArena());
867 }
868
869 RootInlineBox* RenderBlock::createRootInlineBox() 
870 {
871     return new (renderArena()) RootInlineBox(this);
872 }
873
874 RootInlineBox* RenderBlock::createAndAppendRootInlineBox()
875 {
876     RootInlineBox* rootBox = createRootInlineBox();
877     m_lineBoxes.appendLineBox(rootBox);
878     return rootBox;
879 }
880
881 void RenderBlock::moveChildTo(RenderBlock* to, RenderObject* child, RenderObject* beforeChild, bool fullRemoveInsert)
882 {
883     ASSERT(this == child->parent());
884     ASSERT(!beforeChild || to == beforeChild->parent());
885     to->children()->insertChildNode(to, children()->removeChildNode(this, child, fullRemoveInsert), beforeChild, fullRemoveInsert);
886 }
887
888 void RenderBlock::moveChildrenTo(RenderBlock* to, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert)
889 {
890     ASSERT(!beforeChild || to == beforeChild->parent());
891     RenderObject* nextChild = startChild;
892     while (nextChild && nextChild != endChild) {
893         RenderObject* child = nextChild;
894         nextChild = child->nextSibling();
895         to->children()->insertChildNode(to, children()->removeChildNode(this, child, fullRemoveInsert), beforeChild, fullRemoveInsert);
896         if (child == endChild)
897             return;
898     }
899 }
900
901 void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
902 {    
903     // makeChildrenNonInline takes a block whose children are *all* inline and it
904     // makes sure that inline children are coalesced under anonymous
905     // blocks.  If |insertionPoint| is defined, then it represents the insertion point for
906     // the new block child that is causing us to have to wrap all the inlines.  This
907     // means that we cannot coalesce inlines before |insertionPoint| with inlines following
908     // |insertionPoint|, because the new child is going to be inserted in between the inlines,
909     // splitting them.
910     ASSERT(isInlineBlockOrInlineTable() || !isInline());
911     ASSERT(!insertionPoint || insertionPoint->parent() == this);
912
913     setChildrenInline(false);
914
915     RenderObject *child = firstChild();
916     if (!child)
917         return;
918
919     deleteLineBoxTree();
920
921     while (child) {
922         RenderObject *inlineRunStart, *inlineRunEnd;
923         getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);
924
925         if (!inlineRunStart)
926             break;
927
928         child = inlineRunEnd->nextSibling();
929
930         RenderBlock* block = createAnonymousBlock();
931         children()->insertChildNode(this, block, inlineRunStart);
932         moveChildrenTo(block, inlineRunStart, child);
933     }
934
935 #ifndef NDEBUG
936     for (RenderObject *c = firstChild(); c; c = c->nextSibling())
937         ASSERT(!c->isInline());
938 #endif
939
940     repaint();
941 }
942
943 void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
944 {
945     ASSERT(child->isAnonymousBlock());
946     ASSERT(!child->childrenInline());
947     
948     if (child->continuation() || (child->firstChild() && (child->isAnonymousColumnSpanBlock() || child->isAnonymousColumnsBlock())))
949         return;
950     
951     RenderObject* firstAnChild = child->m_children.firstChild();
952     RenderObject* lastAnChild = child->m_children.lastChild();
953     if (firstAnChild) {
954         RenderObject* o = firstAnChild;
955         while (o) {
956             o->setParent(this);
957             o = o->nextSibling();
958         }
959         firstAnChild->setPreviousSibling(child->previousSibling());
960         lastAnChild->setNextSibling(child->nextSibling());
961         if (child->previousSibling())
962             child->previousSibling()->setNextSibling(firstAnChild);
963         if (child->nextSibling())
964             child->nextSibling()->setPreviousSibling(lastAnChild);
965             
966         if (child == m_children.firstChild())
967             m_children.setFirstChild(firstAnChild);
968         if (child == m_children.lastChild())
969             m_children.setLastChild(lastAnChild);
970     } else {
971         if (child == m_children.firstChild())
972             m_children.setFirstChild(child->nextSibling());
973         if (child == m_children.lastChild())
974             m_children.setLastChild(child->previousSibling());
975
976         if (child->previousSibling())
977             child->previousSibling()->setNextSibling(child->nextSibling());
978         if (child->nextSibling())
979             child->nextSibling()->setPreviousSibling(child->previousSibling());
980     }
981     child->setParent(0);
982     child->setPreviousSibling(0);
983     child->setNextSibling(0);
984     
985     child->children()->setFirstChild(0);
986     child->m_next = 0;
987
988     child->destroy();
989 }
990
991 static bool canMergeContiguousAnonymousBlocks(RenderObject* oldChild, RenderObject* prev, RenderObject* next)
992 {
993     if (oldChild->documentBeingDestroyed() || oldChild->isInline() || oldChild->virtualContinuation())
994         return false;
995
996 #if ENABLE(DETAILS)
997     if (oldChild->parent() && oldChild->parent()->isDetails())
998         return false;
999 #endif
1000
1001     if ((prev && (!prev->isAnonymousBlock() || toRenderBlock(prev)->continuation() || toRenderBlock(prev)->beingDestroyed()))
1002         || (next && (!next->isAnonymousBlock() || toRenderBlock(next)->continuation() || toRenderBlock(next)->beingDestroyed())))
1003         return false;
1004
1005     // FIXME: This check isn't required when inline run-ins can't be split into continuations.
1006     if (prev && prev->firstChild() && prev->firstChild()->isInline() && prev->firstChild()->isRunIn())
1007         return false;
1008
1009     if ((prev && (prev->isRubyRun() || prev->isRubyBase()))
1010         || (next && (next->isRubyRun() || next->isRubyBase())))
1011         return false;
1012
1013     if (!prev || !next)
1014         return true;
1015
1016     // Make sure the types of the anonymous blocks match up.
1017     return prev->isAnonymousColumnsBlock() == next->isAnonymousColumnsBlock()
1018            && prev->isAnonymousColumnSpanBlock() == next->isAnonymousColumnSpanBlock();
1019 }
1020
1021 void RenderBlock::removeChild(RenderObject* oldChild)
1022 {
1023     // If this child is a block, and if our previous and next siblings are
1024     // both anonymous blocks with inline content, then we can go ahead and
1025     // fold the inline content back together.
1026     RenderObject* prev = oldChild->previousSibling();
1027     RenderObject* next = oldChild->nextSibling();
1028     bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, prev, next);
1029     if (canMergeAnonymousBlocks && prev && next) {
1030         prev->setNeedsLayoutAndPrefWidthsRecalc();
1031         RenderBlock* nextBlock = toRenderBlock(next);
1032         RenderBlock* prevBlock = toRenderBlock(prev);
1033        
1034         if (prev->childrenInline() != next->childrenInline()) {
1035             RenderBlock* inlineChildrenBlock = prev->childrenInline() ? prevBlock : nextBlock;
1036             RenderBlock* blockChildrenBlock = prev->childrenInline() ? nextBlock : prevBlock;
1037             
1038             // Place the inline children block inside of the block children block instead of deleting it.
1039             // In order to reuse it, we have to reset it to just be a generic anonymous block.  Make sure
1040             // to clear out inherited column properties by just making a new style, and to also clear the
1041             // column span flag if it is set.
1042             ASSERT(!inlineChildrenBlock->continuation());
1043             RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
1044             children()->removeChildNode(this, inlineChildrenBlock, inlineChildrenBlock->hasLayer());
1045             inlineChildrenBlock->setStyle(newStyle);
1046             
1047             // Now just put the inlineChildrenBlock inside the blockChildrenBlock.
1048             blockChildrenBlock->children()->insertChildNode(blockChildrenBlock, inlineChildrenBlock, prev == inlineChildrenBlock ? blockChildrenBlock->firstChild() : 0,
1049                                                             inlineChildrenBlock->hasLayer() || blockChildrenBlock->hasLayer());
1050             next->setNeedsLayoutAndPrefWidthsRecalc();
1051             
1052             // inlineChildrenBlock got reparented to blockChildrenBlock, so it is no longer a child
1053             // of "this". we null out prev or next so that is not used later in the function.
1054             if (inlineChildrenBlock == prevBlock)
1055                 prev = 0;
1056             else
1057                 next = 0;
1058         } else {
1059             // Take all the children out of the |next| block and put them in
1060             // the |prev| block.
1061             nextBlock->moveAllChildrenTo(prevBlock, nextBlock->hasLayer() || prevBlock->hasLayer());        
1062             
1063             // Delete the now-empty block's lines and nuke it.
1064             nextBlock->deleteLineBoxTree();
1065             nextBlock->destroy();
1066             next = 0;
1067         }
1068     }
1069
1070     RenderBox::removeChild(oldChild);
1071
1072     RenderObject* child = prev ? prev : next;
1073     if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && !isFlexibleBoxIncludingDeprecated()) {
1074         // The removal has knocked us down to containing only a single anonymous
1075         // box.  We can go ahead and pull the content right back up into our
1076         // box.
1077         setNeedsLayoutAndPrefWidthsRecalc();
1078         setChildrenInline(child->childrenInline());
1079         RenderBlock* anonBlock = toRenderBlock(children()->removeChildNode(this, child, child->hasLayer()));
1080         anonBlock->moveAllChildrenTo(this, child->hasLayer());
1081         // Delete the now-empty block's lines and nuke it.
1082         anonBlock->deleteLineBoxTree();
1083         anonBlock->destroy();
1084     }
1085
1086     if (!firstChild() && !documentBeingDestroyed()) {
1087         // If this was our last child be sure to clear out our line boxes.
1088         if (childrenInline())
1089             lineBoxes()->deleteLineBoxes(renderArena());
1090     }
1091 }
1092
1093 bool RenderBlock::isSelfCollapsingBlock() const
1094 {
1095     // We are not self-collapsing if we
1096     // (a) have a non-zero height according to layout (an optimization to avoid wasting time)
1097     // (b) are a table,
1098     // (c) have border/padding,
1099     // (d) have a min-height
1100     // (e) have specified that one of our margins can't collapse using a CSS extension
1101     if (logicalHeight() > 0
1102         || isTable() || borderAndPaddingLogicalHeight()
1103         || style()->logicalMinHeight().isPositive()
1104         || style()->marginBeforeCollapse() == MSEPARATE || style()->marginAfterCollapse() == MSEPARATE)
1105         return false;
1106
1107     Length logicalHeightLength = style()->logicalHeight();
1108     bool hasAutoHeight = logicalHeightLength.isAuto();
1109     if (logicalHeightLength.isPercent() && !document()->inQuirksMode()) {
1110         hasAutoHeight = true;
1111         for (RenderBlock* cb = containingBlock(); !cb->isRenderView(); cb = cb->containingBlock()) {
1112             if (cb->style()->logicalHeight().isFixed() || cb->isTableCell())
1113                 hasAutoHeight = false;
1114         }
1115     }
1116
1117     // If the height is 0 or auto, then whether or not we are a self-collapsing block depends
1118     // on whether we have content that is all self-collapsing or not.
1119     if (hasAutoHeight || ((logicalHeightLength.isFixed() || logicalHeightLength.isPercent()) && logicalHeightLength.isZero())) {
1120         // If the block has inline children, see if we generated any line boxes.  If we have any
1121         // line boxes, then we can't be self-collapsing, since we have content.
1122         if (childrenInline())
1123             return !firstLineBox();
1124         
1125         // Whether or not we collapse is dependent on whether all our normal flow children
1126         // are also self-collapsing.
1127         for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
1128             if (child->isFloatingOrPositioned())
1129                 continue;
1130             if (!child->isSelfCollapsingBlock())
1131                 return false;
1132         }
1133         return true;
1134     }
1135     return false;
1136 }
1137
1138 void RenderBlock::startDelayUpdateScrollInfo()
1139 {
1140     if (gDelayUpdateScrollInfo == 0) {
1141         ASSERT(!gDelayedUpdateScrollInfoSet);
1142         gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet;
1143     }
1144     ASSERT(gDelayedUpdateScrollInfoSet);
1145     ++gDelayUpdateScrollInfo;
1146 }
1147
1148 void RenderBlock::finishDelayUpdateScrollInfo()
1149 {
1150     --gDelayUpdateScrollInfo;
1151     ASSERT(gDelayUpdateScrollInfo >= 0);
1152     if (gDelayUpdateScrollInfo == 0) {
1153         ASSERT(gDelayedUpdateScrollInfoSet);
1154
1155         OwnPtr<DelayedUpdateScrollInfoSet> infoSet(adoptPtr(gDelayedUpdateScrollInfoSet));
1156         gDelayedUpdateScrollInfoSet = 0;
1157
1158         for (DelayedUpdateScrollInfoSet::iterator it = infoSet->begin(); it != infoSet->end(); ++it) {
1159             RenderBlock* block = *it;
1160             if (block->hasOverflowClip()) {
1161                 block->layer()->updateScrollInfoAfterLayout();
1162             }
1163         }
1164     }
1165 }
1166
1167 void RenderBlock::updateScrollInfoAfterLayout()
1168 {
1169     if (hasOverflowClip()) {
1170         if (gDelayUpdateScrollInfo)
1171             gDelayedUpdateScrollInfoSet->add(this);
1172         else
1173             layer()->updateScrollInfoAfterLayout();
1174     }
1175 }
1176
1177 void RenderBlock::layout()
1178 {
1179     // Update our first letter info now.
1180     updateFirstLetter();
1181
1182     // Table cells call layoutBlock directly, so don't add any logic here.  Put code into
1183     // layoutBlock().
1184     layoutBlock(false);
1185     
1186     // It's safe to check for control clip here, since controls can never be table cells.
1187     // If we have a lightweight clip, there can never be any overflow from children.
1188     if (hasControlClip() && m_overflow)
1189         clearLayoutOverflow();
1190 }
1191
1192 void RenderBlock::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight, BlockLayoutPass layoutPass)
1193 {
1194     ASSERT(needsLayout());
1195
1196     if (isInline() && !isInlineBlockOrInlineTable()) // Inline <form>s inside various table elements can
1197         return;                                      // cause us to come in here.  Just bail.
1198
1199     if (!relayoutChildren && simplifiedLayout())
1200         return;
1201
1202     LayoutRepainter repainter(*this, m_everHadLayout && checkForRepaintDuringLayout());
1203
1204     LayoutUnit oldWidth = logicalWidth();
1205     LayoutUnit oldColumnWidth = desiredColumnWidth();
1206
1207     computeLogicalWidth();
1208     calcColumnWidth();
1209
1210     m_overflow.clear();
1211
1212     if (oldWidth != logicalWidth() || oldColumnWidth != desiredColumnWidth())
1213         relayoutChildren = true;
1214
1215     // If nothing changed about our floating positioned objects, let's go ahead and try to place them as
1216     // floats to avoid doing two passes.
1217     BlockLayoutPass floatsLayoutPass = layoutPass;
1218     if (floatsLayoutPass == NormalLayoutPass && !relayoutChildren && !positionedFloatsNeedRelayout())
1219         floatsLayoutPass = PositionedFloatLayoutPass;
1220     clearFloats(floatsLayoutPass);
1221
1222     LayoutUnit previousHeight = logicalHeight();
1223     setLogicalHeight(0);
1224     bool hasSpecifiedPageLogicalHeight = false;
1225     bool pageLogicalHeightChanged = false;
1226     ColumnInfo* colInfo = columnInfo();
1227     if (hasColumns()) {
1228         if (!pageLogicalHeight) {
1229             // We need to go ahead and set our explicit page height if one exists, so that we can
1230             // avoid doing two layout passes.
1231             computeLogicalHeight();
1232             LayoutUnit columnHeight = contentLogicalHeight();
1233             if (columnHeight > 0) {
1234                 pageLogicalHeight = columnHeight;
1235                 hasSpecifiedPageLogicalHeight = true;
1236             }
1237             setLogicalHeight(0);
1238         }
1239         if (colInfo->columnHeight() != pageLogicalHeight && m_everHadLayout) {
1240             colInfo->setColumnHeight(pageLogicalHeight);
1241             pageLogicalHeightChanged = true;
1242         }
1243         
1244         if (!hasSpecifiedPageLogicalHeight && !pageLogicalHeight)
1245             colInfo->clearForcedBreaks();
1246     }
1247
1248     RenderView* renderView = view();
1249     LayoutStateMaintainer statePusher(renderView, this, locationOffset(), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode(), pageLogicalHeight, pageLogicalHeightChanged, colInfo);
1250     
1251     if (inRenderFlowThread()) {
1252         // Regions changing widths can force us to relayout our children.
1253         if (logicalWidthChangedInRegions())
1254             relayoutChildren = true;
1255     
1256         // Set our start and end regions. No regions above or below us will be considered by our children. They are
1257         // effectively clamped to our region range.
1258         LayoutUnit oldHeight =  logicalHeight();
1259         LayoutUnit oldLogicalTop = logicalTop();
1260         setLogicalHeight(numeric_limits<LayoutUnit>::max() / 2); 
1261         computeLogicalHeight();
1262         enclosingRenderFlowThread()->setRegionRangeForBox(this, offsetFromLogicalTopOfFirstPage());
1263         setLogicalHeight(oldHeight);
1264         setLogicalTop(oldLogicalTop);
1265     }
1266
1267     // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track
1268     // our current maximal positive and negative margins.  These values are used when we
1269     // are collapsed with adjacent blocks, so for example, if you have block A and B
1270     // collapsing together, then you'd take the maximal positive margin from both A and B
1271     // and subtract it from the maximal negative margin from both A and B to get the
1272     // true collapsed margin.  This algorithm is recursive, so when we finish layout()
1273     // our block knows its current maximal positive/negative values.
1274     //
1275     // Start out by setting our margin values to our current margins.  Table cells have
1276     // no margins, so we don't fill in the values for table cells.
1277     bool isCell = isTableCell();
1278     if (!isCell) {
1279         initMaxMarginValues();
1280         
1281         setMarginBeforeQuirk(style()->marginBefore().quirk());
1282         setMarginAfterQuirk(style()->marginAfter().quirk());
1283
1284         Node* n = node();
1285         if (n && n->hasTagName(formTag) && static_cast<HTMLFormElement*>(n)->isMalformed()) {
1286             // See if this form is malformed (i.e., unclosed). If so, don't give the form
1287             // a bottom margin.
1288             setMaxMarginAfterValues(0, 0);
1289         }
1290         
1291         setPaginationStrut(0);
1292     }
1293
1294     // For overflow:scroll blocks, ensure we have both scrollbars in place always.
1295     if (scrollsOverflow()) {
1296         if (style()->overflowX() == OSCROLL)
1297             layer()->setHasHorizontalScrollbar(true);
1298         if (style()->overflowY() == OSCROLL)
1299             layer()->setHasVerticalScrollbar(true);
1300     }
1301
1302     LayoutUnit repaintLogicalTop = 0;
1303     LayoutUnit repaintLogicalBottom = 0;
1304     LayoutUnit maxFloatLogicalBottom = 0;
1305     if (!firstChild() && !isAnonymousBlock())
1306         setChildrenInline(true);
1307     if (childrenInline())
1308         layoutInlineChildren(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
1309     else
1310         layoutBlockChildren(relayoutChildren, maxFloatLogicalBottom);
1311
1312     // Expand our intrinsic height to encompass floats.
1313     LayoutUnit toAdd = borderAfter() + paddingAfter() + scrollbarLogicalHeight();
1314     if (lowestFloatLogicalBottom() > (logicalHeight() - toAdd) && expandsToEncloseOverhangingFloats())
1315         setLogicalHeight(lowestFloatLogicalBottom() + toAdd);
1316     
1317     if (layoutColumns(hasSpecifiedPageLogicalHeight, pageLogicalHeight, statePusher))
1318         return;
1319  
1320     // Calculate our new height.
1321     LayoutUnit oldHeight = logicalHeight();
1322     LayoutUnit oldClientAfterEdge = clientLogicalBottom();
1323     computeLogicalHeight();
1324     LayoutUnit newHeight = logicalHeight();
1325     if (oldHeight != newHeight) {
1326         if (oldHeight > newHeight && maxFloatLogicalBottom > newHeight && !childrenInline()) {
1327             // One of our children's floats may have become an overhanging float for us. We need to look for it.
1328             for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
1329                 if (child->isBlockFlow() && !child->isFloatingOrPositioned()) {
1330                     RenderBlock* block = toRenderBlock(child);
1331                     if (block->lowestFloatLogicalBottomIncludingPositionedFloats() + block->logicalTop() > newHeight)
1332                         addOverhangingFloats(block, false);
1333                 }
1334             }
1335         }
1336     }
1337
1338     if (previousHeight != newHeight)
1339         relayoutChildren = true;
1340
1341     bool needAnotherLayoutPass = layoutPositionedObjects(relayoutChildren || isRoot());
1342
1343     if (inRenderFlowThread())
1344         enclosingRenderFlowThread()->setRegionRangeForBox(this, offsetFromLogicalTopOfFirstPage());
1345
1346     // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway).
1347     computeOverflow(oldClientAfterEdge);
1348     
1349     statePusher.pop();
1350
1351     if (renderView->layoutState()->m_pageLogicalHeight)
1352         setPageLogicalOffset(renderView->layoutState()->pageLogicalOffset(logicalTop()));
1353
1354     updateLayerTransform();
1355
1356     // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
1357     // we overflow or not.
1358     updateScrollInfoAfterLayout();
1359
1360     // FIXME: This repaint logic should be moved into a separate helper function!
1361     // Repaint with our new bounds if they are different from our old bounds.
1362     bool didFullRepaint = repainter.repaintAfterLayout();
1363     if (!didFullRepaint && repaintLogicalTop != repaintLogicalBottom && (style()->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) {
1364         // FIXME: We could tighten up the left and right invalidation points if we let layoutInlineChildren fill them in based off the particular lines
1365         // it had to lay out.  We wouldn't need the hasOverflowClip() hack in that case either.
1366         LayoutUnit repaintLogicalLeft = logicalLeftVisualOverflow();
1367         LayoutUnit repaintLogicalRight = logicalRightVisualOverflow();
1368         if (hasOverflowClip()) {
1369             // 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.
1370             // 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.
1371             // layoutInlineChildren should be patched to compute the entire repaint rect.
1372             repaintLogicalLeft = min(repaintLogicalLeft, logicalLeftLayoutOverflow());
1373             repaintLogicalRight = max(repaintLogicalRight, logicalRightLayoutOverflow());
1374         }
1375         
1376         LayoutRect repaintRect;
1377         if (isHorizontalWritingMode())
1378             repaintRect = LayoutRect(repaintLogicalLeft, repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop);
1379         else
1380             repaintRect = LayoutRect(repaintLogicalTop, repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft);
1381
1382         // The repaint rect may be split across columns, in which case adjustRectForColumns() will return the union.
1383         adjustRectForColumns(repaintRect);
1384
1385         repaintRect.inflate(maximalOutlineSize(PaintPhaseOutline));
1386         
1387         if (hasOverflowClip()) {
1388             // Adjust repaint rect for scroll offset
1389             repaintRect.move(-layer()->scrolledContentOffset());
1390
1391             // Don't allow this rect to spill out of our overflow box.
1392             repaintRect.intersect(LayoutRect(LayoutPoint(), size()));
1393         }
1394
1395         // Make sure the rect is still non-empty after intersecting for overflow above
1396         if (!repaintRect.isEmpty()) {
1397             // FIXME: Might need rounding once we switch to float, see https://bugs.webkit.org/show_bug.cgi?id=64021
1398             repaintRectangle(repaintRect); // We need to do a partial repaint of our content.
1399             if (hasReflection())
1400                 repaintRectangle(reflectedRect(repaintRect));
1401         }
1402     }
1403     
1404     if (needAnotherLayoutPass && layoutPass == NormalLayoutPass) {
1405         setChildNeedsLayout(true, false);
1406         layoutBlock(false, pageLogicalHeight, PositionedFloatLayoutPass);
1407     } else
1408         setNeedsLayout(false);
1409 }
1410
1411 void RenderBlock::addOverflowFromChildren()
1412 {
1413     if (!hasColumns()) {
1414         if (childrenInline())
1415             addOverflowFromInlineChildren();
1416         else
1417             addOverflowFromBlockChildren();
1418     } else {
1419         ColumnInfo* colInfo = columnInfo();
1420         if (columnCount(colInfo)) {
1421             LayoutRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
1422             addLayoutOverflow(lastRect);
1423             if (!hasOverflowClip())
1424                 addVisualOverflow(lastRect);
1425         }
1426     }
1427 }
1428
1429 void RenderBlock::computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeFloats)
1430 {
1431     // Add overflow from children.
1432     addOverflowFromChildren();
1433
1434     if (!hasColumns() && (recomputeFloats || isRoot() || expandsToEncloseOverhangingFloats() || hasSelfPaintingLayer()))
1435         addOverflowFromFloats();
1436
1437     // Add in the overflow from positioned objects.
1438     addOverflowFromPositionedObjects();
1439
1440     if (hasOverflowClip()) {
1441         // When we have overflow clip, propagate the original spillout since it will include collapsed bottom margins
1442         // and bottom padding.  Set the axis we don't care about to be 1, since we want this overflow to always
1443         // be considered reachable.
1444         LayoutRect clientRect(clientBoxRect());
1445         LayoutRect rectToApply;
1446         if (isHorizontalWritingMode())
1447             rectToApply = LayoutRect(clientRect.x(), clientRect.y(), 1, max<LayoutUnit>(0, oldClientAfterEdge - clientRect.y()));
1448         else
1449             rectToApply = LayoutRect(clientRect.x(), clientRect.y(), max<LayoutUnit>(0, oldClientAfterEdge - clientRect.x()), 1);
1450         addLayoutOverflow(rectToApply);
1451     }
1452         
1453     // Add visual overflow from box-shadow and border-image-outset.
1454     addBoxShadowAndBorderOverflow();
1455 }
1456
1457 void RenderBlock::addOverflowFromBlockChildren()
1458 {
1459     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
1460         if (!child->isFloatingOrPositioned())
1461             addOverflowFromChild(child);
1462     }
1463 }
1464
1465 void RenderBlock::addOverflowFromFloats()
1466 {
1467     if (!m_floatingObjects)
1468         return;
1469
1470     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
1471     FloatingObjectSetIterator end = floatingObjectSet.end();
1472     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
1473         FloatingObject* r = *it;
1474         if (r->m_isDescendant && !r->m_renderer->isPositioned())
1475             addOverflowFromChild(r->m_renderer, IntSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r)));
1476     }
1477     return;
1478 }
1479
1480 void RenderBlock::addOverflowFromPositionedObjects()
1481 {
1482     if (!m_positionedObjects)
1483         return;
1484
1485     RenderBox* positionedObject;
1486     Iterator end = m_positionedObjects->end();
1487     for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
1488         positionedObject = *it;
1489         
1490         // Fixed positioned elements don't contribute to layout overflow, since they don't scroll with the content.
1491         if (positionedObject->style()->position() != FixedPosition)
1492             addOverflowFromChild(positionedObject);
1493     }
1494 }
1495
1496 bool RenderBlock::expandsToEncloseOverhangingFloats() const
1497 {
1498     return isInlineBlockOrInlineTable() || isFloatingOrPositioned() || hasOverflowClip() || (parent() && parent()->isDeprecatedFlexibleBox())
1499            || hasColumns() || isTableCell() || isFieldset() || isWritingModeRoot() || isRoot();
1500 }
1501
1502 void RenderBlock::adjustPositionedBlock(RenderBox* child, const MarginInfo& marginInfo)
1503 {
1504     bool isHorizontal = isHorizontalWritingMode();
1505     bool hasStaticBlockPosition = child->style()->hasStaticBlockPosition(isHorizontal);
1506     
1507     LayoutUnit logicalTop = logicalHeight();
1508     setStaticInlinePositionForChild(child, logicalTop, startOffsetForContent(logicalTop));
1509
1510     if (!marginInfo.canCollapseWithMarginBefore()) {
1511         child->computeBlockDirectionMargins(this);
1512         LayoutUnit marginBefore = marginBeforeForChild(child);
1513         LayoutUnit collapsedBeforePos = marginInfo.positiveMargin();
1514         LayoutUnit collapsedBeforeNeg = marginInfo.negativeMargin();
1515         if (marginBefore > 0) {
1516             if (marginBefore > collapsedBeforePos)
1517                 collapsedBeforePos = marginBefore;
1518         } else {
1519             if (-marginBefore > collapsedBeforeNeg)
1520                 collapsedBeforeNeg = -marginBefore;
1521         }
1522         logicalTop += (collapsedBeforePos - collapsedBeforeNeg) - marginBefore;
1523     }
1524     
1525     RenderLayer* childLayer = child->layer();
1526     if (childLayer->staticBlockPosition() != logicalTop) {
1527         childLayer->setStaticBlockPosition(logicalTop);
1528         if (hasStaticBlockPosition)
1529             child->setChildNeedsLayout(true, false);
1530     }
1531 }
1532
1533 void RenderBlock::adjustFloatingBlock(const MarginInfo& marginInfo)
1534 {
1535     // The float should be positioned taking into account the bottom margin
1536     // of the previous flow.  We add that margin into the height, get the
1537     // float positioned properly, and then subtract the margin out of the
1538     // height again.  In the case of self-collapsing blocks, we always just
1539     // use the top margins, since the self-collapsing block collapsed its
1540     // own bottom margin into its top margin.
1541     //
1542     // Note also that the previous flow may collapse its margin into the top of
1543     // our block.  If this is the case, then we do not add the margin in to our
1544     // height when computing the position of the float.   This condition can be tested
1545     // for by simply calling canCollapseWithMarginBefore.  See
1546     // http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html for
1547     // an example of this scenario.
1548     LayoutUnit marginOffset = marginInfo.canCollapseWithMarginBefore() ? 0 : marginInfo.margin();
1549     setLogicalHeight(logicalHeight() + marginOffset);
1550     positionNewFloats();
1551     setLogicalHeight(logicalHeight() - marginOffset);
1552 }
1553
1554 bool RenderBlock::handleSpecialChild(RenderBox* child, const MarginInfo& marginInfo)
1555 {
1556     // Handle in the given order
1557     return handlePositionedChild(child, marginInfo)
1558         || handleFloatingChild(child, marginInfo)
1559         || handleRunInChild(child);
1560 }
1561
1562
1563 bool RenderBlock::handlePositionedChild(RenderBox* child, const MarginInfo& marginInfo)
1564 {
1565     if (child->isPositioned()) {
1566         child->containingBlock()->insertPositionedObject(child);
1567         adjustPositionedBlock(child, marginInfo);
1568         return true;
1569     }
1570     return false;
1571 }
1572
1573 bool RenderBlock::handleFloatingChild(RenderBox* child, const MarginInfo& marginInfo)
1574 {
1575     if (child->isFloating()) {
1576         insertFloatingObject(child);
1577         adjustFloatingBlock(marginInfo);
1578         return true;
1579     }
1580     return false;
1581 }
1582
1583 bool RenderBlock::handleRunInChild(RenderBox* child)
1584 {
1585     // See if we have a run-in element with inline children.  If the
1586     // children aren't inline, then just treat the run-in as a normal
1587     // block.
1588     if (!child->isRunIn() || !child->childrenInline())
1589         return false;
1590     // FIXME: We don't handle non-block elements with run-in for now.
1591     if (!child->isRenderBlock())
1592         return false;
1593
1594     RenderBlock* blockRunIn = toRenderBlock(child);
1595     RenderObject* curr = blockRunIn->nextSibling();
1596     if (!curr || !curr->isRenderBlock() || !curr->childrenInline() || curr->isRunIn() || curr->isAnonymous() || curr->isFloatingOrPositioned())
1597         return false;
1598
1599     RenderBlock* currBlock = toRenderBlock(curr);
1600
1601     // First we destroy any :before/:after content. It will be regenerated by the new inline.
1602     // Exception is if the run-in itself is generated.
1603     if (child->style()->styleType() != BEFORE && child->style()->styleType() != AFTER) {
1604         RenderObject* generatedContent;
1605         if (child->getCachedPseudoStyle(BEFORE) && (generatedContent = child->beforePseudoElementRenderer()))
1606             generatedContent->destroy();
1607         if (child->getCachedPseudoStyle(AFTER) && (generatedContent = child->afterPseudoElementRenderer()))
1608             generatedContent->destroy();
1609     }
1610
1611     // Remove the old child.
1612     children()->removeChildNode(this, blockRunIn);
1613
1614     // Create an inline.
1615     Node* runInNode = blockRunIn->node();
1616     RenderInline* inlineRunIn = new (renderArena()) RenderInline(runInNode ? runInNode : document());
1617     inlineRunIn->setStyle(blockRunIn->style());
1618
1619     // Move the nodes from the old child to the new child
1620     for (RenderObject* runInChild = blockRunIn->firstChild(); runInChild;) {
1621         RenderObject* nextSibling = runInChild->nextSibling();
1622         blockRunIn->children()->removeChildNode(blockRunIn, runInChild, false);
1623         inlineRunIn->addChild(runInChild); // Use addChild instead of appendChildNode since it handles correct placement of the children relative to :after-generated content.
1624         runInChild = nextSibling;
1625     }
1626
1627     // Now insert the new child under |currBlock|. Use addChild instead of insertChildNode since it handles correct placement of the children, esp where we cannot insert
1628     // anything before the first child. e.g. details tag. See https://bugs.webkit.org/show_bug.cgi?id=58228.
1629     currBlock->addChild(inlineRunIn, currBlock->firstChild());
1630     
1631     // If the run-in had an element, we need to set the new renderer.
1632     if (runInNode)
1633         runInNode->setRenderer(inlineRunIn);
1634
1635     // Destroy the block run-in, which includes deleting its line box tree.
1636     blockRunIn->deleteLineBoxTree();
1637     blockRunIn->destroy();
1638
1639     // The block acts like an inline, so just null out its
1640     // position.
1641     
1642     return true;
1643 }
1644
1645 LayoutUnit RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo)
1646 {
1647     // Get the four margin values for the child and cache them.
1648     const MarginValues childMargins = marginValuesForChild(child);
1649
1650     // Get our max pos and neg top margins.
1651     LayoutUnit posTop = childMargins.positiveMarginBefore();
1652     LayoutUnit negTop = childMargins.negativeMarginBefore();
1653
1654     // For self-collapsing blocks, collapse our bottom margins into our
1655     // top to get new posTop and negTop values.
1656     if (child->isSelfCollapsingBlock()) {
1657         posTop = max(posTop, childMargins.positiveMarginAfter());
1658         negTop = max(negTop, childMargins.negativeMarginAfter());
1659     }
1660     
1661     // See if the top margin is quirky. We only care if this child has
1662     // margins that will collapse with us.
1663     bool topQuirk = child->isMarginBeforeQuirk() || style()->marginBeforeCollapse() == MDISCARD;
1664
1665     if (marginInfo.canCollapseWithMarginBefore()) {
1666         // This child is collapsing with the top of the
1667         // block.  If it has larger margin values, then we need to update
1668         // our own maximal values.
1669         if (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !topQuirk)
1670             setMaxMarginBeforeValues(max(posTop, maxPositiveMarginBefore()), max(negTop, maxNegativeMarginBefore()));
1671
1672         // The minute any of the margins involved isn't a quirk, don't
1673         // collapse it away, even if the margin is smaller (www.webreference.com
1674         // has an example of this, a <dt> with 0.8em author-specified inside
1675         // a <dl> inside a <td>.
1676         if (!marginInfo.determinedMarginBeforeQuirk() && !topQuirk && (posTop - negTop)) {
1677             setMarginBeforeQuirk(false);
1678             marginInfo.setDeterminedMarginBeforeQuirk(true);
1679         }
1680
1681         if (!marginInfo.determinedMarginBeforeQuirk() && topQuirk && !marginBefore())
1682             // We have no top margin and our top child has a quirky margin.
1683             // We will pick up this quirky margin and pass it through.
1684             // This deals with the <td><div><p> case.
1685             // Don't do this for a block that split two inlines though.  You do
1686             // still apply margins in this case.
1687             setMarginBeforeQuirk(true);
1688     }
1689
1690     if (marginInfo.quirkContainer() && marginInfo.atBeforeSideOfBlock() && (posTop - negTop))
1691         marginInfo.setMarginBeforeQuirk(topQuirk);
1692
1693     LayoutUnit beforeCollapseLogicalTop = logicalHeight();
1694     LayoutUnit logicalTop = beforeCollapseLogicalTop;
1695     if (child->isSelfCollapsingBlock()) {
1696         // This child has no height.  We need to compute our
1697         // position before we collapse the child's margins together,
1698         // so that we can get an accurate position for the zero-height block.
1699         LayoutUnit collapsedBeforePos = max(marginInfo.positiveMargin(), childMargins.positiveMarginBefore());
1700         LayoutUnit collapsedBeforeNeg = max(marginInfo.negativeMargin(), childMargins.negativeMarginBefore());
1701         marginInfo.setMargin(collapsedBeforePos, collapsedBeforeNeg);
1702         
1703         // Now collapse the child's margins together, which means examining our
1704         // bottom margin values as well. 
1705         marginInfo.setPositiveMarginIfLarger(childMargins.positiveMarginAfter());
1706         marginInfo.setNegativeMarginIfLarger(childMargins.negativeMarginAfter());
1707
1708         if (!marginInfo.canCollapseWithMarginBefore())
1709             // We need to make sure that the position of the self-collapsing block
1710             // is correct, since it could have overflowing content
1711             // that needs to be positioned correctly (e.g., a block that
1712             // had a specified height of 0 but that actually had subcontent).
1713             logicalTop = logicalHeight() + collapsedBeforePos - collapsedBeforeNeg;
1714     }
1715     else {
1716         if (child->style()->marginBeforeCollapse() == MSEPARATE) {
1717             setLogicalHeight(logicalHeight() + marginInfo.margin() + marginBeforeForChild(child));
1718             logicalTop = logicalHeight();
1719         }
1720         else if (!marginInfo.atBeforeSideOfBlock() ||
1721             (!marginInfo.canCollapseMarginBeforeWithChildren()
1722              && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.marginBeforeQuirk()))) {
1723             // We're collapsing with a previous sibling's margins and not
1724             // with the top of the block.
1725             setLogicalHeight(logicalHeight() + max(marginInfo.positiveMargin(), posTop) - max(marginInfo.negativeMargin(), negTop));
1726             logicalTop = logicalHeight();
1727         }
1728
1729         marginInfo.setPositiveMargin(childMargins.positiveMarginAfter());
1730         marginInfo.setNegativeMargin(childMargins.negativeMarginAfter());
1731
1732         if (marginInfo.margin())
1733             marginInfo.setMarginAfterQuirk(child->isMarginAfterQuirk() || style()->marginAfterCollapse() == MDISCARD);
1734     }
1735     
1736     // If margins would pull us past the top of the next page, then we need to pull back and pretend like the margins
1737     // collapsed into the page edge.
1738     LayoutState* layoutState = view()->layoutState();
1739     if (layoutState->isPaginated() && layoutState->pageLogicalHeight() && logicalTop > beforeCollapseLogicalTop
1740         && hasNextPage(beforeCollapseLogicalTop)) {
1741         LayoutUnit oldLogicalTop = logicalTop;
1742         logicalTop = min(logicalTop, nextPageLogicalTop(beforeCollapseLogicalTop));
1743         setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop));
1744     }
1745     return logicalTop;
1746 }
1747
1748 LayoutUnit RenderBlock::clearFloatsIfNeeded(RenderBox* child, MarginInfo& marginInfo, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPos)
1749 {
1750     LayoutUnit heightIncrease = getClearDelta(child, yPos);
1751     if (!heightIncrease)
1752         return yPos;
1753
1754     if (child->isSelfCollapsingBlock()) {
1755         // For self-collapsing blocks that clear, they can still collapse their
1756         // margins with following siblings.  Reset the current margins to represent
1757         // the self-collapsing block's margins only.
1758         // CSS2.1 states:
1759         // "An element that has had clearance applied to it never collapses its top margin with its parent block's bottom margin.
1760         // Therefore if we are at the bottom of the block, let's go ahead and reset margins to only include the
1761         // self-collapsing block's bottom margin.
1762         bool atBottomOfBlock = true;
1763         for (RenderBox* curr = child->nextSiblingBox(); curr && atBottomOfBlock; curr = curr->nextSiblingBox()) {
1764             if (!curr->isFloatingOrPositioned())
1765                 atBottomOfBlock = false;
1766         }
1767         
1768         MarginValues childMargins = marginValuesForChild(child);
1769         if (atBottomOfBlock) {
1770             marginInfo.setPositiveMargin(childMargins.positiveMarginAfter());
1771             marginInfo.setNegativeMargin(childMargins.negativeMarginAfter());
1772         } else {
1773             marginInfo.setPositiveMargin(max(childMargins.positiveMarginBefore(), childMargins.positiveMarginAfter()));
1774             marginInfo.setNegativeMargin(max(childMargins.negativeMarginBefore(), childMargins.negativeMarginAfter()));
1775         }
1776         
1777         // Adjust our height such that we are ready to be collapsed with subsequent siblings (or the bottom
1778         // of the parent block).
1779         setLogicalHeight(child->y() - max<LayoutUnit>(0, marginInfo.margin()));
1780     } else
1781         // Increase our height by the amount we had to clear.
1782         setLogicalHeight(height() + heightIncrease);
1783     
1784     if (marginInfo.canCollapseWithMarginBefore()) {
1785         // We can no longer collapse with the top of the block since a clear
1786         // occurred.  The empty blocks collapse into the cleared block.
1787         // FIXME: This isn't quite correct.  Need clarification for what to do
1788         // if the height the cleared block is offset by is smaller than the
1789         // margins involved.
1790         setMaxMarginBeforeValues(oldTopPosMargin, oldTopNegMargin);
1791         marginInfo.setAtBeforeSideOfBlock(false);
1792     }
1793     
1794     return yPos + heightIncrease;
1795 }
1796
1797 LayoutUnit RenderBlock::estimateLogicalTopPosition(RenderBox* child, const MarginInfo& marginInfo, LayoutUnit& estimateWithoutPagination)
1798 {
1799     // FIXME: We need to eliminate the estimation of vertical position, because when it's wrong we sometimes trigger a pathological
1800     // relayout if there are intruding floats.
1801     LayoutUnit logicalTopEstimate = logicalHeight();
1802     if (!marginInfo.canCollapseWithMarginBefore()) {
1803         LayoutUnit childMarginBefore = child->selfNeedsLayout() ? marginBeforeForChild(child) : collapsedMarginBeforeForChild(child);
1804         logicalTopEstimate += max(marginInfo.margin(), childMarginBefore);
1805     }
1806
1807     // Adjust logicalTopEstimate down to the next page if the margins are so large that we don't fit on the current
1808     // page.
1809     LayoutState* layoutState = view()->layoutState();
1810     if (layoutState->isPaginated() && layoutState->pageLogicalHeight() && logicalTopEstimate > logicalHeight()
1811         && hasNextPage(logicalHeight()))
1812         logicalTopEstimate = min(logicalTopEstimate, nextPageLogicalTop(logicalHeight()));
1813
1814     logicalTopEstimate += getClearDelta(child, logicalTopEstimate);
1815     
1816     estimateWithoutPagination = logicalTopEstimate;
1817
1818     if (layoutState->isPaginated()) {
1819         // If the object has a page or column break value of "before", then we should shift to the top of the next page.
1820         logicalTopEstimate = applyBeforeBreak(child, logicalTopEstimate);
1821     
1822         // For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one.
1823         logicalTopEstimate = adjustForUnsplittableChild(child, logicalTopEstimate);
1824         
1825         if (!child->selfNeedsLayout() && child->isRenderBlock())
1826             logicalTopEstimate += toRenderBlock(child)->paginationStrut();
1827     }
1828
1829     return logicalTopEstimate;
1830 }
1831
1832 LayoutUnit RenderBlock::computeStartPositionDeltaForChildAvoidingFloats(const RenderBox* child, LayoutUnit childMarginStart,
1833     LayoutUnit childLogicalWidth, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage)
1834 {
1835     LayoutUnit startPosition = startOffsetForContent(region, offsetFromLogicalTopOfFirstPage);
1836
1837     // Add in our start margin.
1838     LayoutUnit oldPosition = startPosition + childMarginStart;
1839     LayoutUnit newPosition = oldPosition;
1840
1841     LayoutUnit blockOffset = logicalTopForChild(child);
1842     if (region)
1843         blockOffset = max(blockOffset, blockOffset + (region->offsetFromLogicalTopOfFirstPage() - offsetFromLogicalTopOfFirstPage));
1844
1845     LayoutUnit startOff = startOffsetForLine(blockOffset, false, region, offsetFromLogicalTopOfFirstPage);
1846     if (style()->textAlign() != WEBKIT_CENTER && !child->style()->marginStartUsing(style()).isAuto()) {
1847         if (childMarginStart < 0)
1848             startOff += childMarginStart;
1849         newPosition = max(newPosition, startOff); // Let the float sit in the child's margin if it can fit.
1850         // FIXME: Needs to use epsilon once we switch to float, see https://bugs.webkit.org/show_bug.cgi?id=64021
1851     } else if (startOff != startPosition) {
1852         // The object is shifting to the "end" side of the block. The object might be centered, so we need to
1853         // recalculate our inline direction margins. Note that the containing block content
1854         // width computation will take into account the delta between |startOff| and |startPosition|
1855         // so that we can just pass the content width in directly to the |computeMarginsInContainingBlockInlineDirection|
1856         // function.
1857         LayoutUnit oldMarginStart = marginStartForChild(child);
1858         LayoutUnit oldMarginEnd = marginEndForChild(child);
1859         RenderBox* mutableChild = const_cast<RenderBox*>(child);
1860         mutableChild->computeInlineDirectionMargins(this,
1861             availableLogicalWidthForLine(blockOffset, false, region, offsetFromLogicalTopOfFirstPage), childLogicalWidth);
1862         newPosition = startOff + marginStartForChild(child);
1863         if (inRenderFlowThread()) {
1864             setMarginStartForChild(mutableChild, oldMarginStart);
1865             setMarginEndForChild(mutableChild, oldMarginEnd);
1866         }
1867     }
1868     
1869     return newPosition - oldPosition;
1870 }
1871
1872 void RenderBlock::determineLogicalLeftPositionForChild(RenderBox* child)
1873 {
1874     LayoutUnit startPosition = borderStart() + paddingStart();
1875     LayoutUnit totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + availableLogicalWidth();
1876
1877     // Add in our start margin.
1878     LayoutUnit childMarginStart = marginStartForChild(child);
1879     LayoutUnit newPosition = startPosition + childMarginStart;
1880         
1881     // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats.  They need
1882     // to shift over as necessary to dodge any floats that might get in the way.
1883     if (child->avoidsFloats() && containsFloats() && !inRenderFlowThread())
1884         newPosition += computeStartPositionDeltaForChildAvoidingFloats(child, marginStartForChild(child), logicalWidthForChild(child));
1885
1886     setLogicalLeftForChild(child, style()->isLeftToRightDirection() ? newPosition : totalAvailableLogicalWidth - newPosition - logicalWidthForChild(child), ApplyLayoutDelta);
1887 }
1888
1889 void RenderBlock::setCollapsedBottomMargin(const MarginInfo& marginInfo)
1890 {
1891     if (marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()) {
1892         // Update our max pos/neg bottom margins, since we collapsed our bottom margins
1893         // with our children.
1894         setMaxMarginAfterValues(max(maxPositiveMarginAfter(), marginInfo.positiveMargin()), max(maxNegativeMarginAfter(), marginInfo.negativeMargin()));
1895
1896         if (!marginInfo.marginAfterQuirk())
1897             setMarginAfterQuirk(false);
1898
1899         if (marginInfo.marginAfterQuirk() && marginAfter() == 0)
1900             // We have no bottom margin and our last child has a quirky margin.
1901             // We will pick up this quirky margin and pass it through.
1902             // This deals with the <td><div><p> case.
1903             setMarginAfterQuirk(true);
1904     }
1905 }
1906
1907 void RenderBlock::handleAfterSideOfBlock(LayoutUnit beforeSide, LayoutUnit afterSide, MarginInfo& marginInfo)
1908 {
1909     marginInfo.setAtAfterSideOfBlock(true);
1910
1911     // If we can't collapse with children then go ahead and add in the bottom margin.
1912     if (!marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()
1913         && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.marginAfterQuirk()))
1914         setLogicalHeight(logicalHeight() + marginInfo.margin());
1915         
1916     // Now add in our bottom border/padding.
1917     setLogicalHeight(logicalHeight() + afterSide);
1918
1919     // Negative margins can cause our height to shrink below our minimal height (border/padding).
1920     // If this happens, ensure that the computed height is increased to the minimal height.
1921     setLogicalHeight(max(logicalHeight(), beforeSide + afterSide));
1922
1923     // Update our bottom collapsed margin info.
1924     setCollapsedBottomMargin(marginInfo);
1925 }
1926
1927 void RenderBlock::setLogicalLeftForChild(RenderBox* child, LayoutUnit logicalLeft, ApplyLayoutDeltaMode applyDelta)
1928 {
1929     if (isHorizontalWritingMode()) {
1930         if (applyDelta == ApplyLayoutDelta)
1931             view()->addLayoutDelta(LayoutSize(child->x() - logicalLeft, 0));
1932         child->setX(logicalLeft);
1933     } else {
1934         if (applyDelta == ApplyLayoutDelta)
1935             view()->addLayoutDelta(LayoutSize(0, child->y() - logicalLeft));
1936         child->setY(logicalLeft);
1937     }
1938 }
1939
1940 void RenderBlock::setLogicalTopForChild(RenderBox* child, LayoutUnit logicalTop, ApplyLayoutDeltaMode applyDelta)
1941 {
1942     if (isHorizontalWritingMode()) {
1943         if (applyDelta == ApplyLayoutDelta)
1944             view()->addLayoutDelta(LayoutSize(0, child->y() - logicalTop));
1945         child->setY(logicalTop);
1946     } else {
1947         if (applyDelta == ApplyLayoutDelta)
1948             view()->addLayoutDelta(LayoutSize(child->x() - logicalTop, 0));
1949         child->setX(logicalTop);
1950     }
1951 }
1952
1953 void RenderBlock::layoutBlockChildren(bool relayoutChildren, LayoutUnit& maxFloatLogicalBottom)
1954 {
1955     if (gPercentHeightDescendantsMap) {
1956         if (HashSet<RenderBox*>* descendants = gPercentHeightDescendantsMap->get(this)) {
1957             HashSet<RenderBox*>::iterator end = descendants->end();
1958             for (HashSet<RenderBox*>::iterator it = descendants->begin(); it != end; ++it) {
1959                 RenderBox* box = *it;
1960                 while (box != this) {
1961                     if (box->normalChildNeedsLayout())
1962                         break;
1963                     box->setChildNeedsLayout(true, false);
1964                     box = box->containingBlock();
1965                     ASSERT(box);
1966                     if (!box)
1967                         break;
1968                 }
1969             }
1970         }
1971     }
1972
1973     LayoutUnit beforeEdge = borderBefore() + paddingBefore();
1974     LayoutUnit afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeight();
1975
1976     setLogicalHeight(beforeEdge);
1977
1978     // The margin struct caches all our current margin collapsing state.  The compact struct caches state when we encounter compacts,
1979     MarginInfo marginInfo(this, beforeEdge, afterEdge);
1980
1981     // Fieldsets need to find their legend and position it inside the border of the object.
1982     // The legend then gets skipped during normal layout.  The same is true for ruby text.
1983     // It doesn't get included in the normal layout process but is instead skipped.
1984     RenderObject* childToExclude = layoutSpecialExcludedChild(relayoutChildren);
1985
1986     LayoutUnit previousFloatLogicalBottom = 0;
1987     maxFloatLogicalBottom = 0;
1988
1989     RenderBox* next = firstChildBox();
1990
1991     while (next) {
1992         RenderBox* child = next;
1993         next = child->nextSiblingBox();
1994
1995         if (childToExclude == child)
1996             continue; // Skip this child, since it will be positioned by the specialized subclass (fieldsets and ruby runs).
1997
1998         // Make sure we layout children if they need it.
1999         // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into
2000         // an auto value.  Add a method to determine this, so that we can avoid the relayout.
2001         if (relayoutChildren || ((child->style()->logicalHeight().isPercent() || child->style()->logicalMinHeight().isPercent() || child->style()->logicalMaxHeight().isPercent()) && !isRenderView()))
2002             child->setChildNeedsLayout(true, false);
2003
2004         // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.
2005         if (relayoutChildren && child->needsPreferredWidthsRecalculation())
2006             child->setPreferredLogicalWidthsDirty(true, false);
2007
2008         // Handle the four types of special elements first.  These include positioned content, floating content, compacts and
2009         // run-ins.  When we encounter these four types of objects, we don't actually lay them out as normal flow blocks.
2010         if (handleSpecialChild(child, marginInfo))
2011             continue;
2012
2013         // Lay out the child.
2014         layoutBlockChild(child, marginInfo, previousFloatLogicalBottom, maxFloatLogicalBottom);
2015     }
2016     
2017     // Now do the handling of the bottom of the block, adding in our bottom border/padding and
2018     // determining the correct collapsed bottom margin information.
2019     handleAfterSideOfBlock(beforeEdge, afterEdge, marginInfo);
2020 }
2021
2022 void RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom)
2023 {
2024     LayoutUnit oldPosMarginBefore = maxPositiveMarginBefore();
2025     LayoutUnit oldNegMarginBefore = maxNegativeMarginBefore();
2026
2027     // The child is a normal flow object.  Compute the margins we will use for collapsing now.
2028     child->computeBlockDirectionMargins(this);
2029
2030     // Do not allow a collapse if the margin-before-collapse style is set to SEPARATE.
2031     if (child->style()->marginBeforeCollapse() == MSEPARATE) {
2032         marginInfo.setAtBeforeSideOfBlock(false);
2033         marginInfo.clearMargin();
2034     }
2035
2036     // Try to guess our correct logical top position.  In most cases this guess will
2037     // be correct.  Only if we're wrong (when we compute the real logical top position)
2038     // will we have to potentially relayout.
2039     LayoutUnit estimateWithoutPagination;
2040     LayoutUnit logicalTopEstimate = estimateLogicalTopPosition(child, marginInfo, estimateWithoutPagination);
2041
2042     // Cache our old rect so that we can dirty the proper repaint rects if the child moves.
2043     LayoutRect oldRect(child->x(), child->y() , child->width(), child->height());
2044     LayoutUnit oldLogicalTop = logicalTopForChild(child);
2045
2046 #ifndef NDEBUG
2047     LayoutSize oldLayoutDelta = view()->layoutDelta();
2048 #endif
2049     // Go ahead and position the child as though it didn't collapse with the top.
2050     setLogicalTopForChild(child, logicalTopEstimate, ApplyLayoutDelta);
2051
2052     RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0;
2053     bool markDescendantsWithFloats = false;
2054     if (logicalTopEstimate != oldLogicalTop && !child->avoidsFloats() && childRenderBlock && childRenderBlock->containsFloats())
2055         markDescendantsWithFloats = true;
2056     else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) {
2057         // If an element might be affected by the presence of floats, then always mark it for
2058         // layout.
2059         LayoutUnit fb = max(previousFloatLogicalBottom, lowestFloatLogicalBottomIncludingPositionedFloats());
2060         if (fb > logicalTopEstimate)
2061             markDescendantsWithFloats = true;
2062     }
2063
2064     if (childRenderBlock) {
2065         if (markDescendantsWithFloats)
2066             childRenderBlock->markAllDescendantsWithFloatsForLayout();
2067         if (!child->isWritingModeRoot())
2068             previousFloatLogicalBottom = max(previousFloatLogicalBottom, oldLogicalTop + childRenderBlock->lowestFloatLogicalBottomIncludingPositionedFloats());
2069     }
2070
2071     if (!child->needsLayout())
2072         child->markForPaginationRelayoutIfNeeded();
2073
2074     bool childHadLayout = child->m_everHadLayout;
2075     bool childNeededLayout = child->needsLayout();
2076     if (childNeededLayout)
2077         child->layout();
2078
2079     // Cache if we are at the top of the block right now.
2080     bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock();
2081
2082     // Now determine the correct ypos based off examination of collapsing margin
2083     // values.
2084     LayoutUnit logicalTopBeforeClear = collapseMargins(child, marginInfo);
2085
2086     // Now check for clear.
2087     LayoutUnit logicalTopAfterClear = clearFloatsIfNeeded(child, marginInfo, oldPosMarginBefore, oldNegMarginBefore, logicalTopBeforeClear);
2088     
2089     bool paginated = view()->layoutState()->isPaginated();
2090     if (paginated)
2091         logicalTopAfterClear = adjustBlockChildForPagination(logicalTopAfterClear, estimateWithoutPagination, child,
2092             atBeforeSideOfBlock && logicalTopBeforeClear == logicalTopAfterClear);
2093
2094     setLogicalTopForChild(child, logicalTopAfterClear, ApplyLayoutDelta);
2095
2096     // Now we have a final top position.  See if it really does end up being different from our estimate.
2097     if (logicalTopAfterClear != logicalTopEstimate) {
2098         if (child->shrinkToAvoidFloats()) {
2099             // The child's width depends on the line width.
2100             // When the child shifts to clear an item, its width can
2101             // change (because it has more available line width).
2102             // So go ahead and mark the item as dirty.
2103             child->setChildNeedsLayout(true, false);
2104         }
2105         
2106         if (childRenderBlock) {
2107             if (!child->avoidsFloats() && childRenderBlock->containsFloats())
2108                 childRenderBlock->markAllDescendantsWithFloatsForLayout();
2109             if (!child->needsLayout())
2110                 child->markForPaginationRelayoutIfNeeded();
2111         }
2112
2113         // Our guess was wrong. Make the child lay itself out again.
2114         child->layoutIfNeeded();
2115     }
2116
2117     // We are no longer at the top of the block if we encounter a non-empty child.  
2118     // This has to be done after checking for clear, so that margins can be reset if a clear occurred.
2119     if (marginInfo.atBeforeSideOfBlock() && !child->isSelfCollapsingBlock())
2120         marginInfo.setAtBeforeSideOfBlock(false);
2121
2122     // Now place the child in the correct left position
2123     determineLogicalLeftPositionForChild(child);
2124
2125     // Update our height now that the child has been placed in the correct position.
2126     setLogicalHeight(logicalHeight() + logicalHeightForChild(child));
2127     if (child->style()->marginAfterCollapse() == MSEPARATE) {
2128         setLogicalHeight(logicalHeight() + marginAfterForChild(child));
2129         marginInfo.clearMargin();
2130     }
2131     // If the child has overhanging floats that intrude into following siblings (or possibly out
2132     // of this block), then the parent gets notified of the floats now.
2133     if (childRenderBlock && childRenderBlock->containsFloats())
2134         maxFloatLogicalBottom = max(maxFloatLogicalBottom, addOverhangingFloats(toRenderBlock(child), !childNeededLayout));
2135
2136     LayoutSize childOffset(child->x() - oldRect.x(), child->y() - oldRect.y());
2137     if (childOffset.width() || childOffset.height()) {
2138         view()->addLayoutDelta(childOffset);
2139
2140         // If the child moved, we have to repaint it as well as any floating/positioned
2141         // descendants.  An exception is if we need a layout.  In this case, we know we're going to
2142         // repaint ourselves (and the child) anyway.
2143         if (childHadLayout && !selfNeedsLayout() && child->checkForRepaintDuringLayout())
2144             child->repaintDuringLayoutIfMoved(oldRect);
2145     }
2146
2147     if (!childHadLayout && child->checkForRepaintDuringLayout()) {
2148         child->repaint();
2149         child->repaintOverhangingFloats(true);
2150     }
2151
2152     if (paginated) {
2153         // Check for an after page/column break.
2154         LayoutUnit newHeight = applyAfterBreak(child, logicalHeight(), marginInfo);
2155         if (newHeight != height())
2156             setLogicalHeight(newHeight);
2157     }
2158
2159     ASSERT(oldLayoutDelta == view()->layoutDelta());
2160 }
2161
2162 void RenderBlock::simplifiedNormalFlowLayout()
2163 {
2164     if (childrenInline()) {
2165         ListHashSet<RootInlineBox*> lineBoxes;
2166         for (InlineWalker walker(this); !walker.atEnd(); walker.advance()) {
2167             RenderObject* o = walker.current();
2168             if (!o->isPositioned() && (o->isReplaced() || o->isFloating())) {
2169                 o->layoutIfNeeded();
2170                 if (toRenderBox(o)->inlineBoxWrapper()) {
2171                     RootInlineBox* box = toRenderBox(o)->inlineBoxWrapper()->root();
2172                     lineBoxes.add(box);
2173                 }
2174             } else if (o->isText() || (o->isRenderInline() && !walker.atEndOfInline()))
2175                 o->setNeedsLayout(false);
2176         }
2177
2178         // FIXME: Glyph overflow will get lost in this case, but not really a big deal.
2179         GlyphOverflowAndFallbackFontsMap textBoxDataMap;                  
2180         for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it != lineBoxes.end(); ++it) {
2181             RootInlineBox* box = *it;
2182             box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap);
2183         }
2184     } else {
2185         for (RenderBox* box = firstChildBox(); box; box = box->nextSiblingBox()) {
2186             if (!box->isPositioned())
2187                 box->layoutIfNeeded();
2188         }
2189     }
2190 }
2191
2192 bool RenderBlock::simplifiedLayout()
2193 {
2194     if ((!posChildNeedsLayout() && !needsSimplifiedNormalFlowLayout()) || normalChildNeedsLayout() || selfNeedsLayout())
2195         return false;
2196
2197     LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
2198     
2199     if (needsPositionedMovementLayout() && !tryLayoutDoingPositionedMovementOnly())
2200         return false;
2201
2202     // Lay out positioned descendants or objects that just need to recompute overflow.
2203     if (needsSimplifiedNormalFlowLayout())
2204         simplifiedNormalFlowLayout();
2205
2206     // Lay out our positioned objects if our positioned child bit is set.
2207     if (posChildNeedsLayout() && layoutPositionedObjects(false))
2208         return false; // If a positioned float is causing our normal flow to change, then we have to bail and do a full layout.
2209
2210     // Recompute our overflow information.
2211     // FIXME: We could do better here by computing a temporary overflow object from layoutPositionedObjects and only
2212     // updating our overflow if we either used to have overflow or if the new temporary object has overflow.
2213     // For now just always recompute overflow.  This is no worse performance-wise than the old code that called rightmostPosition and
2214     // lowestPosition on every relayout so it's not a regression.
2215     m_overflow.clear();
2216     computeOverflow(clientLogicalBottom(), true);
2217
2218     statePusher.pop();
2219     
2220     updateLayerTransform();
2221
2222     updateScrollInfoAfterLayout();
2223
2224     setNeedsLayout(false);
2225     return true;
2226 }
2227
2228 bool RenderBlock::positionedFloatsNeedRelayout()
2229 {
2230     if (!hasPositionedFloats())
2231         return false;
2232     
2233     RenderBox* positionedObject;
2234     Iterator end = m_positionedObjects->end();
2235     for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
2236         positionedObject = *it;
2237         if (!positionedObject->isFloating())
2238             continue;
2239
2240         if (positionedObject->needsLayout())
2241             return true;
2242
2243         if (positionedObject->style()->hasStaticBlockPosition(isHorizontalWritingMode()) && positionedObject->parent() != this && positionedObject->parent()->isBlockFlow())
2244             return true;
2245         
2246         if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(logicalTop()) != pageLogicalOffset()))
2247             return true;
2248     }
2249     
2250     return false;
2251 }
2252
2253 bool RenderBlock::layoutPositionedObjects(bool relayoutChildren)
2254 {
2255     if (!m_positionedObjects)
2256         return false;
2257         
2258     if (hasColumns())
2259         view()->layoutState()->clearPaginationInformation(); // Positioned objects are not part of the column flow, so they don't paginate with the columns.
2260
2261     bool didFloatingBoxRelayout = false;
2262
2263     RenderBox* r;
2264     Iterator end = m_positionedObjects->end();
2265     for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
2266         r = *it;
2267         // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the
2268         // non-positioned block.  Rather than trying to detect all of these movement cases, we just always lay out positioned
2269         // objects that are positioned implicitly like this.  Such objects are rare, and so in typical DHTML menu usage (where everything is
2270         // positioned explicitly) this should not incur a performance penalty.
2271         if (relayoutChildren || (r->style()->hasStaticBlockPosition(isHorizontalWritingMode()) && r->parent() != this))
2272             r->setChildNeedsLayout(true, false);
2273             
2274         // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.
2275         if (relayoutChildren && r->needsPreferredWidthsRecalculation())
2276             r->setPreferredLogicalWidthsDirty(true, false);
2277         
2278         if (!r->needsLayout())
2279             r->markForPaginationRelayoutIfNeeded();
2280         
2281         // FIXME: Technically we could check the old placement and the new placement of the box and only invalidate if
2282         // the margin box of the object actually changed.
2283         if (r->needsLayout() && r->isFloating())
2284             didFloatingBoxRelayout = true;
2285
2286         // We don't have to do a full layout.  We just have to update our position. Try that first. If we have shrink-to-fit width
2287         // and we hit the available width constraint, the layoutIfNeeded() will catch it and do a full layout.
2288         if (r->needsPositionedMovementLayoutOnly() && r->tryLayoutDoingPositionedMovementOnly())
2289             r->setNeedsLayout(false);
2290             
2291         // If we are in a flow thread, go ahead and compute a vertical position for our object now.
2292         // If it's wrong we'll lay out again.
2293         LayoutUnit oldLogicalTop = 0;
2294         bool checkForPaginationRelayout = r->needsLayout() && view()->layoutState()->isPaginated() && view()->layoutState()->pageLogicalHeight(); 
2295         if (checkForPaginationRelayout) {
2296             if (isHorizontalWritingMode() == r->isHorizontalWritingMode())
2297                 r->computeLogicalHeight();
2298             else
2299                 r->computeLogicalWidth();
2300             oldLogicalTop = logicalTopForChild(r);
2301         }
2302             
2303         r->layoutIfNeeded();
2304         
2305         // Lay out again if our estimate was wrong.
2306         if (checkForPaginationRelayout && logicalTopForChild(r) != oldLogicalTop) {
2307             r->setChildNeedsLayout(true, false);
2308             r->layoutIfNeeded();
2309         }
2310     }
2311     
2312     if (hasColumns())
2313         view()->layoutState()->m_columnInfo = columnInfo(); // FIXME: Kind of gross. We just put this back into the layout state so that pop() will work.
2314         
2315     return didFloatingBoxRelayout;
2316 }
2317
2318 void RenderBlock::markPositionedObjectsForLayout()
2319 {
2320     if (m_positionedObjects) {
2321         RenderBox* r;
2322         Iterator end = m_positionedObjects->end();
2323         for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
2324             r = *it;
2325             r->setChildNeedsLayout(true);
2326         }
2327     }
2328 }
2329
2330 void RenderBlock::markForPaginationRelayoutIfNeeded()
2331 {
2332     ASSERT(!needsLayout());
2333     if (needsLayout())
2334         return;
2335
2336     if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(logicalTop()) != pageLogicalOffset()))
2337         setChildNeedsLayout(true, false);
2338 }
2339
2340 void RenderBlock::repaintOverhangingFloats(bool paintAllDescendants)
2341 {
2342     // Repaint any overhanging floats (if we know we're the one to paint them).
2343     // Otherwise, bail out.
2344     if (!hasOverhangingFloats())
2345         return;
2346
2347     // FIXME: Avoid disabling LayoutState. At the very least, don't disable it for floats originating
2348     // in this block. Better yet would be to push extra state for the containers of other floats.
2349     LayoutStateDisabler layoutStateDisabler(view());
2350     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2351     FloatingObjectSetIterator end = floatingObjectSet.end();
2352     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
2353         FloatingObject* r = *it;
2354         // Only repaint the object if it is overhanging, is not in its own layer, and
2355         // is our responsibility to paint (m_shouldPaint is set). When paintAllDescendants is true, the latter
2356         // condition is replaced with being a descendant of us.
2357         if (logicalBottomForFloat(r) > logicalHeight() && ((paintAllDescendants && r->m_renderer->isDescendantOf(this)) || r->m_shouldPaint) && !r->m_renderer->hasSelfPaintingLayer()) {
2358             r->m_renderer->repaint();
2359             r->m_renderer->repaintOverhangingFloats();
2360         }
2361     }
2362 }
2363  
2364 void RenderBlock::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
2365 {
2366     LayoutPoint adjustedPaintOffset = paintOffset + location();
2367     
2368     PaintPhase phase = paintInfo.phase;
2369
2370     // Check if we need to do anything at all.
2371     // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
2372     // paints the root's background.
2373     if (!isRoot()) {
2374         LayoutRect overflowBox = visualOverflowRect();
2375         flipForWritingMode(overflowBox);
2376         overflowBox.inflate(maximalOutlineSize(paintInfo.phase));
2377         overflowBox.moveBy(adjustedPaintOffset);
2378         if (!overflowBox.intersects(paintInfo.rect))
2379             return;
2380     }
2381
2382     bool pushedClip = pushContentsClip(paintInfo, adjustedPaintOffset);
2383     paintObject(paintInfo, adjustedPaintOffset);
2384     if (pushedClip)
2385         popContentsClip(paintInfo, phase, adjustedPaintOffset);
2386
2387     // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
2388     // z-index.  We paint after we painted the background/border, so that the scrollbars will
2389     // sit above the background/border.
2390     if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && paintInfo.shouldPaintWithinRoot(this))
2391         layer()->paintOverflowControls(paintInfo.context, adjustedPaintOffset, paintInfo.rect);
2392 }
2393
2394 void RenderBlock::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
2395 {
2396     if (paintInfo.context->paintingDisabled())
2397         return;
2398
2399     const Color& ruleColor = style()->visitedDependentColor(CSSPropertyWebkitColumnRuleColor);
2400     bool ruleTransparent = style()->columnRuleIsTransparent();
2401     EBorderStyle ruleStyle = style()->columnRuleStyle();
2402     LayoutUnit ruleThickness = style()->columnRuleWidth();
2403     LayoutUnit colGap = columnGap();
2404     bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent && ruleThickness <= colGap;
2405     if (!renderRule)
2406         return;
2407
2408     ColumnInfo* colInfo = columnInfo();
2409     unsigned colCount = columnCount(colInfo);
2410
2411     bool antialias = shouldAntialiasLines(paintInfo.context);
2412
2413     if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
2414         LayoutUnit currLogicalLeftOffset = style()->isLeftToRightDirection() ? 0 : contentLogicalWidth();
2415         LayoutUnit ruleAdd = logicalLeftOffsetForContent();
2416         LayoutUnit ruleLogicalLeft = style()->isLeftToRightDirection() ? 0 : contentLogicalWidth();
2417         LayoutUnit inlineDirectionSize = colInfo->desiredColumnWidth();
2418         BoxSide boxSide = isHorizontalWritingMode()
2419             ? style()->isLeftToRightDirection() ? BSLeft : BSRight
2420             : style()->isLeftToRightDirection() ? BSTop : BSBottom;
2421
2422         for (unsigned i = 0; i < colCount; i++) {
2423             // Move to the next position.
2424             if (style()->isLeftToRightDirection()) {
2425                 ruleLogicalLeft += inlineDirectionSize + colGap / 2;
2426                 currLogicalLeftOffset += inlineDirectionSize + colGap;
2427             } else {
2428                 ruleLogicalLeft -= (inlineDirectionSize + colGap / 2);
2429                 currLogicalLeftOffset -= (inlineDirectionSize + colGap);
2430             }
2431            
2432             // Now paint the column rule.
2433             if (i < colCount - 1) {
2434                 LayoutUnit ruleLeft = isHorizontalWritingMode() ? paintOffset.x() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd : paintOffset.x() + borderLeft() + paddingLeft();
2435                 LayoutUnit ruleRight = isHorizontalWritingMode() ? ruleLeft + ruleThickness : ruleLeft + contentWidth();
2436                 LayoutUnit ruleTop = isHorizontalWritingMode() ? paintOffset.y() + borderTop() + paddingTop() : paintOffset.y() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd;
2437                 LayoutUnit ruleBottom = isHorizontalWritingMode() ? ruleTop + contentHeight() : ruleTop + ruleThickness;
2438                 drawLineForBoxSide(paintInfo.context, ruleLeft, ruleTop, ruleRight, ruleBottom, boxSide, ruleColor, ruleStyle, 0, 0, antialias);
2439             }
2440             
2441             ruleLogicalLeft = currLogicalLeftOffset;
2442         }
2443     } else {
2444         LayoutUnit ruleLeft = isHorizontalWritingMode() ? borderLeft() + paddingLeft() : colGap / 2 - colGap - ruleThickness / 2 + borderBefore() + paddingBefore();
2445         LayoutUnit ruleWidth = isHorizontalWritingMode() ? contentWidth() : ruleThickness;
2446         LayoutUnit ruleTop = isHorizontalWritingMode() ? colGap / 2 - colGap - ruleThickness / 2 + borderBefore() + paddingBefore() : borderStart() + paddingStart();
2447         LayoutUnit ruleHeight = isHorizontalWritingMode() ? ruleThickness : contentHeight();
2448         LayoutRect ruleRect(ruleLeft, ruleTop, ruleWidth, ruleHeight);
2449
2450         flipForWritingMode(ruleRect);
2451         ruleRect.moveBy(paintOffset);
2452
2453         BoxSide boxSide = isHorizontalWritingMode()
2454             ? !style()->isFlippedBlocksWritingMode() ? BSTop : BSBottom
2455             : !style()->isFlippedBlocksWritingMode() ? BSLeft : BSRight;
2456
2457         LayoutSize step(0, !style()->isFlippedBlocksWritingMode() ? colInfo->columnHeight() + colGap : -(colInfo->columnHeight() + colGap));
2458         if (!isHorizontalWritingMode())
2459             step = step.transposedSize();
2460
2461         for (unsigned i = 1; i < colCount; i++) {
2462             ruleRect.move(step);
2463             drawLineForBoxSide(paintInfo.context, ruleRect.x(), ruleRect.y(), ruleRect.maxX(), ruleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
2464         }
2465     }
2466 }
2467
2468 void RenderBlock::paintColumnContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset, bool paintingFloats)
2469 {
2470     // We need to do multiple passes, breaking up our child painting into strips.
2471     GraphicsContext* context = paintInfo.context;
2472     ColumnInfo* colInfo = columnInfo();
2473     unsigned colCount = columnCount(colInfo);
2474     if (!colCount)
2475         return;
2476     LayoutUnit currLogicalTopOffset = 0;
2477     for (unsigned i = 0; i < colCount; i++) {
2478         // For each rect, we clip to the rect, and then we adjust our coords.
2479         LayoutRect colRect = columnRectAt(colInfo, i);
2480         flipForWritingMode(colRect);
2481         LayoutUnit logicalLeftOffset = (isHorizontalWritingMode() ? colRect.x() : colRect.y()) - logicalLeftOffsetForContent();
2482         LayoutSize offset = isHorizontalWritingMode() ? LayoutSize(logicalLeftOffset, currLogicalTopOffset) : LayoutSize(currLogicalTopOffset, logicalLeftOffset);
2483         if (colInfo->progressionAxis() == ColumnInfo::BlockAxis) {
2484             if (isHorizontalWritingMode())
2485                 offset.expand(0, colRect.y() - borderTop() - paddingTop());
2486             else
2487                 offset.expand(colRect.x() - borderLeft() - paddingLeft(), 0);
2488         }
2489         colRect.moveBy(paintOffset);
2490         PaintInfo info(paintInfo);
2491         info.rect.intersect(colRect);
2492         
2493         if (!info.rect.isEmpty()) {
2494             GraphicsContextStateSaver stateSaver(*context);
2495             
2496             // Each strip pushes a clip, since column boxes are specified as being
2497             // like overflow:hidden.
2498             context->clip(colRect);
2499
2500             // Adjust our x and y when painting.
2501             LayoutPoint adjustedPaintOffset = paintOffset + offset;
2502             if (paintingFloats)
2503                 paintFloats(info, adjustedPaintOffset, paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip);
2504             else
2505                 paintContents(info, adjustedPaintOffset);
2506         }
2507
2508         LayoutUnit blockDelta = (isHorizontalWritingMode() ? colRect.height() : colRect.width());
2509         if (style()->isFlippedBlocksWritingMode())
2510             currLogicalTopOffset += blockDelta;
2511         else
2512             currLogicalTopOffset -= blockDelta;
2513     }
2514 }
2515
2516 void RenderBlock::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
2517 {
2518     // Avoid painting descendants of the root element when stylesheets haven't loaded.  This eliminates FOUC.
2519     // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
2520     // will do a full repaint().
2521     if (document()->didLayoutWithPendingStylesheets() && !isRenderView())
2522         return;
2523
2524     // We don't want to hand off painting in the line box tree with the accumulated error of the render tree, as this will cause
2525     // us to mess up painting aligned things (such as underlines in text) with both the render tree and line box tree's error.
2526     LayoutPoint roundedPaintOffset = roundedIntPoint(paintOffset);
2527     if (childrenInline())
2528         m_lineBoxes.paint(this, paintInfo, roundedPaintOffset);
2529     else
2530         paintChildren(paintInfo, roundedPaintOffset);
2531 }
2532
2533 void RenderBlock::paintChildren(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
2534 {
2535     PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase;
2536     newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase;
2537     
2538     // We don't paint our own background, but we do let the kids paint their backgrounds.
2539     PaintInfo info(paintInfo);
2540     info.phase = newPhase;
2541     info.updatePaintingRootForChildren(this);
2542     
2543     // FIXME: Paint-time pagination is obsolete and is now only used by embedded WebViews inside AppKit
2544     // NSViews.  Do not add any more code for this.
2545     RenderView* renderView = view();
2546     bool usePrintRect = !renderView->printRect().isEmpty();
2547     
2548     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {        
2549         // Check for page-break-before: always, and if it's set, break and bail.
2550         bool checkBeforeAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakBefore() == PBALWAYS);
2551         LayoutUnit absoluteChildY = paintOffset.y() + child->y();
2552         if (checkBeforeAlways
2553             && absoluteChildY > paintInfo.rect.y()
2554             && absoluteChildY < paintInfo.rect.maxY()) {
2555             view()->setBestTruncatedAt(absoluteChildY, this, true);
2556             return;
2557         }
2558
2559         if (!child->isFloating() && child->isReplaced() && usePrintRect && child->height() <= renderView->printRect().height()) {
2560             // Paginate block-level replaced elements.
2561             if (absoluteChildY + child->height() > renderView->printRect().maxY()) {
2562                 if (absoluteChildY < renderView->truncatedAt())
2563                     renderView->setBestTruncatedAt(absoluteChildY, child);
2564                 // If we were able to truncate, don't paint.
2565                 if (absoluteChildY >= renderView->truncatedAt())
2566                     break;
2567             }
2568         }
2569
2570         LayoutPoint childPoint = flipForWritingModeForChild(child, paintOffset);
2571         if (!child->hasSelfPaintingLayer() && !child->isFloating())
2572             child->paint(info, childPoint);
2573
2574         // Check for page-break-after: always, and if it's set, break and bail.
2575         bool checkAfterAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakAfter() == PBALWAYS);
2576         if (checkAfterAlways
2577             && (absoluteChildY + child->height()) > paintInfo.rect.y()
2578             && (absoluteChildY + child->height()) < paintInfo.rect.maxY()) {
2579             view()->setBestTruncatedAt(absoluteChildY + child->height() + max<LayoutUnit>(0, child->collapsedMarginAfter()), this, true);
2580             return;
2581         }
2582     }
2583 }
2584
2585 void RenderBlock::paintCaret(PaintInfo& paintInfo, const LayoutPoint& paintOffset, CaretType type)
2586 {
2587     // Paint the caret if the FrameSelection says so or if caret browsing is enabled
2588     bool caretBrowsing = frame()->settings() && frame()->settings()->caretBrowsingEnabled();
2589     RenderObject* caretPainter;
2590     bool isContentEditable;
2591     if (type == CursorCaret) {
2592         caretPainter = frame()->selection()->caretRenderer();
2593         isContentEditable = frame()->selection()->isContentEditable();
2594     } else {
2595         caretPainter = frame()->page()->dragCaretController()->caretRenderer();
2596         isContentEditable = frame()->page()->dragCaretController()->isContentEditable();
2597     }
2598
2599     if (caretPainter == this && (isContentEditable || caretBrowsing)) {
2600         if (type == CursorCaret)
2601             frame()->selection()->paintCaret(paintInfo.context, paintOffset, paintInfo.rect);
2602         else
2603             frame()->page()->dragCaretController()->paintDragCaret(frame(), paintInfo.context, paintOffset, paintInfo.rect);
2604     }
2605 }
2606
2607 void RenderBlock::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
2608 {
2609     PaintPhase paintPhase = paintInfo.phase;
2610
2611     // 1. paint background, borders etc
2612     if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && style()->visibility() == VISIBLE) {
2613         if (hasBoxDecorations())
2614             paintBoxDecorations(paintInfo, paintOffset);
2615         if (hasColumns())
2616             paintColumnRules(paintInfo, paintOffset);
2617     }
2618
2619     if (paintPhase == PaintPhaseMask && style()->visibility() == VISIBLE) {
2620         paintMask(paintInfo, paintOffset);
2621         return;
2622     }
2623
2624     // We're done.  We don't bother painting any children.
2625     if (paintPhase == PaintPhaseBlockBackground)
2626         return;
2627
2628     // Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div).
2629     LayoutPoint scrolledOffset = paintOffset;
2630     if (hasOverflowClip())
2631         scrolledOffset.move(-layer()->scrolledContentOffset());
2632
2633     // 2. paint contents
2634     if (paintPhase != PaintPhaseSelfOutline) {
2635         if (hasColumns())
2636             paintColumnContents(paintInfo, scrolledOffset);
2637         else
2638             paintContents(paintInfo, scrolledOffset);
2639     }
2640
2641     // 3. paint selection
2642     // FIXME: Make this work with multi column layouts.  For now don't fill gaps.
2643     bool isPrinting = document()->printing();
2644     if (!isPrinting && !hasColumns())
2645         paintSelection(paintInfo, scrolledOffset); // Fill in gaps in selection on lines and between blocks.
2646
2647     // 4. paint floats.
2648     if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip) {
2649         if (hasColumns())
2650             paintColumnContents(paintInfo, scrolledOffset, true);
2651         else
2652             paintFloats(paintInfo, scrolledOffset, paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip);
2653     }
2654
2655     // 5. paint outline.
2656     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
2657         paintOutline(paintInfo.context, LayoutRect(paintOffset, size()));
2658
2659     // 6. paint continuation outlines.
2660     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) {
2661         RenderInline* inlineCont = inlineElementContinuation();
2662         if (inlineCont && inlineCont->hasOutline() && inlineCont->style()->visibility() == VISIBLE) {
2663             RenderInline* inlineRenderer = toRenderInline(inlineCont->node()->renderer());
2664             RenderBlock* cb = containingBlock();
2665
2666             bool inlineEnclosedInSelfPaintingLayer = false;
2667             for (RenderBoxModelObject* box = inlineRenderer; box != cb; box = box->parent()->enclosingBoxModelObject()) {
2668                 if (box->hasSelfPaintingLayer()) {
2669                     inlineEnclosedInSelfPaintingLayer = true;
2670                     break;
2671                 }
2672             }
2673
2674             if (!inlineEnclosedInSelfPaintingLayer)
2675                 cb->addContinuationWithOutline(inlineRenderer);
2676             else if (!inlineRenderer->firstLineBox())
2677                 inlineRenderer->paintOutline(paintInfo.context, paintOffset - locationOffset() + inlineRenderer->containingBlock()->location());
2678         }
2679         paintContinuationOutlines(paintInfo, paintOffset);
2680     }
2681
2682     // 7. paint caret.
2683     // If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground,
2684     // then paint the caret.
2685     if (paintPhase == PaintPhaseForeground) {        
2686         paintCaret(paintInfo, paintOffset, CursorCaret);
2687         paintCaret(paintInfo, paintOffset, DragCaret);
2688     }
2689 }
2690
2691 LayoutPoint RenderBlock::flipFloatForWritingModeForChild(const FloatingObject* child, const LayoutPoint& point) const
2692 {
2693     if (!style()->isFlippedBlocksWritingMode())
2694         return point;
2695     
2696     // This is similar to RenderBox::flipForWritingModeForChild. We have to subtract out our left/top offsets twice, since
2697     // it's going to get added back in. We hide this complication here so that the calling code looks normal for the unflipped
2698     // case.
2699     if (isHorizontalWritingMode())
2700         return LayoutPoint(point.x(), point.y() + height() - child->renderer()->height() - 2 * yPositionForFloatIncludingMargin(child));
2701     return LayoutPoint(point.x() + width() - child->width() - 2 * xPositionForFloatIncludingMargin(child), point.y());
2702 }
2703
2704 void RenderBlock::paintFloats(PaintInfo& paintInfo, const LayoutPoint& paintOffset, bool preservePhase)
2705 {
2706     if (!m_floatingObjects)
2707         return;
2708
2709     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2710     FloatingObjectSetIterator end = floatingObjectSet.end();
2711     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
2712         FloatingObject* r = *it;
2713         // Only paint the object if our m_shouldPaint flag is set.
2714         if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
2715             PaintInfo currentPaintInfo(paintInfo);
2716             currentPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
2717             LayoutPoint childPoint = flipFloatForWritingModeForChild(r, LayoutPoint(paintOffset.x() + xPositionForFloatIncludingMargin(r) - r->m_renderer->x(), paintOffset.y() + yPositionForFloatIncludingMargin(r) - r->m_renderer->y()));
2718             r->m_renderer->paint(currentPaintInfo, childPoint);
2719             if (!preservePhase) {
2720                 currentPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
2721                 r->m_renderer->paint(currentPaintInfo, childPoint);
2722                 currentPaintInfo.phase = PaintPhaseFloat;
2723                 r->m_renderer->paint(currentPaintInfo, childPoint);
2724                 currentPaintInfo.phase = PaintPhaseForeground;
2725                 r->m_renderer->paint(currentPaintInfo, childPoint);
2726                 currentPaintInfo.phase = PaintPhaseOutline;
2727                 r->m_renderer->paint(currentPaintInfo, childPoint);
2728             }
2729         }
2730     }
2731 }
2732
2733 void RenderBlock::paintEllipsisBoxes(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
2734 {
2735     if (!paintInfo.shouldPaintWithinRoot(this) || !firstLineBox())
2736         return;
2737
2738     if (style()->visibility() == VISIBLE && paintInfo.phase == PaintPhaseForeground) {
2739         // We can check the first box and last box and avoid painting if we don't
2740         // intersect.
2741         LayoutUnit yPos = paintOffset.y() + firstLineBox()->y();
2742         LayoutUnit h = lastLineBox()->y() + lastLineBox()->logicalHeight() - firstLineBox()->y();
2743         if (yPos >= paintInfo.rect.maxY() || yPos + h <= paintInfo.rect.y())
2744             return;
2745
2746         // See if our boxes intersect with the dirty rect.  If so, then we paint
2747         // them.  Note that boxes can easily overlap, so we can't make any assumptions
2748         // based off positions of our first line box or our last line box.
2749         for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
2750             yPos = paintOffset.y() + curr->y();
2751             h = curr->logicalHeight();
2752             if (curr->ellipsisBox() && yPos < paintInfo.rect.maxY() && yPos + h > paintInfo.rect.y())
2753                 curr->paintEllipsisBox(paintInfo, paintOffset, curr->lineTop(), curr->lineBottom());
2754         }
2755     }
2756 }
2757
2758 RenderInline* RenderBlock::inlineElementContinuation() const
2759
2760     RenderBoxModelObject* continuation = this->continuation();
2761     return continuation && continuation->isInline() ? toRenderInline(continuation) : 0;
2762 }
2763
2764 RenderBlock* RenderBlock::blockElementContinuation() const
2765 {
2766     RenderBoxModelObject* currentContinuation = continuation();
2767     if (!currentContinuation || currentContinuation->isInline())
2768         return 0;
2769     RenderBlock* nextContinuation = toRenderBlock(currentContinuation);
2770     if (nextContinuation->isAnonymousBlock())
2771         return nextContinuation->blockElementContinuation();
2772     return nextContinuation;
2773 }
2774     
2775 static ContinuationOutlineTableMap* continuationOutlineTable()
2776 {
2777     DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ());
2778     return &table;
2779 }
2780
2781 void RenderBlock::addContinuationWithOutline(RenderInline* flow)
2782 {
2783     // We can't make this work if the inline is in a layer.  We'll just rely on the broken
2784     // way of painting.
2785     ASSERT(!flow->layer() && !flow->isInlineElementContinuation());
2786     
2787     ContinuationOutlineTableMap* table = continuationOutlineTable();
2788     ListHashSet<RenderInline*>* continuations = table->get(this);
2789     if (!continuations) {
2790         continuations = new ListHashSet<RenderInline*>;
2791         table->set(this, continuations);
2792     }
2793     
2794     continuations->add(flow);
2795 }
2796
2797 bool RenderBlock::paintsContinuationOutline(RenderInline* flow)
2798 {
2799     ContinuationOutlineTableMap* table = continuationOutlineTable();
2800     if (table->isEmpty())
2801         return false;
2802         
2803     ListHashSet<RenderInline*>* continuations = table->get(this);
2804     if (!continuations)
2805         return false;
2806
2807     return continuations->contains(flow);
2808 }
2809
2810 void RenderBlock::paintContinuationOutlines(PaintInfo& info, const LayoutPoint& paintOffset)
2811 {
2812     ContinuationOutlineTableMap* table = continuationOutlineTable();
2813     if (table->isEmpty())
2814         return;
2815         
2816     ListHashSet<RenderInline*>* continuations = table->get(this);
2817     if (!continuations)
2818         return;
2819
2820     LayoutPoint accumulatedPaintOffset = paintOffset;
2821     // Paint each continuation outline.
2822     ListHashSet<RenderInline*>::iterator end = continuations->end();
2823     for (ListHashSet<RenderInline*>::iterator it = continuations->begin(); it != end; ++it) {
2824         // Need to add in the coordinates of the intervening blocks.
2825         RenderInline* flow = *it;
2826         RenderBlock* block = flow->containingBlock();
2827         for ( ; block && block != this; block = block->containingBlock())
2828             accumulatedPaintOffset.moveBy(block->location());
2829         ASSERT(block);   
2830         flow->paintOutline(info.context, accumulatedPaintOffset);
2831     }
2832     
2833     // Delete
2834     delete continuations;
2835     table->remove(this);
2836 }
2837
2838 bool RenderBlock::shouldPaintSelectionGaps() const
2839 {
2840     return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot();
2841 }
2842
2843 bool RenderBlock::isSelectionRoot() const
2844 {
2845     if (!node())
2846         return false;
2847         
2848     // FIXME: Eventually tables should have to learn how to fill gaps between cells, at least in simple non-spanning cases.
2849     if (isTable())
2850         return false;
2851         
2852     if (isBody() || isRoot() || hasOverflowClip() || isRelPositioned() ||
2853         isFloatingOrPositioned() || isTableCell() || isInlineBlockOrInlineTable() || hasTransform() ||
2854         hasReflection() || hasMask() || isWritingModeRoot())
2855         return true;
2856     
2857     if (view() && view()->selectionStart()) {
2858         Node* startElement = view()->selectionStart()->node();
2859         if (startElement && startElement->rootEditableElement() == node())
2860             return true;
2861     }
2862     
2863     return false;
2864 }
2865
2866 GapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer)
2867 {
2868     ASSERT(!needsLayout());
2869
2870     if (!shouldPaintSelectionGaps())
2871         return GapRects();
2872
2873     // FIXME: this is broken with transforms
2874     TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
2875     mapLocalToContainer(repaintContainer, false, false, transformState);
2876     LayoutPoint offsetFromRepaintContainer = roundedLayoutPoint(transformState.mappedPoint());
2877
2878     if (hasOverflowClip())
2879         offsetFromRepaintContainer -= layer()->scrolledContentOffset();
2880
2881     LayoutUnit lastTop = 0;
2882     LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop);
2883     LayoutUnit lastRight = logicalRightSelectionOffset(this, lastTop);
2884     
2885     return selectionGaps(this, offsetFromRepaintContainer, IntSize(), lastTop, lastLeft, lastRight);
2886 }
2887
2888 void RenderBlock::paintSelection(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
2889 {
2890     if (shouldPaintSelectionGaps() && paintInfo.phase == PaintPhaseForeground) {
2891         LayoutUnit lastTop = 0;
2892         LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop);
2893         LayoutUnit lastRight = logicalRightSelectionOffset(this, lastTop);
2894         GraphicsContextStateSaver stateSaver(*paintInfo.context);
2895
2896         LayoutRect gapRectsBounds = selectionGaps(this, paintOffset, LayoutSize(), lastTop, lastLeft, lastRight, &paintInfo);
2897         if (!gapRectsBounds.isEmpty()) {
2898             if (RenderLayer* layer = enclosingLayer()) {
2899                 gapRectsBounds.moveBy(-paintOffset);
2900                 if (!hasLayer()) {
2901                     LayoutRect localBounds(gapRectsBounds);
2902                     flipForWritingMode(localBounds);
2903                     gapRectsBounds = localToContainerQuad(FloatRect(localBounds), layer->renderer()).enclosingBoundingBox();
2904                     gapRectsBounds.move(layer->scrolledContentOffset());
2905                 }
2906                 layer->addBlockSelectionGapsBounds(gapRectsBounds);
2907             }
2908         }
2909     }
2910 }
2911
2912 static void clipOutPositionedObjects(const PaintInfo* paintInfo, const LayoutPoint& offset, RenderBlock::PositionedObjectsListHashSet* positionedObjects)
2913 {
2914     if (!positionedObjects)
2915         return;
2916     
2917     RenderBlock::PositionedObjectsListHashSet::const_iterator end = positionedObjects->end();
2918     for (RenderBlock::PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
2919         RenderBox* r = *it;
2920         paintInfo->context->clipOut(IntRect(offset.x() + r->x(), offset.y() + r->y(), r->width(), r->height()));
2921     }
2922 }
2923
2924 static int blockDirectionOffset(RenderBlock* rootBlock, const LayoutSize& offsetFromRootBlock)
2925 {
2926     return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.height() : offsetFromRootBlock.width();
2927 }
2928
2929 static int inlineDirectionOffset(RenderBlock* rootBlock, const LayoutSize& offsetFromRootBlock)
2930 {
2931     return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.width() : offsetFromRootBlock.height();
2932 }
2933
2934 LayoutRect RenderBlock::logicalRectToPhysicalRect(const LayoutPoint& rootBlockPhysicalPosition, const LayoutRect& logicalRect)
2935 {
2936     LayoutRect result;
2937     if (isHorizontalWritingMode())
2938         result = logicalRect;
2939     else
2940         result = LayoutRect(logicalRect.y(), logicalRect.x(), logicalRect.height(), logicalRect.width());
2941     flipForWritingMode(result);
2942     result.moveBy(rootBlockPhysicalPosition);
2943     return result;
2944 }
2945
2946 GapRects RenderBlock::selectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
2947                                     LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* paintInfo)
2948 {
2949     // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore.
2950     // Clip out floating and positioned objects when painting selection gaps.
2951     if (paintInfo) {
2952         // Note that we don't clip out overflow for positioned objects.  We just stick to the border box.
2953         LayoutRect flippedBlockRect(offsetFromRootBlock.width(), offsetFromRootBlock.height(), width(), height());
2954         rootBlock->flipForWritingMode(flippedBlockRect);
2955         flippedBlockRect.moveBy(rootBlockPhysicalPosition);
2956         clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), m_positionedObjects.get());
2957         if (isBody() || isRoot()) // The <body> must make sure to examine its containingBlock's positioned objects.
2958             for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock())
2959                 clipOutPositionedObjects(paintInfo, LayoutPoint(cb->x(), cb->y()), cb->m_positionedObjects.get()); // FIXME: Not right for flipped writing modes.
2960         if (m_floatingObjects) {
2961             const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
2962             FloatingObjectSetIterator end = floatingObjectSet.end();
2963             for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
2964                 FloatingObject* r = *it;
2965                 LayoutRect floatBox(offsetFromRootBlock.width() + xPositionForFloatIncludingMargin(r),
2966                                     offsetFromRootBlock.height() + yPositionForFloatIncludingMargin(r),
2967                                     r->m_renderer->width(), r->m_renderer->height());
2968                 rootBlock->flipForWritingMode(floatBox);
2969                 floatBox.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
2970                 paintInfo->context->clipOut(floatBox);
2971             }
2972         }
2973     }
2974
2975     // FIXME: overflow: auto/scroll regions need more math here, since painting in the border box is different from painting in the padding box (one is scrolled, the other is
2976     // fixed).
2977     GapRects result;
2978     if (!isBlockFlow()) // FIXME: Make multi-column selection gap filling work someday.
2979         return result;
2980
2981     if (hasColumns() || hasTransform() || style()->columnSpan()) {
2982         // FIXME: We should learn how to gap fill multiple columns and transforms eventually.
2983         lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
2984         lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight());
2985         lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight());
2986         return result;
2987     }
2988
2989     if (childrenInline())
2990         result = inlineSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
2991     else
2992         result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
2993
2994     // Go ahead and fill the vertical gap all the way to the bottom of our block if the selection extends past our block.
2995     if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd))
2996         result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, 
2997                                              logicalHeight(), paintInfo));
2998     return result;
2999 }
3000
3001 GapRects RenderBlock::inlineSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
3002                                           LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* paintInfo)
3003 {
3004     GapRects result;
3005
3006     bool containsStart = selectionState() == SelectionStart || selectionState() == SelectionBoth;
3007
3008     if (!firstLineBox()) {
3009         if (containsStart) {
3010             // Go ahead and update our lastLogicalTop to be the bottom of the block.  <hr>s or empty blocks with height can trip this
3011             // case.
3012             lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
3013             lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight());
3014             lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight());
3015         }
3016         return result;
3017     }
3018
3019     RootInlineBox* lastSelectedLine = 0;
3020     RootInlineBox* curr;
3021     for (curr = firstRootBox(); curr && !curr->hasSelectedChildren(); curr = curr->nextRootBox()) { }
3022
3023     // Now paint the gaps for the lines.
3024     for (; curr && curr->hasSelectedChildren(); curr = curr->nextRootBox()) {
3025         LayoutUnit selTop =  curr->selectionTop();
3026         LayoutUnit selHeight = curr->selectionHeight();
3027
3028         if (!containsStart && !lastSelectedLine &&
3029             selectionState() != SelectionStart && selectionState() != SelectionBoth)
3030             result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, 
3031                                                  selTop, paintInfo));
3032         
3033         LayoutRect logicalRect(curr->logicalLeft(), selTop, curr->logicalWidth(), selTop + selHeight);
3034         logicalRect.move(isHorizontalWritingMode() ? offsetFromRootBlock : offsetFromRootBlock.transposedSize());
3035         LayoutRect physicalRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect);
3036         if (!paintInfo || (isHorizontalWritingMode() && physicalRect.y() < paintInfo->rect.maxY() && physicalRect.maxY() > paintInfo->rect.y())
3037             || (!isHorizontalWritingMode() && physicalRect.x() < paintInfo->rect.maxX() && physicalRect.maxX() > paintInfo->rect.x()))
3038             result.unite(curr->lineSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, selTop, selHeight, paintInfo));
3039
3040         lastSelectedLine = curr;
3041     }
3042
3043     if (containsStart && !lastSelectedLine)
3044         // VisibleSelection must start just after our last line.
3045         lastSelectedLine = lastRootBox();
3046
3047     if (lastSelectedLine && selectionState() != SelectionEnd && selectionState() != SelectionBoth) {
3048         // Go ahead and update our lastY to be the bottom of the last selected line.
3049         lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + lastSelectedLine->selectionBottom();
3050         lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
3051         lastLogicalRight = logicalRightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
3052     }
3053     return result;
3054 }
3055
3056 GapRects RenderBlock::blockSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
3057                                          LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* paintInfo)
3058 {
3059     GapRects result;
3060
3061     // Go ahead and jump right to the first block child that contains some selected objects.
3062     RenderBox* curr;
3063     for (curr = firstChildBox(); curr && curr->selectionState() == SelectionNone; curr = curr->nextSiblingBox()) { }
3064
3065     for (bool sawSelectionEnd = false; curr && !sawSelectionEnd; curr = curr->nextSiblingBox()) {
3066         SelectionState childState = curr->selectionState();
3067         if (childState == SelectionBoth || childState == SelectionEnd)
3068             sawSelectionEnd = true;
3069
3070         if (curr->isFloatingOrPositioned())
3071             continue; // We must be a normal flow object in order to even be considered.
3072
3073         if (curr->isRelPositioned() && curr->hasLayer()) {
3074             // If the relposition offset is anything other than 0, then treat this just like an absolute positioned element.
3075             // Just disregard it completely.
3076             LayoutSize relOffset = curr->layer()->relativePositionOffset();
3077             if (relOffset.width() || relOffset.height())
3078                 continue;
3079         }
3080
3081         bool paintsOwnSelection = curr->shouldPaintSelectionGaps() || curr->isTable(); // FIXME: Eventually we won't special-case table like this.
3082         bool fillBlockGaps = paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone);
3083         if (fillBlockGaps) {
3084             // We need to fill the vertical gap above this object.
3085             if (childState == SelectionEnd || childState == SelectionInside)
3086                 // Fill the gap above the object.
3087                 result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, 
3088                                                      curr->logicalTop(), paintInfo));
3089
3090             // Only fill side gaps for objects that paint their own selection if we know for sure the selection is going to extend all the way *past*
3091             // our object.  We know this if the selection did not end inside our object.
3092             if (paintsOwnSelection && (childState == SelectionStart || sawSelectionEnd))
3093                 childState = SelectionNone;
3094
3095             // Fill side gaps on this object based off its state.
3096             bool leftGap, rightGap;
3097             getSelectionGapInfo(childState, leftGap, rightGap);
3098
3099             if (leftGap)
3100                 result.uniteLeft(logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalLeft(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
3101             if (rightGap)
3102                 result.uniteRight(logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalRight(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
3103
3104             // Update lastLogicalTop to be just underneath the object.  lastLogicalLeft and lastLogicalRight extend as far as
3105             // they can without bumping into floating or positioned objects.  Ideally they will go right up
3106             // to the border of the root selection block.
3107             lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + curr->logicalBottom();
3108             lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, curr->logicalBottom());
3109             lastLogicalRight = logicalRightSelectionOffset(rootBlock, curr->logicalBottom());
3110         } else if (childState != SelectionNone)
3111             // We must be a block that has some selected object inside it.  Go ahead and recur.
3112             result.unite(toRenderBlock(curr)->selectionGaps(rootBlock, rootBlockPhysicalPosition, LayoutSize(offsetFromRootBlock.width() + curr->x(), offsetFromRootBlock.height() + curr->y()), 
3113                                                             lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo));
3114     }
3115     return result;
3116 }
3117
3118 LayoutRect RenderBlock::blockSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
3119                                           LayoutUnit lastLogicalTop, LayoutUnit lastLogicalLeft, LayoutUnit lastLogicalRight, LayoutUnit logicalBottom, const PaintInfo* paintInfo)
3120 {
3121     LayoutUnit logicalTop = lastLogicalTop;
3122     LayoutUnit logicalHeight = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalBottom - logicalTop;
3123     if (logicalHeight <= static_cast<LayoutUnit>(0))
3124         return LayoutRect();
3125
3126     // Get the selection offsets for the bottom of the gap
3127     LayoutUnit logicalLeft = max(lastLogicalLeft, logicalLeftSelectionOffset(rootBlock, logicalBottom));
3128     LayoutUnit logicalRight = min(lastLogicalRight, logicalRightSelectionOffset(rootBlock, logicalBottom));
3129     LayoutUnit logicalWidth = logicalRight - logicalLeft;
3130     if (logicalWidth <= static_cast<LayoutUnit>(0))
3131         return LayoutRect();
3132
3133     LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(logicalLeft, logicalTop, logicalWidth, logicalHeight));
3134     if (paintInfo)
3135         paintInfo->context->fillRect(gapRect, selectionBackgroundColor(), style()->colorSpace());
3136     return gapRect;
3137 }
3138
3139 LayoutRect RenderBlock::logicalLeftSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
3140                                                 RenderObject* selObj, LayoutUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo* paintInfo)
3141 {
3142     LayoutUnit rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
3143     LayoutUnit rootBlockLogicalLeft = max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight));
3144     LayoutUnit rootBlockLogicalRight = min(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalLeft, min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight)));
3145     LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
3146     if (rootBlockLogicalWidth <= static_cast<LayoutUnit>(0))
3147         return LayoutRect();
3148
3149     LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
3150     if (paintInfo)
3151         paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
3152     return gapRect;
3153 }
3154
3155 LayoutRect RenderBlock::logicalRightSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
3156                                                  RenderObject* selObj, LayoutUnit logicalRight, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo* paintInfo)
3157 {
3158     LayoutUnit rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
3159     LayoutUnit rootBlockLogicalLeft = max(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalRight, max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight)));
3160     LayoutUnit rootBlockLogicalRight = min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight));
3161     LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
3162     if (rootBlockLogicalWidth <= static_cast<LayoutUnit>(0))
3163         return LayoutRect();
3164
3165     LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
3166     if (paintInfo)
3167         paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
3168     return gapRect;
3169 }
3170
3171 void RenderBlock::getSelectionGapInfo(SelectionState state, bool& leftGap, bool& rightGap)
3172 {
3173     bool ltr = style()->isLeftToRightDirection();
3174     leftGap = (state == RenderObject::SelectionInside) ||
3175               (state == RenderObject::SelectionEnd && ltr) ||
3176               (state == RenderObject::SelectionStart && !ltr);
3177     rightGap = (state == RenderObject::SelectionInside) ||
3178                (state == RenderObject::SelectionStart && ltr) ||
3179                (state == RenderObject::SelectionEnd && !ltr);
3180 }
3181
3182 LayoutUnit RenderBlock::logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position)
3183 {
3184     LayoutUnit logicalLeft = logicalLeftOffsetForLine(position, false);
3185     if (logicalLeft == logicalLeftOffsetForContent()) {
3186         if (rootBlock != this)
3187             // The border can potentially be further extended by our containingBlock().
3188             return containingBlock()->logicalLeftSelectionOffset(rootBlock, position + logicalTop());
3189         return logicalLeft;
3190     } else {
3191         RenderBlock* cb = this;
3192         while (cb != rootBlock) {
3193             logicalLeft += cb->logicalLeft();
3194             cb = cb->containingBlock();
3195         }
3196     }
3197     return logicalLeft;
3198 }
3199
3200 LayoutUnit RenderBlock::logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position)
3201 {
3202     LayoutUnit logicalRight = logicalRightOffsetForLine(position, false);
3203     if (logicalRight == logicalRightOffsetForContent()) {
3204         if (rootBlock != this)
3205             // The border can potentially be further extended by our containingBlock().
3206             return containingBlock()->logicalRightSelectionOffset(rootBlock, position + logicalTop());
3207         return logicalRight;
3208     } else {
3209         RenderBlock* cb = this;
3210         while (cb != rootBlock) {
3211             logicalRight += cb->logicalLeft();
3212             cb = cb->containingBlock();
3213         }
3214     }
3215     return logicalRight;
3216 }
3217
3218 void RenderBlock::insertPositionedObject(RenderBox* o)
3219 {
3220     if (o->isRenderFlowThread())
3221         return;
3222     
3223     // Create the list of special objects if we don't aleady have one
3224     if (!m_positionedObjects)
3225         m_positionedObjects = adoptPtr(new PositionedObjectsListHashSet);
3226
3227     m_positionedObjects->add(o);
3228 }
3229
3230 void RenderBlock::removePositionedObject(RenderBox* o)
3231 {
3232     if (m_positionedObjects)
3233         m_positionedObjects->remove(o);
3234 }
3235
3236 void RenderBlock::removePositionedObjects(RenderBlock* o)
3237 {
3238     if (!m_positionedObjects)
3239         return;
3240     
3241     RenderBox* r;
3242     
3243     Iterator end = m_positionedObjects->end();
3244     
3245     Vector<RenderBox*, 16> deadObjects;
3246
3247     for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
3248         r = *it;
3249         if (!o || r->isDescendantOf(o)) {
3250             if (o)
3251                 r->setChildNeedsLayout(true, false);
3252             
3253             // It is parent blocks job to add positioned child to positioned objects list of its containing block
3254             // Parent layout needs to be invalidated to ensure this happens.
3255             RenderObject* p = r->parent();
3256             while (p && !p->isRenderBlock())
3257                 p = p->parent();
3258             if (p)
3259                 p->setChildNeedsLayout(true);
3260             
3261             deadObjects.append(r);
3262         }
3263     }
3264     
3265     for (unsigned i = 0; i < deadObjects.size(); i++)
3266         m_positionedObjects->remove(deadObjects.at(i));
3267 }
3268
3269 RenderBlock::FloatingObject* RenderBlock::insertFloatingObject(RenderBox* o)
3270 {
3271     ASSERT(o->isFloating());
3272
3273     // Create the list of special objects if we don't aleady have one
3274     if (!m_floatingObjects)
3275         m_floatingObjects = adoptPtr(new FloatingObjects(isHorizontalWritingMode()));
3276     else {
3277         // Don't insert the object again if it's already in the list
3278         const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
3279         FloatingObjectSetIterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(o);
3280         if (it != floatingObjectSet.end())
3281             return *it;
3282     }
3283
3284     // Create the special object entry & append it to the list
3285
3286     FloatingObject* newObj = new FloatingObject(o->style()->floating());
3287     
3288     // Our location is irrelevant if we're unsplittable or no pagination is in effect.
3289     // Just go ahead and lay out the float.
3290     if (!o->isPositioned()) {
3291         bool isChildRenderBlock = o->isRenderBlock();
3292         if (isChildRenderBlock && !o->needsLayout() && view()->layoutState()->pageLogicalHeightChanged())
3293             o->setChildNeedsLayout(true, false);
3294             
3295         bool affectedByPagination = isChildRenderBlock && view()->layoutState()->m_pageLogicalHeight;
3296         if (!affectedByPagination || isWritingModeRoot()) // We are unsplittable if we're a block flow root.
3297             o->layoutIfNeeded();
3298         else {
3299             o->computeLogicalWidth();
3300             o->computeBlockDirectionMargins(this);
3301         }
3302     }
3303     setLogicalWidthForFloat(newObj, logicalWidthForChild(o) + marginStartForChild(o) + marginEndForChild(o));
3304
3305     newObj->m_shouldPaint = !o->hasSelfPaintingLayer(); // If a layer exists, the float will paint itself.  Otherwise someone else will.
3306     newObj->m_isDescendant = true;
3307     newObj->m_renderer = o;
3308
3309     m_floatingObjects->add(newObj);
3310     
3311     return newObj;
3312 }
3313
3314 void RenderBlock::removeFloatingObject(RenderBox* o)
3315 {
3316     if (m_floatingObjects) {
3317         const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
3318         FloatingObjectSetIterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(o);
3319         if (it != floatingObjectSet.end()) {
3320             FloatingObject* r = *it;
3321             if (childrenInline()) {
3322                 LayoutUnit logicalTop = logicalTopForFloat(r);
3323                 LayoutUnit logicalBottom = logicalBottomForFloat(r);
3324
3325                 // Fix for https://bugs.webkit.org/show_bug.cgi?id=54995.
3326                 if (logicalBottom < 0 || logicalBottom < logicalTop || logicalTop == numeric_limits<LayoutUnit>::max())
3327                     logicalBottom = numeric_limits<LayoutUnit>::max();
3328                 else {
3329                     // Special-case zero- and less-than-zero-height floats: those don't touch
3330                     // the line that they're on, but it still needs to be dirtied. This is
3331                     // accomplished by pretending they have a height of 1.
3332                     logicalBottom = max(logicalBottom, logicalTop + 1);
3333                 }
3334                 if (r->m_originatingLine) {
3335                     if (!selfNeedsLayout()) {
3336                         ASSERT(r->m_originatingLine->renderer() == this);
3337                         r->m_originatingLine->markDirty();
3338                     }
3339 #if !ASSERT_DISABLED
3340                     r->m_originatingLine = 0;
3341 #endif
3342                 }
3343                 markLinesDirtyInBlockRange(0, logicalBottom);
3344             }
3345             m_floatingObjects->remove(r);
3346             ASSERT(!r->m_originatingLine);
3347             delete r;
3348         }
3349     }
3350 }
3351
3352 void RenderBlock::removeFloatingObjectsBelow(FloatingObject* lastFloat, int logicalOffset)
3353 {
3354     if (!m_floatingObjects)
3355         return;
3356     
3357     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
3358     FloatingObject* curr = floatingObjectSet.last();
3359     while (curr != lastFloat && (!curr->isPlaced() || logicalTopForFloat(curr) >= logicalOffset)) {
3360         m_floatingObjects->remove(curr);
3361         ASSERT(!curr->m_originatingLine);
3362         delete curr;
3363         if (floatingObjectSet.isEmpty())
3364             break;
3365         curr = floatingObjectSet.last();
3366     }
3367 }
3368
3369 LayoutPoint RenderBlock::computeLogicalLocationForFloat(const FloatingObject* floatingObject, LayoutUnit logicalTopOffset) const
3370 {
3371     RenderBox* childBox = floatingObject->renderer();
3372     LayoutUnit logicalRightOffset = logicalRightOffsetForContent(logicalTopOffset); // Constant part of right offset.
3373     LayoutUnit logicalLeftOffset = logicalLeftOffsetForContent(logicalTopOffset); // Constant part of left offset.
3374     LayoutUnit floatLogicalWidth = min(logicalWidthForFloat(floatingObject), logicalRightOffset - logicalLeftOffset); // The width we look for.
3375
3376     LayoutUnit floatLogicalLeft;
3377
3378     if (childBox->style()->floating() == LeftFloat) {
3379         LayoutUnit heightRemainingLeft = 1;
3380         LayoutUnit heightRemainingRight = 1;
3381         floatLogicalLeft = logicalLeftOffsetForLine(logicalTopOffset, logicalLeftOffset, false, &heightRemainingLeft);
3382         while (logicalRightOffsetForLine(logicalTopOffset, logicalRightOffset, false, &heightRemainingRight) - floatLogicalLeft < floatLogicalWidth) {
3383             logicalTopOffset += min(heightRemainingLeft, heightRemainingRight);
3384             floatLogicalLeft = logicalLeftOffsetForLine(logicalTopOffset, logicalLeftOffset, false, &heightRemainingLeft);
3385             if (inRenderFlowThread()) {
3386                 // Have to re-evaluate all of our offsets, since they may have changed.
3387                 logicalRightOffset = logicalRightOffsetForContent(logicalTopOffset); // Constant part of right offset.
3388                 logicalLeftOffset = logicalLeftOffsetForContent(logicalTopOffset); // Constant part of left offset.
3389                 floatLogicalWidth = min(logicalWidthForFloat(floatingObject), logicalRightOffset - logicalLeftOffset);
3390             }
3391         }
3392         floatLogicalLeft = max<LayoutUnit>(logicalLeftOffset - borderAndPaddingLogicalLeft(), floatLogicalLeft);
3393     } else {
3394         LayoutUnit heightRemainingLeft = 1;
3395         LayoutUnit heightRemainingRight = 1;
3396         floatLogicalLeft = logicalRightOffsetForLine(logicalTopOffset, logicalRightOffset, false, &heightRemainingRight);
3397         while (floatLogicalLeft - logicalLeftOffsetForLine(logicalTopOffset, logicalLeftOffset, false, &heightRemainingLeft) < floatLogicalWidth) {
3398             logicalTopOffset += min(heightRemainingLeft, heightRemainingRight);
3399             floatLogicalLeft = logicalRightOffsetForLine(logicalTopOffset, logicalRightOffset, false, &heightRemainingRight);
3400             if (inRenderFlowThread()) {
3401                 // Have to re-evaluate all of our offsets, since they may have changed.
3402                 logicalRightOffset = logicalRightOffsetForContent(logicalTopOffset); // Constant part of right offset.
3403                 logicalLeftOffset = logicalLeftOffsetForContent(logicalTopOffset); // Constant part of left offset.
3404                 floatLogicalWidth = min(logicalWidthForFloat(floatingObject), logicalRightOffset - logicalLeftOffset);
3405             }
3406         }
3407         floatLogicalLeft -= logicalWidthForFloat(floatingObject); // Use the original width of the float here, since the local variable
3408                                                                   // |floatLogicalWidth| was capped to the available line width.
3409                                                                   // See fast/block/float/clamped-right-float.html.
3410     }
3411     
3412     return LayoutPoint(floatLogicalLeft, logicalTopOffset);
3413 }
3414
3415 bool RenderBlock::positionNewFloats()
3416 {
3417     if (!m_floatingObjects)
3418         return false;
3419
3420     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
3421     if (floatingObjectSet.isEmpty())
3422         return false;
3423
3424     // If all floats have already been positioned, then we have no work to do.
3425     if (floatingObjectSet.last()->isPlaced())
3426         return false;
3427
3428     // Move backwards through our floating object list until we find a float that has
3429     // already been positioned.  Then we'll be able to move forward, positioning all of
3430     // the new floats that need it.
3431     FloatingObjectSetIterator it = floatingObjectSet.end();
3432     --it; // Go to last item.
3433     FloatingObjectSetIterator begin = floatingObjectSet.begin();
3434     FloatingObject* lastPlacedFloatingObject = 0;
3435     while (it != begin) {
3436         --it;
3437         if ((*it)->isPlaced()) {
3438             lastPlacedFloatingObject = *it;
3439             ++it;
3440             break;
3441         }
3442     }
3443
3444     LayoutUnit logicalTop = logicalHeight();
3445     
3446     // The float cannot start above the top position of the last positioned float.
3447     if (lastPlacedFloatingObject)
3448         logicalTop = max(logicalTopForFloat(lastPlacedFloatingObject), logicalTop);
3449
3450     FloatingObjectSetIterator end = floatingObjectSet.end();
3451     // Now walk through the set of unpositioned floats and place them.
3452     for (; it != end; ++it) {
3453         FloatingObject* floatingObject = *it;
3454         // The containing block is responsible for positioning floats, so if we have floats in our
3455         // list that come from somewhere else, do not attempt to position them. Also don't attempt to handle
3456         // positioned floats, since the positioning layout code handles those.
3457         if (floatingObject->renderer()->containingBlock() != this || floatingObject->renderer()->isPositioned())
3458             continue;
3459
3460         RenderBox* childBox = floatingObject->renderer();
3461         LayoutUnit childLogicalLeftMargin = style()->isLeftToRightDirection() ? marginStartForChild(childBox) : marginEndForChild(childBox);
3462
3463         LayoutRect oldRect(childBox->x(), childBox->y() , childBox->width(), childBox->height());
3464
3465         if (childBox->style()->clear() & CLEFT)
3466             logicalTop = max(lowestFloatLogicalBottom(FloatingObject::FloatLeft), logicalTop);
3467         if (childBox->style()->clear() & CRIGHT)
3468             logicalTop = max(lowestFloatLogicalBottom(FloatingObject::FloatRight), logicalTop);
3469
3470         LayoutPoint floatLogicalLocation = computeLogicalLocationForFloat(floatingObject, logicalTop);
3471
3472         setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x());
3473         setLogicalLeftForChild(childBox, floatLogicalLocation.x() + childLogicalLeftMargin);
3474         setLogicalTopForChild(childBox, floatLogicalLocation.y() + marginBeforeForChild(childBox));
3475
3476         if (view()->layoutState()->isPaginated()) {
3477             RenderBlock* childBlock = childBox->isRenderBlock() ? toRenderBlock(childBox) : 0;
3478
3479             if (!childBox->needsLayout())
3480                 childBox->markForPaginationRelayoutIfNeeded();
3481             childBox->layoutIfNeeded();
3482
3483             // If we are unsplittable and don't fit, then we need to move down.
3484             // We include our margins as part of the unsplittable area.
3485             LayoutUnit newLogicalTop = adjustForUnsplittableChild(childBox, floatLogicalLocation.y(), true);
3486             
3487             // See if we have a pagination strut that is making us move down further.
3488             // Note that an unsplittable child can't also have a pagination strut, so this is
3489             // exclusive with the case above.
3490             if (childBlock && childBlock->paginationStrut()) {
3491                 newLogicalTop += childBlock->paginationStrut();
3492                 childBlock->setPaginationStrut(0);
3493             }
3494             
3495             if (newLogicalTop != floatLogicalLocation.y()) {
3496                 floatingObject->m_paginationStrut = newLogicalTop - floatLogicalLocation.y();
3497
3498                 floatLogicalLocation = computeLogicalLocationForFloat(floatingObject, newLogicalTop);
3499                 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x());
3500                 setLogicalLeftForChild(childBox, floatLogicalLocation.x() + childLogicalLeftMargin);
3501                 setLogicalTopForChild(childBox, floatLogicalLocation.y() + marginBeforeForChild(childBox));
3502         
3503                 if (childBlock)
3504                     childBlock->setChildNeedsLayout(true, false);
3505                 childBox->layoutIfNeeded();
3506             }
3507         }
3508
3509         setLogicalTopForFloat(floatingObject, floatLogicalLocation.y());
3510         setLogicalHeightForFloat(floatingObject, logicalHeightForChild(childBox) + marginBeforeForChild(childBox) + marginAfterForChild(childBox));
3511
3512         m_floatingObjects->addPlacedObject(floatingObject);
3513
3514         // If the child moved, we have to repaint it.
3515         if (childBox->checkForRepaintDuringLayout())
3516             childBox->repaintDuringLayoutIfMoved(oldRect);
3517     }
3518     return true;
3519 }
3520
3521 void RenderBlock::newLine(EClear clear)
3522 {
3523     positionNewFloats();
3524     // set y position
3525     int newY = 0;
3526     switch (clear)
3527     {
3528         case CLEFT:
3529             newY = lowestFloatLogicalBottom(FloatingObject::FloatLeft);
3530             break;
3531         case CRIGHT:
3532             newY = lowestFloatLogicalBottom(FloatingObject::FloatRight);
3533             break;
3534         case CBOTH:
3535             newY = lowestFloatLogicalBottom();
3536         default:
3537             break;
3538     }
3539     if (height() < newY)
3540         setLogicalHeight(newY);
3541 }
3542
3543 void RenderBlock::addPercentHeightDescendant(RenderBox* descendant)
3544 {
3545     if (!gPercentHeightDescendantsMap) {
3546         gPercentHeightDescendantsMap = new PercentHeightDescendantsMap;
3547         gPercentHeightContainerMap = new PercentHeightContainerMap;
3548     }
3549
3550     HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(this);
3551     if (!descendantSet) {
3552         descendantSet = new HashSet<RenderBox*>;
3553         gPercentHeightDescendantsMap->set(this, descendantSet);
3554     }
3555     bool added = descendantSet->add(descendant).second;
3556     if (!added) {
3557         ASSERT(gPercentHeightContainerMap->get(descendant));
3558         ASSERT(gPercentHeightContainerMap->get(descendant)->contains(this));
3559         return;
3560     }
3561
3562     HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->get(descendant);
3563     if (!containerSet) {
3564         containerSet = new HashSet<RenderBlock*>;
3565         gPercentHeightContainerMap->set(descendant, containerSet);
3566     }
3567     ASSERT(!containerSet->contains(this));
3568     containerSet->add(this);
3569 }
3570
3571 void RenderBlock::removePercentHeightDescendant(RenderBox* descendant)
3572 {
3573     if (!gPercentHeightContainerMap)
3574         return;
3575
3576     HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->take(descendant);
3577     if (!containerSet)
3578         return;
3579
3580     HashSet<RenderBlock*>::iterator end = containerSet->end();
3581     for (HashSet<RenderBlock*>::iterator it = containerSet->begin(); it != end; ++it) {
3582         RenderBlock* container = *it;
3583         HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(container);
3584         ASSERT(descendantSet);
3585         if (!descendantSet)
3586             continue;
3587         ASSERT(descendantSet->contains(descendant));
3588         descendantSet->remove(descendant);
3589         if (descendantSet->isEmpty()) {
3590             gPercentHeightDescendantsMap->remove(container);
3591             delete descendantSet;
3592         }
3593     }
3594
3595     delete containerSet;
3596 }
3597
3598 HashSet<RenderBox*>* RenderBlock::percentHeightDescendants() const
3599 {
3600     return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0;
3601 }
3602
3603 #if !ASSERT_DISABLED
3604 bool RenderBlock::hasPercentHeightDescendant(RenderBox* descendant)
3605 {
3606     ASSERT(descendant);
3607     if (!gPercentHeightContainerMap)
3608         return false;
3609     HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->take(descendant);
3610     return containerSet && containerSet->size();
3611 }
3612 #endif
3613
3614 template <RenderBlock::FloatingObject::Type FloatTypeValue>
3615 inline void RenderBlock::FloatIntervalSearchAdapter<FloatTypeValue>::collectIfNeeded(const IntervalType& interval) const
3616 {
3617     const FloatingObject* r = interval.data();
3618     if (r->type() == FloatTypeValue && interval.low() <= m_value && m_value < interval.high()) {
3619         // All the objects returned from the tree should be already placed.
3620         ASSERT(r->isPlaced() && m_renderer->logicalTopForFloat(r) <= m_value && m_renderer->logicalBottomForFloat(r) > m_value);
3621
3622         if (FloatTypeValue == FloatingObject::FloatLeft 
3623             && m_renderer->logicalRightForFloat(r) > m_offset) {
3624             m_offset = m_renderer->logicalRightForFloat(r);
3625             if (m_heightRemaining)
3626                 *m_heightRemaining = m_renderer->logicalBottomForFloat(r) - m_value;
3627         }
3628
3629         if (FloatTypeValue == FloatingObject::FloatRight
3630             && m_renderer->logicalLeftForFloat(r) < m_offset) {
3631             m_offset = m_renderer->logicalLeftForFloat(r);
3632             if (m_heightRemaining)
3633                 *m_heightRemaining = m_renderer->logicalBottomForFloat(r) - m_value;
3634         }
3635     }
3636 }
3637
3638 LayoutUnit RenderBlock::textIndentOffset() const
3639 {
3640     LayoutUnit cw = 0;
3641     if (style()->textIndent().isPercent())
3642         cw = containingBlock()->availableLogicalWidth();
3643     return style()->textIndent().calcMinValue(cw);
3644 }
3645
3646 LayoutUnit RenderBlock::logicalLeftOffsetForContent(RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage) const
3647 {
3648     LayoutUnit logicalLeftOffset = style()->isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop();
3649     if (!inRenderFlowThread())
3650         return logicalLeftOffset;
3651     LayoutRect boxRect = borderBoxRectInRegion(region, offsetFromLogicalTopOfFirstPage);
3652     return logicalLeftOffset + (isHorizontalWritingMode() ? boxRect.x() : boxRect.y());
3653 }
3654
3655 LayoutUnit RenderBlock::logicalRightOffsetForContent(RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage) const
3656 {
3657     LayoutUnit logicalRightOffset = style()->isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop();
3658     logicalRightOffset += availableLogicalWidth();
3659     if (!inRenderFlowThread())
3660         return logicalRightOffset;
3661     LayoutRect boxRect = borderBoxRectInRegion(region, offsetFromLogicalTopOfFirstPage);
3662     return logicalRightOffset - (logicalWidth() - (isHorizontalWritingMode() ? boxRect.maxX() : boxRect.maxY()));
3663 }
3664
3665 LayoutUnit RenderBlock::logicalLeftOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining) const
3666 {
3667     LayoutUnit left = fixedOffset;
3668     if (m_floatingObjects && m_floatingObjects->hasLeftObjects()) {
3669         if (heightRemaining)
3670             *heightRemaining = 1;
3671
3672         FloatIntervalSearchAdapter<FloatingObject::FloatLeft> adapter(this, logicalTop, left, heightRemaining);
3673         m_floatingObjects->placedFloatsTree().allOverlapsWithAdapter(adapter);
3674     }
3675
3676     if (applyTextIndent && style()->isLeftToRightDirection())
3677         left += textIndentOffset();
3678
3679     return left;
3680 }
3681
3682 LayoutUnit RenderBlock::logicalRightOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining) const
3683 {
3684     LayoutUnit right = fixedOffset;
3685     if (m_floatingObjects && m_floatingObjects->hasRightObjects()) {
3686         if (heightRemaining)
3687             *heightRemaining = 1;
3688
3689         LayoutUnit rightFloatOffset = fixedOffset;
3690         FloatIntervalSearchAdapter<FloatingObject::FloatRight> adapter(this, logicalTop, rightFloatOffset, heightRemaining);
3691         m_floatingObjects->placedFloatsTree().allOverlapsWithAdapter(adapter);
3692         right = min(right, rightFloatOffset);
3693     }
3694     
3695     if (applyTextIndent && !style()->isLeftToRightDirection())
3696         right -= textIndentOffset();
3697     
3698     return right;
3699 }
3700
3701 LayoutUnit RenderBlock::nextFloatLogicalBottomBelow(LayoutUnit logicalHeight) const
3702 {
3703     if (!m_floatingObjects)
3704         return logicalHeight;
3705
3706     LayoutUnit bottom = numeric_limits<LayoutUnit>::max();
3707     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
3708     FloatingObjectSetIterator end = floatingObjectSet.end();
3709     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end;