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