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                                     (!next || (next->isAnonymousBlock() && next->childrenInline()));
    545     if (canDeleteAnonymousBlocks && prev && next) {
    546         // Take all the children out of the |next| block and put them in
    547         // the |prev| block.
    548         prev->setNeedsLayoutAndPrefWidthsRecalc();
    549         RenderBlock* nextBlock = toRenderBlock(next);
    550         RenderBlock* prevBlock = toRenderBlock(prev);
    551         nextBlock->moveAllChildrenTo(prevBlock, prevBlock->children());
    552         // Delete the now-empty block's lines and nuke it.
    553         nextBlock->deleteLineBoxTree();
    554         nextBlock->destroy();
    555     }
    556 
    557     RenderBox::removeChild(oldChild);
    558 
    559     RenderObject* child = prev ? prev : next;
    560     if (canDeleteAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && !isFlexibleBox()) {
    561         // The removal has knocked us down to containing only a single anonymous
    562         // box.  We can go ahead and pull the content right back up into our
    563         // box.
    564         setNeedsLayoutAndPrefWidthsRecalc();
    565         RenderBlock* anonBlock = toRenderBlock(children()->removeChildNode(this, child, false));
    566         setChildrenInline(true);
    567         anonBlock->moveAllChildrenTo(this, children());
    568         // Delete the now-empty block's lines and nuke it.
    569         anonBlock->deleteLineBoxTree();
    570         anonBlock->destroy();
    571     }
    572 
    573     // If this was our last child be sure to clear out our line boxes.
    574     if (childrenInline() && !firstChild())
    575         lineBoxes()->deleteLineBoxes(renderArena());
    576 }
    577 
    578 bool RenderBlock::isSelfCollapsingBlock() const
    579 {
    580     // We are not self-collapsing if we
    581     // (a) have a non-zero height according to layout (an optimization to avoid wasting time)
    582     // (b) are a table,
    583     // (c) have border/padding,
    584     // (d) have a min-height
    585     // (e) have specified that one of our margins can't collapse using a CSS extension
    586     if (height() > 0 ||
    587         isTable() || (borderBottom() + paddingBottom() + borderTop() + paddingTop()) != 0 ||
    588         style()->minHeight().isPositive() ||
    589         style()->marginTopCollapse() == MSEPARATE || style()->marginBottomCollapse() == MSEPARATE)
    590         return false;
    591 
    592     bool hasAutoHeight = style()->height().isAuto();
    593     if (style()->height().isPercent() && !style()->htmlHacks()) {
    594         hasAutoHeight = true;
    595         for (RenderBlock* cb = containingBlock(); !cb->isRenderView(); cb = cb->containingBlock()) {
    596             if (cb->style()->height().isFixed() || cb->isTableCell())
    597                 hasAutoHeight = false;
    598         }
    599     }
    600 
    601     // If the height is 0 or auto, then whether or not we are a self-collapsing block depends
    602     // on whether we have content that is all self-collapsing or not.
    603     if (hasAutoHeight || ((style()->height().isFixed() || style()->height().isPercent()) && style()->height().isZero())) {
    604         // If the block has inline children, see if we generated any line boxes.  If we have any
    605         // line boxes, then we can't be self-collapsing, since we have content.
    606         if (childrenInline())
    607             return !firstLineBox();
    608 
    609         // Whether or not we collapse is dependent on whether all our normal flow children
    610         // are also self-collapsing.
    611         for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
    612             if (child->isFloatingOrPositioned())
    613                 continue;
    614             if (!child->isSelfCollapsingBlock())
    615                 return false;
    616         }
    617         return true;
    618     }
    619     return false;
    620 }
    621 
    622 void RenderBlock::startDelayUpdateScrollInfo()
    623 {
    624     if (gDelayUpdateScrollInfo == 0) {
    625         ASSERT(!gDelayedUpdateScrollInfoSet);
    626         gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet;
    627     }
    628     ASSERT(gDelayedUpdateScrollInfoSet);
    629     ++gDelayUpdateScrollInfo;
    630 }
    631 
    632 void RenderBlock::finishDelayUpdateScrollInfo()
    633 {
    634     --gDelayUpdateScrollInfo;
    635     ASSERT(gDelayUpdateScrollInfo >= 0);
    636     if (gDelayUpdateScrollInfo == 0) {
    637         ASSERT(gDelayedUpdateScrollInfoSet);
    638 
    639         OwnPtr<DelayedUpdateScrollInfoSet> infoSet(gDelayedUpdateScrollInfoSet);
    640         gDelayedUpdateScrollInfoSet = 0;
    641 
    642         for (DelayedUpdateScrollInfoSet::iterator it = infoSet->begin(); it != infoSet->end(); ++it) {
    643             RenderBlock* block = *it;
    644             if (block->hasOverflowClip()) {
    645                 block->layer()->updateScrollInfoAfterLayout();
    646             }
    647         }
    648     }
    649 }
    650 
    651 void RenderBlock::updateScrollInfoAfterLayout()
    652 {
    653     if (hasOverflowClip()) {
    654         if (gDelayUpdateScrollInfo)
    655             gDelayedUpdateScrollInfoSet->add(this);
    656         else
    657             layer()->updateScrollInfoAfterLayout();
    658     }
    659 }
    660 
    661 void RenderBlock::layout()
    662 {
    663     // Update our first letter info now.
    664     updateFirstLetter();
    665 
    666     // Table cells call layoutBlock directly, so don't add any logic here.  Put code into
    667     // layoutBlock().
    668     layoutBlock(false);
    669 
    670     // It's safe to check for control clip here, since controls can never be table cells.
    671     // If we have a lightweight clip, there can never be any overflow from children.
    672     if (hasControlClip() && m_overflow)
    673         clearLayoutOverflow();
    674 }
    675 
    676 void RenderBlock::layoutBlock(bool relayoutChildren)
    677 {
    678     ASSERT(needsLayout());
    679 
    680     if (isInline() && !isInlineBlockOrInlineTable()) // Inline <form>s inside various table elements can
    681         return;                                      // cause us to come in here.  Just bail.
    682 
    683     if (!relayoutChildren && layoutOnlyPositionedObjects())
    684         return;
    685 
    686     LayoutRepainter repainter(*this, m_everHadLayout && checkForRepaintDuringLayout());
    687     LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection());
    688 
    689     int oldWidth = width();
    690     int oldColumnWidth = desiredColumnWidth();
    691 
    692 #ifdef ANDROID_LAYOUT
    693     int oldVisibleWidth = m_visibleWidth;
    694 #endif
    695 
    696     calcWidth();
    697     calcColumnWidth();
    698 
    699     m_overflow.clear();
    700 
    701     if (oldWidth != width() || oldColumnWidth != desiredColumnWidth())
    702         relayoutChildren = true;
    703 
    704 #ifdef ANDROID_LAYOUT
    705     const Settings* settings = document()->settings();
    706     ASSERT(settings);
    707     if (oldVisibleWidth != m_visibleWidth
    708             && settings->layoutAlgorithm() == Settings::kLayoutFitColumnToScreen)
    709         relayoutChildren = true;
    710 #endif
    711 
    712     clearFloats();
    713 
    714     int previousHeight = height();
    715     setHeight(0);
    716 
    717     // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track
    718     // our current maximal positive and negative margins.  These values are used when we
    719     // are collapsed with adjacent blocks, so for example, if you have block A and B
    720     // collapsing together, then you'd take the maximal positive margin from both A and B
    721     // and subtract it from the maximal negative margin from both A and B to get the
    722     // true collapsed margin.  This algorithm is recursive, so when we finish layout()
    723     // our block knows its current maximal positive/negative values.
    724     //
    725     // Start out by setting our margin values to our current margins.  Table cells have
    726     // no margins, so we don't fill in the values for table cells.
    727     bool isCell = isTableCell();
    728     if (!isCell) {
    729         initMaxMarginValues();
    730 
    731         setTopMarginQuirk(style()->marginTop().quirk());
    732         setBottomMarginQuirk(style()->marginBottom().quirk());
    733 
    734         Node* n = node();
    735         if (n && n->hasTagName(formTag) && static_cast<HTMLFormElement*>(n)->isMalformed()) {
    736             // See if this form is malformed (i.e., unclosed). If so, don't give the form
    737             // a bottom margin.
    738             setMaxBottomMargins(0, 0);
    739         }
    740     }
    741 
    742     // For overflow:scroll blocks, ensure we have both scrollbars in place always.
    743     if (scrollsOverflow()) {
    744         if (style()->overflowX() == OSCROLL)
    745             layer()->setHasHorizontalScrollbar(true);
    746         if (style()->overflowY() == OSCROLL)
    747             layer()->setHasVerticalScrollbar(true);
    748     }
    749 
    750     int repaintTop = 0;
    751     int repaintBottom = 0;
    752     int maxFloatBottom = 0;
    753     if (childrenInline())
    754         layoutInlineChildren(relayoutChildren, repaintTop, repaintBottom);
    755     else
    756         layoutBlockChildren(relayoutChildren, maxFloatBottom);
    757 
    758     // Expand our intrinsic height to encompass floats.
    759     int toAdd = borderBottom() + paddingBottom() + horizontalScrollbarHeight();
    760     if (floatBottom() > (height() - toAdd) && expandsToEncloseOverhangingFloats())
    761         setHeight(floatBottom() + toAdd);
    762 
    763     // Now lay out our columns within this intrinsic height, since they can slightly affect the intrinsic height as
    764     // we adjust for clean column breaks.
    765     int singleColumnBottom = layoutColumns();
    766 
    767     // Calculate our new height.
    768     int oldHeight = height();
    769     calcHeight();
    770     if (oldHeight != height()) {
    771         if (oldHeight > height() && maxFloatBottom > height() && !childrenInline()) {
    772             // One of our children's floats may have become an overhanging float for us. We need to look for it.
    773             for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
    774                 if (child->isBlockFlow() && !child->isFloatingOrPositioned()) {
    775                     RenderBlock* block = toRenderBlock(child);
    776                     if (block->floatBottom() + block->y() > height())
    777                         addOverhangingFloats(block, -block->x(), -block->y(), false);
    778                 }
    779             }
    780         }
    781 
    782         // We have to rebalance columns to the new height.
    783         layoutColumns(singleColumnBottom);
    784     }
    785 
    786     if (previousHeight != height())
    787         relayoutChildren = true;
    788 
    789     // It's weird that we're treating float information as normal flow overflow, but we do this because floatRect() isn't
    790     // able to be propagated up the render tree yet.  Overflow information is however.  This check is designed to catch anyone
    791     // who wasn't going to propagate float information up to the parent and yet could potentially be painted by its ancestor.
    792     if (isRoot() || expandsToEncloseOverhangingFloats())
    793         addOverflowFromFloats();
    794 
    795     // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway).
    796     if (!hasColumns()) {
    797         if (childrenInline())
    798             addOverflowFromInlineChildren();
    799         else
    800             addOverflowFromBlockChildren();
    801     }
    802 
    803     // Add visual overflow from box-shadow and reflections.
    804     addShadowOverflow();
    805 
    806     layoutPositionedObjects(relayoutChildren || isRoot());
    807 
    808     positionListMarker();
    809 
    810     statePusher.pop();
    811 
    812     // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
    813     // we overflow or not.
    814     updateScrollInfoAfterLayout();
    815 
    816     // Repaint with our new bounds if they are different from our old bounds.
    817     bool didFullRepaint = repainter.repaintAfterLayout();
    818     if (!didFullRepaint && repaintTop != repaintBottom && (style()->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) {
    819         int repaintLeft = min(leftVisualOverflow(), leftLayoutOverflow());
    820         int repaintRight = max(rightVisualOverflow(), rightLayoutOverflow());
    821         IntRect repaintRect(repaintLeft, repaintTop, repaintRight - repaintLeft, repaintBottom - repaintTop);
    822 
    823         // FIXME: Deal with multiple column repainting.  We have to split the repaint
    824         // rect up into multiple rects if it spans columns.
    825 
    826         repaintRect.inflate(maximalOutlineSize(PaintPhaseOutline));
    827 
    828         if (hasOverflowClip()) {
    829             // Adjust repaint rect for scroll offset
    830             int x = repaintRect.x();
    831             int y = repaintRect.y();
    832             layer()->subtractScrolledContentOffset(x, y);
    833             repaintRect.setX(x);
    834             repaintRect.setY(y);
    835 
    836             // Don't allow this rect to spill out of our overflow box.
    837             repaintRect.intersect(IntRect(0, 0, width(), height()));
    838         }
    839 
    840         // Make sure the rect is still non-empty after intersecting for overflow above
    841         if (!repaintRect.isEmpty()) {
    842             repaintRectangle(repaintRect); // We need to do a partial repaint of our content.
    843             if (hasReflection())
    844                 repaintRectangle(reflectedRect(repaintRect));
    845         }
    846     }
    847     setNeedsLayout(false);
    848 }
    849 
    850 void RenderBlock::addOverflowFromBlockChildren()
    851 {
    852     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
    853         if (!child->isFloatingOrPositioned())
    854             addOverflowFromChild(child);
    855     }
    856 }
    857 
    858 void RenderBlock::addOverflowFromFloats()
    859 {
    860     IntRect result;
    861     if (!m_floatingObjects)
    862         return;
    863     FloatingObject* r;
    864     DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
    865     for (; (r = it.current()); ++it) {
    866         if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer())
    867             addOverflowFromChild(r->m_renderer, IntSize(r->m_left + r->m_renderer->marginLeft(), r->m_top + r->m_renderer->marginTop()));
    868     }
    869     return;
    870 }
    871 
    872 bool RenderBlock::expandsToEncloseOverhangingFloats() const
    873 {
    874     return isInlineBlockOrInlineTable() || isFloatingOrPositioned() || hasOverflowClip() || (parent() && parent()->isFlexibleBox()) || hasColumns() || isTableCell() || isFieldset();
    875 }
    876 
    877 void RenderBlock::adjustPositionedBlock(RenderBox* child, const MarginInfo& marginInfo)
    878 {
    879     if (child->style()->hasStaticX()) {
    880         if (style()->direction() == LTR)
    881             child->layer()->setStaticX(borderLeft() + paddingLeft());
    882         else
    883             child->layer()->setStaticX(borderRight() + paddingRight());
    884     }
    885 
    886     if (child->style()->hasStaticY()) {
    887         int y = height();
    888         if (!marginInfo.canCollapseWithTop()) {
    889             child->calcVerticalMargins();
    890             int marginTop = child->marginTop();
    891             int collapsedTopPos = marginInfo.posMargin();
    892             int collapsedTopNeg = marginInfo.negMargin();
    893             if (marginTop > 0) {
    894                 if (marginTop > collapsedTopPos)
    895                     collapsedTopPos = marginTop;
    896             } else {
    897                 if (-marginTop > collapsedTopNeg)
    898                     collapsedTopNeg = -marginTop;
    899             }
    900             y += (collapsedTopPos - collapsedTopNeg) - marginTop;
    901         }
    902         RenderLayer* childLayer = child->layer();
    903         if (childLayer->staticY() != y) {
    904             child->layer()->setStaticY(y);
    905             child->setChildNeedsLayout(true, false);
    906         }
    907     }
    908 }
    909 
    910 void RenderBlock::adjustFloatingBlock(const MarginInfo& marginInfo)
    911 {
    912     // The float should be positioned taking into account the bottom margin
    913     // of the previous flow.  We add that margin into the height, get the
    914     // float positioned properly, and then subtract the margin out of the
    915     // height again.  In the case of self-collapsing blocks, we always just
    916     // use the top margins, since the self-collapsing block collapsed its
    917     // own bottom margin into its top margin.
    918     //
    919     // Note also that the previous flow may collapse its margin into the top of
    920     // our block.  If this is the case, then we do not add the margin in to our
    921     // height when computing the position of the float.   This condition can be tested
    922     // for by simply calling canCollapseWithTop.  See
    923     // http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html for
    924     // an example of this scenario.
    925     int marginOffset = marginInfo.canCollapseWithTop() ? 0 : marginInfo.margin();
    926     setHeight(height() + marginOffset);
    927     positionNewFloats();
    928     setHeight(height() - marginOffset);
    929 }
    930 
    931 bool RenderBlock::handleSpecialChild(RenderBox* child, const MarginInfo& marginInfo)
    932 {
    933     // Handle in the given order
    934     return handlePositionedChild(child, marginInfo)
    935         || handleFloatingChild(child, marginInfo)
    936         || handleRunInChild(child);
    937 }
    938 
    939 
    940 bool RenderBlock::handlePositionedChild(RenderBox* child, const MarginInfo& marginInfo)
    941 {
    942     if (child->isPositioned()) {
    943         child->containingBlock()->insertPositionedObject(child);
    944         adjustPositionedBlock(child, marginInfo);
    945         return true;
    946     }
    947     return false;
    948 }
    949 
    950 bool RenderBlock::handleFloatingChild(RenderBox* child, const MarginInfo& marginInfo)
    951 {
    952     if (child->isFloating()) {
    953         insertFloatingObject(child);
    954         adjustFloatingBlock(marginInfo);
    955         return true;
    956     }
    957     return false;
    958 }
    959 
    960 bool RenderBlock::handleRunInChild(RenderBox* child)
    961 {
    962     // See if we have a run-in element with inline children.  If the
    963     // children aren't inline, then just treat the run-in as a normal
    964     // block.
    965     if (!child->isRunIn() || !child->childrenInline())
    966         return false;
    967     // FIXME: We don't handle non-block elements with run-in for now.
    968     if (!child->isRenderBlock())
    969         return false;
    970 
    971     // Get the next non-positioned/non-floating RenderBlock.
    972     RenderBlock* blockRunIn = toRenderBlock(child);
    973     RenderObject* curr = blockRunIn->nextSibling();
    974     while (curr && curr->isFloatingOrPositioned())
    975         curr = curr->nextSibling();
    976 
    977     if (!curr || !curr->isRenderBlock() || !curr->childrenInline() || curr->isRunIn() || curr->isAnonymous())
    978         return false;
    979 
    980     RenderBlock* currBlock = toRenderBlock(curr);
    981 
    982     // Remove the old child.
    983     children()->removeChildNode(this, blockRunIn);
    984 
    985     // Create an inline.
    986     Node* runInNode = blockRunIn->node();
    987     RenderInline* inlineRunIn = new (renderArena()) RenderInline(runInNode ? runInNode : document());
    988     inlineRunIn->setStyle(blockRunIn->style());
    989 
    990     bool runInIsGenerated = child->style()->styleType() == BEFORE || child->style()->styleType() == AFTER;
    991 
    992     // Move the nodes from the old child to the new child, but skip any :before/:after content.  It has already
    993     // been regenerated by the new inline.
    994     for (RenderObject* runInChild = blockRunIn->firstChild(); runInChild; runInChild = runInChild->nextSibling()) {
    995         if (runInIsGenerated || (runInChild->style()->styleType() != BEFORE && runInChild->style()->styleType() != AFTER)) {
    996             blockRunIn->children()->removeChildNode(blockRunIn, runInChild, false);
    997             inlineRunIn->addChild(runInChild); // Use addChild instead of appendChildNode since it handles correct placement of the children relative to :after-generated content.
    998         }
    999     }
   1000 
   1001     // Now insert the new child under |currBlock|.
   1002     currBlock->children()->insertChildNode(currBlock, inlineRunIn, currBlock->firstChild());
   1003 
   1004     // If the run-in had an element, we need to set the new renderer.
   1005     if (runInNode)
   1006         runInNode->setRenderer(inlineRunIn);
   1007 
   1008     // Destroy the block run-in.
   1009     blockRunIn->destroy();
   1010 
   1011     // The block acts like an inline, so just null out its
   1012     // position.
   1013 
   1014     return true;
   1015 }
   1016 
   1017 int RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo)
   1018 {
   1019     // Get our max pos and neg top margins.
   1020     int posTop = child->maxTopMargin(true);
   1021     int negTop = child->maxTopMargin(false);
   1022 
   1023     // For self-collapsing blocks, collapse our bottom margins into our
   1024     // top to get new posTop and negTop values.
   1025     if (child->isSelfCollapsingBlock()) {
   1026         posTop = max(posTop, child->maxBottomMargin(true));
   1027         negTop = max(negTop, child->maxBottomMargin(false));
   1028     }
   1029 
   1030     // See if the top margin is quirky. We only care if this child has
   1031     // margins that will collapse with us.
   1032     bool topQuirk = child->isTopMarginQuirk() || style()->marginTopCollapse() == MDISCARD;
   1033 
   1034     if (marginInfo.canCollapseWithTop()) {
   1035         // This child is collapsing with the top of the
   1036         // block.  If it has larger margin values, then we need to update
   1037         // our own maximal values.
   1038         if (!style()->htmlHacks() || !marginInfo.quirkContainer() || !topQuirk)
   1039             setMaxTopMargins(max(posTop, maxTopPosMargin()), max(negTop, maxTopNegMargin()));
   1040 
   1041         // The minute any of the margins involved isn't a quirk, don't
   1042         // collapse it away, even if the margin is smaller (www.webreference.com
   1043         // has an example of this, a <dt> with 0.8em author-specified inside
   1044         // a <dl> inside a <td>.
   1045         if (!marginInfo.determinedTopQuirk() && !topQuirk && (posTop-negTop)) {
   1046             setTopMarginQuirk(false);
   1047             marginInfo.setDeterminedTopQuirk(true);
   1048         }
   1049 
   1050         if (!marginInfo.determinedTopQuirk() && topQuirk && marginTop() == 0)
   1051             // We have no top margin and our top child has a quirky margin.
   1052             // We will pick up this quirky margin and pass it through.
   1053             // This deals with the <td><div><p> case.
   1054             // Don't do this for a block that split two inlines though.  You do
   1055             // still apply margins in this case.
   1056             setTopMarginQuirk(true);
   1057     }
   1058 
   1059     if (marginInfo.quirkContainer() && marginInfo.atTopOfBlock() && (posTop - negTop))
   1060         marginInfo.setTopQuirk(topQuirk);
   1061 
   1062     int ypos = height();
   1063     if (child->isSelfCollapsingBlock()) {
   1064         // This child has no height.  We need to compute our
   1065         // position before we collapse the child's margins together,
   1066         // so that we can get an accurate position for the zero-height block.
   1067         int collapsedTopPos = max(marginInfo.posMargin(), child->maxTopMargin(true));
   1068         int collapsedTopNeg = max(marginInfo.negMargin(), child->maxTopMargin(false));
   1069         marginInfo.setMargin(collapsedTopPos, collapsedTopNeg);
   1070 
   1071         // Now collapse the child's margins together, which means examining our
   1072         // bottom margin values as well.
   1073         marginInfo.setPosMarginIfLarger(child->maxBottomMargin(true));
   1074         marginInfo.setNegMarginIfLarger(child->maxBottomMargin(false));
   1075 
   1076         if (!marginInfo.canCollapseWithTop())
   1077             // We need to make sure that the position of the self-collapsing block
   1078             // is correct, since it could have overflowing content
   1079             // that needs to be positioned correctly (e.g., a block that
   1080             // had a specified height of 0 but that actually had subcontent).
   1081             ypos = height() + collapsedTopPos - collapsedTopNeg;
   1082     }
   1083     else {
   1084         if (child->style()->marginTopCollapse() == MSEPARATE) {
   1085             setHeight(height() + marginInfo.margin() + child->marginTop());
   1086             ypos = height();
   1087         }
   1088         else if (!marginInfo.atTopOfBlock() ||
   1089             (!marginInfo.canCollapseTopWithChildren()
   1090              && (!style()->htmlHacks() || !marginInfo.quirkContainer() || !marginInfo.topQuirk()))) {
   1091             // We're collapsing with a previous sibling's margins and not
   1092             // with the top of the block.
   1093             setHeight(height() + max(marginInfo.posMargin(), posTop) - max(marginInfo.negMargin(), negTop));
   1094             ypos = height();
   1095         }
   1096 
   1097         marginInfo.setPosMargin(child->maxBottomMargin(true));
   1098         marginInfo.setNegMargin(child->maxBottomMargin(false));
   1099 
   1100         if (marginInfo.margin())
   1101             marginInfo.setBottomQuirk(child->isBottomMarginQuirk() || style()->marginBottomCollapse() == MDISCARD);
   1102     }
   1103 
   1104     return ypos;
   1105 }
   1106 
   1107 int RenderBlock::clearFloatsIfNeeded(RenderBox* child, MarginInfo& marginInfo, int oldTopPosMargin, int oldTopNegMargin, int yPos)
   1108 {
   1109     int heightIncrease = getClearDelta(child, yPos);
   1110     if (!heightIncrease)
   1111         return yPos;
   1112 
   1113     if (child->isSelfCollapsingBlock()) {
   1114         // For self-collapsing blocks that clear, they can still collapse their
   1115         // margins with following siblings.  Reset the current margins to represent
   1116         // the self-collapsing block's margins only.
   1117         // CSS2.1 states:
   1118         // "An element that has had clearance applied to it never collapses its top margin with its parent block's bottom margin.
   1119         // Therefore if we are at the bottom of the block, let's go ahead and reset margins to only include the
   1120         // self-collapsing block's bottom margin.
   1121         bool atBottomOfBlock = true;
   1122         for (RenderBox* curr = child->nextSiblingBox(); curr && atBottomOfBlock; curr = curr->nextSiblingBox()) {
   1123             if (!curr->isFloatingOrPositioned())
   1124                 atBottomOfBlock = false;
   1125         }
   1126         if (atBottomOfBlock) {
   1127             marginInfo.setPosMargin(child->maxBottomMargin(true));
   1128             marginInfo.setNegMargin(child->maxBottomMargin(false));
   1129         } else {
   1130             marginInfo.setPosMargin(max(child->maxTopMargin(true), child->maxBottomMargin(true)));
   1131             marginInfo.setNegMargin(max(child->maxTopMargin(false), child->maxBottomMargin(false)));
   1132         }
   1133 
   1134         // Adjust our height such that we are ready to be collapsed with subsequent siblings (or the bottom
   1135         // of the parent block).
   1136         setHeight(child->y() - max(0, marginInfo.margin()));
   1137     } else
   1138         // Increase our height by the amount we had to clear.
   1139         setHeight(height() + heightIncrease);
   1140 
   1141     if (marginInfo.canCollapseWithTop()) {
   1142         // We can no longer collapse with the top of the block since a clear
   1143         // occurred.  The empty blocks collapse into the cleared block.
   1144         // FIXME: This isn't quite correct.  Need clarification for what to do
   1145         // if the height the cleared block is offset by is smaller than the
   1146         // margins involved.
   1147         setMaxTopMargins(oldTopPosMargin, oldTopNegMargin);
   1148         marginInfo.setAtTopOfBlock(false);
   1149     }
   1150 
   1151     return yPos + heightIncrease;
   1152 }
   1153 
   1154 int RenderBlock::estimateVerticalPosition(RenderBox* child, const MarginInfo& marginInfo)
   1155 {
   1156     // FIXME: We need to eliminate the estimation of vertical position, because when it's wrong we sometimes trigger a pathological
   1157     // relayout if there are intruding floats.
   1158     int yPosEstimate = height();
   1159     if (!marginInfo.canCollapseWithTop()) {
   1160         int childMarginTop = child->selfNeedsLayout() ? child->marginTop() : child->collapsedMarginTop();
   1161         yPosEstimate += max(marginInfo.margin(), childMarginTop);
   1162     }
   1163     yPosEstimate += getClearDelta(child, yPosEstimate);
   1164     return yPosEstimate;
   1165 }
   1166 
   1167 void RenderBlock::determineHorizontalPosition(RenderBox* child)
   1168 {
   1169     if (style()->direction() == LTR) {
   1170         int xPos = borderLeft() + paddingLeft();
   1171 
   1172         // Add in our left margin.
   1173         int chPos = xPos + child->marginLeft();
   1174 
   1175         // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats.  They need
   1176         // to shift over as necessary to dodge any floats that might get in the way.
   1177         if (child->avoidsFloats()) {
   1178             int leftOff = leftOffset(height(), false);
   1179             if (style()->textAlign() != WEBKIT_CENTER && child->style()->marginLeft().type() != Auto) {
   1180                 if (child->marginLeft() < 0)
   1181                     leftOff += child->marginLeft();
   1182                 chPos = max(chPos, leftOff); // Let the float sit in the child's margin if it can fit.
   1183             }
   1184             else if (leftOff != xPos) {
   1185                 // The object is shifting right. The object might be centered, so we need to
   1186                 // recalculate our horizontal margins. Note that the containing block content
   1187                 // width computation will take into account the delta between |leftOff| and |xPos|
   1188                 // so that we can just pass the content width in directly to the |calcHorizontalMargins|
   1189                 // function.
   1190                 child->calcHorizontalMargins(child->style()->marginLeft(), child->style()->marginRight(), lineWidth(child->y(), false));
   1191                 chPos = leftOff + child->marginLeft();
   1192             }
   1193         }
   1194         view()->addLayoutDelta(IntSize(child->x() - chPos, 0));
   1195         child->setLocation(chPos, child->y());
   1196     } else {
   1197         int xPos = width() - borderRight() - paddingRight() - verticalScrollbarWidth();
   1198         int chPos = xPos - (child->width() + child->marginRight());
   1199         if (child->avoidsFloats()) {
   1200             int rightOff = rightOffset(height(), false);
   1201             if (style()->textAlign() != WEBKIT_CENTER && child->style()->marginRight().type() != Auto) {
   1202                 if (child->marginRight() < 0)
   1203                     rightOff -= child->marginRight();
   1204                 chPos = min(chPos, rightOff - child->width()); // Let the float sit in the child's margin if it can fit.
   1205             } else if (rightOff != xPos) {
   1206                 // The object is shifting left. The object might be centered, so we need to
   1207                 // recalculate our horizontal margins. Note that the containing block content
   1208                 // width computation will take into account the delta between |rightOff| and |xPos|
   1209                 // so that we can just pass the content width in directly to the |calcHorizontalMargins|
   1210                 // function.
   1211                 child->calcHorizontalMargins(child->style()->marginLeft(), child->style()->marginRight(), lineWidth(child->y(), false));
   1212                 chPos = rightOff - child->marginRight() - child->width();
   1213             }
   1214         }
   1215         view()->addLayoutDelta(IntSize(child->x() - chPos, 0));
   1216         child->setLocation(chPos, child->y());
   1217     }
   1218 }
   1219 
   1220 void RenderBlock::setCollapsedBottomMargin(const MarginInfo& marginInfo)
   1221 {
   1222     if (marginInfo.canCollapseWithBottom() && !marginInfo.canCollapseWithTop()) {
   1223         // Update our max pos/neg bottom margins, since we collapsed our bottom margins
   1224         // with our children.
   1225         setMaxBottomMargins(max(maxBottomPosMargin(), marginInfo.posMargin()), max(maxBottomNegMargin(), marginInfo.negMargin()));
   1226 
   1227         if (!marginInfo.bottomQuirk())
   1228             setBottomMarginQuirk(false);
   1229 
   1230         if (marginInfo.bottomQuirk() && marginBottom() == 0)
   1231             // We have no bottom margin and our last child has a quirky margin.
   1232             // We will pick up this quirky margin and pass it through.
   1233             // This deals with the <td><div><p> case.
   1234             setBottomMarginQuirk(true);
   1235     }
   1236 }
   1237 
   1238 void RenderBlock::handleBottomOfBlock(int top, int bottom, MarginInfo& marginInfo)
   1239 {
   1240     marginInfo.setAtBottomOfBlock(true);
   1241 
   1242     // If we can't collapse with children then go ahead and add in the bottom margin.
   1243     if (!marginInfo.canCollapseWithBottom() && !marginInfo.canCollapseWithTop()
   1244         && (!style()->htmlHacks() || !marginInfo.quirkContainer() || !marginInfo.bottomQuirk()))
   1245         setHeight(height() + marginInfo.margin());
   1246 
   1247     // Now add in our bottom border/padding.
   1248     setHeight(height() + bottom);
   1249 
   1250     // Negative margins can cause our height to shrink below our minimal height (border/padding).
   1251     // If this happens, ensure that the computed height is increased to the minimal height.
   1252     setHeight(max(height(), top + bottom));
   1253 
   1254     // Update our bottom collapsed margin info.
   1255     setCollapsedBottomMargin(marginInfo);
   1256 }
   1257 
   1258 void RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatBottom)
   1259 {
   1260     if (gPercentHeightDescendantsMap) {
   1261         if (HashSet<RenderBox*>* descendants = gPercentHeightDescendantsMap->get(this)) {
   1262             HashSet<RenderBox*>::iterator end = descendants->end();
   1263             for (HashSet<RenderBox*>::iterator it = descendants->begin(); it != end; ++it) {
   1264                 RenderBox* box = *it;
   1265                 while (box != this) {
   1266                     if (box->normalChildNeedsLayout())
   1267                         break;
   1268                     box->setChildNeedsLayout(true, false);
   1269                     box = box->containingBlock();
   1270                     ASSERT(box);
   1271                     if (!box)
   1272                         break;
   1273                 }
   1274             }
   1275         }
   1276     }
   1277 
   1278     int top = borderTop() + paddingTop();
   1279     int bottom = borderBottom() + paddingBottom() + horizontalScrollbarHeight();
   1280 
   1281     setHeight(top);
   1282 
   1283     // The margin struct caches all our current margin collapsing state.  The compact struct caches state when we encounter compacts,
   1284     MarginInfo marginInfo(this, top, bottom);
   1285 
   1286     // Fieldsets need to find their legend and position it inside the border of the object.
   1287     // The legend then gets skipped during normal layout.
   1288     RenderObject* legend = layoutLegend(relayoutChildren);
   1289 
   1290     int previousFloatBottom = 0;
   1291     maxFloatBottom = 0;
   1292 
   1293     RenderBox* next = firstChildBox();
   1294 
   1295     while (next) {
   1296         RenderBox* child = next;
   1297         next = child->nextSiblingBox();
   1298 
   1299         if (legend == child)
   1300             continue; // Skip the legend, since it has already been positioned up in the fieldset's border.
   1301 
   1302         // Make sure we layout children if they need it.
   1303         // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into
   1304         // an auto value.  Add a method to determine this, so that we can avoid the relayout.
   1305         if (relayoutChildren || ((child->style()->height().isPercent() || child->style()->minHeight().isPercent() || child->style()->maxHeight().isPercent()) && !isRenderView()))
   1306             child->setChildNeedsLayout(true, false);
   1307 
   1308         // If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths.
   1309         if (relayoutChildren && (child->style()->paddingLeft().isPercent() || child->style()->paddingRight().isPercent()))
   1310             child->setPrefWidthsDirty(true, false);
   1311 
   1312         // Handle the four types of special elements first.  These include positioned content, floating content, compacts and
   1313         // run-ins.  When we encounter these four types of objects, we don't actually lay them out as normal flow blocks.
   1314         if (handleSpecialChild(child, marginInfo))
   1315             continue;
   1316 
   1317         // Lay out the child.
   1318         layoutBlockChild(child, marginInfo, previousFloatBottom, maxFloatBottom);
   1319     }
   1320 
   1321     // Now do the handling of the bottom of the block, adding in our bottom border/padding and
   1322     // determining the correct collapsed bottom margin information.
   1323     handleBottomOfBlock(top, bottom, marginInfo);
   1324 }
   1325 
   1326 void RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, int& previousFloatBottom, int& maxFloatBottom)
   1327 {
   1328     int oldTopPosMargin = maxTopPosMargin();
   1329     int oldTopNegMargin = maxTopNegMargin();
   1330 
   1331     // The child is a normal flow object.  Compute its vertical margins now.
   1332     child->calcVerticalMargins();
   1333 
   1334     // Do not allow a collapse if the margin top collapse style is set to SEPARATE.
   1335     if (child->style()->marginTopCollapse() == MSEPARATE) {
   1336         marginInfo.setAtTopOfBlock(false);
   1337         marginInfo.clearMargin();
   1338     }
   1339 
   1340     // Try to guess our correct y position.  In most cases this guess will
   1341     // be correct.  Only if we're wrong (when we compute the real y position)
   1342     // will we have to potentially relayout.
   1343     int yPosEstimate = estimateVerticalPosition(child, marginInfo);
   1344 
   1345     // Cache our old rect so that we can dirty the proper repaint rects if the child moves.
   1346     IntRect oldRect(child->x(), child->y() , child->width(), child->height());
   1347 #ifndef NDEBUG
   1348     IntSize oldLayoutDelta = view()->layoutDelta();
   1349 #endif
   1350     // Go ahead and position the child as though it didn't collapse with the top.
   1351     view()->addLayoutDelta(IntSize(0, child->y() - yPosEstimate));
   1352     child->setLocation(child->x(), yPosEstimate);
   1353 
   1354     bool markDescendantsWithFloats = false;
   1355     if (yPosEstimate != oldRect.y() && !child->avoidsFloats() && child->isBlockFlow() && toRenderBlock(child)->containsFloats())
   1356         markDescendantsWithFloats = true;
   1357     else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) {
   1358         // If an element might be affected by the presence of floats, then always mark it for
   1359         // layout.
   1360         int fb = max(previousFloatBottom, floatBottom());
   1361         if (fb > yPosEstimate)
   1362             markDescendantsWithFloats = true;
   1363     }
   1364 
   1365     if (child->isRenderBlock()) {
   1366         if (markDescendantsWithFloats)
   1367             toRenderBlock(child)->markAllDescendantsWithFloatsForLayout();
   1368 
   1369         previousFloatBottom = max(previousFloatBottom, oldRect.y() + toRenderBlock(child)->floatBottom());
   1370     }
   1371 
   1372     bool childHadLayout = child->m_everHadLayout;
   1373     bool childNeededLayout = child->needsLayout();
   1374     if (childNeededLayout)
   1375         child->layout();
   1376 
   1377     // Now determine the correct ypos based off examination of collapsing margin
   1378     // values.
   1379     int yBeforeClear = collapseMargins(child, marginInfo);
   1380 
   1381     // Now check for clear.
   1382     int yAfterClear = clearFloatsIfNeeded(child, marginInfo, oldTopPosMargin, oldTopNegMargin, yBeforeClear);
   1383 
   1384     view()->addLayoutDelta(IntSize(0, yPosEstimate - yAfterClear));
   1385     child->setLocation(child->x(), yAfterClear);
   1386 
   1387     // Now we have a final y position.  See if it really does end up being different from our estimate.
   1388     if (yAfterClear != yPosEstimate) {
   1389         if (child->shrinkToAvoidFloats()) {
   1390             // The child's width depends on the line width.
   1391             // When the child shifts to clear an item, its width can
   1392             // change (because it has more available line width).
   1393             // So go ahead and mark the item as dirty.
   1394             child->setChildNeedsLayout(true, false);
   1395         }
   1396         if (!child->avoidsFloats() && child->isBlockFlow() && toRenderBlock(child)->containsFloats())
   1397             toRenderBlock(child)->markAllDescendantsWithFloatsForLayout();
   1398         // Our guess was wrong. Make the child lay itself out again.
   1399         child->layoutIfNeeded();
   1400     }
   1401 
   1402     // We are no longer at the top of the block if we encounter a non-empty child.
   1403     // This has to be done after checking for clear, so that margins can be reset if a clear occurred.
   1404     if (marginInfo.atTopOfBlock() && !child->isSelfCollapsingBlock())
   1405         marginInfo.setAtTopOfBlock(false);
   1406 
   1407     // Now place the child in the correct horizontal position
   1408     determineHorizontalPosition(child);
   1409 
   1410     // Update our height now that the child has been placed in the correct position.
   1411     setHeight(height() + child->height());
   1412     if (child->style()->marginBottomCollapse() == MSEPARATE) {
   1413         setHeight(height() + child->marginBottom());
   1414         marginInfo.clearMargin();
   1415     }
   1416     // If the child has overhanging floats that intrude into following siblings (or possibly out
   1417     // of this block), then the parent gets notified of the floats now.
   1418     if (child->isBlockFlow() && toRenderBlock(child)->containsFloats())
   1419         maxFloatBottom = max(maxFloatBottom, addOverhangingFloats(toRenderBlock(child), -child->x(), -child->y(), !childNeededLayout));
   1420 
   1421     IntSize childOffset(child->x() - oldRect.x(), child->y() - oldRect.y());
   1422     if (childOffset.width() || childOffset.height()) {
   1423         view()->addLayoutDelta(childOffset);
   1424 
   1425         // If the child moved, we have to repaint it as well as any floating/positioned
   1426         // descendants.  An exception is if we need a layout.  In this case, we know we're going to
   1427         // repaint ourselves (and the child) anyway.
   1428         if (childHadLayout && !selfNeedsLayout() && child->checkForRepaintDuringLayout())
   1429             child->repaintDuringLayoutIfMoved(oldRect);
   1430     }
   1431 
   1432     if (!childHadLayout && child->checkForRepaintDuringLayout()) {
   1433         child->repaint();
   1434         child->repaintOverhangingFloats(true);
   1435     }
   1436 
   1437     ASSERT(oldLayoutDelta == view()->layoutDelta());
   1438 }
   1439 
   1440 bool RenderBlock::layoutOnlyPositionedObjects()
   1441 {
   1442     if (!posChildNeedsLayout() || normalChildNeedsLayout() || selfNeedsLayout())
   1443         return false;
   1444 
   1445     LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection());
   1446 
   1447     if (needsPositionedMovementLayout()) {
   1448         tryLayoutDoingPositionedMovementOnly();
   1449         if (needsLayout())
   1450             return false;
   1451     }
   1452 
   1453     // All we have to is lay out our positioned objects.
   1454     layoutPositionedObjects(false);
   1455 
   1456     statePusher.pop();
   1457 
   1458     updateScrollInfoAfterLayout();
   1459 
   1460 #ifdef ANDROID_FIX
   1461     // iframe flatten will call FrameView::layout() which calls performPostLayoutTasks,
   1462     // which may make us need to layout again
   1463     if (!posChildNeedsLayout() || normalChildNeedsLayout() || selfNeedsLayout())
   1464         return false;
   1465 #endif
   1466 
   1467     setNeedsLayout(false);
   1468     return true;
   1469 }
   1470 
   1471 void RenderBlock::layoutPositionedObjects(bool relayoutChildren)
   1472 {
   1473     if (m_positionedObjects) {
   1474         RenderBox* r;
   1475         Iterator end = m_positionedObjects->end();
   1476         for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
   1477             r = *it;
   1478             // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the
   1479             // non-positioned block.  Rather than trying to detect all of these movement cases, we just always lay out positioned
   1480             // objects that are positioned implicitly like this.  Such objects are rare, and so in typical DHTML menu usage (where everything is
   1481             // positioned explicitly) this should not incur a performance penalty.
   1482             if (relayoutChildren || (r->style()->hasStaticY() && r->parent() != this && r->parent()->isBlockFlow()))
   1483                 r->setChildNeedsLayout(true, false);
   1484 
   1485             // If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths.
   1486             //if (relayoutChildren && (r->style()->paddingLeft().isPercent() || r->style()->paddingRight().isPercent()))
   1487                 r->setPrefWidthsDirty(true, false);
   1488 
   1489             // 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
   1490             // and we hit the available width constraint, the layoutIfNeeded() will catch it and do a full layout.
   1491             if (r->needsPositionedMovementLayoutOnly())
   1492                 r->tryLayoutDoingPositionedMovementOnly();
   1493             r->layoutIfNeeded();
   1494         }
   1495     }
   1496 }
   1497 
   1498 void RenderBlock::markPositionedObjectsForLayout()
   1499 {
   1500     if (m_positionedObjects) {
   1501         RenderBox* r;
   1502         Iterator end = m_positionedObjects->end();
   1503         for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
   1504             r = *it;
   1505             r->setChildNeedsLayout(true);
   1506         }
   1507     }
   1508 }
   1509 
   1510 void RenderBlock::repaintOverhangingFloats(bool paintAllDescendants)
   1511 {
   1512     // Repaint any overhanging floats (if we know we're the one to paint them).
   1513     if (hasOverhangingFloats()) {
   1514         // We think that we must be in a bad state if m_floatingObjects is nil at this point, so
   1515         // we assert on Debug builds and nil-check Release builds.
   1516         ASSERT(m_floatingObjects);
   1517         if (!m_floatingObjects)
   1518             return;
   1519 
   1520         FloatingObject* r;
   1521         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   1522 
   1523         // FIXME: Avoid disabling LayoutState. At the very least, don't disable it for floats originating
   1524         // in this block. Better yet would be to push extra state for the containers of other floats.
   1525         view()->disableLayoutState();
   1526         for ( ; (r = it.current()); ++it) {
   1527             // Only repaint the object if it is overhanging, is not in its own layer, and
   1528             // is our responsibility to paint (m_shouldPaint is set). When paintAllDescendants is true, the latter
   1529             // condition is replaced with being a descendant of us.
   1530             if (r->m_bottom > height() && ((paintAllDescendants && r->m_renderer->isDescendantOf(this)) || r->m_shouldPaint) && !r->m_renderer->hasSelfPaintingLayer()) {
   1531                 r->m_renderer->repaint();
   1532                 r->m_renderer->repaintOverhangingFloats();
   1533             }
   1534         }
   1535         view()->enableLayoutState();
   1536     }
   1537 }
   1538 
   1539 void RenderBlock::paint(PaintInfo& paintInfo, int tx, int ty)
   1540 {
   1541     tx += x();
   1542     ty += y();
   1543 
   1544     PaintPhase phase = paintInfo.phase;
   1545 
   1546     // Check if we need to do anything at all.
   1547     // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
   1548     // paints the root's background.
   1549     if (!isRoot()) {
   1550         IntRect overflowBox = visibleOverflowRect();
   1551         overflowBox.inflate(maximalOutlineSize(paintInfo.phase));
   1552         overflowBox.move(tx, ty);
   1553         if (!overflowBox.intersects(paintInfo.rect))
   1554             return;
   1555     }
   1556 
   1557     bool pushedClip = pushContentsClip(paintInfo, tx, ty);
   1558     paintObject(paintInfo, tx, ty);
   1559     if (pushedClip)
   1560         popContentsClip(paintInfo, phase, tx, ty);
   1561 
   1562     // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
   1563     // z-index.  We paint after we painted the background/border, so that the scrollbars will
   1564     // sit above the background/border.
   1565     if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && shouldPaintWithinRoot(paintInfo))
   1566         layer()->paintOverflowControls(paintInfo.context, tx, ty, paintInfo.rect);
   1567 }
   1568 
   1569 void RenderBlock::paintColumnRules(PaintInfo& paintInfo, int tx, int ty)
   1570 {
   1571     const Color& ruleColor = style()->columnRuleColor();
   1572     bool ruleTransparent = style()->columnRuleIsTransparent();
   1573     EBorderStyle ruleStyle = style()->columnRuleStyle();
   1574     int ruleWidth = style()->columnRuleWidth();
   1575     int colGap = columnGap();
   1576     bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent && ruleWidth <= colGap;
   1577     if (!renderRule)
   1578         return;
   1579 
   1580     // We need to do multiple passes, breaking up our child painting into strips.
   1581     int currXOffset = 0;
   1582     int ruleAdd = borderLeft() + paddingLeft();
   1583     int ruleX = 0;
   1584     Vector<IntRect>* colRects = columnRects();
   1585     unsigned colCount = colRects->size();
   1586     for (unsigned i = 0; i < colCount; i++) {
   1587         // For each rect, we clip to the rect, and then we adjust our coords.
   1588         IntRect colRect = colRects->at(i);
   1589 
   1590         // Move to the next position.
   1591         if (style()->direction() == LTR) {
   1592             ruleX += colRect.width() + colGap / 2;
   1593             currXOffset += colRect.width() + colGap;
   1594         } else {
   1595             ruleX -= (colRect.width() + colGap / 2);
   1596             currXOffset -= (colRect.width() + colGap);
   1597         }
   1598 
   1599         // Now paint the column rule.
   1600         if (i < colCount - 1) {
   1601             int ruleStart = tx + ruleX - ruleWidth / 2 + ruleAdd;
   1602             int ruleEnd = ruleStart + ruleWidth;
   1603             int ruleTop = ty + borderTop() + paddingTop();
   1604             int ruleBottom = ruleTop + contentHeight();
   1605             drawLineForBoxSide(paintInfo.context, ruleStart, ruleTop, ruleEnd, ruleBottom,
   1606                                style()->direction() == LTR ? BSLeft : BSRight, ruleColor, style()->color(), ruleStyle, 0, 0);
   1607         }
   1608 
   1609         ruleX = currXOffset;
   1610     }
   1611 }
   1612 
   1613 void RenderBlock::paintColumnContents(PaintInfo& paintInfo, int tx, int ty, bool paintingFloats)
   1614 {
   1615     // We need to do multiple passes, breaking up our child painting into strips.
   1616     GraphicsContext* context = paintInfo.context;
   1617     int currXOffset = 0;
   1618     int currYOffset = 0;
   1619     int colGap = columnGap();
   1620     Vector<IntRect>* colRects = columnRects();
   1621     unsigned colCount = colRects->size();
   1622     for (unsigned i = 0; i < colCount; i++) {
   1623         // For each rect, we clip to the rect, and then we adjust our coords.
   1624         IntRect colRect = colRects->at(i);
   1625         colRect.move(tx, ty);
   1626         context->save();
   1627 
   1628         // Each strip pushes a clip, since column boxes are specified as being
   1629         // like overflow:hidden.
   1630         context->clip(colRect);
   1631 
   1632         // Adjust tx and ty to change where we paint.
   1633         PaintInfo info(paintInfo);
   1634         info.rect.intersect(colRect);
   1635 
   1636         // Adjust our x and y when painting.
   1637         int finalX = tx + currXOffset;
   1638         int finalY = ty + currYOffset;
   1639         if (paintingFloats)
   1640             paintFloats(info, finalX, finalY, paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip);
   1641         else
   1642             paintContents(info, finalX, finalY);
   1643 
   1644         // Move to the next position.
   1645         if (style()->direction() == LTR)
   1646             currXOffset += colRect.width() + colGap;
   1647         else
   1648             currXOffset -= (colRect.width() + colGap);
   1649 
   1650         currYOffset -= colRect.height();
   1651 
   1652         context->restore();
   1653     }
   1654 }
   1655 
   1656 void RenderBlock::paintContents(PaintInfo& paintInfo, int tx, int ty)
   1657 {
   1658     // Avoid painting descendants of the root element when stylesheets haven't loaded.  This eliminates FOUC.
   1659     // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
   1660     // will do a full repaint().
   1661     if (document()->didLayoutWithPendingStylesheets() && !isRenderView())
   1662         return;
   1663 
   1664     if (childrenInline())
   1665         m_lineBoxes.paint(this, paintInfo, tx, ty);
   1666     else
   1667         paintChildren(paintInfo, tx, ty);
   1668 }
   1669 
   1670 void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
   1671 {
   1672     PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase;
   1673     newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase;
   1674 
   1675     // We don't paint our own background, but we do let the kids paint their backgrounds.
   1676     PaintInfo info(paintInfo);
   1677     info.phase = newPhase;
   1678     info.paintingRoot = paintingRootForChildren(paintInfo);
   1679     bool isPrinting = document()->printing();
   1680 
   1681     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
   1682         // Check for page-break-before: always, and if it's set, break and bail.
   1683         if (isPrinting && !childrenInline() && child->style()->pageBreakBefore() == PBALWAYS &&
   1684             inRootBlockContext() && (ty + child->y()) > paintInfo.rect.y() &&
   1685             (ty + child->y()) < paintInfo.rect.bottom()) {
   1686             view()->setBestTruncatedAt(ty + child->y(), this, true);
   1687             return;
   1688         }
   1689 
   1690         if (!child->hasSelfPaintingLayer() && !child->isFloating())
   1691             child->paint(info, tx, ty);
   1692 
   1693         // Check for page-break-after: always, and if it's set, break and bail.
   1694         if (isPrinting && !childrenInline() && child->style()->pageBreakAfter() == PBALWAYS &&
   1695             inRootBlockContext() && (ty + child->y() + child->height()) > paintInfo.rect.y() &&
   1696             (ty + child->y() + child->height()) < paintInfo.rect.bottom()) {
   1697             view()->setBestTruncatedAt(ty + child->y() + child->height() + max(0, child->collapsedMarginBottom()), this, true);
   1698             return;
   1699         }
   1700     }
   1701 }
   1702 
   1703 void RenderBlock::paintCaret(PaintInfo& paintInfo, int tx, int ty, CaretType type)
   1704 {
   1705     SelectionController* selection = type == CursorCaret ? document()->frame()->selection() : document()->frame()->dragCaretController();
   1706 
   1707     // Paint the caret if the SelectionController says so or if caret browsing is enabled
   1708     bool caretBrowsing = document()->frame()->settings() && document()->frame()->settings()->caretBrowsingEnabled();
   1709     RenderObject* caretPainter = selection->caretRenderer();
   1710     if (caretPainter == this && (selection->isContentEditable() || caretBrowsing)) {
   1711         // Convert the painting offset into the local coordinate system of this renderer,
   1712         // to match the localCaretRect computed by the SelectionController
   1713         offsetForContents(tx, ty);
   1714 
   1715         if (type == CursorCaret)
   1716             document()->frame()->selection()->paintCaret(paintInfo.context, tx, ty, paintInfo.rect);
   1717         else
   1718             document()->frame()->paintDragCaret(paintInfo.context, tx, ty, paintInfo.rect);
   1719     }
   1720 }
   1721 
   1722 void RenderBlock::paintObject(PaintInfo& paintInfo, int tx, int ty)
   1723 {
   1724     PaintPhase paintPhase = paintInfo.phase;
   1725 
   1726     // 1. paint background, borders etc
   1727     if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && style()->visibility() == VISIBLE) {
   1728         if (hasBoxDecorations())
   1729             paintBoxDecorations(paintInfo, tx, ty);
   1730         if (hasColumns())
   1731             paintColumnRules(paintInfo, tx, ty);
   1732     }
   1733 
   1734     if (paintPhase == PaintPhaseMask && style()->visibility() == VISIBLE) {
   1735         paintMask(paintInfo, tx, ty);
   1736         return;
   1737     }
   1738 
   1739     // We're done.  We don't bother painting any children.
   1740     if (paintPhase == PaintPhaseBlockBackground)
   1741         return;
   1742 
   1743     // Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div).s
   1744     int scrolledX = tx;
   1745     int scrolledY = ty;
   1746     if (hasOverflowClip())
   1747         layer()->subtractScrolledContentOffset(scrolledX, scrolledY);
   1748 
   1749     // 2. paint contents
   1750     if (paintPhase != PaintPhaseSelfOutline) {
   1751         if (hasColumns())
   1752             paintColumnContents(paintInfo, scrolledX, scrolledY);
   1753         else
   1754             paintContents(paintInfo, scrolledX, scrolledY);
   1755     }
   1756 
   1757     // 3. paint selection
   1758     // FIXME: Make this work with multi column layouts.  For now don't fill gaps.
   1759     bool isPrinting = document()->printing();
   1760     if (!isPrinting && !hasColumns())
   1761         paintSelection(paintInfo, scrolledX, scrolledY); // Fill in gaps in selection on lines and between blocks.
   1762 
   1763     // 4. paint floats.
   1764     if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip) {
   1765         if (hasColumns())
   1766             paintColumnContents(paintInfo, scrolledX, scrolledY, true);
   1767         else
   1768             paintFloats(paintInfo, scrolledX, scrolledY, paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip);
   1769     }
   1770 
   1771     // 5. paint outline.
   1772     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
   1773         paintOutline(paintInfo.context, tx, ty, width(), height(), style());
   1774 
   1775     // 6. paint continuation outlines.
   1776     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) {
   1777         if (inlineContinuation() && inlineContinuation()->hasOutline() && inlineContinuation()->style()->visibility() == VISIBLE) {
   1778             RenderInline* inlineRenderer = toRenderInline(inlineContinuation()->node()->renderer());
   1779             if (!inlineRenderer->hasSelfPaintingLayer())
   1780                 containingBlock()->addContinuationWithOutline(inlineRenderer);
   1781             else if (!inlineRenderer->firstLineBox())
   1782                 inlineRenderer->paintOutline(paintInfo.context, tx - x() + inlineRenderer->containingBlock()->x(),
   1783                                              ty - y() + inlineRenderer->containingBlock()->y());
   1784         }
   1785         paintContinuationOutlines(paintInfo, tx, ty);
   1786     }
   1787 
   1788     // 7. paint caret.
   1789     // If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground,
   1790     // then paint the caret.
   1791     if (paintPhase == PaintPhaseForeground) {
   1792         paintCaret(paintInfo, scrolledX, scrolledY, CursorCaret);
   1793         paintCaret(paintInfo, scrolledX, scrolledY, DragCaret);
   1794     }
   1795 }
   1796 
   1797 void RenderBlock::paintFloats(PaintInfo& paintInfo, int tx, int ty, bool preservePhase)
   1798 {
   1799     if (!m_floatingObjects)
   1800         return;
   1801 
   1802     FloatingObject* r;
   1803     DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   1804     for (; (r = it.current()); ++it) {
   1805         // Only paint the object if our m_shouldPaint flag is set.
   1806         if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
   1807             PaintInfo currentPaintInfo(paintInfo);
   1808             currentPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
   1809             int currentTX = tx + r->m_left - r->m_renderer->x() + r->m_renderer->marginLeft();
   1810             int currentTY = ty + r->m_top - r->m_renderer->y() + r->m_renderer->marginTop();
   1811             r->m_renderer->paint(currentPaintInfo, currentTX, currentTY);
   1812             if (!preservePhase) {
   1813                 currentPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
   1814                 r->m_renderer->paint(currentPaintInfo, currentTX, currentTY);
   1815                 currentPaintInfo.phase = PaintPhaseFloat;
   1816                 r->m_renderer->paint(currentPaintInfo, currentTX, currentTY);
   1817                 currentPaintInfo.phase = PaintPhaseForeground;
   1818                 r->m_renderer->paint(currentPaintInfo, currentTX, currentTY);
   1819                 currentPaintInfo.phase = PaintPhaseOutline;
   1820                 r->m_renderer->paint(currentPaintInfo, currentTX, currentTY);
   1821             }
   1822         }
   1823     }
   1824 }
   1825 
   1826 void RenderBlock::paintEllipsisBoxes(PaintInfo& paintInfo, int tx, int ty)
   1827 {
   1828     if (!shouldPaintWithinRoot(paintInfo) || !firstLineBox())
   1829         return;
   1830 
   1831     if (style()->visibility() == VISIBLE && paintInfo.phase == PaintPhaseForeground) {
   1832         // We can check the first box and last box and avoid painting if we don't
   1833         // intersect.
   1834         int yPos = ty + firstLineBox()->y();
   1835         int h = lastLineBox()->y() + lastLineBox()->height() - firstLineBox()->y();
   1836         if (yPos >= paintInfo.rect.bottom() || yPos + h <= paintInfo.rect.y())
   1837             return;
   1838 
   1839         // See if our boxes intersect with the dirty rect.  If so, then we paint
   1840         // them.  Note that boxes can easily overlap, so we can't make any assumptions
   1841         // based off positions of our first line box or our last line box.
   1842         for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
   1843             yPos = ty + curr->y();
   1844             h = curr->height();
   1845             if (curr->ellipsisBox() && yPos < paintInfo.rect.bottom() && yPos + h > paintInfo.rect.y())
   1846                 curr->paintEllipsisBox(paintInfo, tx, ty);
   1847         }
   1848     }
   1849 }
   1850 
   1851 static ContinuationOutlineTableMap* continuationOutlineTable()
   1852 {
   1853     DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ());
   1854     return &table;
   1855 }
   1856 
   1857 void RenderBlock::addContinuationWithOutline(RenderInline* flow)
   1858 {
   1859     // We can't make this work if the inline is in a layer.  We'll just rely on the broken
   1860     // way of painting.
   1861     ASSERT(!flow->layer() && !flow->isInlineContinuation());
   1862 
   1863     ContinuationOutlineTableMap* table = continuationOutlineTable();
   1864     ListHashSet<RenderInline*>* continuations = table->get(this);
   1865     if (!continuations) {
   1866         continuations = new ListHashSet<RenderInline*>;
   1867         table->set(this, continuations);
   1868     }
   1869 
   1870     continuations->add(flow);
   1871 }
   1872 
   1873 void RenderBlock::paintContinuationOutlines(PaintInfo& info, int tx, int ty)
   1874 {
   1875     ContinuationOutlineTableMap* table = continuationOutlineTable();
   1876     if (table->isEmpty())
   1877         return;
   1878 
   1879     ListHashSet<RenderInline*>* continuations = table->get(this);
   1880     if (!continuations)
   1881         return;
   1882 
   1883     // Paint each continuation outline.
   1884     ListHashSet<RenderInline*>::iterator end = continuations->end();
   1885     for (ListHashSet<RenderInline*>::iterator it = continuations->begin(); it != end; ++it) {
   1886         // Need to add in the coordinates of the intervening blocks.
   1887         RenderInline* flow = *it;
   1888         RenderBlock* block = flow->containingBlock();
   1889         for ( ; block && block != this; block = block->containingBlock()) {
   1890             tx += block->x();
   1891             ty += block->y();
   1892         }
   1893         ASSERT(block);
   1894         flow->paintOutline(info.context, tx, ty);
   1895     }
   1896 
   1897     // Delete
   1898     delete continuations;
   1899     table->remove(this);
   1900 }
   1901 
   1902 void RenderBlock::setSelectionState(SelectionState s)
   1903 {
   1904     if (selectionState() == s)
   1905         return;
   1906 
   1907     if (s == SelectionInside && selectionState() != SelectionNone)
   1908         return;
   1909 
   1910     if ((s == SelectionStart && selectionState() == SelectionEnd) ||
   1911         (s == SelectionEnd && selectionState() == SelectionStart))
   1912         RenderBox::setSelectionState(SelectionBoth);
   1913     else
   1914         RenderBox::setSelectionState(s);
   1915 
   1916     RenderBlock* cb = containingBlock();
   1917     if (cb && !cb->isRenderView())
   1918         cb->setSelectionState(s);
   1919 }
   1920 
   1921 bool RenderBlock::shouldPaintSelectionGaps() const
   1922 {
   1923     return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot();
   1924 }
   1925 
   1926 bool RenderBlock::isSelectionRoot() const
   1927 {
   1928     if (!node())
   1929         return false;
   1930 
   1931     // FIXME: Eventually tables should have to learn how to fill gaps between cells, at least in simple non-spanning cases.
   1932     if (isTable())
   1933         return false;
   1934 
   1935     if (isBody() || isRoot() || hasOverflowClip() || isRelPositioned() ||
   1936         isFloatingOrPositioned() || isTableCell() || isInlineBlockOrInlineTable() || hasTransform() ||
   1937         hasReflection() || hasMask())
   1938         return true;
   1939 
   1940     if (view() && view()->selectionStart()) {
   1941         Node* startElement = view()->selectionStart()->node();
   1942         if (startElement && startElement->rootEditableElement() == node())
   1943             return true;
   1944     }
   1945 
   1946     return false;
   1947 }
   1948 
   1949 GapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer)
   1950 {
   1951     ASSERT(!needsLayout());
   1952 
   1953     if (!shouldPaintSelectionGaps())
   1954         return GapRects();
   1955 
   1956     // FIXME: this is broken with transforms
   1957     TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
   1958     mapLocalToContainer(repaintContainer, false, false, transformState);
   1959     FloatPoint offsetFromRepaintContainer = transformState.mappedPoint();
   1960     int x = offsetFromRepaintContainer.x();
   1961     int y = offsetFromRepaintContainer.y();
   1962 
   1963     if (hasOverflowClip())
   1964         layer()->subtractScrolledContentOffset(x, y);
   1965 
   1966     int lastTop = 0;
   1967     int lastLeft = leftSelectionOffset(this, lastTop);
   1968     int lastRight = rightSelectionOffset(this, lastTop);
   1969 
   1970     return fillSelectionGaps(this, x, y, x, y, lastTop, lastLeft, lastRight);
   1971 }
   1972 
   1973 void RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty)
   1974 {
   1975     if (shouldPaintSelectionGaps() && paintInfo.phase == PaintPhaseForeground) {
   1976         int lastTop = 0;
   1977         int lastLeft = leftSelectionOffset(this, lastTop);
   1978         int lastRight = rightSelectionOffset(this, lastTop);
   1979         paintInfo.context->save();
   1980         IntRect gapRectsBounds = fillSelectionGaps(this, tx, ty, tx, ty, lastTop, lastLeft, lastRight, &paintInfo);
   1981         if (!gapRectsBounds.isEmpty()) {
   1982             if (RenderLayer* layer = enclosingLayer()) {
   1983                 gapRectsBounds.move(IntSize(-tx, -ty));
   1984                 if (!hasLayer()) {
   1985                     FloatRect localBounds(gapRectsBounds);
   1986                     gapRectsBounds = localToContainerQuad(localBounds, layer->renderer()).enclosingBoundingBox();
   1987                 }
   1988                 layer->addBlockSelectionGapsBounds(gapRectsBounds);
   1989             }
   1990         }
   1991         paintInfo.context->restore();
   1992     }
   1993 }
   1994 
   1995 #ifndef BUILDING_ON_TIGER
   1996 static void clipOutPositionedObjects(const RenderObject::PaintInfo* paintInfo, int tx, int ty, ListHashSet<RenderBox*>* positionedObjects)
   1997 {
   1998     if (!positionedObjects)
   1999         return;
   2000 
   2001     ListHashSet<RenderBox*>::const_iterator end = positionedObjects->end();
   2002     for (ListHashSet<RenderBox*>::const_iterator it = positionedObjects->begin(); it != end; ++it) {
   2003         RenderBox* r = *it;
   2004         paintInfo->context->clipOut(IntRect(tx + r->x(), ty + r->y(), r->width(), r->height()));
   2005     }
   2006 }
   2007 #endif
   2008 
   2009 GapRects RenderBlock::fillSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty,
   2010                                         int& lastTop, int& lastLeft, int& lastRight, const PaintInfo* paintInfo)
   2011 {
   2012 #ifndef BUILDING_ON_TIGER
   2013     // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore.
   2014     // Clip out floating and positioned objects when painting selection gaps.
   2015     if (paintInfo) {
   2016         // Note that we don't clip out overflow for positioned objects.  We just stick to the border box.
   2017         clipOutPositionedObjects(paintInfo, tx, ty, m_positionedObjects);
   2018         if (isBody() || isRoot()) // The <body> must make sure to examine its containingBlock's positioned objects.
   2019             for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock())
   2020                 clipOutPositionedObjects(paintInfo, cb->x(), cb->y(), cb->m_positionedObjects);
   2021         if (m_floatingObjects) {
   2022             for (DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects); it.current(); ++it) {
   2023                 FloatingObject* r = it.current();
   2024                 paintInfo->context->clipOut(IntRect(tx + r->m_left + r->m_renderer->marginLeft(),
   2025                                                     ty + r->m_top + r->m_renderer->marginTop(),
   2026                                                     r->m_renderer->width(), r->m_renderer->height()));
   2027             }
   2028         }
   2029     }
   2030 #endif
   2031 
   2032     // 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
   2033     // fixed).
   2034     GapRects result;
   2035     if (!isBlockFlow()) // FIXME: Make multi-column selection gap filling work someday.
   2036         return result;
   2037 
   2038     if (hasColumns() || hasTransform()) {
   2039         // FIXME: We should learn how to gap fill multiple columns and transforms eventually.
   2040         lastTop = (ty - blockY) + height();
   2041         lastLeft = leftSelectionOffset(rootBlock, height());
   2042         lastRight = rightSelectionOffset(rootBlock, height());
   2043         return result;
   2044     }
   2045 
   2046     if (childrenInline())
   2047         result = fillInlineSelectionGaps(rootBlock, blockX, blockY, tx, ty, lastTop, lastLeft, lastRight, paintInfo);
   2048     else
   2049         result = fillBlockSelectionGaps(rootBlock, blockX, blockY, tx, ty, lastTop, lastLeft, lastRight, paintInfo);
   2050 
   2051     // Go ahead and fill the vertical gap all the way to the bottom of our block if the selection extends past our block.
   2052     if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd))
   2053         result.uniteCenter(fillVerticalSelectionGap(lastTop, lastLeft, lastRight, ty + height(),
   2054                                                     rootBlock, blockX, blockY, paintInfo));
   2055     return result;
   2056 }
   2057 
   2058 GapRects RenderBlock::fillInlineSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty,
   2059                                               int& lastTop, int& lastLeft, int& lastRight, const PaintInfo* paintInfo)
   2060 {
   2061     GapRects result;
   2062 
   2063     bool containsStart = selectionState() == SelectionStart || selectionState() == SelectionBoth;
   2064 
   2065     if (!firstLineBox()) {
   2066         if (containsStart) {
   2067             // Go ahead and update our lastY to be the bottom of the block.  <hr>s or empty blocks with height can trip this
   2068             // case.
   2069             lastTop = (ty - blockY) + height();
   2070             lastLeft = leftSelectionOffset(rootBlock, height());
   2071             lastRight = rightSelectionOffset(rootBlock, height());
   2072         }
   2073         return result;
   2074     }
   2075 
   2076     RootInlineBox* lastSelectedLine = 0;
   2077     RootInlineBox* curr;
   2078     for (curr = firstRootBox(); curr && !curr->hasSelectedChildren(); curr = curr->nextRootBox()) { }
   2079 
   2080     // Now paint the gaps for the lines.
   2081     for (; curr && curr->hasSelectedChildren(); curr = curr->nextRootBox()) {
   2082         int selTop =  curr->selectionTop();
   2083         int selHeight = curr->selectionHeight();
   2084 
   2085         if (!containsStart && !lastSelectedLine &&
   2086             selectionState() != SelectionStart && selectionState() != SelectionBoth)
   2087             result.uniteCenter(fillVerticalSelectionGap(lastTop, lastLeft, lastRight, ty + selTop,
   2088                                                         rootBlock, blockX, blockY, paintInfo));
   2089 
   2090         if (!paintInfo || (ty + selTop < paintInfo->rect.bottom() && ty + selTop + selHeight > paintInfo->rect.y()))
   2091             result.unite(curr->fillLineSelectionGap(selTop, selHeight, rootBlock, blockX, blockY, tx, ty, paintInfo));
   2092 
   2093         lastSelectedLine = curr;
   2094     }
   2095 
   2096     if (containsStart && !lastSelectedLine)
   2097         // VisibleSelection must start just after our last line.
   2098         lastSelectedLine = lastRootBox();
   2099 
   2100     if (lastSelectedLine && selectionState() != SelectionEnd && selectionState() != SelectionBoth) {
   2101         // Go ahead and update our lastY to be the bottom of the last selected line.
   2102         lastTop = (ty - blockY) + lastSelectedLine->selectionBottom();
   2103         lastLeft = leftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
   2104         lastRight = rightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
   2105     }
   2106     return result;
   2107 }
   2108 
   2109 GapRects RenderBlock::fillBlockSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty,
   2110                                              int& lastTop, int& lastLeft, int& lastRight, const PaintInfo* paintInfo)
   2111 {
   2112     GapRects result;
   2113 
   2114     // Go ahead and jump right to the first block child that contains some selected objects.
   2115     RenderBox* curr;
   2116     for (curr = firstChildBox(); curr && curr->selectionState() == SelectionNone; curr = curr->nextSiblingBox()) { }
   2117 
   2118     for (bool sawSelectionEnd = false; curr && !sawSelectionEnd; curr = curr->nextSiblingBox()) {
   2119         SelectionState childState = curr->selectionState();
   2120         if (childState == SelectionBoth || childState == SelectionEnd)
   2121             sawSelectionEnd = true;
   2122 
   2123         if (curr->isFloatingOrPositioned())
   2124             continue; // We must be a normal flow object in order to even be considered.
   2125 
   2126         if (curr->isRelPositioned() && curr->hasLayer()) {
   2127             // If the relposition offset is anything other than 0, then treat this just like an absolute positioned element.
   2128             // Just disregard it completely.
   2129             IntSize relOffset = curr->layer()->relativePositionOffset();
   2130             if (relOffset.width() || relOffset.height())
   2131                 continue;
   2132         }
   2133 
   2134         bool paintsOwnSelection = curr->shouldPaintSelectionGaps() || curr->isTable(); // FIXME: Eventually we won't special-case table like this.
   2135         bool fillBlockGaps = paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone);
   2136         if (fillBlockGaps) {
   2137             // We need to fill the vertical gap above this object.
   2138             if (childState == SelectionEnd || childState == SelectionInside)
   2139                 // Fill the gap above the object.
   2140                 result.uniteCenter(fillVerticalSelectionGap(lastTop, lastLeft, lastRight,
   2141                                                             ty + curr->y(), rootBlock, blockX, blockY, paintInfo));
   2142 
   2143             // 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*
   2144             // our object.  We know this if the selection did not end inside our object.
   2145             if (paintsOwnSelection && (childState == SelectionStart || sawSelectionEnd))
   2146                 childState = SelectionNone;
   2147 
   2148             // Fill side gaps on this object based off its state.
   2149             bool leftGap, rightGap;
   2150             getHorizontalSelectionGapInfo(childState, leftGap, rightGap);
   2151 
   2152             if (leftGap)
   2153                 result.uniteLeft(fillLeftSelectionGap(this, curr->x(), curr->y(), curr->height(), rootBlock, blockX, blockY, tx, ty, paintInfo));
   2154             if (rightGap)
   2155                 result.uniteRight(fillRightSelectionGap(this, curr->x() + curr->width(), curr->y(), curr->height(), rootBlock, blockX, blockY, tx, ty, paintInfo));
   2156 
   2157             // Update lastTop to be just underneath the object.  lastLeft and lastRight extend as far as
   2158             // they can without bumping into floating or positioned objects.  Ideally they will go right up
   2159             // to the border of the root selection block.
   2160             lastTop = (ty - blockY) + (curr->y() + curr->height());
   2161             lastLeft = leftSelectionOffset(rootBlock, curr->y() + curr->height());
   2162             lastRight = rightSelectionOffset(rootBlock, curr->y() + curr->height());
   2163         } else if (childState != SelectionNone)
   2164             // We must be a block that has some selected object inside it.  Go ahead and recur.
   2165             result.unite(toRenderBlock(curr)->fillSelectionGaps(rootBlock, blockX, blockY, tx + curr->x(), ty + curr->y(),
   2166                                                                             lastTop, lastLeft, lastRight, paintInfo));
   2167     }
   2168     return result;
   2169 }
   2170 
   2171 IntRect RenderBlock::fillHorizontalSelectionGap(RenderObject* selObj, int xPos, int yPos, int width, int height, const PaintInfo* paintInfo)
   2172 {
   2173     if (width <= 0 || height <= 0)
   2174         return IntRect();
   2175     IntRect gapRect(xPos, yPos, width, height);
   2176     if (paintInfo && selObj->style()->visibility() == VISIBLE)
   2177         paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
   2178     return gapRect;
   2179 }
   2180 
   2181 IntRect RenderBlock::fillVerticalSelectionGap(int lastTop, int lastLeft, int lastRight, int bottomY, RenderBlock* rootBlock,
   2182                                               int blockX, int blockY, const PaintInfo* paintInfo)
   2183 {
   2184     int top = blockY + lastTop;
   2185     int height = bottomY - top;
   2186     if (height <= 0)
   2187         return IntRect();
   2188 
   2189     // Get the selection offsets for the bottom of the gap
   2190     int left = blockX + max(lastLeft, leftSelectionOffset(rootBlock, bottomY));
   2191     int right = blockX + min(lastRight, rightSelectionOffset(rootBlock, bottomY));
   2192     int width = right - left;
   2193     if (width <= 0)
   2194         return IntRect();
   2195 
   2196     IntRect gapRect(left, top, width, height);
   2197     if (paintInfo)
   2198         paintInfo->context->fillRect(gapRect, selectionBackgroundColor(), style()->colorSpace());
   2199     return gapRect;
   2200 }
   2201 
   2202 IntRect RenderBlock::fillLeftSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock,
   2203                                           int blockX, int /*blockY*/, int tx, int ty, const PaintInfo* paintInfo)
   2204 {
   2205     int top = yPos + ty;
   2206     int left = blockX + max(leftSelectionOffset(rootBlock, yPos), leftSelectionOffset(rootBlock, yPos + height));
   2207     int right = min(xPos + tx, blockX + min(rightSelectionOffset(rootBlock, yPos), rightSelectionOffset(rootBlock, yPos + height)));
   2208     int width = right - left;
   2209     if (width <= 0)
   2210         return IntRect();
   2211 
   2212     IntRect gapRect(left, top, width, height);
   2213     if (paintInfo)
   2214         paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
   2215     return gapRect;
   2216 }
   2217 
   2218 IntRect RenderBlock::fillRightSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock,
   2219                                            int blockX, int /*blockY*/, int tx, int ty, const PaintInfo* paintInfo)
   2220 {
   2221     int left = max(xPos + tx, blockX + max(leftSelectionOffset(rootBlock, yPos), leftSelectionOffset(rootBlock, yPos + height)));
   2222     int top = yPos + ty;
   2223     int right = blockX + min(rightSelectionOffset(rootBlock, yPos), rightSelectionOffset(rootBlock, yPos + height));
   2224     int width = right - left;
   2225     if (width <= 0)
   2226         return IntRect();
   2227 
   2228     IntRect gapRect(left, top, width, height);
   2229     if (paintInfo)
   2230         paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
   2231     return gapRect;
   2232 }
   2233 
   2234 void RenderBlock::getHorizontalSelectionGapInfo(SelectionState state, bool& leftGap, bool& rightGap)
   2235 {
   2236     bool ltr = style()->direction() == LTR;
   2237     leftGap = (state == RenderObject::SelectionInside) ||
   2238               (state == RenderObject::SelectionEnd && ltr) ||
   2239               (state == RenderObject::SelectionStart && !ltr);
   2240     rightGap = (state == RenderObject::SelectionInside) ||
   2241                (state == RenderObject::SelectionStart && ltr) ||
   2242                (state == RenderObject::SelectionEnd && !ltr);
   2243 }
   2244 
   2245 int RenderBlock::leftSelectionOffset(RenderBlock* rootBlock, int yPos)
   2246 {
   2247     int left = leftOffset(yPos, false);
   2248     if (left == borderLeft() + paddingLeft()) {
   2249         if (rootBlock != this)
   2250             // The border can potentially be further extended by our containingBlock().
   2251             return containingBlock()->leftSelectionOffset(rootBlock, yPos + y());
   2252         return left;
   2253     }
   2254     else {
   2255         RenderBlock* cb = this;
   2256         while (cb != rootBlock) {
   2257             left += cb->x();
   2258             cb = cb->containingBlock();
   2259         }
   2260     }
   2261 
   2262     return left;
   2263 }
   2264 
   2265 int RenderBlock::rightSelectionOffset(RenderBlock* rootBlock, int yPos)
   2266 {
   2267     int right = rightOffset(yPos, false);
   2268     if (right == (contentWidth() + (borderLeft() + paddingLeft()))) {
   2269         if (rootBlock != this)
   2270             // The border can potentially be further extended by our containingBlock().
   2271             return containingBlock()->rightSelectionOffset(rootBlock, yPos + y());
   2272         return right;
   2273     }
   2274     else {
   2275         RenderBlock* cb = this;
   2276         while (cb != rootBlock) {
   2277             right += cb->x();
   2278             cb = cb->containingBlock();
   2279         }
   2280     }
   2281     return right;
   2282 }
   2283 
   2284 void RenderBlock::insertPositionedObject(RenderBox* o)
   2285 {
   2286     // Create the list of special objects if we don't aleady have one
   2287     if (!m_positionedObjects)
   2288         m_positionedObjects = new ListHashSet<RenderBox*>;
   2289 
   2290     m_positionedObjects->add(o);
   2291 }
   2292 
   2293 void RenderBlock::removePositionedObject(RenderBox* o)
   2294 {
   2295     if (m_positionedObjects)
   2296         m_positionedObjects->remove(o);
   2297 }
   2298 
   2299 void RenderBlock::removePositionedObjects(RenderBlock* o)
   2300 {
   2301     if (!m_positionedObjects)
   2302         return;
   2303 
   2304     RenderBox* r;
   2305 
   2306     Iterator end = m_positionedObjects->end();
   2307 
   2308     Vector<RenderBox*, 16> deadObjects;
   2309 
   2310     for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
   2311         r = *it;
   2312         if (!o || r->isDescendantOf(o)) {
   2313             if (o)
   2314                 r->setChildNeedsLayout(true, false);
   2315 
   2316             // It is parent blocks job to add positioned child to positioned objects list of its containing block
   2317             // Parent layout needs to be invalidated to ensure this happens.
   2318             RenderObject* p = r->parent();
   2319             while (p && !p->isRenderBlock())
   2320                 p = p->parent();
   2321             if (p)
   2322                 p->setChildNeedsLayout(true);
   2323 
   2324             deadObjects.append(r);
   2325         }
   2326     }
   2327 
   2328     for (unsigned i = 0; i < deadObjects.size(); i++)
   2329         m_positionedObjects->remove(deadObjects.at(i));
   2330 }
   2331 
   2332 void RenderBlock::insertFloatingObject(RenderBox* o)
   2333 {
   2334     ASSERT(o->isFloating());
   2335 
   2336     // Create the list of special objects if we don't aleady have one
   2337     if (!m_floatingObjects) {
   2338         m_floatingObjects = new DeprecatedPtrList<FloatingObject>;
   2339         m_floatingObjects->setAutoDelete(true);
   2340     } else {
   2341         // Don't insert the object again if it's already in the list
   2342         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2343         FloatingObject* f;
   2344         while ( (f = it.current()) ) {
   2345             if (f->m_renderer == o) return;
   2346             ++it;
   2347         }
   2348     }
   2349 
   2350     // Create the special object entry & append it to the list
   2351 
   2352     o->layoutIfNeeded();
   2353 
   2354     FloatingObject* newObj = new FloatingObject(o->style()->floating() == FLEFT ? FloatingObject::FloatLeft : FloatingObject::FloatRight);
   2355 
   2356     newObj->m_top = -1;
   2357     newObj->m_bottom = -1;
   2358     newObj->m_width = o->width() + o->marginLeft() + o->marginRight();
   2359     newObj->m_shouldPaint = !o->hasSelfPaintingLayer(); // If a layer exists, the float will paint itself.  Otherwise someone else will.
   2360     newObj->m_isDescendant = true;
   2361     newObj->m_renderer = o;
   2362 
   2363     m_floatingObjects->append(newObj);
   2364 }
   2365 
   2366 void RenderBlock::removeFloatingObject(RenderBox* o)
   2367 {
   2368     if (m_floatingObjects) {
   2369         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2370         while (it.current()) {
   2371             if (it.current()->m_renderer == o) {
   2372                 if (childrenInline())
   2373                     markLinesDirtyInVerticalRange(0, it.current()->m_bottom);
   2374                 m_floatingObjects->removeRef(it.current());
   2375             }
   2376             ++it;
   2377         }
   2378     }
   2379 }
   2380 
   2381 bool RenderBlock::positionNewFloats()
   2382 {
   2383     if (!m_floatingObjects)
   2384         return false;
   2385 
   2386     FloatingObject* f = m_floatingObjects->last();
   2387 
   2388     // If all floats have already been positioned, then we have no work to do.
   2389     if (!f || f->m_top != -1)
   2390         return false;
   2391 
   2392     // Move backwards through our floating object list until we find a float that has
   2393     // already been positioned.  Then we'll be able to move forward, positioning all of
   2394     // the new floats that need it.
   2395     FloatingObject* lastFloat = m_floatingObjects->getPrev();
   2396     while (lastFloat && lastFloat->m_top == -1) {
   2397         f = m_floatingObjects->prev();
   2398         lastFloat = m_floatingObjects->getPrev();
   2399     }
   2400 
   2401     int y = height();
   2402 
   2403     // The float cannot start above the y position of the last positioned float.
   2404     if (lastFloat)
   2405         y = max(lastFloat->m_top, y);
   2406 
   2407     // Now walk through the set of unpositioned floats and place them.
   2408     while (f) {
   2409         // The containing block is responsible for positioning floats, so if we have floats in our
   2410         // list that come from somewhere else, do not attempt to position them.
   2411         if (f->m_renderer->containingBlock() != this) {
   2412             f = m_floatingObjects->next();
   2413             continue;
   2414         }
   2415 
   2416         RenderBox* o = f->m_renderer;
   2417         int _height = o->height() + o->marginTop() + o->marginBottom();
   2418 
   2419         int ro = rightOffset(); // Constant part of right offset.
   2420         int lo = leftOffset(); // Constat part of left offset.
   2421         int fwidth = f->m_width; // The width we look for.
   2422         if (ro - lo < fwidth)
   2423             fwidth = ro - lo; // Never look for more than what will be available.
   2424 
   2425         IntRect oldRect(o->x(), o->y() , o->width(), o->height());
   2426 
   2427         if (o->style()->clear() & CLEFT)
   2428             y = max(leftBottom(), y);
   2429         if (o->style()->clear() & CRIGHT)
   2430             y = max(rightBottom(), y);
   2431 
   2432         if (o->style()->floating() == FLEFT) {
   2433             int heightRemainingLeft = 1;
   2434             int heightRemainingRight = 1;
   2435             int fx = leftRelOffset(y, lo, false, &heightRemainingLeft);
   2436             while (rightRelOffset(y, ro, false, &heightRemainingRight)-fx < fwidth) {
   2437                 y += min(heightRemainingLeft, heightRemainingRight);
   2438                 fx = leftRelOffset(y, lo, false, &heightRemainingLeft);
   2439             }
   2440             fx = max(0, fx);
   2441             f->m_left = fx;
   2442             o->setLocation(fx + o->marginLeft(), y + o->marginTop());
   2443         } else {
   2444             int heightRemainingLeft = 1;
   2445             int heightRemainingRight = 1;
   2446             int fx = rightRelOffset(y, ro, false, &heightRemainingRight);
   2447             while (fx - leftRelOffset(y, lo, false, &heightRemainingLeft) < fwidth) {
   2448                 y += min(heightRemainingLeft, heightRemainingRight);
   2449                 fx = rightRelOffset(y, ro, false, &heightRemainingRight);
   2450             }
   2451             f->m_left = fx - f->m_width;
   2452             o->setLocation(fx - o->marginRight() - o->width(), y + o->marginTop());
   2453         }
   2454 
   2455         f->m_top = y;
   2456         f->m_bottom = f->m_top + _height;
   2457 
   2458         // If the child moved, we have to repaint it.
   2459         if (o->checkForRepaintDuringLayout())
   2460             o->repaintDuringLayoutIfMoved(oldRect);
   2461 
   2462         f = m_floatingObjects->next();
   2463     }
   2464     return true;
   2465 }
   2466 
   2467 void RenderBlock::newLine(EClear clear)
   2468 {
   2469     positionNewFloats();
   2470     // set y position
   2471     int newY = 0;
   2472     switch (clear)
   2473     {
   2474         case CLEFT:
   2475             newY = leftBottom();
   2476             break;
   2477         case CRIGHT:
   2478             newY = rightBottom();
   2479             break;
   2480         case CBOTH:
   2481             newY = floatBottom();
   2482         default:
   2483             break;
   2484     }
   2485     if (height() < newY)
   2486         setHeight(newY);
   2487 }
   2488 
   2489 void RenderBlock::addPercentHeightDescendant(RenderBox* descendant)
   2490 {
   2491     if (!gPercentHeightDescendantsMap) {
   2492         gPercentHeightDescendantsMap = new PercentHeightDescendantsMap;
   2493         gPercentHeightContainerMap = new PercentHeightContainerMap;
   2494     }
   2495 
   2496     HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(this);
   2497     if (!descendantSet) {
   2498         descendantSet = new HashSet<RenderBox*>;
   2499         gPercentHeightDescendantsMap->set(this, descendantSet);
   2500     }
   2501     bool added = descendantSet->add(descendant).second;
   2502     if (!added) {
   2503         ASSERT(gPercentHeightContainerMap->get(descendant));
   2504         ASSERT(gPercentHeightContainerMap->get(descendant)->contains(this));
   2505         return;
   2506     }
   2507 
   2508     HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->get(descendant);
   2509     if (!containerSet) {
   2510         containerSet = new HashSet<RenderBlock*>;
   2511         gPercentHeightContainerMap->set(descendant, containerSet);
   2512     }
   2513     ASSERT(!containerSet->contains(this));
   2514     containerSet->add(this);
   2515 }
   2516 
   2517 void RenderBlock::removePercentHeightDescendant(RenderBox* descendant)
   2518 {
   2519     if (!gPercentHeightContainerMap)
   2520         return;
   2521 
   2522     HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->take(descendant);
   2523     if (!containerSet)
   2524         return;
   2525 
   2526     HashSet<RenderBlock*>::iterator end = containerSet->end();
   2527     for (HashSet<RenderBlock*>::iterator it = containerSet->begin(); it != end; ++it) {
   2528         RenderBlock* container = *it;
   2529         HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(container);
   2530         ASSERT(descendantSet);
   2531         if (!descendantSet)
   2532             continue;
   2533         ASSERT(descendantSet->contains(descendant));
   2534         descendantSet->remove(descendant);
   2535         if (descendantSet->isEmpty()) {
   2536             gPercentHeightDescendantsMap->remove(container);
   2537             delete descendantSet;
   2538         }
   2539     }
   2540 
   2541     delete containerSet;
   2542 }
   2543 
   2544 HashSet<RenderBox*>* RenderBlock::percentHeightDescendants() const
   2545 {
   2546     return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0;
   2547 }
   2548 
   2549 int RenderBlock::leftOffset() const
   2550 {
   2551     return borderLeft() + paddingLeft();
   2552 }
   2553 
   2554 int RenderBlock::leftRelOffset(int y, int fixedOffset, bool applyTextIndent, int* heightRemaining) const
   2555 {
   2556     int left = fixedOffset;
   2557     if (m_floatingObjects) {
   2558         if ( heightRemaining ) *heightRemaining = 1;
   2559         FloatingObject* r;
   2560         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2561         for ( ; (r = it.current()); ++it )
   2562         {
   2563             if (r->m_top <= y && r->m_bottom > y &&
   2564                 r->type() == FloatingObject::FloatLeft &&
   2565                 r->m_left + r->m_width > left) {
   2566                 left = r->m_left + r->m_width;
   2567                 if ( heightRemaining ) *heightRemaining = r->m_bottom - y;
   2568             }
   2569         }
   2570     }
   2571 
   2572     if (applyTextIndent && style()->direction() == LTR) {
   2573         int cw = 0;
   2574         if (style()->textIndent().isPercent())
   2575             cw = containingBlock()->availableWidth();
   2576         left += style()->textIndent().calcMinValue(cw);
   2577     }
   2578 
   2579     return left;
   2580 }
   2581 
   2582 int RenderBlock::rightOffset() const
   2583 {
   2584     return borderLeft() + paddingLeft() + availableWidth();
   2585 }
   2586 
   2587 int RenderBlock::rightRelOffset(int y, int fixedOffset, bool applyTextIndent, int* heightRemaining) const
   2588 {
   2589     int right = fixedOffset;
   2590 
   2591     if (m_floatingObjects) {
   2592         if (heightRemaining) *heightRemaining = 1;
   2593         FloatingObject* r;
   2594         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2595         for ( ; (r = it.current()); ++it )
   2596         {
   2597             if (r->m_top <= y && r->m_bottom > y &&
   2598                 r->type() == FloatingObject::FloatRight &&
   2599                 r->m_left < right) {
   2600                 right = r->m_left;
   2601                 if ( heightRemaining ) *heightRemaining = r->m_bottom - y;
   2602             }
   2603         }
   2604     }
   2605 
   2606     if (applyTextIndent && style()->direction() == RTL) {
   2607         int cw = 0;
   2608         if (style()->textIndent().isPercent())
   2609             cw = containingBlock()->availableWidth();
   2610         right -= style()->textIndent().calcMinValue(cw);
   2611     }
   2612 
   2613     return right;
   2614 }
   2615 
   2616 int
   2617 RenderBlock::lineWidth(int y, bool firstLine) const
   2618 {
   2619     int result = rightOffset(y, firstLine) - leftOffset(y, firstLine);
   2620     return (result < 0) ? 0 : result;
   2621 }
   2622 
   2623 int RenderBlock::nextFloatBottomBelow(int height) const
   2624 {
   2625     if (!m_floatingObjects)
   2626         return 0;
   2627 
   2628     int bottom = INT_MAX;
   2629     FloatingObject* r;
   2630     DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2631     for ( ; (r = it.current()); ++it) {
   2632         if (r->m_bottom > height)
   2633             bottom = min(r->m_bottom, bottom);
   2634     }
   2635 
   2636     return bottom == INT_MAX ? 0 : bottom;
   2637 }
   2638 
   2639 int
   2640 RenderBlock::floatBottom() const
   2641 {
   2642     if (!m_floatingObjects) return 0;
   2643     int bottom = 0;
   2644     FloatingObject* r;
   2645     DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2646     for ( ; (r = it.current()); ++it )
   2647         if (r->m_bottom>bottom)
   2648             bottom = r->m_bottom;
   2649     return bottom;
   2650 }
   2651 
   2652 IntRect RenderBlock::floatRect() const
   2653 {
   2654     IntRect result;
   2655     if (!m_floatingObjects || hasOverflowClip() || hasColumns())
   2656         return result;
   2657     FloatingObject* r;
   2658     DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2659     for (; (r = it.current()); ++it) {
   2660         if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
   2661             IntRect childRect = r->m_renderer->visibleOverflowRect();
   2662             childRect.move(r->m_left + r->m_renderer->marginLeft(), r->m_top + r->m_renderer->marginTop());
   2663             result.unite(childRect);
   2664         }
   2665     }
   2666 
   2667     return result;
   2668 }
   2669 
   2670 int RenderBlock::lowestPosition(bool includeOverflowInterior, bool includeSelf) const
   2671 {
   2672     int bottom = includeSelf && width() > 0 ? height() : 0;
   2673 
   2674     if (!includeOverflowInterior && (hasOverflowClip() || hasControlClip()))
   2675         return bottom;
   2676 
   2677     if (!firstChild() && (!width() || !height()))
   2678         return bottom;
   2679 
   2680     if (!hasColumns()) {
   2681         // FIXME: Come up with a way to use the layer tree to avoid visiting all the kids.
   2682         // For now, we have to descend into all the children, since we may have a huge abs div inside
   2683         // a tiny rel div buried somewhere deep in our child tree.  In this case we have to get to
   2684         // the abs div.
   2685         // See the last test case in https://bugs.webkit.org/show_bug.cgi?id=9314 for why this is a problem.
   2686         // For inline children, we miss relative positioned boxes that might be buried inside <span>s.
   2687         for (RenderObject* c = firstChild(); c; c = c->nextSibling()) {
   2688             if (!c->isFloatingOrPositioned() && c->isBox()) {
   2689                 RenderBox* childBox = toRenderBox(c);
   2690                 bottom = max(bottom, childBox->y() + childBox->lowestPosition(false));
   2691             }
   2692         }
   2693     }
   2694 
   2695     if (includeSelf && isRelPositioned())
   2696         bottom += relativePositionOffsetY();
   2697     if (!includeOverflowInterior && hasOverflowClip())
   2698         return bottom;
   2699 
   2700     int relativeOffset = includeSelf && isRelPositioned() ? relativePositionOffsetY() : 0;
   2701 
   2702     if (includeSelf)
   2703         bottom = max(bottom, bottomLayoutOverflow() + relativeOffset);
   2704 
   2705     if (m_positionedObjects) {
   2706         RenderBox* r;
   2707         Iterator end = m_positionedObjects->end();
   2708         for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
   2709             r = *it;
   2710             // Fixed positioned objects do not scroll and thus should not constitute
   2711             // part of the lowest position.
   2712             if (r->style()->position() != FixedPosition) {
   2713                 // FIXME: Should work for overflow sections too.
   2714                 // If a positioned object lies completely to the left of the root it will be unreachable via scrolling.
   2715                 // Therefore we should not allow it to contribute to the lowest position.
   2716                 if (!isRenderView() || r->x() + r->width() > 0 || r->x() + r->rightmostPosition(false) > 0) {
   2717                     int lp = r->y() + r->lowestPosition(false);
   2718                     bottom = max(bottom, lp + relativeOffset);
   2719                 }
   2720             }
   2721         }
   2722     }
   2723 
   2724     if (hasColumns()) {
   2725         Vector<IntRect>* colRects = columnRects();
   2726         for (unsigned i = 0; i < colRects->size(); i++)
   2727             bottom = max(bottom, colRects->at(i).bottom() + relativeOffset);
   2728         return bottom;
   2729     }
   2730 
   2731     if (m_floatingObjects) {
   2732         FloatingObject* r;
   2733         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2734         for ( ; (r = it.current()); ++it ) {
   2735             if (r->m_shouldPaint || r->m_renderer->hasSelfPaintingLayer()) {
   2736                 int lp = r->m_top + r->m_renderer->marginTop() + r->m_renderer->lowestPosition(false);
   2737                 bottom = max(bottom, lp + relativeOffset);
   2738             }
   2739         }
   2740     }
   2741 
   2742     if (!includeSelf) {
   2743         bottom = max(bottom, borderTop() + paddingTop() + paddingBottom() + relativeOffset);
   2744         if (childrenInline()) {
   2745             if (lastRootBox()) {
   2746                 int childBottomEdge = lastRootBox()->selectionBottom();
   2747                 bottom = max(bottom, childBottomEdge + paddingBottom() + relativeOffset);
   2748             }
   2749         } else {
   2750             // Find the last normal flow child.
   2751             RenderBox* currBox = lastChildBox();
   2752             while (currBox && currBox->isFloatingOrPositioned())
   2753                 currBox = currBox->previousSiblingBox();
   2754             if (currBox) {
   2755                 int childBottomEdge = currBox->y() + currBox->height() + currBox->collapsedMarginBottom();
   2756                 bottom = max(bottom, childBottomEdge + paddingBottom() + relativeOffset);
   2757             }
   2758         }
   2759     }
   2760 
   2761     return bottom;
   2762 }
   2763 
   2764 int RenderBlock::rightmostPosition(bool includeOverflowInterior, bool includeSelf) const
   2765 {
   2766     int right = includeSelf && height() > 0 ? width() : 0;
   2767 
   2768     if (!includeOverflowInterior && (hasOverflowClip() || hasControlClip()))
   2769         return right;
   2770 
   2771     if (!firstChild() && (!width() || !height()))
   2772         return right;
   2773 
   2774     if (!hasColumns()) {
   2775         // FIXME: Come up with a way to use the layer tree to avoid visiting all the kids.
   2776         // For now, we have to descend into all the children, since we may have a huge abs div inside
   2777         // a tiny rel div buried somewhere deep in our child tree.  In this case we have to get to
   2778         // the abs div.
   2779         for (RenderObject* c = firstChild(); c; c = c->nextSibling()) {
   2780             if (!c->isFloatingOrPositioned() && c->isBox()) {
   2781                 RenderBox* childBox = toRenderBox(c);
   2782                 right = max(right, childBox->x() + childBox->rightmostPosition(false));
   2783             }
   2784         }
   2785     }
   2786 
   2787     if (includeSelf && isRelPositioned())
   2788         right += relativePositionOffsetX();
   2789 
   2790     if (!includeOverflowInterior && hasOverflowClip())
   2791         return right;
   2792 
   2793     int relativeOffset = includeSelf && isRelPositioned() ? relativePositionOffsetX() : 0;
   2794 
   2795     if (includeSelf)
   2796         right = max(right, rightLayoutOverflow() + relativeOffset);
   2797 
   2798     if (m_positionedObjects) {
   2799         RenderBox* r;
   2800         Iterator end = m_positionedObjects->end();
   2801         for (Iterator it = m_positionedObjects->begin() ; it != end; ++it) {
   2802             r = *it;
   2803             // Fixed positioned objects do not scroll and thus should not constitute
   2804             // part of the rightmost position.
   2805             if (r->style()->position() != FixedPosition) {
   2806                 // FIXME: Should work for overflow sections too.
   2807                 // If a positioned object lies completely above the root it will be unreachable via scrolling.
   2808                 // Therefore we should not allow it to contribute to the rightmost position.
   2809                 if (!isRenderView() || r->y() + r->height() > 0 || r->y() + r->lowestPosition(false) > 0) {
   2810                     int rp = r->x() + r->rightmostPosition(false);
   2811                     right = max(right, rp + relativeOffset);
   2812                 }
   2813             }
   2814         }
   2815     }
   2816 
   2817     if (hasColumns()) {
   2818         // This only matters for LTR
   2819         if (style()->direction() == LTR)
   2820             right = max(columnRects()->last().right() + relativeOffset, right);
   2821         return right;
   2822     }
   2823 
   2824     if (m_floatingObjects) {
   2825         FloatingObject* r;
   2826         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2827         for ( ; (r = it.current()); ++it ) {
   2828             if (r->m_shouldPaint || r->m_renderer->hasSelfPaintingLayer()) {
   2829                 int rp = r->m_left + r->m_renderer->marginLeft() + r->m_renderer->rightmostPosition(false);
   2830                 right = max(right, rp + relativeOffset);
   2831             }
   2832         }
   2833     }
   2834 
   2835     if (!includeSelf) {
   2836         right = max(right, borderLeft() + paddingLeft() + paddingRight() + relativeOffset);
   2837         if (childrenInline()) {
   2838             for (InlineRunBox* currBox = firstLineBox(); currBox; currBox = currBox->nextLineBox()) {
   2839                 int childRightEdge = currBox->x() + currBox->width();
   2840 
   2841                 // If this node is a root editable element, then the rightmostPosition should account for a caret at the end.
   2842                 // FIXME: Need to find another way to do this, since scrollbars could show when we don't want them to.
   2843                 if (node() && node()->isContentEditable() && node() == node()->rootEditableElement() && style()->direction() == LTR && !paddingRight())
   2844                     childRightEdge += 1;
   2845                 right = max(right, childRightEdge + paddingRight() + relativeOffset);
   2846             }
   2847         } else {
   2848             // Walk all normal flow children.
   2849             for (RenderBox* currBox = firstChildBox(); currBox; currBox = currBox->nextSiblingBox()) {
   2850                 if (currBox->isFloatingOrPositioned())
   2851                     continue;
   2852                 int childRightEdge = currBox->x() + currBox->width() + currBox->marginRight();
   2853                 right = max(right, childRightEdge + paddingRight() + relativeOffset);
   2854             }
   2855         }
   2856     }
   2857 
   2858     return right;
   2859 }
   2860 
   2861 int RenderBlock::leftmostPosition(bool includeOverflowInterior, bool includeSelf) const
   2862 {
   2863     int left = includeSelf && height() > 0 ? 0 : width();
   2864 
   2865     if (!includeOverflowInterior && (hasOverflowClip() || hasControlClip()))
   2866         return left;
   2867 
   2868     if (!firstChild() && (!width() || !height()))
   2869         return left;
   2870 
   2871     if (!hasColumns()) {
   2872         // FIXME: Come up with a way to use the layer tree to avoid visiting all the kids.
   2873         // For now, we have to descend into all the children, since we may have a huge abs div inside
   2874         // a tiny rel div buried somewhere deep in our child tree.  In this case we have to get to
   2875         // the abs div.
   2876         for (RenderObject* c = firstChild(); c; c = c->nextSibling()) {
   2877             if (!c->isFloatingOrPositioned() && c->isBox()) {
   2878                 RenderBox* childBox = toRenderBox(c);
   2879                 left = min(left, childBox->x() + childBox->leftmostPosition(false));
   2880             }
   2881         }
   2882     }
   2883 
   2884     if (includeSelf && isRelPositioned())
   2885         left += relativePositionOffsetX();
   2886 
   2887     if (!includeOverflowInterior && hasOverflowClip())
   2888         return left;
   2889 
   2890     int relativeOffset = includeSelf && isRelPositioned() ? relativePositionOffsetX() : 0;
   2891 
   2892     if (includeSelf)
   2893         left = min(left, leftLayoutOverflow() + relativeOffset);
   2894 
   2895     if (m_positionedObjects) {
   2896         RenderBox* r;
   2897         Iterator end = m_positionedObjects->end();
   2898         for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
   2899             r = *it;
   2900             // Fixed positioned objects do not scroll and thus should not constitute
   2901             // part of the leftmost position.
   2902             if (r->style()->position() != FixedPosition) {
   2903                 // FIXME: Should work for overflow sections too.
   2904                 // If a positioned object lies completely above the root it will be unreachable via scrolling.
   2905                 // Therefore we should not allow it to contribute to the leftmost position.
   2906                 if (!isRenderView() || r->y() + r->height() > 0 || r->y() + r->lowestPosition(false) > 0) {
   2907                     int lp = r->x() + r->leftmostPosition(false);
   2908                     left = min(left, lp + relativeOffset);
   2909                 }
   2910             }
   2911         }
   2912     }
   2913 
   2914     if (hasColumns()) {
   2915         // This only matters for RTL
   2916         if (style()->direction() == RTL)
   2917             left = min(columnRects()->last().x() + relativeOffset, left);
   2918         return left;
   2919     }
   2920 
   2921     if (m_floatingObjects) {
   2922         FloatingObject* r;
   2923         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2924         for ( ; (r = it.current()); ++it ) {
   2925             if (r->m_shouldPaint || r->m_renderer->hasSelfPaintingLayer()) {
   2926                 int lp = r->m_left + r->m_renderer->marginLeft() + r->m_renderer->leftmostPosition(false);
   2927                 left = min(left, lp + relativeOffset);
   2928             }
   2929         }
   2930     }
   2931 
   2932     if (!includeSelf && firstLineBox()) {
   2933         for (InlineRunBox* currBox = firstLineBox(); currBox; currBox = currBox->nextLineBox())
   2934             left = min(left, (int)currBox->x() + relativeOffset);
   2935     }
   2936 
   2937     return left;
   2938 }
   2939 
   2940 int
   2941 RenderBlock::leftBottom()
   2942 {
   2943     if (!m_floatingObjects) return 0;
   2944     int bottom = 0;
   2945     FloatingObject* r;
   2946     DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2947     for ( ; (r = it.current()); ++it )
   2948         if (r->m_bottom > bottom && r->type() == FloatingObject::FloatLeft)
   2949             bottom = r->m_bottom;
   2950 
   2951     return bottom;
   2952 }
   2953 
   2954 int
   2955 RenderBlock::rightBottom()
   2956 {
   2957     if (!m_floatingObjects) return 0;
   2958     int bottom = 0;
   2959     FloatingObject* r;
   2960     DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2961     for ( ; (r = it.current()); ++it )
   2962         if (r->m_bottom>bottom && r->type() == FloatingObject::FloatRight)
   2963             bottom = r->m_bottom;
   2964 
   2965     return bottom;
   2966 }
   2967 
   2968 void RenderBlock::markLinesDirtyInVerticalRange(int top, int bottom, RootInlineBox* highest)
   2969 {
   2970     if (top >= bottom)
   2971         return;
   2972 
   2973     RootInlineBox* lowestDirtyLine = lastRootBox();
   2974     RootInlineBox* afterLowest = lowestDirtyLine;
   2975     while (lowestDirtyLine && lowestDirtyLine->blockHeight() >= bottom) {
   2976         afterLowest = lowestDirtyLine;
   2977         lowestDirtyLine = lowestDirtyLine->prevRootBox();
   2978     }
   2979 
   2980     while (afterLowest && afterLowest != highest && afterLowest->blockHeight() >= top) {
   2981         afterLowest->markDirty();
   2982         afterLowest = afterLowest->prevRootBox();
   2983     }
   2984 }
   2985 
   2986 void RenderBlock::clearFloats()
   2987 {
   2988     // Inline blocks are covered by the isReplaced() check in the avoidFloats method.
   2989     if (avoidsFloats() || isRoot() || isRenderView() || isFloatingOrPositioned() || isTableCell()) {
   2990         if (m_floatingObjects)
   2991