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