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