Home | History | Annotate | Download | only in rendering
      1 /*
      2  * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org)
      3  *           (C) 1999 Antti Koivisto (koivisto (at) kde.org)
      4  *           (C) 2007 David Smith (catfish.man (at) gmail.com)
      5  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
      6  *
      7  * This library is free software; you can redistribute it and/or
      8  * modify it under the terms of the GNU Library General Public
      9  * License as published by the Free Software Foundation; either
     10  * version 2 of the License, or (at your option) any later version.
     11  *
     12  * This library is distributed in the hope that it will be useful,
     13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15  * Library General Public License for more details.
     16  *
     17  * You should have received a copy of the GNU Library General Public License
     18  * along with this library; see the file COPYING.LIB.  If not, write to
     19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     20  * Boston, MA 02110-1301, USA.
     21  */
     22 
     23 #include "config.h"
     24 #include "RenderBlock.h"
     25 
     26 #include "Document.h"
     27 #include "Element.h"
     28 #include "FloatQuad.h"
     29 #include "Frame.h"
     30 #include "FrameView.h"
     31 #include "GraphicsContext.h"
     32 #include "HTMLFormElement.h"
     33 #include "HTMLNames.h"
     34 #include "HitTestResult.h"
     35 #include "InlineTextBox.h"
     36 #include "RenderFlexibleBox.h"
     37 #include "RenderImage.h"
     38 #include "RenderInline.h"
     39 #include "RenderMarquee.h"
     40 #include "RenderReplica.h"
     41 #include "RenderTableCell.h"
     42 #include "RenderTextFragment.h"
     43 #include "RenderTheme.h"
     44 #include "RenderView.h"
     45 #include "SelectionController.h"
     46 #include "Settings.h"
     47 #include "TransformState.h"
     48 #include <wtf/StdLibExtras.h>
     49 
     50 #ifdef ANDROID_LAYOUT
     51 #include "Settings.h"
     52 #endif
     53 
     54 using namespace std;
     55 using namespace WTF;
     56 using namespace Unicode;
     57 
     58 namespace WebCore {
     59 
     60 // Number of pixels to allow as a fudge factor when clicking above or below a line.
     61 // clicking up to verticalLineClickFudgeFactor pixels above a line will correspond to the closest point on the line.
     62 static const int verticalLineClickFudgeFactor = 3;
     63 
     64 using namespace HTMLNames;
     65 
     66 struct ColumnInfo : public Noncopyable {
     67     ColumnInfo()
     68         : m_desiredColumnWidth(0)
     69         , m_desiredColumnCount(1)
     70         { }
     71     int m_desiredColumnWidth;
     72     unsigned m_desiredColumnCount;
     73     Vector<IntRect> m_columnRects;
     74 };
     75 
     76 typedef WTF::HashMap<const RenderBox*, ColumnInfo*> ColumnInfoMap;
     77 static ColumnInfoMap* gColumnInfoMap = 0;
     78 
     79 typedef WTF::HashMap<const RenderBlock*, HashSet<RenderBox*>*> PercentHeightDescendantsMap;
     80 static PercentHeightDescendantsMap* gPercentHeightDescendantsMap = 0;
     81 
     82 typedef WTF::HashMap<const RenderBox*, HashSet<RenderBlock*>*> PercentHeightContainerMap;
     83 static PercentHeightContainerMap* gPercentHeightContainerMap = 0;
     84 
     85 typedef WTF::HashMap<RenderBlock*, ListHashSet<RenderInline*>*> ContinuationOutlineTableMap;
     86 
     87 typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet;
     88 static int gDelayUpdateScrollInfo = 0;
     89 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0;
     90 
     91 // Our MarginInfo state used when laying out block children.
     92 RenderBlock::MarginInfo::MarginInfo(RenderBlock* block, int top, int bottom)
     93 {
     94     // Whether or not we can collapse our own margins with our children.  We don't do this
     95     // if we had any border/padding (obviously), if we're the root or HTML elements, or if
     96     // we're positioned, floating, a table cell.
     97     m_canCollapseWithChildren = !block->isRenderView() && !block->isRoot() && !block->isPositioned() &&
     98         !block->isFloating() && !block->isTableCell() && !block->hasOverflowClip() && !block->isInlineBlockOrInlineTable();
     99 
    100     m_canCollapseTopWithChildren = m_canCollapseWithChildren && (top == 0) && block->style()->marginTopCollapse() != MSEPARATE;
    101 
    102     // If any height other than auto is specified in CSS, then we don't collapse our bottom
    103     // margins with our children's margins.  To do otherwise would be to risk odd visual
    104     // effects when the children overflow out of the parent block and yet still collapse
    105     // with it.  We also don't collapse if we have any bottom border/padding.
    106     m_canCollapseBottomWithChildren = m_canCollapseWithChildren && (bottom == 0) &&
    107         (block->style()->height().isAuto() && block->style()->height().value() == 0) && block->style()->marginBottomCollapse() != MSEPARATE;
    108 
    109     m_quirkContainer = block->isTableCell() || block->isBody() || block->style()->marginTopCollapse() == MDISCARD ||
    110         block->style()->marginBottomCollapse() == MDISCARD;
    111 
    112     m_atTopOfBlock = true;
    113     m_atBottomOfBlock = false;
    114 
    115     m_posMargin = m_canCollapseTopWithChildren ? block->maxTopMargin(true) : 0;
    116     m_negMargin = m_canCollapseTopWithChildren ? block->maxTopMargin(false) : 0;
    117 
    118     m_topQuirk = m_bottomQuirk = m_determinedTopQuirk = false;
    119 }
    120 
    121 // -------------------------------------------------------------------------------------------------------
    122 
    123 RenderBlock::RenderBlock(Node* node)
    124       : RenderBox(node)
    125       , m_floatingObjects(0)
    126       , m_positionedObjects(0)
    127       , m_inlineContinuation(0)
    128       , m_maxMargin(0)
    129       , m_lineHeight(-1)
    130 {
    131     setChildrenInline(true);
    132 }
    133 
    134 RenderBlock::~RenderBlock()
    135 {
    136     delete m_floatingObjects;
    137     delete m_positionedObjects;
    138     delete m_maxMargin;
    139 
    140     if (hasColumns())
    141         delete gColumnInfoMap->take(this);
    142 
    143     if (gPercentHeightDescendantsMap) {
    144         if (HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->take(this)) {
    145             HashSet<RenderBox*>::iterator end = descendantSet->end();
    146             for (HashSet<RenderBox*>::iterator descendant = descendantSet->begin(); descendant != end; ++descendant) {
    147                 HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->get(*descendant);
    148                 ASSERT(containerSet);
    149                 if (!containerSet)
    150                     continue;
    151                 ASSERT(containerSet->contains(this));
    152                 containerSet->remove(this);
    153                 if (containerSet->isEmpty()) {
    154                     gPercentHeightContainerMap->remove(*descendant);
    155                     delete containerSet;
    156                 }
    157             }
    158             delete descendantSet;
    159         }
    160     }
    161 }
    162 
    163 void RenderBlock::destroy()
    164 {
    165     // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
    166     // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
    167     children()->destroyLeftoverChildren();
    168 
    169     // Destroy our continuation before anything other than anonymous children.
    170     // The reason we don't destroy it before anonymous children is that they may
    171     // have continuations of their own that are anonymous children of our continuation.
    172     if (m_inlineContinuation) {
    173         m_inlineContinuation->destroy();
    174         m_inlineContinuation = 0;
    175     }
    176 
    177     if (!documentBeingDestroyed()) {
    178         if (firstLineBox()) {
    179             // We can't wait for RenderBox::destroy to clear the selection,
    180             // because by then we will have nuked the line boxes.
    181             // FIXME: The SelectionController should be responsible for this when it
    182             // is notified of DOM mutations.
    183             if (isSelectionBorder())
    184                 view()->clearSelection();
    185 
    186             // If we are an anonymous block, then our line boxes might have children
    187             // that will outlast this block. In the non-anonymous block case those
    188             // children will be destroyed by the time we return from this function.
    189             if (isAnonymousBlock()) {
    190                 for (InlineFlowBox* box = firstLineBox(); box; box = box->nextFlowBox()) {
    191                     while (InlineBox* childBox = box->firstChild())
    192                         childBox->remove();
    193                 }
    194             }
    195         } else if (isInline() && parent())
    196             parent()->dirtyLinesFromChangedChild(this);
    197     }
    198 
    199     m_lineBoxes.deleteLineBoxes(renderArena());
    200 
    201     RenderBox::destroy();
    202 }
    203 
    204 void RenderBlock::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
    205 {
    206     setReplaced(newStyle->isDisplayReplacedType());
    207 
    208     if (style() && parent() && diff == StyleDifferenceLayout && style()->position() != newStyle->position()) {
    209         if (newStyle->position() == StaticPosition)
    210             // Clear our positioned objects list. Our absolutely positioned descendants will be
    211             // inserted into our containing block's positioned objects list during layout.
    212             removePositionedObjects(0);
    213         else if (style()->position() == StaticPosition) {
    214             // Remove our absolutely positioned descendants from their current containing block.
    215             // They will be inserted into our positioned objects list during layout.
    216             RenderObject* cb = parent();
    217             while (cb && (cb->style()->position() == StaticPosition || (cb->isInline() && !cb->isReplaced())) && !cb->isRenderView()) {
    218                 if (cb->style()->position() == RelativePosition && cb->isInline() && !cb->isReplaced()) {
    219                     cb = cb->containingBlock();
    220                     break;
    221                 }
    222                 cb = cb->parent();
    223             }
    224 
    225             if (cb->isRenderBlock())
    226                 toRenderBlock(cb)->removePositionedObjects(this);
    227         }
    228     }
    229 
    230     RenderBox::styleWillChange(diff, newStyle);
    231 }
    232 
    233 void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
    234 {
    235     RenderBox::styleDidChange(diff, oldStyle);
    236 
    237     // FIXME: We could save this call when the change only affected non-inherited properties
    238     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
    239         if (child->isAnonymousBlock()) {
    240             RefPtr<RenderStyle> newStyle = RenderStyle::create();
    241             newStyle->inheritFrom(style());
    242             newStyle->setDisplay(BLOCK);
    243             child->setStyle(newStyle.release());
    244         }
    245     }
    246 
    247     m_lineHeight = -1;
    248 
    249     // Update pseudos for :before and :after now.
    250     if (!isAnonymous() && document()->usesBeforeAfterRules() && canHaveChildren()) {
    251         updateBeforeAfterContent(BEFORE);
    252         updateBeforeAfterContent(AFTER);
    253     }
    254     updateFirstLetter();
    255 }
    256 
    257 void RenderBlock::updateBeforeAfterContent(PseudoId pseudoId)
    258 {
    259     // If this is an anonymous wrapper, then the parent applies its own pseudo-element style to it.
    260     if (parent() && parent()->createsAnonymousWrapper())
    261         return;
    262     return children()->updateBeforeAfterContent(this, pseudoId);
    263 }
    264 
    265 void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
    266 {
    267     // Make sure we don't append things after :after-generated content if we have it.
    268     if (!beforeChild && isAfterContent(lastChild()))
    269         beforeChild = lastChild();
    270 
    271     bool madeBoxesNonInline = false;
    272 
    273     // If the requested beforeChild is not one of our children, then this is because
    274     // there is an anonymous container within this object that contains the beforeChild.
    275     if (beforeChild && beforeChild->parent() != this) {
    276         RenderObject* anonymousChild = beforeChild->parent();
    277         ASSERT(anonymousChild);
    278 
    279         while (anonymousChild->parent() != this)
    280             anonymousChild = anonymousChild->parent();
    281 
    282         ASSERT(anonymousChild->isAnonymous());
    283 
    284         if (anonymousChild->isAnonymousBlock()) {
    285             // Insert the child into the anonymous block box instead of here.
    286             if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)
    287                 beforeChild->parent()->addChild(newChild, beforeChild);
    288             else
    289                 addChild(newChild, beforeChild->parent());
    290             return;
    291         }
    292 
    293         ASSERT(anonymousChild->isTable());
    294         if ((newChild->isTableCol() && newChild->style()->display() == TABLE_COLUMN_GROUP)
    295                 || (newChild->isRenderBlock() && newChild->style()->display() == TABLE_CAPTION)
    296                 || newChild->isTableSection()
    297                 || newChild->isTableRow()
    298                 || newChild->isTableCell()) {
    299             // Insert into the anonymous table.
    300             anonymousChild->addChild(newChild, beforeChild);
    301             return;
    302         }
    303 
    304         // Go on to insert before the anonymous table.
    305         beforeChild = anonymousChild;
    306     }
    307 
    308     // A block has to either have all of its children inline, or all of its children as blocks.
    309     // So, if our children are currently inline and a block child has to be inserted, we move all our
    310     // inline children into anonymous block boxes.
    311     if (childrenInline() && !newChild->isInline() && !newChild->isFloatingOrPositioned()) {
    312         // This is a block with inline content. Wrap the inline content in anonymous blocks.
    313         makeChildrenNonInline(beforeChild);
    314         madeBoxesNonInline = true;
    315 
    316         if (beforeChild && beforeChild->parent() != this) {
    317             beforeChild = beforeChild->parent();
    318             ASSERT(beforeChild->isAnonymousBlock());
    319             ASSERT(beforeChild->parent() == this);
    320         }
    321     } else if (!childrenInline() && (newChild->isFloatingOrPositioned() || newChild->isInline())) {
    322         // If we're inserting an inline child but all of our children are blocks, then we have to make sure
    323         // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise
    324         // a new one is created and inserted into our list of children in the appropriate position.
    325         RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();
    326 
    327         if (afterChild && afterChild->isAnonymousBlock()) {
    328             afterChild->addChild(newChild);
    329             return;
    330         }
    331 
    332         if (newChild->isInline()) {
    333             // No suitable existing anonymous box - create a new one.
    334             RenderBlock* newBox = createAnonymousBlock();
    335             RenderBox::addChild(newBox, beforeChild);
    336             newBox->addChild(newChild);
    337             return;
    338         }
    339     }
    340 
    341     RenderBox::addChild(newChild, beforeChild);
    342 
    343     if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRenderBlock())
    344         toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
    345     // this object may be dead here
    346 }
    347 
    348 static void getInlineRun(RenderObject* start, RenderObject* boundary,
    349                          RenderObject*& inlineRunStart,
    350                          RenderObject*& inlineRunEnd)
    351 {
    352     // Beginning at |start| we find the largest contiguous run of inlines that
    353     // we can.  We denote the run with start and end points, |inlineRunStart|
    354     // and |inlineRunEnd|.  Note that these two values may be the same if
    355     // we encounter only one inline.
    356     //
    357     // We skip any non-inlines we encounter as long as we haven't found any
    358     // inlines yet.
    359     //
    360     // |boundary| indicates a non-inclusive boundary point.  Regardless of whether |boundary|
    361     // is inline or not, we will not include it in a run with inlines before it.  It's as though we encountered
    362     // a non-inline.
    363 
    364     // Start by skipping as many non-inlines as we can.
    365     RenderObject * curr = start;
    366     bool sawInline;
    367     do {
    368         while (curr && !(curr->isInline() || curr->isFloatingOrPositioned()))
    369             curr = curr->nextSibling();
    370 
    371         inlineRunStart = inlineRunEnd = curr;
    372 
    373         if (!curr)
    374             return; // No more inline children to be found.
    375 
    376         sawInline = curr->isInline();
    377 
    378         curr = curr->nextSibling();
    379         while (curr && (curr->isInline() || curr->isFloatingOrPositioned()) && (curr != boundary)) {
    380             inlineRunEnd = curr;
    381             if (curr->isInline())
    382                 sawInline = true;
    383             curr = curr->nextSibling();
    384         }
    385     } while (!sawInline);
    386 }
    387 
    388 void RenderBlock::deleteLineBoxTree()
    389 {
    390     m_lineBoxes.deleteLineBoxTree(renderArena());
    391 }
    392 
    393 RootInlineBox* RenderBlock::createRootInlineBox()
    394 {
    395     return new (renderArena()) RootInlineBox(this);
    396 }
    397 
    398 RootInlineBox* RenderBlock::createAndAppendRootInlineBox()
    399 {
    400     RootInlineBox* rootBox = createRootInlineBox();
    401     m_lineBoxes.appendLineBox(rootBox);
    402     return rootBox;
    403 }
    404 
    405 void RenderBlock::moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* child)
    406 {
    407     ASSERT(this == child->parent());
    408     toChildList->appendChildNode(to, children()->removeChildNode(this, child, false), false);
    409 }
    410 
    411 void RenderBlock::moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* beforeChild, RenderObject* child)
    412 {
    413     ASSERT(this == child->parent());
    414     ASSERT(!beforeChild || to == beforeChild->parent());
    415     toChildList->insertChildNode(to, children()->removeChildNode(this, child, false), beforeChild, false);
    416 }
    417 
    418 void RenderBlock::moveAllChildrenTo(RenderObject* to, RenderObjectChildList* toChildList)
    419 {
    420     RenderObject* nextChild = children()->firstChild();
    421     while (nextChild) {
    422         RenderObject* child = nextChild;
    423         nextChild = child->nextSibling();
    424         toChildList->appendChildNode(to, children()->removeChildNode(this, child, false), false);
    425     }
    426 }
    427 
    428 void RenderBlock::moveAllChildrenTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* beforeChild)
    429 {
    430     ASSERT(!beforeChild || to == beforeChild->parent());
    431     if (!beforeChild) {
    432         moveAllChildrenTo(to, toChildList);
    433         return;
    434     }
    435     RenderObject* nextChild = children()->firstChild();
    436     while (nextChild) {
    437         RenderObject* child = nextChild;
    438         nextChild = child->nextSibling();
    439         toChildList->insertChildNode(to, children()->removeChildNode(this, child, false), beforeChild, false);
    440     }
    441 }
    442 
    443 void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
    444 {
    445     // makeChildrenNonInline takes a block whose children are *all* inline and it
    446     // makes sure that inline children are coalesced under anonymous
    447     // blocks.  If |insertionPoint| is defined, then it represents the insertion point for
    448     // the new block child that is causing us to have to wrap all the inlines.  This
    449     // means that we cannot coalesce inlines before |insertionPoint| with inlines following
    450     // |insertionPoint|, because the new child is going to be inserted in between the inlines,
    451     // splitting them.
    452     ASSERT(isInlineBlockOrInlineTable() || !isInline());
    453     ASSERT(!insertionPoint || insertionPoint->parent() == this);
    454 
    455     setChildrenInline(false);
    456 
    457     RenderObject *child = firstChild();
    458     if (!child)
    459         return;
    460 
    461     deleteLineBoxTree();
    462 
    463     while (child) {
    464         RenderObject *inlineRunStart, *inlineRunEnd;
    465         getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);
    466 
    467         if (!inlineRunStart)
    468             break;
    469 
    470         child = inlineRunEnd->nextSibling();
    471 
    472         RenderBlock* block = createAnonymousBlock();
    473         children()->insertChildNode(this, block, inlineRunStart);
    474         RenderObject* o = inlineRunStart;
    475         while (o != inlineRunEnd) {
    476             RenderObject* no = o;
    477             o = no->nextSibling();
    478 
    479             moveChildTo(block, block->children(), no);
    480         }
    481         moveChildTo(block, block->children(), inlineRunEnd);
    482     }
    483 
    484 #ifndef NDEBUG
    485     for (RenderObject *c = firstChild(); c; c = c->nextSibling())
    486         ASSERT(!c->isInline());
    487 #endif
    488 
    489     repaint();
    490 }
    491 
    492 void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
    493 {
    494     ASSERT(child->isAnonymousBlock());
    495     ASSERT(!child->childrenInline());
    496 
    497     if (child->inlineContinuation())
    498         return;
    499 
    500     RenderObject* firstAnChild = child->m_children.firstChild();
    501     RenderObject* lastAnChild = child->m_children.lastChild();
    502     if (firstAnChild) {
    503         RenderObject* o = firstAnChild;
    504         while (o) {
    505             o->setParent(this);
    506             o = o->nextSibling();
    507         }
    508         firstAnChild->setPreviousSibling(child->previousSibling());
    509         lastAnChild->setNextSibling(child->nextSibling());
    510         if (child->previousSibling())
    511             child->previousSibling()->setNextSibling(firstAnChild);
    512         if (child->nextSibling())
    513             child->nextSibling()->setPreviousSibling(lastAnChild);
    514     } else {
    515         if (child->previousSibling())
    516             child->previousSibling()->setNextSibling(child->nextSibling());
    517         if (child->nextSibling())
    518             child->nextSibling()->setPreviousSibling(child->previousSibling());
    519     }
    520     if (child == m_children.firstChild())
    521         m_children.setFirstChild(firstAnChild);
    522     if (child == m_children.lastChild())
    523         m_children.setLastChild(lastAnChild);
    524     child->setParent(0);
    525     child->setPreviousSibling(0);
    526     child->setNextSibling(0);
    527 
    528     child->children()->setFirstChild(0);
    529     child->m_next = 0;
    530 
    531     child->destroy();
    532 }
    533 
    534 void RenderBlock::removeChild(RenderObject* oldChild)
    535 {
    536     // If this child is a block, and if our previous and next siblings are
    537     // both anonymous blocks with inline content, then we can go ahead and
    538     // fold the inline content back together.
    539     RenderObject* prev = oldChild->previousSibling();
    540     RenderObject* next = oldChild->nextSibling();
    541     bool canDeleteAnonymousBlocks = !documentBeingDestroyed() && !isInline() && !oldChild->isInline() &&
    542                                     (!oldChild->isRenderBlock() || !toRenderBlock(oldChild)->inlineContinuation()) &&
    543                                     (!prev || (prev->isAnonymousBlock() && prev->childrenInline())) &&
    544                                     (!prev || (!prev->firstChild() || !prev->firstChild()->isInline() || !prev->firstChild()->isRunIn())) &&
    545                                     (!next || (next->isAnonymousBlock() && next->childrenInline()));
    546     if (canDeleteAnonymousBlocks && prev && next) {
    547         // Take all the children out of the |next| block and put them in
    548         // the |prev| block.
    549         prev->setNeedsLayoutAndPrefWidthsRecalc();
    550         RenderBlock* nextBlock = toRenderBlock(next);
    551         RenderBlock* prevBlock = toRenderBlock(prev);
    552         nextBlock->moveAllChildrenTo(prevBlock, prevBlock->children());
    553         // Delete the now-empty block's lines and nuke it.
    554         nextBlock->deleteLineBoxTree();
    555         nextBlock->destroy();
    556     }
    557 
    558     RenderBox::removeChild(oldChild);
    559 
    560     RenderObject* child = prev ? prev : next;
    561     if (canDeleteAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && !isFlexibleBox()) {
    562         // The removal has knocked us down to containing only a single anonymous
    563         // box.  We can go ahead and pull the content right back up into our
    564         // box.
    565         setNeedsLayoutAndPrefWidthsRecalc();
    566         RenderBlock* anonBlock = toRenderBlock(children()->removeChildNode(this, child, false));
    567         setChildrenInline(true);
    568         anonBlock->moveAllChildrenTo(this, children());
    569         // Delete the now-empty block's lines and nuke it.
    570         anonBlock->deleteLineBoxTree();
    571         anonBlock->destroy();
    572     }
    573 
    574     // If this was our last child be sure to clear out our line boxes.
    575     if (childrenInline() && !firstChild())
    576         lineBoxes()->deleteLineBoxes(renderArena());
    577 }
    578 
    579 bool RenderBlock::isSelfCollapsingBlock() const
    580 {
    581     // We are not self-collapsing if we
    582     // (a) have a non-zero height according to layout (an optimization to avoid wasting time)
    583     // (b) are a table,
    584     // (c) have border/padding,
    585     // (d) have a min-height
    586     // (e) have specified that one of our margins can't collapse using a CSS extension
    587     if (height() > 0 ||
    588         isTable() || (borderBottom() + paddingBottom() + borderTop() + paddingTop()) != 0 ||
    589         style()->minHeight().isPositive() ||
    590         style()->marginTopCollapse() == MSEPARATE || style()->marginBottomCollapse() == MSEPARATE)
    591         return false;
    592 
    593     bool hasAutoHeight = style()->height().isAuto();
    594     if (style()->height().isPercent() && !style()->htmlHacks()) {
    595         hasAutoHeight = true;
    596         for (RenderBlock* cb = containingBlock(); !cb->isRenderView(); cb = cb->containingBlock()) {
    597             if (cb->style()->height().isFixed() || cb->isTableCell())
    598                 hasAutoHeight = false;
    599         }
    600     }
    601 
    602     // If the height is 0 or auto, then whether or not we are a self-collapsing block depends
    603     // on whether we have content that is all self-collapsing or not.
    604     if (hasAutoHeight || ((style()->height().isFixed() || style()->height().isPercent()) && style()->height().isZero())) {
    605         // If the block has inline children, see if we generated any line boxes.  If we have any
    606         // line boxes, then we can't be self-collapsing, since we have content.
    607         if (childrenInline())
    608             return !firstLineBox();
    609 
    610         // Whether or not we collapse is dependent on whether all our normal flow children
    611         // are also self-collapsing.
    612         for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
    613             if (child->isFloatingOrPositioned())
    614                 continue;
    615             if (!child->isSelfCollapsingBlock())
    616                 return false;
    617         }
    618         return true;
    619     }
    620     return false;
    621 }
    622 
    623 void RenderBlock::startDelayUpdateScrollInfo()
    624 {
    625     if (gDelayUpdateScrollInfo == 0) {
    626         ASSERT(!gDelayedUpdateScrollInfoSet);
    627         gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet;
    628     }
    629     ASSERT(gDelayedUpdateScrollInfoSet);
    630     ++gDelayUpdateScrollInfo;
    631 }
    632 
    633 void RenderBlock::finishDelayUpdateScrollInfo()
    634 {
    635     --gDelayUpdateScrollInfo;
    636     ASSERT(gDelayUpdateScrollInfo >= 0);
    637     if (gDelayUpdateScrollInfo == 0) {
    638         ASSERT(gDelayedUpdateScrollInfoSet);
    639 
    640         OwnPtr<DelayedUpdateScrollInfoSet> infoSet(gDelayedUpdateScrollInfoSet);
    641         gDelayedUpdateScrollInfoSet = 0;
    642 
    643         for (DelayedUpdateScrollInfoSet::iterator it = infoSet->begin(); it != infoSet->end(); ++it) {
    644             RenderBlock* block = *it;
    645             if (block->hasOverflowClip()) {
    646                 block->layer()->updateScrollInfoAfterLayout();
    647             }
    648         }
    649     }
    650 }
    651 
    652 void RenderBlock::updateScrollInfoAfterLayout()
    653 {
    654     if (hasOverflowClip()) {
    655         if (gDelayUpdateScrollInfo)
    656             gDelayedUpdateScrollInfoSet->add(this);
    657         else
    658             layer()->updateScrollInfoAfterLayout();
    659     }
    660 }
    661 
    662 void RenderBlock::layout()
    663 {
    664     // Update our first letter info now.
    665     updateFirstLetter();
    666 
    667     // Table cells call layoutBlock directly, so don't add any logic here.  Put code into
    668     // layoutBlock().
    669     layoutBlock(false);
    670 
    671     // It's safe to check for control clip here, since controls can never be table cells.
    672     // If we have a lightweight clip, there can never be any overflow from children.
    673     if (hasControlClip() && m_overflow)
    674         clearLayoutOverflow();
    675 }
    676 
    677 void RenderBlock::layoutBlock(bool relayoutChildren)
    678 {
    679     ASSERT(needsLayout());
    680 
    681     if (isInline() && !isInlineBlockOrInlineTable()) // Inline <form>s inside various table elements can
    682         return;                                      // cause us to come in here.  Just bail.
    683 
    684     if (!relayoutChildren && layoutOnlyPositionedObjects())
    685         return;
    686 
    687     LayoutRepainter repainter(*this, m_everHadLayout && checkForRepaintDuringLayout());
    688     LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection());
    689 
    690     int oldWidth = width();
    691     int oldColumnWidth = desiredColumnWidth();
    692 
    693 #ifdef ANDROID_LAYOUT
    694     int oldVisibleWidth = m_visibleWidth;
    695 #endif
    696 
    697     calcWidth();
    698     calcColumnWidth();
    699 
    700     m_overflow.clear();
    701 
    702     if (oldWidth != width() || oldColumnWidth != desiredColumnWidth())
    703         relayoutChildren = true;
    704 
    705 #ifdef ANDROID_LAYOUT
    706     const Settings* settings = document()->settings();
    707     ASSERT(settings);
    708     if (oldVisibleWidth != m_visibleWidth
    709             && settings->layoutAlgorithm() == Settings::kLayoutFitColumnToScreen)
    710         relayoutChildren = true;
    711 #endif
    712 
    713     clearFloats();
    714 
    715     int previousHeight = height();
    716     setHeight(0);
    717 
    718     // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track
    719     // our current maximal positive and negative margins.  These values are used when we
    720     // are collapsed with adjacent blocks, so for example, if you have block A and B
    721     // collapsing together, then you'd take the maximal positive margin from both A and B
    722     // and subtract it from the maximal negative margin from both A and B to get the
    723     // true collapsed margin.  This algorithm is recursive, so when we finish layout()
    724     // our block knows its current maximal positive/negative values.
    725     //
    726     // Start out by setting our margin values to our current margins.  Table cells have
    727     // no margins, so we don't fill in the values for table cells.
    728     bool isCell = isTableCell();
    729     if (!isCell) {
    730         initMaxMarginValues();
    731 
    732         setTopMarginQuirk(style()->marginTop().quirk());
    733         setBottomMarginQuirk(style()->marginBottom().quirk());
    734 
    735         Node* n = node();
    736         if (n && n->hasTagName(formTag) && static_cast<HTMLFormElement*>(n)->isMalformed()) {
    737             // See if this form is malformed (i.e., unclosed). If so, don't give the form
    738             // a bottom margin.
    739             setMaxBottomMargins(0, 0);
    740         }
    741     }
    742 
    743     // For overflow:scroll blocks, ensure we have both scrollbars in place always.
    744     if (scrollsOverflow()) {
    745         if (style()->overflowX() == OSCROLL)
    746             layer()->setHasHorizontalScrollbar(true);
    747         if (style()->overflowY() == OSCROLL)
    748             layer()->setHasVerticalScrollbar(true);
    749     }
    750 
    751     int repaintTop = 0;
    752     int repaintBottom = 0;
    753     int maxFloatBottom = 0;
    754     if (childrenInline())
    755         layoutInlineChildren(relayoutChildren, repaintTop, repaintBottom);
    756     else
    757         layoutBlockChildren(relayoutChildren, maxFloatBottom);
    758 
    759     // Expand our intrinsic height to encompass floats.
    760     int toAdd = borderBottom() + paddingBottom() + horizontalScrollbarHeight();
    761     if (floatBottom() > (height() - toAdd) && expandsToEncloseOverhangingFloats())
    762         setHeight(floatBottom() + toAdd);
    763 
    764     // Now lay out our columns within this intrinsic height, since they can slightly affect the intrinsic height as
    765     // we adjust for clean column breaks.
    766     int singleColumnBottom = layoutColumns();
    767 
    768     // Calculate our new height.
    769     int oldHeight = height();
    770     calcHeight();
    771     if (oldHeight != height()) {
    772         if (oldHeight > height() && maxFloatBottom > height() && !childrenInline()) {
    773             // One of our children's floats may have become an overhanging float for us. We need to look for it.
    774             for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
    775                 if (child->isBlockFlow() && !child->isFloatingOrPositioned()) {
    776                     RenderBlock* block = toRenderBlock(child);
    777                     if (block->floatBottom() + block->y() > height())
    778                         addOverhangingFloats(block, -block->x(), -block->y(), false);
    779                 }
    780             }
    781         }
    782 
    783         // We have to rebalance columns to the new height.
    784         layoutColumns(singleColumnBottom);
    785     }
    786 
    787     if (previousHeight != height())
    788         relayoutChildren = true;
    789 
    790     // It's weird that we're treating float information as normal flow overflow, but we do this because floatRect() isn't
    791     // able to be propagated up the render tree yet.  Overflow information is however.  This check is designed to catch anyone
    792     // who wasn't going to propagate float information up to the parent and yet could potentially be painted by its ancestor.
    793     if (isRoot() || expandsToEncloseOverhangingFloats())
    794         addOverflowFromFloats();
    795 
    796     // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway).
    797     if (!hasColumns()) {
    798         if (childrenInline())
    799             addOverflowFromInlineChildren();
    800         else
    801             addOverflowFromBlockChildren();
    802     }
    803 
    804     // Add visual overflow from box-shadow and reflections.
    805     addShadowOverflow();
    806 
    807     layoutPositionedObjects(relayoutChildren || isRoot());
    808 
    809     positionListMarker();
    810 
    811     statePusher.pop();
    812 
    813     // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
    814     // we overflow or not.
    815     updateScrollInfoAfterLayout();
    816 
    817     // Repaint with our new bounds if they are different from our old bounds.
    818     bool didFullRepaint = repainter.repaintAfterLayout();
    819     if (!didFullRepaint && repaintTop != repaintBottom && (style()->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) {
    820         int repaintLeft = min(leftVisualOverflow(), leftLayoutOverflow());
    821         int repaintRight = max(rightVisualOverflow(), rightLayoutOverflow());
    822         IntRect repaintRect(repaintLeft, repaintTop, repaintRight - repaintLeft, repaintBottom - repaintTop);
    823 
    824         // FIXME: Deal with multiple column repainting.  We have to split the repaint
    825         // rect up into multiple rects if it spans columns.
    826 
    827         repaintRect.inflate(maximalOutlineSize(PaintPhaseOutline));
    828 
    829         if (hasOverflowClip()) {
    830             // Adjust repaint rect for scroll offset
    831             int x = repaintRect.x();
    832             int y = repaintRect.y();
    833             layer()->subtractScrolledContentOffset(x, y);
    834             repaintRect.setX(x);
    835             repaintRect.setY(y);
    836 
    837             // Don't allow this rect to spill out of our overflow box.
    838             repaintRect.intersect(IntRect(0, 0, width(), height()));
    839         }
    840 
    841         // Make sure the rect is still non-empty after intersecting for overflow above
    842         if (!repaintRect.isEmpty()) {
    843             repaintRectangle(repaintRect); // We need to do a partial repaint of our content.
    844             if (hasReflection())
    845                 repaintRectangle(reflectedRect(repaintRect));
    846         }
    847     }
    848     setNeedsLayout(false);
    849 }
    850 
    851 void RenderBlock::addOverflowFromBlockChildren()
    852 {
    853     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
    854         if (!child->isFloatingOrPositioned())
    855             addOverflowFromChild(child);
    856     }
    857 }
    858 
    859 void RenderBlock::addOverflowFromFloats()
    860 {
    861     IntRect result;
    862     if (!m_floatingObjects)
    863         return;
    864     FloatingObject* r;
    865     DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
    866     for (; (r = it.current()); ++it) {
    867         if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer())
    868             addOverflowFromChild(r->m_renderer, IntSize(r->m_left + r->m_renderer->marginLeft(), r->m_top + r->m_renderer->marginTop()));
    869     }
    870     return;
    871 }
    872 
    873 bool RenderBlock::expandsToEncloseOverhangingFloats() const
    874 {
    875     return isInlineBlockOrInlineTable() || isFloatingOrPositioned() || hasOverflowClip() || (parent() && parent()->isFlexibleBox()) || hasColumns() || isTableCell() || isFieldset();
    876 }
    877 
    878 void RenderBlock::adjustPositionedBlock(RenderBox* child, const MarginInfo& marginInfo)
    879 {
    880     if (child->style()->hasStaticX()) {
    881         if (style()->direction() == LTR)
    882             child->layer()->setStaticX(borderLeft() + paddingLeft());
    883         else
    884             child->layer()->setStaticX(borderRight() + paddingRight());
    885     }
    886 
    887     if (child->style()->hasStaticY()) {
    888         int y = height();
    889         if (!marginInfo.canCollapseWithTop()) {
    890             child->calcVerticalMargins();
    891             int marginTop = child->marginTop();
    892             int collapsedTopPos = marginInfo.posMargin();
    893             int collapsedTopNeg = marginInfo.negMargin();
    894             if (marginTop > 0) {
    895                 if (marginTop > collapsedTopPos)
    896                     collapsedTopPos = marginTop;
    897             } else {
    898                 if (-marginTop > collapsedTopNeg)
    899                     collapsedTopNeg = -marginTop;
    900             }
    901             y += (collapsedTopPos - collapsedTopNeg) - marginTop;
    902         }
    903         RenderLayer* childLayer = child->layer();
    904         if (childLayer->staticY() != y) {
    905             child->layer()->setStaticY(y);
    906             child->setChildNeedsLayout(true, false);
    907         }
    908     }
    909 }
    910 
    911 void RenderBlock::adjustFloatingBlock(const MarginInfo& marginInfo)
    912 {
    913     // The float should be positioned taking into account the bottom margin
    914     // of the previous flow.  We add that margin into the height, get the
    915     // float positioned properly, and then subtract the margin out of the
    916     // height again.  In the case of self-collapsing blocks, we always just
    917     // use the top margins, since the self-collapsing block collapsed its
    918     // own bottom margin into its top margin.
    919     //
    920     // Note also that the previous flow may collapse its margin into the top of
    921     // our block.  If this is the case, then we do not add the margin in to our
    922     // height when computing the position of the float.   This condition can be tested
    923     // for by simply calling canCollapseWithTop.  See
    924     // http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html for
    925     // an example of this scenario.
    926     int marginOffset = marginInfo.canCollapseWithTop() ? 0 : marginInfo.margin();
    927     setHeight(height() + marginOffset);
    928     positionNewFloats();
    929     setHeight(height() - marginOffset);
    930 }
    931 
    932 bool RenderBlock::handleSpecialChild(RenderBox* child, const MarginInfo& marginInfo)
    933 {
    934     // Handle in the given order
    935     return handlePositionedChild(child, marginInfo)
    936         || handleFloatingChild(child, marginInfo)
    937         || handleRunInChild(child);
    938 }
    939 
    940 
    941 bool RenderBlock::handlePositionedChild(RenderBox* child, const MarginInfo& marginInfo)
    942 {
    943     if (child->isPositioned()) {
    944         child->containingBlock()->insertPositionedObject(child);
    945         adjustPositionedBlock(child, marginInfo);
    946         return true;
    947     }
    948     return false;
    949 }
    950 
    951 bool RenderBlock::handleFloatingChild(RenderBox* child, const MarginInfo& marginInfo)
    952 {
    953     if (child->isFloating()) {
    954         insertFloatingObject(child);
    955         adjustFloatingBlock(marginInfo);
    956         return true;
    957     }
    958     return false;
    959 }
    960 
    961 bool RenderBlock::handleRunInChild(RenderBox* child)
    962 {
    963     // See if we have a run-in element with inline children.  If the
    964     // children aren't inline, then just treat the run-in as a normal
    965     // block.
    966     if (!child->isRunIn() || !child->childrenInline())
    967         return false;
    968     // FIXME: We don't handle non-block elements with run-in for now.
    969     if (!child->isRenderBlock())
    970         return false;
    971 
    972     // Get the next non-positioned/non-floating RenderBlock.
    973     RenderBlock* blockRunIn = toRenderBlock(child);
    974     RenderObject* curr = blockRunIn->nextSibling();
    975     while (curr && curr->isFloatingOrPositioned())
    976         curr = curr->nextSibling();
    977 
    978     if (!curr || !curr->isRenderBlock() || !curr->childrenInline() || curr->isRunIn() || curr->isAnonymous())
    979         return false;
    980 
    981     RenderBlock* currBlock = toRenderBlock(curr);
    982 
    983     // Remove the old child.
    984     children()->removeChildNode(this, blockRunIn);
    985 
    986     // Create an inline.
    987     Node* runInNode = blockRunIn->node();
    988     RenderInline* inlineRunIn = new (renderArena()) RenderInline(runInNode ? runInNode : document());
    989     inlineRunIn->setStyle(blockRunIn->style());
    990 
    991     bool runInIsGenerated = child->style()->styleType() == BEFORE || child->style()->styleType() == AFTER;
    992 
    993     // Move the nodes from the old child to the new child, but skip any :before/:after content.  It has already
    994     // been regenerated by the new inline.
    995     for (RenderObject* runInChild = blockRunIn->firstChild(); runInChild; runInChild = runInChild->nextSibling()) {
    996         if (runInIsGenerated || (runInChild->style()->styleType() != BEFORE && runInChild->style()->styleType() != AFTER)) {
    997             blockRunIn->children()->removeChildNode(blockRunIn, runInChild, false);
    998             inlineRunIn->addChild(runInChild); // Use addChild instead of appendChildNode since it handles correct placement of the children relative to :after-generated content.
    999         }
   1000     }
   1001 
   1002     // Now insert the new child under |currBlock|.
   1003     currBlock->children()->insertChildNode(currBlock, inlineRunIn, currBlock->firstChild());
   1004 
   1005     // If the run-in had an element, we need to set the new renderer.
   1006     if (runInNode)
   1007         runInNode->setRenderer(inlineRunIn);
   1008 
   1009     // Destroy the block run-in, which includes deleting its line box tree.
   1010     blockRunIn->deleteLineBoxTree();
   1011     blockRunIn->destroy();
   1012 
   1013     // The block acts like an inline, so just null out its
   1014     // position.
   1015 
   1016     return true;
   1017 }
   1018 
   1019 int RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo)
   1020 {
   1021     // Get our max pos and neg top margins.
   1022     int posTop = child->maxTopMargin(true);
   1023     int negTop = child->maxTopMargin(false);
   1024 
   1025     // For self-collapsing blocks, collapse our bottom margins into our
   1026     // top to get new posTop and negTop values.
   1027     if (child->isSelfCollapsingBlock()) {
   1028         posTop = max(posTop, child->maxBottomMargin(true));
   1029         negTop = max(negTop, child->maxBottomMargin(false));
   1030     }
   1031 
   1032     // See if the top margin is quirky. We only care if this child has
   1033     // margins that will collapse with us.
   1034     bool topQuirk = child->isTopMarginQuirk() || style()->marginTopCollapse() == MDISCARD;
   1035 
   1036     if (marginInfo.canCollapseWithTop()) {
   1037         // This child is collapsing with the top of the
   1038         // block.  If it has larger margin values, then we need to update
   1039         // our own maximal values.
   1040         if (!style()->htmlHacks() || !marginInfo.quirkContainer() || !topQuirk)
   1041             setMaxTopMargins(max(posTop, maxTopPosMargin()), max(negTop, maxTopNegMargin()));
   1042 
   1043         // The minute any of the margins involved isn't a quirk, don't
   1044         // collapse it away, even if the margin is smaller (www.webreference.com
   1045         // has an example of this, a <dt> with 0.8em author-specified inside
   1046         // a <dl> inside a <td>.
   1047         if (!marginInfo.determinedTopQuirk() && !topQuirk && (posTop-negTop)) {
   1048             setTopMarginQuirk(false);
   1049             marginInfo.setDeterminedTopQuirk(true);
   1050         }
   1051 
   1052         if (!marginInfo.determinedTopQuirk() && topQuirk && marginTop() == 0)
   1053             // We have no top margin and our top child has a quirky margin.
   1054             // We will pick up this quirky margin and pass it through.
   1055             // This deals with the <td><div><p> case.
   1056             // Don't do this for a block that split two inlines though.  You do
   1057             // still apply margins in this case.
   1058             setTopMarginQuirk(true);
   1059     }
   1060 
   1061     if (marginInfo.quirkContainer() && marginInfo.atTopOfBlock() && (posTop - negTop))
   1062         marginInfo.setTopQuirk(topQuirk);
   1063 
   1064     int ypos = height();
   1065     if (child->isSelfCollapsingBlock()) {
   1066         // This child has no height.  We need to compute our
   1067         // position before we collapse the child's margins together,
   1068         // so that we can get an accurate position for the zero-height block.
   1069         int collapsedTopPos = max(marginInfo.posMargin(), child->maxTopMargin(true));
   1070         int collapsedTopNeg = max(marginInfo.negMargin(), child->maxTopMargin(false));
   1071         marginInfo.setMargin(collapsedTopPos, collapsedTopNeg);
   1072 
   1073         // Now collapse the child's margins together, which means examining our
   1074         // bottom margin values as well.
   1075         marginInfo.setPosMarginIfLarger(child->maxBottomMargin(true));
   1076         marginInfo.setNegMarginIfLarger(child->maxBottomMargin(false));
   1077 
   1078         if (!marginInfo.canCollapseWithTop())
   1079             // We need to make sure that the position of the self-collapsing block
   1080             // is correct, since it could have overflowing content
   1081             // that needs to be positioned correctly (e.g., a block that
   1082             // had a specified height of 0 but that actually had subcontent).
   1083             ypos = height() + collapsedTopPos - collapsedTopNeg;
   1084     }
   1085     else {
   1086         if (child->style()->marginTopCollapse() == MSEPARATE) {
   1087             setHeight(height() + marginInfo.margin() + child->marginTop());
   1088             ypos = height();
   1089         }
   1090         else if (!marginInfo.atTopOfBlock() ||
   1091             (!marginInfo.canCollapseTopWithChildren()
   1092              && (!style()->htmlHacks() || !marginInfo.quirkContainer() || !marginInfo.topQuirk()))) {
   1093             // We're collapsing with a previous sibling's margins and not
   1094             // with the top of the block.
   1095             setHeight(height() + max(marginInfo.posMargin(), posTop) - max(marginInfo.negMargin(), negTop));
   1096             ypos = height();
   1097         }
   1098 
   1099         marginInfo.setPosMargin(child->maxBottomMargin(true));
   1100         marginInfo.setNegMargin(child->maxBottomMargin(false));
   1101 
   1102         if (marginInfo.margin())
   1103             marginInfo.setBottomQuirk(child->isBottomMarginQuirk() || style()->marginBottomCollapse() == MDISCARD);
   1104     }
   1105 
   1106     return ypos;
   1107 }
   1108 
   1109 int RenderBlock::clearFloatsIfNeeded(RenderBox* child, MarginInfo& marginInfo, int oldTopPosMargin, int oldTopNegMargin, int yPos)
   1110 {
   1111     int heightIncrease = getClearDelta(child, yPos);
   1112     if (!heightIncrease)
   1113         return yPos;
   1114 
   1115     if (child->isSelfCollapsingBlock()) {
   1116         // For self-collapsing blocks that clear, they can still collapse their
   1117         // margins with following siblings.  Reset the current margins to represent
   1118         // the self-collapsing block's margins only.
   1119         // CSS2.1 states:
   1120         // "An element that has had clearance applied to it never collapses its top margin with its parent block's bottom margin.
   1121         // Therefore if we are at the bottom of the block, let's go ahead and reset margins to only include the
   1122         // self-collapsing block's bottom margin.
   1123         bool atBottomOfBlock = true;
   1124         for (RenderBox* curr = child->nextSiblingBox(); curr && atBottomOfBlock; curr = curr->nextSiblingBox()) {
   1125             if (!curr->isFloatingOrPositioned())
   1126                 atBottomOfBlock = false;
   1127         }
   1128         if (atBottomOfBlock) {
   1129             marginInfo.setPosMargin(child->maxBottomMargin(true));
   1130             marginInfo.setNegMargin(child->maxBottomMargin(false));
   1131         } else {
   1132             marginInfo.setPosMargin(max(child->maxTopMargin(true), child->maxBottomMargin(true)));
   1133             marginInfo.setNegMargin(max(child->maxTopMargin(false), child->maxBottomMargin(false)));
   1134         }
   1135 
   1136         // Adjust our height such that we are ready to be collapsed with subsequent siblings (or the bottom
   1137         // of the parent block).
   1138         setHeight(child->y() - max(0, marginInfo.margin()));
   1139     } else
   1140         // Increase our height by the amount we had to clear.
   1141         setHeight(height() + heightIncrease);
   1142 
   1143     if (marginInfo.canCollapseWithTop()) {
   1144         // We can no longer collapse with the top of the block since a clear
   1145         // occurred.  The empty blocks collapse into the cleared block.
   1146         // FIXME: This isn't quite correct.  Need clarification for what to do
   1147         // if the height the cleared block is offset by is smaller than the
   1148         // margins involved.
   1149         setMaxTopMargins(oldTopPosMargin, oldTopNegMargin);
   1150         marginInfo.setAtTopOfBlock(false);
   1151     }
   1152 
   1153     return yPos + heightIncrease;
   1154 }
   1155 
   1156 int RenderBlock::estimateVerticalPosition(RenderBox* child, const MarginInfo& marginInfo)
   1157 {
   1158     // FIXME: We need to eliminate the estimation of vertical position, because when it's wrong we sometimes trigger a pathological
   1159     // relayout if there are intruding floats.
   1160     int yPosEstimate = height();
   1161     if (!marginInfo.canCollapseWithTop()) {
   1162         int childMarginTop = child->selfNeedsLayout() ? child->marginTop() : child->collapsedMarginTop();
   1163         yPosEstimate += max(marginInfo.margin(), childMarginTop);
   1164     }
   1165     yPosEstimate += getClearDelta(child, yPosEstimate);
   1166     return yPosEstimate;
   1167 }
   1168 
   1169 void RenderBlock::determineHorizontalPosition(RenderBox* child)
   1170 {
   1171     if (style()->direction() == LTR) {
   1172         int xPos = borderLeft() + paddingLeft();
   1173 
   1174         // Add in our left margin.
   1175         int chPos = xPos + child->marginLeft();
   1176 
   1177         // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats.  They need
   1178         // to shift over as necessary to dodge any floats that might get in the way.
   1179         if (child->avoidsFloats()) {
   1180             int leftOff = leftOffset(height(), false);
   1181             if (style()->textAlign() != WEBKIT_CENTER && child->style()->marginLeft().type() != Auto) {
   1182                 if (child->marginLeft() < 0)
   1183                     leftOff += child->marginLeft();
   1184                 chPos = max(chPos, leftOff); // Let the float sit in the child's margin if it can fit.
   1185             }
   1186             else if (leftOff != xPos) {
   1187                 // The object is shifting right. The object might be centered, so we need to
   1188                 // recalculate our horizontal margins. Note that the containing block content
   1189                 // width computation will take into account the delta between |leftOff| and |xPos|
   1190                 // so that we can just pass the content width in directly to the |calcHorizontalMargins|
   1191                 // function.
   1192                 child->calcHorizontalMargins(child->style()->marginLeft(), child->style()->marginRight(), lineWidth(child->y(), false));
   1193                 chPos = leftOff + child->marginLeft();
   1194             }
   1195         }
   1196         view()->addLayoutDelta(IntSize(child->x() - chPos, 0));
   1197         child->setLocation(chPos, child->y());
   1198     } else {
   1199         int xPos = width() - borderRight() - paddingRight() - verticalScrollbarWidth();
   1200         int chPos = xPos - (child->width() + child->marginRight());
   1201         if (child->avoidsFloats()) {
   1202             int rightOff = rightOffset(height(), false);
   1203             if (style()->textAlign() != WEBKIT_CENTER && child->style()->marginRight().type() != Auto) {
   1204                 if (child->marginRight() < 0)
   1205                     rightOff -= child->marginRight();
   1206                 chPos = min(chPos, rightOff - child->width()); // Let the float sit in the child's margin if it can fit.
   1207             } else if (rightOff != xPos) {
   1208                 // The object is shifting left. The object might be centered, so we need to
   1209                 // recalculate our horizontal margins. Note that the containing block content
   1210                 // width computation will take into account the delta between |rightOff| and |xPos|
   1211                 // so that we can just pass the content width in directly to the |calcHorizontalMargins|
   1212                 // function.
   1213                 child->calcHorizontalMargins(child->style()->marginLeft(), child->style()->marginRight(), lineWidth(child->y(), false));
   1214                 chPos = rightOff - child->marginRight() - child->width();
   1215             }
   1216         }
   1217         view()->addLayoutDelta(IntSize(child->x() - chPos, 0));
   1218         child->setLocation(chPos, child->y());
   1219     }
   1220 }
   1221 
   1222 void RenderBlock::setCollapsedBottomMargin(const MarginInfo& marginInfo)
   1223 {
   1224     if (marginInfo.canCollapseWithBottom() && !marginInfo.canCollapseWithTop()) {
   1225         // Update our max pos/neg bottom margins, since we collapsed our bottom margins
   1226         // with our children.
   1227         setMaxBottomMargins(max(maxBottomPosMargin(), marginInfo.posMargin()), max(maxBottomNegMargin(), marginInfo.negMargin()));
   1228 
   1229         if (!marginInfo.bottomQuirk())
   1230             setBottomMarginQuirk(false);
   1231 
   1232         if (marginInfo.bottomQuirk() && marginBottom() == 0)
   1233             // We have no bottom margin and our last child has a quirky margin.
   1234             // We will pick up this quirky margin and pass it through.
   1235             // This deals with the <td><div><p> case.
   1236             setBottomMarginQuirk(true);
   1237     }
   1238 }
   1239 
   1240 void RenderBlock::handleBottomOfBlock(int top, int bottom, MarginInfo& marginInfo)
   1241 {
   1242     marginInfo.setAtBottomOfBlock(true);
   1243 
   1244     // If we can't collapse with children then go ahead and add in the bottom margin.
   1245     if (!marginInfo.canCollapseWithBottom() && !marginInfo.canCollapseWithTop()
   1246         && (!style()->htmlHacks() || !marginInfo.quirkContainer() || !marginInfo.bottomQuirk()))
   1247         setHeight(height() + marginInfo.margin());
   1248 
   1249     // Now add in our bottom border/padding.
   1250     setHeight(height() + bottom);
   1251 
   1252     // Negative margins can cause our height to shrink below our minimal height (border/padding).
   1253     // If this happens, ensure that the computed height is increased to the minimal height.
   1254     setHeight(max(height(), top + bottom));
   1255 
   1256     // Update our bottom collapsed margin info.
   1257     setCollapsedBottomMargin(marginInfo);
   1258 }
   1259 
   1260 void RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatBottom)
   1261 {
   1262     if (gPercentHeightDescendantsMap) {
   1263         if (HashSet<RenderBox*>* descendants = gPercentHeightDescendantsMap->get(this)) {
   1264             HashSet<RenderBox*>::iterator end = descendants->end();
   1265             for (HashSet<RenderBox*>::iterator it = descendants->begin(); it != end; ++it) {
   1266                 RenderBox* box = *it;
   1267                 while (box != this) {
   1268                     if (box->normalChildNeedsLayout())
   1269                         break;
   1270                     box->setChildNeedsLayout(true, false);
   1271                     box = box->containingBlock();
   1272                     ASSERT(box);
   1273                     if (!box)
   1274                         break;
   1275                 }
   1276             }
   1277         }
   1278     }
   1279 
   1280     int top = borderTop() + paddingTop();
   1281     int bottom = borderBottom() + paddingBottom() + horizontalScrollbarHeight();
   1282 
   1283     setHeight(top);
   1284 
   1285     // The margin struct caches all our current margin collapsing state.  The compact struct caches state when we encounter compacts,
   1286     MarginInfo marginInfo(this, top, bottom);
   1287 
   1288     // Fieldsets need to find their legend and position it inside the border of the object.
   1289     // The legend then gets skipped during normal layout.
   1290     RenderObject* legend = layoutLegend(relayoutChildren);
   1291 
   1292     int previousFloatBottom = 0;
   1293     maxFloatBottom = 0;
   1294 
   1295     RenderBox* next = firstChildBox();
   1296 
   1297     while (next) {
   1298         RenderBox* child = next;
   1299         next = child->nextSiblingBox();
   1300 
   1301         if (legend == child)
   1302             continue; // Skip the legend, since it has already been positioned up in the fieldset's border.
   1303 
   1304         // Make sure we layout children if they need it.
   1305         // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into
   1306         // an auto value.  Add a method to determine this, so that we can avoid the relayout.
   1307         if (relayoutChildren || ((child->style()->height().isPercent() || child->style()->minHeight().isPercent() || child->style()->maxHeight().isPercent()) && !isRenderView()))
   1308             child->setChildNeedsLayout(true, false);
   1309 
   1310         // If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths.
   1311         if (relayoutChildren && (child->style()->paddingLeft().isPercent() || child->style()->paddingRight().isPercent()))
   1312             child->setPrefWidthsDirty(true, false);
   1313 
   1314         // Handle the four types of special elements first.  These include positioned content, floating content, compacts and
   1315         // run-ins.  When we encounter these four types of objects, we don't actually lay them out as normal flow blocks.
   1316         if (handleSpecialChild(child, marginInfo))
   1317             continue;
   1318 
   1319         // Lay out the child.
   1320         layoutBlockChild(child, marginInfo, previousFloatBottom, maxFloatBottom);
   1321     }
   1322 
   1323     // Now do the handling of the bottom of the block, adding in our bottom border/padding and
   1324     // determining the correct collapsed bottom margin information.
   1325     handleBottomOfBlock(top, bottom, marginInfo);
   1326 }
   1327 
   1328 void RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, int& previousFloatBottom, int& maxFloatBottom)
   1329 {
   1330     int oldTopPosMargin = maxTopPosMargin();
   1331     int oldTopNegMargin = maxTopNegMargin();
   1332 
   1333     // The child is a normal flow object.  Compute its vertical margins now.
   1334     child->calcVerticalMargins();
   1335 
   1336     // Do not allow a collapse if the margin top collapse style is set to SEPARATE.
   1337     if (child->style()->marginTopCollapse() == MSEPARATE) {
   1338         marginInfo.setAtTopOfBlock(false);
   1339         marginInfo.clearMargin();
   1340     }
   1341 
   1342     // Try to guess our correct y position.  In most cases this guess will
   1343     // be correct.  Only if we're wrong (when we compute the real y position)
   1344     // will we have to potentially relayout.
   1345     int yPosEstimate = estimateVerticalPosition(child, marginInfo);
   1346 
   1347     // Cache our old rect so that we can dirty the proper repaint rects if the child moves.
   1348     IntRect oldRect(child->x(), child->y() , child->width(), child->height());
   1349 #ifndef NDEBUG
   1350     IntSize oldLayoutDelta = view()->layoutDelta();
   1351 #endif
   1352     // Go ahead and position the child as though it didn't collapse with the top.
   1353     view()->addLayoutDelta(IntSize(0, child->y() - yPosEstimate));
   1354     child->setLocation(child->x(), yPosEstimate);
   1355 
   1356     bool markDescendantsWithFloats = false;
   1357     if (yPosEstimate != oldRect.y() && !child->avoidsFloats() && child->isBlockFlow() && toRenderBlock(child)->containsFloats())
   1358         markDescendantsWithFloats = true;
   1359     else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) {
   1360         // If an element might be affected by the presence of floats, then always mark it for
   1361         // layout.
   1362         int fb = max(previousFloatBottom, floatBottom());
   1363         if (fb > yPosEstimate)
   1364             markDescendantsWithFloats = true;
   1365     }
   1366 
   1367     if (child->isRenderBlock()) {
   1368         if (markDescendantsWithFloats)
   1369             toRenderBlock(child)->markAllDescendantsWithFloatsForLayout();
   1370 
   1371         previousFloatBottom = max(previousFloatBottom, oldRect.y() + toRenderBlock(child)->floatBottom());
   1372     }
   1373 
   1374     bool childHadLayout = child->m_everHadLayout;
   1375     bool childNeededLayout = child->needsLayout();
   1376     if (childNeededLayout)
   1377         child->layout();
   1378 
   1379     // Now determine the correct ypos based off examination of collapsing margin
   1380     // values.
   1381     int yBeforeClear = collapseMargins(child, marginInfo);
   1382 
   1383     // Now check for clear.
   1384     int yAfterClear = clearFloatsIfNeeded(child, marginInfo, oldTopPosMargin, oldTopNegMargin, yBeforeClear);
   1385 
   1386     view()->addLayoutDelta(IntSize(0, yPosEstimate - yAfterClear));
   1387     child->setLocation(child->x(), yAfterClear);
   1388 
   1389     // Now we have a final y position.  See if it really does end up being different from our estimate.
   1390     if (yAfterClear != yPosEstimate) {
   1391         if (child->shrinkToAvoidFloats()) {
   1392             // The child's width depends on the line width.
   1393             // When the child shifts to clear an item, its width can
   1394             // change (because it has more available line width).
   1395             // So go ahead and mark the item as dirty.
   1396             child->setChildNeedsLayout(true, false);
   1397         }
   1398         if (!child->avoidsFloats() && child->isBlockFlow() && toRenderBlock(child)->containsFloats())
   1399             toRenderBlock(child)->markAllDescendantsWithFloatsForLayout();
   1400         // Our guess was wrong. Make the child lay itself out again.
   1401         child->layoutIfNeeded();
   1402     }
   1403 
   1404     // We are no longer at the top of the block if we encounter a non-empty child.
   1405     // This has to be done after checking for clear, so that margins can be reset if a clear occurred.
   1406     if (marginInfo.atTopOfBlock() && !child->isSelfCollapsingBlock())
   1407         marginInfo.setAtTopOfBlock(false);
   1408 
   1409     // Now place the child in the correct horizontal position
   1410     determineHorizontalPosition(child);
   1411 
   1412     // Update our height now that the child has been placed in the correct position.
   1413     setHeight(height() + child->height());
   1414     if (child->style()->marginBottomCollapse() == MSEPARATE) {
   1415         setHeight(height() + child->marginBottom());
   1416         marginInfo.clearMargin();
   1417     }
   1418     // If the child has overhanging floats that intrude into following siblings (or possibly out
   1419     // of this block), then the parent gets notified of the floats now.
   1420     if (child->isBlockFlow() && toRenderBlock(child)->containsFloats())
   1421         maxFloatBottom = max(maxFloatBottom, addOverhangingFloats(toRenderBlock(child), -child->x(), -child->y(), !childNeededLayout));
   1422 
   1423     IntSize childOffset(child->x() - oldRect.x(), child->y() - oldRect.y());
   1424     if (childOffset.width() || childOffset.height()) {
   1425         view()->addLayoutDelta(childOffset);
   1426 
   1427         // If the child moved, we have to repaint it as well as any floating/positioned
   1428         // descendants.  An exception is if we need a layout.  In this case, we know we're going to
   1429         // repaint ourselves (and the child) anyway.
   1430         if (childHadLayout && !selfNeedsLayout() && child->checkForRepaintDuringLayout())
   1431             child->repaintDuringLayoutIfMoved(oldRect);
   1432     }
   1433 
   1434     if (!childHadLayout && child->checkForRepaintDuringLayout()) {
   1435         child->repaint();
   1436         child->repaintOverhangingFloats(true);
   1437     }
   1438 
   1439     ASSERT(oldLayoutDelta == view()->layoutDelta());
   1440 }
   1441 
   1442 bool RenderBlock::layoutOnlyPositionedObjects()
   1443 {
   1444     if (!posChildNeedsLayout() || normalChildNeedsLayout() || selfNeedsLayout())
   1445         return false;
   1446 
   1447     LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection());
   1448 
   1449     if (needsPositionedMovementLayout()) {
   1450         tryLayoutDoingPositionedMovementOnly();
   1451         if (needsLayout())
   1452             return false;
   1453     }
   1454 
   1455     // All we have to is lay out our positioned objects.
   1456     layoutPositionedObjects(false);
   1457 
   1458     statePusher.pop();
   1459 
   1460     updateScrollInfoAfterLayout();
   1461 
   1462 #ifdef ANDROID_FIX
   1463     // iframe flatten will call FrameView::layout() which calls performPostLayoutTasks,
   1464     // which may make us need to layout again
   1465     if (!posChildNeedsLayout() || normalChildNeedsLayout() || selfNeedsLayout())
   1466         return false;
   1467 #endif
   1468 
   1469     setNeedsLayout(false);
   1470     return true;
   1471 }
   1472 
   1473 void RenderBlock::layoutPositionedObjects(bool relayoutChildren)
   1474 {
   1475     if (m_positionedObjects) {
   1476         RenderBox* r;
   1477         Iterator end = m_positionedObjects->end();
   1478         for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
   1479             r = *it;
   1480             // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the
   1481             // non-positioned block.  Rather than trying to detect all of these movement cases, we just always lay out positioned
   1482             // objects that are positioned implicitly like this.  Such objects are rare, and so in typical DHTML menu usage (where everything is
   1483             // positioned explicitly) this should not incur a performance penalty.
   1484             if (relayoutChildren || (r->style()->hasStaticY() && r->parent() != this && r->parent()->isBlockFlow()))
   1485                 r->setChildNeedsLayout(true, false);
   1486 
   1487             // If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths.
   1488             //if (relayoutChildren && (r->style()->paddingLeft().isPercent() || r->style()->paddingRight().isPercent()))
   1489                 r->setPrefWidthsDirty(true, false);
   1490 
   1491             // 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
   1492             // and we hit the available width constraint, the layoutIfNeeded() will catch it and do a full layout.
   1493             if (r->needsPositionedMovementLayoutOnly())
   1494                 r->tryLayoutDoingPositionedMovementOnly();
   1495             r->layoutIfNeeded();
   1496         }
   1497     }
   1498 }
   1499 
   1500 void RenderBlock::markPositionedObjectsForLayout()
   1501 {
   1502     if (m_positionedObjects) {
   1503         RenderBox* r;
   1504         Iterator end = m_positionedObjects->end();
   1505         for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
   1506             r = *it;
   1507             r->setChildNeedsLayout(true);
   1508         }
   1509     }
   1510 }
   1511 
   1512 void RenderBlock::repaintOverhangingFloats(bool paintAllDescendants)
   1513 {
   1514     // Repaint any overhanging floats (if we know we're the one to paint them).
   1515     if (hasOverhangingFloats()) {
   1516         // We think that we must be in a bad state if m_floatingObjects is nil at this point, so
   1517         // we assert on Debug builds and nil-check Release builds.
   1518         ASSERT(m_floatingObjects);
   1519         if (!m_floatingObjects)
   1520             return;
   1521 
   1522         FloatingObject* r;
   1523         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   1524 
   1525         // FIXME: Avoid disabling LayoutState. At the very least, don't disable it for floats originating
   1526         // in this block. Better yet would be to push extra state for the containers of other floats.
   1527         view()->disableLayoutState();
   1528         for ( ; (r = it.current()); ++it) {
   1529             // Only repaint the object if it is overhanging, is not in its own layer, and
   1530             // is our responsibility to paint (m_shouldPaint is set). When paintAllDescendants is true, the latter
   1531             // condition is replaced with being a descendant of us.
   1532             if (r->m_bottom > height() && ((paintAllDescendants && r->m_renderer->isDescendantOf(this)) || r->m_shouldPaint) && !r->m_renderer->hasSelfPaintingLayer()) {
   1533                 r->m_renderer->repaint();
   1534                 r->m_renderer->repaintOverhangingFloats();
   1535             }
   1536         }
   1537         view()->enableLayoutState();
   1538     }
   1539 }
   1540 
   1541 void RenderBlock::paint(PaintInfo& paintInfo, int tx, int ty)
   1542 {
   1543     tx += x();
   1544     ty += y();
   1545 
   1546     PaintPhase phase = paintInfo.phase;
   1547 
   1548     // Check if we need to do anything at all.
   1549     // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
   1550     // paints the root's background.
   1551     if (!isRoot()) {
   1552         IntRect overflowBox = visibleOverflowRect();
   1553         overflowBox.inflate(maximalOutlineSize(paintInfo.phase));
   1554         overflowBox.move(tx, ty);
   1555         if (!overflowBox.intersects(paintInfo.rect))
   1556             return;
   1557     }
   1558 
   1559     bool pushedClip = pushContentsClip(paintInfo, tx, ty);
   1560     paintObject(paintInfo, tx, ty);
   1561     if (pushedClip)
   1562         popContentsClip(paintInfo, phase, tx, ty);
   1563 
   1564     // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
   1565     // z-index.  We paint after we painted the background/border, so that the scrollbars will
   1566     // sit above the background/border.
   1567     if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && shouldPaintWithinRoot(paintInfo))
   1568         layer()->paintOverflowControls(paintInfo.context, tx, ty, paintInfo.rect);
   1569 }
   1570 
   1571 void RenderBlock::paintColumnRules(PaintInfo& paintInfo, int tx, int ty)
   1572 {
   1573     const Color& ruleColor = style()->columnRuleColor();
   1574     bool ruleTransparent = style()->columnRuleIsTransparent();
   1575     EBorderStyle ruleStyle = style()->columnRuleStyle();
   1576     int ruleWidth = style()->columnRuleWidth();
   1577     int colGap = columnGap();
   1578     bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent && ruleWidth <= colGap;
   1579     if (!renderRule)
   1580         return;
   1581 
   1582     // We need to do multiple passes, breaking up our child painting into strips.
   1583     int currXOffset = 0;
   1584     int ruleAdd = borderLeft() + paddingLeft();
   1585     int ruleX = 0;
   1586     Vector<IntRect>* colRects = columnRects();
   1587     unsigned colCount = colRects->size();
   1588     for (unsigned i = 0; i < colCount; i++) {
   1589         // For each rect, we clip to the rect, and then we adjust our coords.
   1590         IntRect colRect = colRects->at(i);
   1591 
   1592         // Move to the next position.
   1593         if (style()->direction() == LTR) {
   1594             ruleX += colRect.width() + colGap / 2;
   1595             currXOffset += colRect.width() + colGap;
   1596         } else {
   1597             ruleX -= (colRect.width() + colGap / 2);
   1598             currXOffset -= (colRect.width() + colGap);
   1599         }
   1600 
   1601         // Now paint the column rule.
   1602         if (i < colCount - 1) {
   1603             int ruleStart = tx + ruleX - ruleWidth / 2 + ruleAdd;
   1604             int ruleEnd = ruleStart + ruleWidth;
   1605             int ruleTop = ty + borderTop() + paddingTop();
   1606             int ruleBottom = ruleTop + contentHeight();
   1607             drawLineForBoxSide(paintInfo.context, ruleStart, ruleTop, ruleEnd, ruleBottom,
   1608                                style()->direction() == LTR ? BSLeft : BSRight, ruleColor, style()->color(), ruleStyle, 0, 0);
   1609         }
   1610 
   1611         ruleX = currXOffset;
   1612     }
   1613 }
   1614 
   1615 void RenderBlock::paintColumnContents(PaintInfo& paintInfo, int tx, int ty, bool paintingFloats)
   1616 {
   1617     // We need to do multiple passes, breaking up our child painting into strips.
   1618     GraphicsContext* context = paintInfo.context;
   1619     int currXOffset = 0;
   1620     int currYOffset = 0;
   1621     int colGap = columnGap();
   1622     Vector<IntRect>* colRects = columnRects();
   1623     unsigned colCount = colRects->size();
   1624     for (unsigned i = 0; i < colCount; i++) {
   1625         // For each rect, we clip to the rect, and then we adjust our coords.
   1626         IntRect colRect = colRects->at(i);
   1627         colRect.move(tx, ty);
   1628         context->save();
   1629 
   1630         // Each strip pushes a clip, since column boxes are specified as being
   1631         // like overflow:hidden.
   1632         context->clip(colRect);
   1633 
   1634         // Adjust tx and ty to change where we paint.
   1635         PaintInfo info(paintInfo);
   1636         info.rect.intersect(colRect);
   1637 
   1638         // Adjust our x and y when painting.
   1639         int finalX = tx + currXOffset;
   1640         int finalY = ty + currYOffset;
   1641         if (paintingFloats)
   1642             paintFloats(info, finalX, finalY, paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip);
   1643         else
   1644             paintContents(info, finalX, finalY);
   1645 
   1646         // Move to the next position.
   1647         if (style()->direction() == LTR)
   1648             currXOffset += colRect.width() + colGap;
   1649         else
   1650             currXOffset -= (colRect.width() + colGap);
   1651 
   1652         currYOffset -= colRect.height();
   1653 
   1654         context->restore();
   1655     }
   1656 }
   1657 
   1658 void RenderBlock::paintContents(PaintInfo& paintInfo, int tx, int ty)
   1659 {
   1660     // Avoid painting descendants of the root element when stylesheets haven't loaded.  This eliminates FOUC.
   1661     // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
   1662     // will do a full repaint().
   1663     if (document()->didLayoutWithPendingStylesheets() && !isRenderView())
   1664         return;
   1665 
   1666     if (childrenInline())
   1667         m_lineBoxes.paint(this, paintInfo, tx, ty);
   1668     else
   1669         paintChildren(paintInfo, tx, ty);
   1670 }
   1671 
   1672 void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
   1673 {
   1674     PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase;
   1675     newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase;
   1676 
   1677     // We don't paint our own background, but we do let the kids paint their backgrounds.
   1678     PaintInfo info(paintInfo);
   1679     info.phase = newPhase;
   1680     info.paintingRoot = paintingRootForChildren(paintInfo);
   1681     bool isPrinting = document()->printing();
   1682 
   1683     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
   1684         // Check for page-break-before: always, and if it's set, break and bail.
   1685         if (isPrinting && !childrenInline() && child->style()->pageBreakBefore() == PBALWAYS &&
   1686             inRootBlockContext() && (ty + child->y()) > paintInfo.rect.y() &&
   1687             (ty + child->y()) < paintInfo.rect.bottom()) {
   1688             view()->setBestTruncatedAt(ty + child->y(), this, true);
   1689             return;
   1690         }
   1691 
   1692         if (!child->hasSelfPaintingLayer() && !child->isFloating())
   1693             child->paint(info, tx, ty);
   1694 
   1695         // Check for page-break-after: always, and if it's set, break and bail.
   1696         if (isPrinting && !childrenInline() && child->style()->pageBreakAfter() == PBALWAYS &&
   1697             inRootBlockContext() && (ty + child->y() + child->height()) > paintInfo.rect.y() &&
   1698             (ty + child->y() + child->height()) < paintInfo.rect.bottom()) {
   1699             view()->setBestTruncatedAt(ty + child->y() + child->height() + max(0, child->collapsedMarginBottom()), this, true);
   1700             return;
   1701         }
   1702     }
   1703 }
   1704 
   1705 void RenderBlock::paintCaret(PaintInfo& paintInfo, int tx, int ty, CaretType type)
   1706 {
   1707     SelectionController* selection = type == CursorCaret ? document()->frame()->selection() : document()->frame()->dragCaretController();
   1708 
   1709     // Paint the caret if the SelectionController says so or if caret browsing is enabled
   1710     bool caretBrowsing = document()->frame()->settings() && document()->frame()->settings()->caretBrowsingEnabled();
   1711     RenderObject* caretPainter = selection->caretRenderer();
   1712     if (caretPainter == this && (selection->isContentEditable() || caretBrowsing)) {
   1713         // Convert the painting offset into the local coordinate system of this renderer,
   1714         // to match the localCaretRect computed by the SelectionController
   1715         offsetForContents(tx, ty);
   1716 
   1717         if (type == CursorCaret)
   1718             document()->frame()->selection()->paintCaret(paintInfo.context, tx, ty, paintInfo.rect);
   1719         else
   1720             document()->frame()->paintDragCaret(paintInfo.context, tx, ty, paintInfo.rect);
   1721     }
   1722 }
   1723 
   1724 void RenderBlock::paintObject(PaintInfo& paintInfo, int tx, int ty)
   1725 {
   1726     PaintPhase paintPhase = paintInfo.phase;
   1727 
   1728     // 1. paint background, borders etc
   1729     if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && style()->visibility() == VISIBLE) {
   1730         if (hasBoxDecorations())
   1731             paintBoxDecorations(paintInfo, tx, ty);
   1732         if (hasColumns())
   1733             paintColumnRules(paintInfo, tx, ty);
   1734     }
   1735 
   1736     if (paintPhase == PaintPhaseMask && style()->visibility() == VISIBLE) {
   1737         paintMask(paintInfo, tx, ty);
   1738         return;
   1739     }
   1740 
   1741     // We're done.  We don't bother painting any children.
   1742     if (paintPhase == PaintPhaseBlockBackground)
   1743         return;
   1744 
   1745     // Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div).s
   1746     int scrolledX = tx;
   1747     int scrolledY = ty;
   1748     if (hasOverflowClip())
   1749         layer()->subtractScrolledContentOffset(scrolledX, scrolledY);
   1750 
   1751     // 2. paint contents
   1752     if (paintPhase != PaintPhaseSelfOutline) {
   1753         if (hasColumns())
   1754             paintColumnContents(paintInfo, scrolledX, scrolledY);
   1755         else
   1756             paintContents(paintInfo, scrolledX, scrolledY);
   1757     }
   1758 
   1759     // 3. paint selection
   1760     // FIXME: Make this work with multi column layouts.  For now don't fill gaps.
   1761     bool isPrinting = document()->printing();
   1762     if (!isPrinting && !hasColumns())
   1763         paintSelection(paintInfo, scrolledX, scrolledY); // Fill in gaps in selection on lines and between blocks.
   1764 
   1765     // 4. paint floats.
   1766     if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip) {
   1767         if (hasColumns())
   1768             paintColumnContents(paintInfo, scrolledX, scrolledY, true);
   1769         else
   1770             paintFloats(paintInfo, scrolledX, scrolledY, paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip);
   1771     }
   1772 
   1773     // 5. paint outline.
   1774     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
   1775         paintOutline(paintInfo.context, tx, ty, width(), height(), style());
   1776 
   1777     // 6. paint continuation outlines.
   1778     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) {
   1779         if (inlineContinuation() && inlineContinuation()->hasOutline() && inlineContinuation()->style()->visibility() == VISIBLE) {
   1780             RenderInline* inlineRenderer = toRenderInline(inlineContinuation()->node()->renderer());
   1781             RenderBlock* cb = containingBlock();
   1782 
   1783             bool inlineEnclosedInSelfPaintingLayer = false;
   1784             for (RenderBoxModelObject* box = inlineRenderer; box != cb; box = box->parent()->enclosingBoxModelObject()) {
   1785                 if (box->hasSelfPaintingLayer()) {
   1786                     inlineEnclosedInSelfPaintingLayer = true;
   1787                     break;
   1788                 }
   1789             }
   1790 
   1791             if (!inlineEnclosedInSelfPaintingLayer)
   1792                 cb->addContinuationWithOutline(inlineRenderer);
   1793             else if (!inlineRenderer->firstLineBox())
   1794                 inlineRenderer->paintOutline(paintInfo.context, tx - x() + inlineRenderer->containingBlock()->x(),
   1795                                              ty - y() + inlineRenderer->containingBlock()->y());
   1796         }
   1797         paintContinuationOutlines(paintInfo, tx, ty);
   1798     }
   1799 
   1800     // 7. paint caret.
   1801     // If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground,
   1802     // then paint the caret.
   1803     if (paintPhase == PaintPhaseForeground) {
   1804         paintCaret(paintInfo, scrolledX, scrolledY, CursorCaret);
   1805         paintCaret(paintInfo, scrolledX, scrolledY, DragCaret);
   1806     }
   1807 }
   1808 
   1809 void RenderBlock::paintFloats(PaintInfo& paintInfo, int tx, int ty, bool preservePhase)
   1810 {
   1811     if (!m_floatingObjects)
   1812         return;
   1813 
   1814     FloatingObject* r;
   1815     DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   1816     for (; (r = it.current()); ++it) {
   1817         // Only paint the object if our m_shouldPaint flag is set.
   1818         if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
   1819             PaintInfo currentPaintInfo(paintInfo);
   1820             currentPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
   1821             int currentTX = tx + r->m_left - r->m_renderer->x() + r->m_renderer->marginLeft();
   1822             int currentTY = ty + r->m_top - r->m_renderer->y() + r->m_renderer->marginTop();
   1823             r->m_renderer->paint(currentPaintInfo, currentTX, currentTY);
   1824             if (!preservePhase) {
   1825                 currentPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
   1826                 r->m_renderer->paint(currentPaintInfo, currentTX, currentTY);
   1827                 currentPaintInfo.phase = PaintPhaseFloat;
   1828                 r->m_renderer->paint(currentPaintInfo, currentTX, currentTY);
   1829                 currentPaintInfo.phase = PaintPhaseForeground;
   1830                 r->m_renderer->paint(currentPaintInfo, currentTX, currentTY);
   1831                 currentPaintInfo.phase = PaintPhaseOutline;
   1832                 r->m_renderer->paint(currentPaintInfo, currentTX, currentTY);
   1833             }
   1834         }
   1835     }
   1836 }
   1837 
   1838 void RenderBlock::paintEllipsisBoxes(PaintInfo& paintInfo, int tx, int ty)
   1839 {
   1840     if (!shouldPaintWithinRoot(paintInfo) || !firstLineBox())
   1841         return;
   1842 
   1843     if (style()->visibility() == VISIBLE && paintInfo.phase == PaintPhaseForeground) {
   1844         // We can check the first box and last box and avoid painting if we don't
   1845         // intersect.
   1846         int yPos = ty + firstLineBox()->y();
   1847         int h = lastLineBox()->y() + lastLineBox()->height() - firstLineBox()->y();
   1848         if (yPos >= paintInfo.rect.bottom() || yPos + h <= paintInfo.rect.y())
   1849             return;
   1850 
   1851         // See if our boxes intersect with the dirty rect.  If so, then we paint
   1852         // them.  Note that boxes can easily overlap, so we can't make any assumptions
   1853         // based off positions of our first line box or our last line box.
   1854         for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
   1855             yPos = ty + curr->y();
   1856             h = curr->height();
   1857             if (curr->ellipsisBox() && yPos < paintInfo.rect.bottom() && yPos + h > paintInfo.rect.y())
   1858                 curr->paintEllipsisBox(paintInfo, tx, ty);
   1859         }
   1860     }
   1861 }
   1862 
   1863 static ContinuationOutlineTableMap* continuationOutlineTable()
   1864 {
   1865     DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ());
   1866     return &table;
   1867 }
   1868 
   1869 void RenderBlock::addContinuationWithOutline(RenderInline* flow)
   1870 {
   1871     // We can't make this work if the inline is in a layer.  We'll just rely on the broken
   1872     // way of painting.
   1873     ASSERT(!flow->layer() && !flow->isInlineContinuation());
   1874 
   1875     ContinuationOutlineTableMap* table = continuationOutlineTable();
   1876     ListHashSet<RenderInline*>* continuations = table->get(this);
   1877     if (!continuations) {
   1878         continuations = new ListHashSet<RenderInline*>;
   1879         table->set(this, continuations);
   1880     }
   1881 
   1882     continuations->add(flow);
   1883 }
   1884 
   1885 void RenderBlock::paintContinuationOutlines(PaintInfo& info, int tx, int ty)
   1886 {
   1887     ContinuationOutlineTableMap* table = continuationOutlineTable();
   1888     if (table->isEmpty())
   1889         return;
   1890 
   1891     ListHashSet<RenderInline*>* continuations = table->get(this);
   1892     if (!continuations)
   1893         return;
   1894 
   1895     // Paint each continuation outline.
   1896     ListHashSet<RenderInline*>::iterator end = continuations->end();
   1897     for (ListHashSet<RenderInline*>::iterator it = continuations->begin(); it != end; ++it) {
   1898         // Need to add in the coordinates of the intervening blocks.
   1899         RenderInline* flow = *it;
   1900         RenderBlock* block = flow->containingBlock();
   1901         for ( ; block && block != this; block = block->containingBlock()) {
   1902             tx += block->x();
   1903             ty += block->y();
   1904         }
   1905         ASSERT(block);
   1906         flow->paintOutline(info.context, tx, ty);
   1907     }
   1908 
   1909     // Delete
   1910     delete continuations;
   1911     table->remove(this);
   1912 }
   1913 
   1914 void RenderBlock::setSelectionState(SelectionState s)
   1915 {
   1916     if (selectionState() == s)
   1917         return;
   1918 
   1919     if (s == SelectionInside && selectionState() != SelectionNone)
   1920         return;
   1921 
   1922     if ((s == SelectionStart && selectionState() == SelectionEnd) ||
   1923         (s == SelectionEnd && selectionState() == SelectionStart))
   1924         RenderBox::setSelectionState(SelectionBoth);
   1925     else
   1926         RenderBox::setSelectionState(s);
   1927 
   1928     RenderBlock* cb = containingBlock();
   1929     if (cb && !cb->isRenderView())
   1930         cb->setSelectionState(s);
   1931 }
   1932 
   1933 bool RenderBlock::shouldPaintSelectionGaps() const
   1934 {
   1935     return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot();
   1936 }
   1937 
   1938 bool RenderBlock::isSelectionRoot() const
   1939 {
   1940     if (!node())
   1941         return false;
   1942 
   1943     // FIXME: Eventually tables should have to learn how to fill gaps between cells, at least in simple non-spanning cases.
   1944     if (isTable())
   1945         return false;
   1946 
   1947     if (isBody() || isRoot() || hasOverflowClip() || isRelPositioned() ||
   1948         isFloatingOrPositioned() || isTableCell() || isInlineBlockOrInlineTable() || hasTransform() ||
   1949         hasReflection() || hasMask())
   1950         return true;
   1951 
   1952     if (view() && view()->selectionStart()) {
   1953         Node* startElement = view()->selectionStart()->node();
   1954         if (startElement && startElement->rootEditableElement() == node())
   1955             return true;
   1956     }
   1957 
   1958     return false;
   1959 }
   1960 
   1961 GapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer)
   1962 {
   1963     ASSERT(!needsLayout());
   1964 
   1965     if (!shouldPaintSelectionGaps())
   1966         return GapRects();
   1967 
   1968     // FIXME: this is broken with transforms
   1969     TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
   1970     mapLocalToContainer(repaintContainer, false, false, transformState);
   1971     FloatPoint offsetFromRepaintContainer = transformState.mappedPoint();
   1972     int x = offsetFromRepaintContainer.x();
   1973     int y = offsetFromRepaintContainer.y();
   1974 
   1975     if (hasOverflowClip())
   1976         layer()->subtractScrolledContentOffset(x, y);
   1977 
   1978     int lastTop = 0;
   1979     int lastLeft = leftSelectionOffset(this, lastTop);
   1980     int lastRight = rightSelectionOffset(this, lastTop);
   1981 
   1982     return fillSelectionGaps(this, x, y, x, y, lastTop, lastLeft, lastRight);
   1983 }
   1984 
   1985 void RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty)
   1986 {
   1987     if (shouldPaintSelectionGaps() && paintInfo.phase == PaintPhaseForeground) {
   1988         int lastTop = 0;
   1989         int lastLeft = leftSelectionOffset(this, lastTop);
   1990         int lastRight = rightSelectionOffset(this, lastTop);
   1991         paintInfo.context->save();
   1992         IntRect gapRectsBounds = fillSelectionGaps(this, tx, ty, tx, ty, lastTop, lastLeft, lastRight, &paintInfo);
   1993         if (!gapRectsBounds.isEmpty()) {
   1994             if (RenderLayer* layer = enclosingLayer()) {
   1995                 gapRectsBounds.move(IntSize(-tx, -ty));
   1996                 if (!hasLayer()) {
   1997                     FloatRect localBounds(gapRectsBounds);
   1998                     gapRectsBounds = localToContainerQuad(localBounds, layer->renderer()).enclosingBoundingBox();
   1999                 }
   2000                 layer->addBlockSelectionGapsBounds(gapRectsBounds);
   2001             }
   2002         }
   2003         paintInfo.context->restore();
   2004     }
   2005 }
   2006 
   2007 #ifndef BUILDING_ON_TIGER
   2008 static void clipOutPositionedObjects(const RenderObject::PaintInfo* paintInfo, int tx, int ty, ListHashSet<RenderBox*>* positionedObjects)
   2009 {
   2010     if (!positionedObjects)
   2011         return;
   2012 
   2013     ListHashSet<RenderBox*>::const_iterator end = positionedObjects->end();
   2014     for (ListHashSet<RenderBox*>::const_iterator it = positionedObjects->begin(); it != end; ++it) {
   2015         RenderBox* r = *it;
   2016         paintInfo->context->clipOut(IntRect(tx + r->x(), ty + r->y(), r->width(), r->height()));
   2017     }
   2018 }
   2019 #endif
   2020 
   2021 GapRects RenderBlock::fillSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty,
   2022                                         int& lastTop, int& lastLeft, int& lastRight, const PaintInfo* paintInfo)
   2023 {
   2024 #ifndef BUILDING_ON_TIGER
   2025     // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore.
   2026     // Clip out floating and positioned objects when painting selection gaps.
   2027     if (paintInfo) {
   2028         // Note that we don't clip out overflow for positioned objects.  We just stick to the border box.
   2029         clipOutPositionedObjects(paintInfo, tx, ty, m_positionedObjects);
   2030         if (isBody() || isRoot()) // The <body> must make sure to examine its containingBlock's positioned objects.
   2031             for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock())
   2032                 clipOutPositionedObjects(paintInfo, cb->x(), cb->y(), cb->m_positionedObjects);
   2033         if (m_floatingObjects) {
   2034             for (DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects); it.current(); ++it) {
   2035                 FloatingObject* r = it.current();
   2036                 paintInfo->context->clipOut(IntRect(tx + r->m_left + r->m_renderer->marginLeft(),
   2037                                                     ty + r->m_top + r->m_renderer->marginTop(),
   2038                                                     r->m_renderer->width(), r->m_renderer->height()));
   2039             }
   2040         }
   2041     }
   2042 #endif
   2043 
   2044     // 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
   2045     // fixed).
   2046     GapRects result;
   2047     if (!isBlockFlow()) // FIXME: Make multi-column selection gap filling work someday.
   2048         return result;
   2049 
   2050     if (hasColumns() || hasTransform()) {
   2051         // FIXME: We should learn how to gap fill multiple columns and transforms eventually.
   2052         lastTop = (ty - blockY) + height();
   2053         lastLeft = leftSelectionOffset(rootBlock, height());
   2054         lastRight = rightSelectionOffset(rootBlock, height());
   2055         return result;
   2056     }
   2057 
   2058     if (childrenInline())
   2059         result = fillInlineSelectionGaps(rootBlock, blockX, blockY, tx, ty, lastTop, lastLeft, lastRight, paintInfo);
   2060     else
   2061         result = fillBlockSelectionGaps(rootBlock, blockX, blockY, tx, ty, lastTop, lastLeft, lastRight, paintInfo);
   2062 
   2063     // Go ahead and fill the vertical gap all the way to the bottom of our block if the selection extends past our block.
   2064     if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd))
   2065         result.uniteCenter(fillVerticalSelectionGap(lastTop, lastLeft, lastRight, ty + height(),
   2066                                                     rootBlock, blockX, blockY, paintInfo));
   2067     return result;
   2068 }
   2069 
   2070 GapRects RenderBlock::fillInlineSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty,
   2071                                               int& lastTop, int& lastLeft, int& lastRight, const PaintInfo* paintInfo)
   2072 {
   2073     GapRects result;
   2074 
   2075     bool containsStart = selectionState() == SelectionStart || selectionState() == SelectionBoth;
   2076 
   2077     if (!firstLineBox()) {
   2078         if (containsStart) {
   2079             // Go ahead and update our lastY to be the bottom of the block.  <hr>s or empty blocks with height can trip this
   2080             // case.
   2081             lastTop = (ty - blockY) + height();
   2082             lastLeft = leftSelectionOffset(rootBlock, height());
   2083             lastRight = rightSelectionOffset(rootBlock, height());
   2084         }
   2085         return result;
   2086     }
   2087 
   2088     RootInlineBox* lastSelectedLine = 0;
   2089     RootInlineBox* curr;
   2090     for (curr = firstRootBox(); curr && !curr->hasSelectedChildren(); curr = curr->nextRootBox()) { }
   2091 
   2092     // Now paint the gaps for the lines.
   2093     for (; curr && curr->hasSelectedChildren(); curr = curr->nextRootBox()) {
   2094         int selTop =  curr->selectionTop();
   2095         int selHeight = curr->selectionHeight();
   2096 
   2097         if (!containsStart && !lastSelectedLine &&
   2098             selectionState() != SelectionStart && selectionState() != SelectionBoth)
   2099             result.uniteCenter(fillVerticalSelectionGap(lastTop, lastLeft, lastRight, ty + selTop,
   2100                                                         rootBlock, blockX, blockY, paintInfo));
   2101 
   2102         if (!paintInfo || (ty + selTop < paintInfo->rect.bottom() && ty + selTop + selHeight > paintInfo->rect.y()))
   2103             result.unite(curr->fillLineSelectionGap(selTop, selHeight, rootBlock, blockX, blockY, tx, ty, paintInfo));
   2104 
   2105         lastSelectedLine = curr;
   2106     }
   2107 
   2108     if (containsStart && !lastSelectedLine)
   2109         // VisibleSelection must start just after our last line.
   2110         lastSelectedLine = lastRootBox();
   2111 
   2112     if (lastSelectedLine && selectionState() != SelectionEnd && selectionState() != SelectionBoth) {
   2113         // Go ahead and update our lastY to be the bottom of the last selected line.
   2114         lastTop = (ty - blockY) + lastSelectedLine->selectionBottom();
   2115         lastLeft = leftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
   2116         lastRight = rightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
   2117     }
   2118     return result;
   2119 }
   2120 
   2121 GapRects RenderBlock::fillBlockSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty,
   2122                                              int& lastTop, int& lastLeft, int& lastRight, const PaintInfo* paintInfo)
   2123 {
   2124     GapRects result;
   2125 
   2126     // Go ahead and jump right to the first block child that contains some selected objects.
   2127     RenderBox* curr;
   2128     for (curr = firstChildBox(); curr && curr->selectionState() == SelectionNone; curr = curr->nextSiblingBox()) { }
   2129 
   2130     for (bool sawSelectionEnd = false; curr && !sawSelectionEnd; curr = curr->nextSiblingBox()) {
   2131         SelectionState childState = curr->selectionState();
   2132         if (childState == SelectionBoth || childState == SelectionEnd)
   2133             sawSelectionEnd = true;
   2134 
   2135         if (curr->isFloatingOrPositioned())
   2136             continue; // We must be a normal flow object in order to even be considered.
   2137 
   2138         if (curr->isRelPositioned() && curr->hasLayer()) {
   2139             // If the relposition offset is anything other than 0, then treat this just like an absolute positioned element.
   2140             // Just disregard it completely.
   2141             IntSize relOffset = curr->layer()->relativePositionOffset();
   2142             if (relOffset.width() || relOffset.height())
   2143                 continue;
   2144         }
   2145 
   2146         bool paintsOwnSelection = curr->shouldPaintSelectionGaps() || curr->isTable(); // FIXME: Eventually we won't special-case table like this.
   2147         bool fillBlockGaps = paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone);
   2148         if (fillBlockGaps) {
   2149             // We need to fill the vertical gap above this object.
   2150             if (childState == SelectionEnd || childState == SelectionInside)
   2151                 // Fill the gap above the object.
   2152                 result.uniteCenter(fillVerticalSelectionGap(lastTop, lastLeft, lastRight,
   2153                                                             ty + curr->y(), rootBlock, blockX, blockY, paintInfo));
   2154 
   2155             // 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*
   2156             // our object.  We know this if the selection did not end inside our object.
   2157             if (paintsOwnSelection && (childState == SelectionStart || sawSelectionEnd))
   2158                 childState = SelectionNone;
   2159 
   2160             // Fill side gaps on this object based off its state.
   2161             bool leftGap, rightGap;
   2162             getHorizontalSelectionGapInfo(childState, leftGap, rightGap);
   2163 
   2164             if (leftGap)
   2165                 result.uniteLeft(fillLeftSelectionGap(this, curr->x(), curr->y(), curr->height(), rootBlock, blockX, blockY, tx, ty, paintInfo));
   2166             if (rightGap)
   2167                 result.uniteRight(fillRightSelectionGap(this, curr->x() + curr->width(), curr->y(), curr->height(), rootBlock, blockX, blockY, tx, ty, paintInfo));
   2168 
   2169             // Update lastTop to be just underneath the object.  lastLeft and lastRight extend as far as
   2170             // they can without bumping into floating or positioned objects.  Ideally they will go right up
   2171             // to the border of the root selection block.
   2172             lastTop = (ty - blockY) + (curr->y() + curr->height());
   2173             lastLeft = leftSelectionOffset(rootBlock, curr->y() + curr->height());
   2174             lastRight = rightSelectionOffset(rootBlock, curr->y() + curr->height());
   2175         } else if (childState != SelectionNone)
   2176             // We must be a block that has some selected object inside it.  Go ahead and recur.
   2177             result.unite(toRenderBlock(curr)->fillSelectionGaps(rootBlock, blockX, blockY, tx + curr->x(), ty + curr->y(),
   2178                                                                             lastTop, lastLeft, lastRight, paintInfo));
   2179     }
   2180     return result;
   2181 }
   2182 
   2183 IntRect RenderBlock::fillHorizontalSelectionGap(RenderObject* selObj, int xPos, int yPos, int width, int height, const PaintInfo* paintInfo)
   2184 {
   2185     if (width <= 0 || height <= 0)
   2186         return IntRect();
   2187     IntRect gapRect(xPos, yPos, width, height);
   2188     if (paintInfo && selObj->style()->visibility() == VISIBLE)
   2189         paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
   2190     return gapRect;
   2191 }
   2192 
   2193 IntRect RenderBlock::fillVerticalSelectionGap(int lastTop, int lastLeft, int lastRight, int bottomY, RenderBlock* rootBlock,
   2194                                               int blockX, int blockY, const PaintInfo* paintInfo)
   2195 {
   2196     int top = blockY + lastTop;
   2197     int height = bottomY - top;
   2198     if (height <= 0)
   2199         return IntRect();
   2200 
   2201     // Get the selection offsets for the bottom of the gap
   2202     int left = blockX + max(lastLeft, leftSelectionOffset(rootBlock, bottomY));
   2203     int right = blockX + min(lastRight, rightSelectionOffset(rootBlock, bottomY));
   2204     int width = right - left;
   2205     if (width <= 0)
   2206         return IntRect();
   2207 
   2208     IntRect gapRect(left, top, width, height);
   2209     if (paintInfo)
   2210         paintInfo->context->fillRect(gapRect, selectionBackgroundColor(), style()->colorSpace());
   2211     return gapRect;
   2212 }
   2213 
   2214 IntRect RenderBlock::fillLeftSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock,
   2215                                           int blockX, int /*blockY*/, int tx, int ty, const PaintInfo* paintInfo)
   2216 {
   2217     int top = yPos + ty;
   2218     int left = blockX + max(leftSelectionOffset(rootBlock, yPos), leftSelectionOffset(rootBlock, yPos + height));
   2219     int right = min(xPos + tx, blockX + min(rightSelectionOffset(rootBlock, yPos), rightSelectionOffset(rootBlock, yPos + height)));
   2220     int width = right - left;
   2221     if (width <= 0)
   2222         return IntRect();
   2223 
   2224     IntRect gapRect(left, top, width, height);
   2225     if (paintInfo)
   2226         paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
   2227     return gapRect;
   2228 }
   2229 
   2230 IntRect RenderBlock::fillRightSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock,
   2231                                            int blockX, int /*blockY*/, int tx, int ty, const PaintInfo* paintInfo)
   2232 {
   2233     int left = max(xPos + tx, blockX + max(leftSelectionOffset(rootBlock, yPos), leftSelectionOffset(rootBlock, yPos + height)));
   2234     int top = yPos + ty;
   2235     int right = blockX + min(rightSelectionOffset(rootBlock, yPos), rightSelectionOffset(rootBlock, yPos + height));
   2236     int width = right - left;
   2237     if (width <= 0)
   2238         return IntRect();
   2239 
   2240     IntRect gapRect(left, top, width, height);
   2241     if (paintInfo)
   2242         paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
   2243     return gapRect;
   2244 }
   2245 
   2246 void RenderBlock::getHorizontalSelectionGapInfo(SelectionState state, bool& leftGap, bool& rightGap)
   2247 {
   2248     bool ltr = style()->direction() == LTR;
   2249     leftGap = (state == RenderObject::SelectionInside) ||
   2250               (state == RenderObject::SelectionEnd && ltr) ||
   2251               (state == RenderObject::SelectionStart && !ltr);
   2252     rightGap = (state == RenderObject::SelectionInside) ||
   2253                (state == RenderObject::SelectionStart && ltr) ||
   2254                (state == RenderObject::SelectionEnd && !ltr);
   2255 }
   2256 
   2257 int RenderBlock::leftSelectionOffset(RenderBlock* rootBlock, int yPos)
   2258 {
   2259     int left = leftOffset(yPos, false);
   2260     if (left == borderLeft() + paddingLeft()) {
   2261         if (rootBlock != this)
   2262             // The border can potentially be further extended by our containingBlock().
   2263             return containingBlock()->leftSelectionOffset(rootBlock, yPos + y());
   2264         return left;
   2265     }
   2266     else {
   2267         RenderBlock* cb = this;
   2268         while (cb != rootBlock) {
   2269             left += cb->x();
   2270             cb = cb->containingBlock();
   2271         }
   2272     }
   2273 
   2274     return left;
   2275 }
   2276 
   2277 int RenderBlock::rightSelectionOffset(RenderBlock* rootBlock, int yPos)
   2278 {
   2279     int right = rightOffset(yPos, false);
   2280     if (right == (contentWidth() + (borderLeft() + paddingLeft()))) {
   2281         if (rootBlock != this)
   2282             // The border can potentially be further extended by our containingBlock().
   2283             return containingBlock()->rightSelectionOffset(rootBlock, yPos + y());
   2284         return right;
   2285     }
   2286     else {
   2287         RenderBlock* cb = this;
   2288         while (cb != rootBlock) {
   2289             right += cb->x();
   2290             cb = cb->containingBlock();
   2291         }
   2292     }
   2293     return right;
   2294 }
   2295 
   2296 void RenderBlock::insertPositionedObject(RenderBox* o)
   2297 {
   2298     // Create the list of special objects if we don't aleady have one
   2299     if (!m_positionedObjects)
   2300         m_positionedObjects = new ListHashSet<RenderBox*>;
   2301 
   2302     m_positionedObjects->add(o);
   2303 }
   2304 
   2305 void RenderBlock::removePositionedObject(RenderBox* o)
   2306 {
   2307     if (m_positionedObjects)
   2308         m_positionedObjects->remove(o);
   2309 }
   2310 
   2311 void RenderBlock::removePositionedObjects(RenderBlock* o)
   2312 {
   2313     if (!m_positionedObjects)
   2314         return;
   2315 
   2316     RenderBox* r;
   2317 
   2318     Iterator end = m_positionedObjects->end();
   2319 
   2320     Vector<RenderBox*, 16> deadObjects;
   2321 
   2322     for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
   2323         r = *it;
   2324         if (!o || r->isDescendantOf(o)) {
   2325             if (o)
   2326                 r->setChildNeedsLayout(true, false);
   2327 
   2328             // It is parent blocks job to add positioned child to positioned objects list of its containing block
   2329             // Parent layout needs to be invalidated to ensure this happens.
   2330             RenderObject* p = r->parent();
   2331             while (p && !p->isRenderBlock())
   2332                 p = p->parent();
   2333             if (p)
   2334                 p->setChildNeedsLayout(true);
   2335 
   2336             deadObjects.append(r);
   2337         }
   2338     }
   2339 
   2340     for (unsigned i = 0; i < deadObjects.size(); i++)
   2341         m_positionedObjects->remove(deadObjects.at(i));
   2342 }
   2343 
   2344 void RenderBlock::insertFloatingObject(RenderBox* o)
   2345 {
   2346     ASSERT(o->isFloating());
   2347 
   2348     // Create the list of special objects if we don't aleady have one
   2349     if (!m_floatingObjects) {
   2350         m_floatingObjects = new DeprecatedPtrList<FloatingObject>;
   2351         m_floatingObjects->setAutoDelete(true);
   2352     } else {
   2353         // Don't insert the object again if it's already in the list
   2354         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2355         FloatingObject* f;
   2356         while ( (f = it.current()) ) {
   2357             if (f->m_renderer == o) return;
   2358             ++it;
   2359         }
   2360     }
   2361 
   2362     // Create the special object entry & append it to the list
   2363 
   2364     o->layoutIfNeeded();
   2365 
   2366     FloatingObject* newObj = new FloatingObject(o->style()->floating() == FLEFT ? FloatingObject::FloatLeft : FloatingObject::FloatRight);
   2367 
   2368     newObj->m_top = -1;
   2369     newObj->m_bottom = -1;
   2370     newObj->m_width = o->width() + o->marginLeft() + o->marginRight();
   2371     newObj->m_shouldPaint = !o->hasSelfPaintingLayer(); // If a layer exists, the float will paint itself.  Otherwise someone else will.
   2372     newObj->m_isDescendant = true;
   2373     newObj->m_renderer = o;
   2374 
   2375     m_floatingObjects->append(newObj);
   2376 }
   2377 
   2378 void RenderBlock::removeFloatingObject(RenderBox* o)
   2379 {
   2380     if (m_floatingObjects) {
   2381         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2382         while (it.current()) {
   2383             if (it.current()->m_renderer == o) {
   2384                 if (childrenInline())
   2385                     markLinesDirtyInVerticalRange(0, it.current()->m_bottom);
   2386                 m_floatingObjects->removeRef(it.current());
   2387             }
   2388             ++it;
   2389         }
   2390     }
   2391 }
   2392 
   2393 bool RenderBlock::positionNewFloats()
   2394 {
   2395     if (!m_floatingObjects)
   2396         return false;
   2397 
   2398     FloatingObject* f = m_floatingObjects->last();
   2399 
   2400     // If all floats have already been positioned, then we have no work to do.
   2401     if (!f || f->m_top != -1)
   2402         return false;
   2403 
   2404     // Move backwards through our floating object list until we find a float that has
   2405     // already been positioned.  Then we'll be able to move forward, positioning all of
   2406     // the new floats that need it.
   2407     FloatingObject* lastFloat = m_floatingObjects->getPrev();
   2408     while (lastFloat && lastFloat->m_top == -1) {
   2409         f = m_floatingObjects->prev();
   2410         lastFloat = m_floatingObjects->getPrev();
   2411     }
   2412 
   2413     int y = height();
   2414 
   2415     // The float cannot start above the y position of the last positioned float.
   2416     if (lastFloat)
   2417         y = max(lastFloat->m_top, y);
   2418 
   2419     // Now walk through the set of unpositioned floats and place them.
   2420     while (f) {
   2421         // The containing block is responsible for positioning floats, so if we have floats in our
   2422         // list that come from somewhere else, do not attempt to position them.
   2423         if (f->m_renderer->containingBlock() != this) {
   2424             f = m_floatingObjects->next();
   2425             continue;
   2426         }
   2427 
   2428         RenderBox* o = f->m_renderer;
   2429         int _height = o->height() + o->marginTop() + o->marginBottom();
   2430 
   2431         int ro = rightOffset(); // Constant part of right offset.
   2432         int lo = leftOffset(); // Constat part of left offset.
   2433         int fwidth = f->m_width; // The width we look for.
   2434         if (ro - lo < fwidth)
   2435             fwidth = ro - lo; // Never look for more than what will be available.
   2436 
   2437         IntRect oldRect(o->x(), o->y() , o->width(), o->height());
   2438 
   2439         if (o->style()->clear() & CLEFT)
   2440             y = max(leftBottom(), y);
   2441         if (o->style()->clear() & CRIGHT)
   2442             y = max(rightBottom(), y);
   2443 
   2444         if (o->style()->floating() == FLEFT) {
   2445             int heightRemainingLeft = 1;
   2446             int heightRemainingRight = 1;
   2447             int fx = leftRelOffset(y, lo, false, &heightRemainingLeft);
   2448             while (rightRelOffset(y, ro, false, &heightRemainingRight)-fx < fwidth) {
   2449                 y += min(heightRemainingLeft, heightRemainingRight);
   2450                 fx = leftRelOffset(y, lo, false, &heightRemainingLeft);
   2451             }
   2452             fx = max(0, fx);
   2453             f->m_left = fx;
   2454             o->setLocation(fx + o->marginLeft(), y + o->marginTop());
   2455         } else {
   2456             int heightRemainingLeft = 1;
   2457             int heightRemainingRight = 1;
   2458             int fx = rightRelOffset(y, ro, false, &heightRemainingRight);
   2459             while (fx - leftRelOffset(y, lo, false, &heightRemainingLeft) < fwidth) {
   2460                 y += min(heightRemainingLeft, heightRemainingRight);
   2461                 fx = rightRelOffset(y, ro, false, &heightRemainingRight);
   2462             }
   2463             f->m_left = fx - f->m_width;
   2464             o->setLocation(fx - o->marginRight() - o->width(), y + o->marginTop());
   2465         }
   2466 
   2467         f->m_top = y;
   2468         f->m_bottom = f->m_top + _height;
   2469 
   2470         // If the child moved, we have to repaint it.
   2471         if (o->checkForRepaintDuringLayout())
   2472             o->repaintDuringLayoutIfMoved(oldRect);
   2473 
   2474         f = m_floatingObjects->next();
   2475     }
   2476     return true;
   2477 }
   2478 
   2479 void RenderBlock::newLine(EClear clear)
   2480 {
   2481     positionNewFloats();
   2482     // set y position
   2483     int newY = 0;
   2484     switch (clear)
   2485     {
   2486         case CLEFT:
   2487             newY = leftBottom();
   2488             break;
   2489         case CRIGHT:
   2490             newY = rightBottom();
   2491             break;
   2492         case CBOTH:
   2493             newY = floatBottom();
   2494         default:
   2495             break;
   2496     }
   2497     if (height() < newY)
   2498         setHeight(newY);
   2499 }
   2500 
   2501 void RenderBlock::addPercentHeightDescendant(RenderBox* descendant)
   2502 {
   2503     if (!gPercentHeightDescendantsMap) {
   2504         gPercentHeightDescendantsMap = new PercentHeightDescendantsMap;
   2505         gPercentHeightContainerMap = new PercentHeightContainerMap;
   2506     }
   2507 
   2508     HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(this);
   2509     if (!descendantSet) {
   2510         descendantSet = new HashSet<RenderBox*>;
   2511         gPercentHeightDescendantsMap->set(this, descendantSet);
   2512     }
   2513     bool added = descendantSet->add(descendant).second;
   2514     if (!added) {
   2515         ASSERT(gPercentHeightContainerMap->get(descendant));
   2516         ASSERT(gPercentHeightContainerMap->get(descendant)->contains(this));
   2517         return;
   2518     }
   2519 
   2520     HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->get(descendant);
   2521     if (!containerSet) {
   2522         containerSet = new HashSet<RenderBlock*>;
   2523         gPercentHeightContainerMap->set(descendant, containerSet);
   2524     }
   2525     ASSERT(!containerSet->contains(this));
   2526     containerSet->add(this);
   2527 }
   2528 
   2529 void RenderBlock::removePercentHeightDescendant(RenderBox* descendant)
   2530 {
   2531     if (!gPercentHeightContainerMap)
   2532         return;
   2533 
   2534     HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->take(descendant);
   2535     if (!containerSet)
   2536         return;
   2537 
   2538     HashSet<RenderBlock*>::iterator end = containerSet->end();
   2539     for (HashSet<RenderBlock*>::iterator it = containerSet->begin(); it != end; ++it) {
   2540         RenderBlock* container = *it;
   2541         HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(container);
   2542         ASSERT(descendantSet);
   2543         if (!descendantSet)
   2544             continue;
   2545         ASSERT(descendantSet->contains(descendant));
   2546         descendantSet->remove(descendant);
   2547         if (descendantSet->isEmpty()) {
   2548             gPercentHeightDescendantsMap->remove(container);
   2549             delete descendantSet;
   2550         }
   2551     }
   2552 
   2553     delete containerSet;
   2554 }
   2555 
   2556 HashSet<RenderBox*>* RenderBlock::percentHeightDescendants() const
   2557 {
   2558     return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0;
   2559 }
   2560 
   2561 int RenderBlock::leftOffset() const
   2562 {
   2563     return borderLeft() + paddingLeft();
   2564 }
   2565 
   2566 int RenderBlock::leftRelOffset(int y, int fixedOffset, bool applyTextIndent, int* heightRemaining) const
   2567 {
   2568     int left = fixedOffset;
   2569     if (m_floatingObjects) {
   2570         if ( heightRemaining ) *heightRemaining = 1;
   2571         FloatingObject* r;
   2572         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2573         for ( ; (r = it.current()); ++it )
   2574         {
   2575             if (r->m_top <= y && r->m_bottom > y &&
   2576                 r->type() == FloatingObject::FloatLeft &&
   2577                 r->m_left + r->m_width > left) {
   2578                 left = r->m_left + r->m_width;
   2579                 if ( heightRemaining ) *heightRemaining = r->m_bottom - y;
   2580             }
   2581         }
   2582     }
   2583 
   2584     if (applyTextIndent && style()->direction() == LTR) {
   2585         int cw = 0;
   2586         if (style()->textIndent().isPercent())
   2587             cw = containingBlock()->availableWidth();
   2588         left += style()->textIndent().calcMinValue(cw);
   2589     }
   2590 
   2591     return left;
   2592 }
   2593 
   2594 int RenderBlock::rightOffset() const
   2595 {
   2596     return borderLeft() + paddingLeft() + availableWidth();
   2597 }
   2598 
   2599 int RenderBlock::rightRelOffset(int y, int fixedOffset, bool applyTextIndent, int* heightRemaining) const
   2600 {
   2601     int right = fixedOffset;
   2602 
   2603     if (m_floatingObjects) {
   2604         if (heightRemaining) *heightRemaining = 1;
   2605         FloatingObject* r;
   2606         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2607         for ( ; (r = it.current()); ++it )
   2608         {
   2609             if (r->m_top <= y && r->m_bottom > y &&
   2610                 r->type() == FloatingObject::FloatRight &&
   2611                 r->m_left < right) {
   2612                 right = r->m_left;
   2613                 if ( heightRemaining ) *heightRemaining = r->m_bottom - y;
   2614             }
   2615         }
   2616     }
   2617 
   2618     if (applyTextIndent && style()->direction() == RTL) {
   2619         int cw = 0;
   2620         if (style()->textIndent().isPercent())
   2621             cw = containingBlock()->availableWidth();
   2622         right -= style()->textIndent().calcMinValue(cw);
   2623     }
   2624 
   2625     return right;
   2626 }
   2627 
   2628 int
   2629 RenderBlock::lineWidth(int y, bool firstLine) const
   2630 {
   2631     int result = rightOffset(y, firstLine) - leftOffset(y, firstLine);
   2632     return (result < 0) ? 0 : result;
   2633 }
   2634 
   2635 int RenderBlock::nextFloatBottomBelow(int height) const
   2636 {
   2637     if (!m_floatingObjects)
   2638         return 0;
   2639 
   2640     int bottom = INT_MAX;
   2641     FloatingObject* r;
   2642     DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2643     for ( ; (r = it.current()); ++it) {
   2644         if (r->m_bottom > height)
   2645             bottom = min(r->m_bottom, bottom);
   2646     }
   2647 
   2648     return bottom == INT_MAX ? 0 : bottom;
   2649 }
   2650 
   2651 int
   2652 RenderBlock::floatBottom() const
   2653 {
   2654     if (!m_floatingObjects) return 0;
   2655     int bottom = 0;
   2656     FloatingObject* r;
   2657     DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2658     for ( ; (r = it.current()); ++it )
   2659         if (r->m_bottom>bottom)
   2660             bottom = r->m_bottom;
   2661     return bottom;
   2662 }
   2663 
   2664 IntRect RenderBlock::floatRect() const
   2665 {
   2666     IntRect result;
   2667     if (!m_floatingObjects || hasOverflowClip() || hasColumns())
   2668         return result;
   2669     FloatingObject* r;
   2670     DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2671     for (; (r = it.current()); ++it) {
   2672         if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
   2673             IntRect childRect = r->m_renderer->visibleOverflowRect();
   2674             childRect.move(r->m_left + r->m_renderer->marginLeft(), r->m_top + r->m_renderer->marginTop());
   2675             result.unite(childRect);
   2676         }
   2677     }
   2678 
   2679     return result;
   2680 }
   2681 
   2682 int RenderBlock::lowestPosition(bool includeOverflowInterior, bool includeSelf) const
   2683 {
   2684     int bottom = includeSelf && width() > 0 ? height() : 0;
   2685 
   2686     if (!includeOverflowInterior && (hasOverflowClip() || hasControlClip()))
   2687         return bottom;
   2688 
   2689     if (!firstChild() && (!width() || !height()))
   2690         return bottom;
   2691 
   2692     if (!hasColumns()) {
   2693         // FIXME: Come up with a way to use the layer tree to avoid visiting all the kids.
   2694         // For now, we have to descend into all the children, since we may have a huge abs div inside
   2695         // a tiny rel div buried somewhere deep in our child tree.  In this case we have to get to
   2696         // the abs div.
   2697         // See the last test case in https://bugs.webkit.org/show_bug.cgi?id=9314 for why this is a problem.
   2698         // For inline children, we miss relative positioned boxes that might be buried inside <span>s.
   2699         for (RenderObject* c = firstChild(); c; c = c->nextSibling()) {
   2700             if (!c->isFloatingOrPositioned() && c->isBox()) {
   2701                 RenderBox* childBox = toRenderBox(c);
   2702                 bottom = max(bottom, childBox->y() + childBox->lowestPosition(false));
   2703             }
   2704         }
   2705     }
   2706 
   2707     if (includeSelf && isRelPositioned())
   2708         bottom += relativePositionOffsetY();
   2709     if (!includeOverflowInterior && hasOverflowClip())
   2710         return bottom;
   2711 
   2712     int relativeOffset = includeSelf && isRelPositioned() ? relativePositionOffsetY() : 0;
   2713 
   2714     if (includeSelf)
   2715         bottom = max(bottom, bottomLayoutOverflow() + relativeOffset);
   2716 
   2717     if (m_positionedObjects) {
   2718         RenderBox* r;
   2719         Iterator end = m_positionedObjects->end();
   2720         for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
   2721             r = *it;
   2722             // Fixed positioned objects do not scroll and thus should not constitute
   2723             // part of the lowest position.
   2724             if (r->style()->position() != FixedPosition) {
   2725                 // FIXME: Should work for overflow sections too.
   2726                 // If a positioned object lies completely to the left of the root it will be unreachable via scrolling.
   2727                 // Therefore we should not allow it to contribute to the lowest position.
   2728                 if (!isRenderView() || r->x() + r->width() > 0 || r->x() + r->rightmostPosition(false) > 0) {
   2729                     int lp = r->y() + r->lowestPosition(false);
   2730                     bottom = max(bottom, lp + relativeOffset);
   2731                 }
   2732             }
   2733         }
   2734     }
   2735 
   2736     if (hasColumns()) {
   2737         Vector<IntRect>* colRects = columnRects();
   2738         for (unsigned i = 0; i < colRects->size(); i++)
   2739             bottom = max(bottom, colRects->at(i).bottom() + relativeOffset);
   2740         return bottom;
   2741     }
   2742 
   2743     if (m_floatingObjects) {
   2744         FloatingObject* r;
   2745         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2746         for ( ; (r = it.current()); ++it ) {
   2747             if (r->m_shouldPaint || r->m_renderer->hasSelfPaintingLayer()) {
   2748                 int lp = r->m_top + r->m_renderer->marginTop() + r->m_renderer->lowestPosition(false);
   2749                 bottom = max(bottom, lp + relativeOffset);
   2750             }
   2751         }
   2752     }
   2753 
   2754     if (!includeSelf) {
   2755         bottom = max(bottom, borderTop() + paddingTop() + paddingBottom() + relativeOffset);
   2756         if (childrenInline()) {
   2757             if (lastRootBox()) {
   2758                 int childBottomEdge = lastRootBox()->selectionBottom();
   2759                 bottom = max(bottom, childBottomEdge + paddingBottom() + relativeOffset);
   2760             }
   2761         } else {
   2762             // Find the last normal flow child.
   2763             RenderBox* currBox = lastChildBox();
   2764             while (currBox && currBox->isFloatingOrPositioned())
   2765                 currBox = currBox->previousSiblingBox();
   2766             if (currBox) {
   2767                 int childBottomEdge = currBox->y() + currBox->height() + currBox->collapsedMarginBottom();
   2768                 bottom = max(bottom, childBottomEdge + paddingBottom() + relativeOffset);
   2769             }
   2770         }
   2771     }
   2772 
   2773     return bottom;
   2774 }
   2775 
   2776 int RenderBlock::rightmostPosition(bool includeOverflowInterior, bool includeSelf) const
   2777 {
   2778     int right = includeSelf && height() > 0 ? width() : 0;
   2779 
   2780     if (!includeOverflowInterior && (hasOverflowClip() || hasControlClip()))
   2781         return right;
   2782 
   2783     if (!firstChild() && (!width() || !height()))
   2784         return right;
   2785 
   2786     if (!hasColumns()) {
   2787         // FIXME: Come up with a way to use the layer tree to avoid visiting all the kids.
   2788         // For now, we have to descend into all the children, since we may have a huge abs div inside
   2789         // a tiny rel div buried somewhere deep in our child tree.  In this case we have to get to
   2790         // the abs div.
   2791         for (RenderObject* c = firstChild(); c; c = c->nextSibling()) {
   2792             if (!c->isFloatingOrPositioned() && c->isBox()) {
   2793                 RenderBox* childBox = toRenderBox(c);
   2794                 right = max(right, childBox->x() + childBox->rightmostPosition(false));
   2795             }
   2796         }
   2797     }
   2798 
   2799     if (includeSelf && isRelPositioned())
   2800         right