Home | History | Annotate | Download | only in rendering
      1 /*
      2  * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org)
      3  *           (C) 1999 Antti Koivisto (koivisto (at) kde.org)
      4  *           (C) 2007 David Smith (catfish.man (at) gmail.com)
      5  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
      6  *
      7  * This library is free software; you can redistribute it and/or
      8  * modify it under the terms of the GNU Library General Public
      9  * License as published by the Free Software Foundation; either
     10  * version 2 of the License, or (at your option) any later version.
     11  *
     12  * This library is distributed in the hope that it will be useful,
     13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15  * Library General Public License for more details.
     16  *
     17  * You should have received a copy of the GNU Library General Public License
     18  * along with this library; see the file COPYING.LIB.  If not, write to
     19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     20  * Boston, MA 02110-1301, USA.
     21  */
     22 
     23 #include "config.h"
     24 #include "RenderBlock.h"
     25 
     26 #include "Document.h"
     27 #include "Element.h"
     28 #include "FloatQuad.h"
     29 #include "Frame.h"
     30 #include "FrameView.h"
     31 #include "GraphicsContext.h"
     32 #include "HTMLFormElement.h"
     33 #include "HTMLNames.h"
     34 #include "HitTestResult.h"
     35 #include "InlineTextBox.h"
     36 #include "RenderFlexibleBox.h"
     37 #include "RenderImage.h"
     38 #include "RenderInline.h"
     39 #include "RenderMarquee.h"
     40 #include "RenderReplica.h"
     41 #include "RenderTableCell.h"
     42 #include "RenderTextFragment.h"
     43 #include "RenderTheme.h"
     44 #include "RenderView.h"
     45 #include "SelectionController.h"
     46 #include "Settings.h"
     47 #include "TransformState.h"
     48 #include <wtf/StdLibExtras.h>
     49 
     50 #ifdef ANDROID_LAYOUT
     51 #include "Settings.h"
     52 #endif
     53 
     54 using namespace std;
     55 using namespace WTF;
     56 using namespace Unicode;
     57 
     58 namespace WebCore {
     59 
     60 // Number of pixels to allow as a fudge factor when clicking above or below a line.
     61 // clicking up to verticalLineClickFudgeFactor pixels above a line will correspond to the closest point on the line.
     62 static const int verticalLineClickFudgeFactor = 3;
     63 
     64 using namespace HTMLNames;
     65 
     66 struct ColumnInfo : public Noncopyable {
     67     ColumnInfo()
     68         : m_desiredColumnWidth(0)
     69         , m_desiredColumnCount(1)
     70         { }
     71     int m_desiredColumnWidth;
     72     unsigned m_desiredColumnCount;
     73     Vector<IntRect> m_columnRects;
     74 };
     75 
     76 typedef WTF::HashMap<const RenderBox*, ColumnInfo*> ColumnInfoMap;
     77 static ColumnInfoMap* gColumnInfoMap = 0;
     78 
     79 typedef WTF::HashMap<const RenderBlock*, HashSet<RenderBox*>*> PercentHeightDescendantsMap;
     80 static PercentHeightDescendantsMap* gPercentHeightDescendantsMap = 0;
     81 
     82 typedef WTF::HashMap<const RenderBox*, HashSet<RenderBlock*>*> PercentHeightContainerMap;
     83 static PercentHeightContainerMap* gPercentHeightContainerMap = 0;
     84 
     85 typedef WTF::HashMap<RenderBlock*, ListHashSet<RenderInline*>*> ContinuationOutlineTableMap;
     86 
     87 typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet;
     88 static int gDelayUpdateScrollInfo = 0;
     89 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0;
     90 
     91 // Our MarginInfo state used when laying out block children.
     92 RenderBlock::MarginInfo::MarginInfo(RenderBlock* block, int top, int bottom)
     93 {
     94     // Whether or not we can collapse our own margins with our children.  We don't do this
     95     // if we had any border/padding (obviously), if we're the root or HTML elements, or if
     96     // we're positioned, floating, a table cell.
     97     m_canCollapseWithChildren = !block->isRenderView() && !block->isRoot() && !block->isPositioned() &&
     98         !block->isFloating() && !block->isTableCell() && !block->hasOverflowClip() && !block->isInlineBlockOrInlineTable();
     99 
    100     m_canCollapseTopWithChildren = m_canCollapseWithChildren && (top == 0) && block->style()->marginTopCollapse() != MSEPARATE;
    101 
    102     // If any height other than auto is specified in CSS, then we don't collapse our bottom
    103     // margins with our children's margins.  To do otherwise would be to risk odd visual
    104     // effects when the children overflow out of the parent block and yet still collapse
    105     // with it.  We also don't collapse if we have any bottom border/padding.
    106     m_canCollapseBottomWithChildren = m_canCollapseWithChildren && (bottom == 0) &&
    107         (block->style()->height().isAuto() && block->style()->height().value() == 0) && block->style()->marginBottomCollapse() != MSEPARATE;
    108 
    109     m_quirkContainer = block->isTableCell() || block->isBody() || block->style()->marginTopCollapse() == MDISCARD ||
    110         block->style()->marginBottomCollapse() == MDISCARD;
    111 
    112     m_atTopOfBlock = true;
    113     m_atBottomOfBlock = false;
    114 
    115     m_posMargin = m_canCollapseTopWithChildren ? block->maxTopMargin(true) : 0;
    116     m_negMargin = m_canCollapseTopWithChildren ? block->maxTopMargin(false) : 0;
    117 
    118     m_topQuirk = m_bottomQuirk = m_determinedTopQuirk = false;
    119 }
    120 
    121 // -------------------------------------------------------------------------------------------------------
    122 
    123 RenderBlock::RenderBlock(Node* node)
    124       : RenderBox(node)
    125       , m_floatingObjects(0)
    126       , m_positionedObjects(0)
    127       , m_inlineContinuation(0)
    128       , m_maxMargin(0)
    129       , m_lineHeight(-1)
    130 {
    131     setChildrenInline(true);
    132 }
    133 
    134 RenderBlock::~RenderBlock()
    135 {
    136     delete m_floatingObjects;
    137     delete m_positionedObjects;
    138     delete m_maxMargin;
    139 
    140     if (hasColumns())
    141         delete gColumnInfoMap->take(this);
    142 
    143     if (gPercentHeightDescendantsMap) {
    144         if (HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->take(this)) {
    145             HashSet<RenderBox*>::iterator end = descendantSet->end();
    146             for (HashSet<RenderBox*>::iterator descendant = descendantSet->begin(); descendant != end; ++descendant) {
    147                 HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->get(*descendant);
    148                 ASSERT(containerSet);
    149                 if (!containerSet)
    150                     continue;
    151                 ASSERT(containerSet->contains(this));
    152                 containerSet->remove(this);
    153                 if (containerSet->isEmpty()) {
    154                     gPercentHeightContainerMap->remove(*descendant);
    155                     delete containerSet;
    156                 }
    157             }
    158             delete descendantSet;
    159         }
    160     }
    161 }
    162 
    163 void RenderBlock::destroy()
    164 {
    165     // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
    166     // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
    167     children()->destroyLeftoverChildren();
    168 
    169     // Destroy our continuation before anything other than anonymous children.
    170     // The reason we don't destroy it before anonymous children is that they may
    171     // have continuations of their own that are anonymous children of our continuation.
    172     if (m_inlineContinuation) {
    173         m_inlineContinuation->destroy();
    174         m_inlineContinuation = 0;
    175     }
    176 
    177     if (!documentBeingDestroyed()) {
    178         if (firstLineBox()) {
    179             // We can't wait for RenderBox::destroy to clear the selection,
    180             // because by then we will have nuked the line boxes.
    181             // FIXME: The SelectionController should be responsible for this when it
    182             // is notified of DOM mutations.
    183             if (isSelectionBorder())
    184                 view()->clearSelection();
    185 
    186             // If we are an anonymous block, then our line boxes might have children
    187             // that will outlast this block. In the non-anonymous block case those
    188             // children will be destroyed by the time we return from this function.
    189             if (isAnonymousBlock()) {
    190                 for (InlineFlowBox* box = firstLineBox(); box; box = box->nextFlowBox()) {
    191                     while (InlineBox* childBox = box->firstChild())
    192                         childBox->remove();
    193                 }
    194             }
    195         } else if (isInline() && parent())
    196             parent()->dirtyLinesFromChangedChild(this);
    197     }
    198 
    199     m_lineBoxes.deleteLineBoxes(renderArena());
    200 
    201     RenderBox::destroy();
    202 }
    203 
    204 void RenderBlock::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
    205 {
    206     setReplaced(newStyle->isDisplayReplacedType());
    207 
    208     if (style() && parent() && diff == StyleDifferenceLayout && style()->position() != newStyle->position()) {
    209         if (newStyle->position() == StaticPosition)
    210             // Clear our positioned objects list. Our absolutely positioned descendants will be
    211             // inserted into our containing block's positioned objects list during layout.
    212             removePositionedObjects(0);
    213         else if (style()->position() == StaticPosition) {
    214             // Remove our absolutely positioned descendants from their current containing block.
    215             // They will be inserted into our positioned objects list during layout.
    216             RenderObject* cb = parent();
    217             while (cb && (cb->style()->position() == StaticPosition || (cb->isInline() && !cb->isReplaced())) && !cb->isRenderView()) {
    218                 if (cb->style()->position() == RelativePosition && cb->isInline() && !cb->isReplaced()) {
    219                     cb = cb->containingBlock();
    220                     break;
    221                 }
    222                 cb = cb->parent();
    223             }
    224 
    225             if (cb->isRenderBlock())
    226                 toRenderBlock(cb)->removePositionedObjects(this);
    227         }
    228     }
    229 
    230     RenderBox::styleWillChange(diff, newStyle);
    231 }
    232 
    233 void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
    234 {
    235     RenderBox::styleDidChange(diff, oldStyle);
    236 
    237     // FIXME: We could save this call when the change only affected non-inherited properties
    238     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
    239         if (child->isAnonymousBlock()) {
    240             RefPtr<RenderStyle> newStyle = RenderStyle::create();
    241             newStyle->inheritFrom(style());
    242             newStyle->setDisplay(BLOCK);
    243             child->setStyle(newStyle.release());
    244         }
    245     }
    246 
    247     m_lineHeight = -1;
    248 
    249     // Update pseudos for :before and :after now.
    250     if (!isAnonymous() && document()->usesBeforeAfterRules() && canHaveChildren()) {
    251         updateBeforeAfterContent(BEFORE);
    252         updateBeforeAfterContent(AFTER);
    253     }
    254     updateFirstLetter();
    255 }
    256 
    257 void RenderBlock::updateBeforeAfterContent(PseudoId pseudoId)
    258 {
    259     // If this is an anonymous wrapper, then the parent applies its own pseudo-element style to it.
    260     if (parent() && parent()->createsAnonymousWrapper())
    261         return;
    262     return children()->updateBeforeAfterContent(this, pseudoId);
    263 }
    264 
    265 void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
    266 {
    267     // Make sure we don't append things after :after-generated content if we have it.
    268     if (!beforeChild && isAfterContent(lastChild()))
    269         beforeChild = lastChild();
    270 
    271     bool madeBoxesNonInline = false;
    272 
    273     // If the requested beforeChild is not one of our children, then this is because
    274     // there is an anonymous container within this object that contains the beforeChild.
    275     if (beforeChild && beforeChild->parent() != this) {
    276         RenderObject* anonymousChild = beforeChild->parent();
    277         ASSERT(anonymousChild);
    278 
    279         while (anonymousChild->parent() != this)
    280             anonymousChild = anonymousChild->parent();
    281 
    282         ASSERT(anonymousChild->isAnonymous());
    283 
    284         if (anonymousChild->isAnonymousBlock()) {
    285             // Insert the child into the anonymous block box instead of here.
    286             if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)
    287                 beforeChild->parent()->addChild(newChild, beforeChild);
    288             else
    289                 addChild(newChild, beforeChild->parent());
    290             return;
    291         }
    292 
    293         ASSERT(anonymousChild->isTable());
    294         if ((newChild->isTableCol() && newChild->style()->display() == TABLE_COLUMN_GROUP)
    295                 || (newChild->isRenderBlock() && newChild->style()->display() == TABLE_CAPTION)
    296                 || newChild->isTableSection()
    297                 || newChild->isTableRow()
    298                 || newChild->isTableCell()) {
    299             // Insert into the anonymous table.
    300             anonymousChild->addChild(newChild, beforeChild);
    301             return;
    302         }
    303 
    304         // Go on to insert before the anonymous table.
    305         beforeChild = anonymousChild;
    306     }
    307 
    308     // A block has to either have all of its children inline, or all of its children as blocks.
    309     // So, if our children are currently inline and a block child has to be inserted, we move all our
    310     // inline children into anonymous block boxes.
    311     if (childrenInline() && !newChild->isInline() && !newChild->isFloatingOrPositioned()) {
    312         // This is a block with inline content. Wrap the inline content in anonymous blocks.
    313         makeChildrenNonInline(beforeChild);
    314         madeBoxesNonInline = true;
    315 
    316         if (beforeChild && beforeChild->parent() != this) {
    317             beforeChild = beforeChild->parent();
    318             ASSERT(beforeChild->isAnonymousBlock());
    319             ASSERT(beforeChild->parent() == this);
    320         }
    321     } else if (!childrenInline() && (newChild->isFloatingOrPositioned() || newChild->isInline())) {
    322         // If we're inserting an inline child but all of our children are blocks, then we have to make sure
    323         // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise
    324         // a new one is created and inserted into our list of children in the appropriate position.
    325         RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();
    326 
    327         if (afterChild && afterChild->isAnonymousBlock()) {
    328             afterChild->addChild(newChild);
    329             return;
    330         }
    331 
    332         if (newChild->isInline()) {
    333             // No suitable existing anonymous box - create a new one.
    334             RenderBlock* newBox = createAnonymousBlock();
    335             RenderBox::addChild(newBox, beforeChild);
    336             newBox->addChild(newChild);
    337             return;
    338         }
    339     }
    340 
    341     RenderBox::addChild(newChild, beforeChild);
    342 
    343     if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRenderBlock())
    344         toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
    345     // this object may be dead here
    346 }
    347 
    348 static void getInlineRun(RenderObject* start, RenderObject* boundary,
    349                          RenderObject*& inlineRunStart,
    350                          RenderObject*& inlineRunEnd)
    351 {
    352     // Beginning at |start| we find the largest contiguous run of inlines that
    353     // we can.  We denote the run with start and end points, |inlineRunStart|
    354     // and |inlineRunEnd|.  Note that these two values may be the same if
    355     // we encounter only one inline.
    356     //
    357     // We skip any non-inlines we encounter as long as we haven't found any
    358     // inlines yet.
    359     //
    360     // |boundary| indicates a non-inclusive boundary point.  Regardless of whether |boundary|
    361     // is inline or not, we will not include it in a run with inlines before it.  It's as though we encountered
    362     // a non-inline.
    363 
    364     // Start by skipping as many non-inlines as we can.
    365     RenderObject * curr = start;
    366     bool sawInline;
    367     do {
    368         while (curr && !(curr->isInline() || curr->isFloatingOrPositioned()))
    369             curr = curr->nextSibling();
    370 
    371         inlineRunStart = inlineRunEnd = curr;
    372 
    373         if (!curr)
    374             return; // No more inline children to be found.
    375 
    376         sawInline = curr->isInline();
    377 
    378         curr = curr->nextSibling();
    379         while (curr && (curr->isInline() || curr->isFloatingOrPositioned()) && (curr != boundary)) {
    380             inlineRunEnd = curr;
    381             if (curr->isInline())
    382                 sawInline = true;
    383             curr = curr->nextSibling();
    384         }
    385     } while (!sawInline);
    386 }
    387 
    388 void RenderBlock::deleteLineBoxTree()
    389 {
    390     m_lineBoxes.deleteLineBoxTree(renderArena());
    391 }
    392 
    393 RootInlineBox* RenderBlock::createRootInlineBox()
    394 {
    395     return new (renderArena()) RootInlineBox(this);
    396 }
    397 
    398 RootInlineBox* RenderBlock::createAndAppendRootInlineBox()
    399 {
    400     RootInlineBox* rootBox = createRootInlineBox();
    401     m_lineBoxes.appendLineBox(rootBox);
    402     return rootBox;
    403 }
    404 
    405 void RenderBlock::moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* child)
    406 {
    407     ASSERT(this == child->parent());
    408     toChildList->appendChildNode(to, children()->removeChildNode(this, child, false), false);
    409 }
    410 
    411 void RenderBlock::moveChildTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* beforeChild, RenderObject* child)
    412 {
    413     ASSERT(this == child->parent());
    414     ASSERT(!beforeChild || to == beforeChild->parent());
    415     toChildList->insertChildNode(to, children()->removeChildNode(this, child, false), beforeChild, false);
    416 }
    417 
    418 void RenderBlock::moveAllChildrenTo(RenderObject* to, RenderObjectChildList* toChildList)
    419 {
    420     RenderObject* nextChild = children()->firstChild();
    421     while (nextChild) {
    422         RenderObject* child = nextChild;
    423         nextChild = child->nextSibling();
    424         toChildList->appendChildNode(to, children()->removeChildNode(this, child, false), false);
    425     }
    426 }
    427 
    428 void RenderBlock::moveAllChildrenTo(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* beforeChild)
    429 {
    430     ASSERT(!beforeChild || to == beforeChild->parent());
    431     if (!beforeChild) {
    432         moveAllChildrenTo(to, toChildList);
    433         return;
    434     }
    435     RenderObject* nextChild = children()->firstChild();
    436     while (nextChild) {
    437         RenderObject* child = nextChild;
    438         nextChild = child->nextSibling();
    439         toChildList->insertChildNode(to, children()->removeChildNode(this, child, false), beforeChild, false);
    440     }
    441 }
    442 
    443 void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
    444 {
    445     // makeChildrenNonInline takes a block whose children are *all* inline and it
    446     // makes sure that inline children are coalesced under anonymous
    447     // blocks.  If |insertionPoint| is defined, then it represents the insertion point for
    448     // the new block child that is causing us to have to wrap all the inlines.  This
    449     // means that we cannot coalesce inlines before |insertionPoint| with inlines following
    450     // |insertionPoint|, because the new child is going to be inserted in between the inlines,
    451     // splitting them.
    452     ASSERT(isInlineBlockOrInlineTable() || !isInline());
    453     ASSERT(!insertionPoint || insertionPoint->parent() == this);
    454 
    455     setChildrenInline(false);
    456 
    457     RenderObject *child = firstChild();
    458     if (!child)
    459         return;
    460 
    461     deleteLineBoxTree();
    462 
    463     while (child) {
    464         RenderObject *inlineRunStart, *inlineRunEnd;
    465         getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);
    466 
    467         if (!inlineRunStart)
    468             break;
    469 
    470         child = inlineRunEnd->nextSibling();
    471 
    472         RenderBlock* block = createAnonymousBlock();
    473         children()->insertChildNode(this, block, inlineRunStart);
    474         RenderObject* o = inlineRunStart;
    475         while (o != inlineRunEnd) {
    476             RenderObject* no = o;
    477             o = no->nextSibling();
    478 
    479             moveChildTo(block, block->children(), no);
    480         }
    481         moveChildTo(block, block->children(), inlineRunEnd);
    482     }
    483 
    484 #ifndef NDEBUG
    485     for (RenderObject *c = firstChild(); c; c = c->nextSibling())
    486         ASSERT(!c->isInline());
    487 #endif
    488 
    489     repaint();
    490 }
    491 
    492 void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
    493 {
    494     ASSERT(child->isAnonymousBlock());
    495     ASSERT(!child->childrenInline());
    496 
    497     if (child->inlineContinuation())
    498         return;
    499 
    500     RenderObject* firstAnChild = child->m_children.firstChild();
    501     RenderObject* lastAnChild = child->m_children.lastChild();
    502     if (firstAnChild) {
    503         RenderObject* o = firstAnChild;
    504         while (o) {
    505             o->setParent(this);
    506             o = o->nextSibling();
    507         }
    508         firstAnChild->setPreviousSibling(child->previousSibling());
    509         lastAnChild->setNextSibling(child->nextSibling());
    510         if (child->previousSibling())
    511             child->previousSibling()->setNextSibling(firstAnChild);
    512         if (child->nextSibling())
    513             child->nextSibling()->setPreviousSibling(lastAnChild);
    514     } else {
    515         if (child->previousSibling())
    516             child->previousSibling()->setNextSibling(child->nextSibling());
    517         if (child->nextSibling())
    518             child->nextSibling()->setPreviousSibling(child->previousSibling());
    519     }
    520     if (child == m_children.firstChild())
    521         m_children.setFirstChild(firstAnChild);
    522     if (child == m_children.lastChild())
    523         m_children.setLastChild(lastAnChild);
    524     child->setParent(0);
    525     child->setPreviousSibling(0);
    526     child->setNextSibling(0);
    527 
    528     child->children()->setFirstChild(0);
    529     child->m_next = 0;
    530 
    531     child->destroy();
    532 }
    533 
    534 void RenderBlock::removeChild(RenderObject* oldChild)
    535 {
    536     // If this child is a block, and if our previous and next siblings are
    537     // both anonymous blocks with inline content, then we can go ahead and
    538     // fold the inline content back together.
    539     RenderObject* prev = oldChild->previousSibling();
    540     RenderObject* next = oldChild->nextSibling();
    541     bool canDeleteAnonymousBlocks = !documentBeingDestroyed() && !isInline() && !oldChild->isInline() &&
    542                                     (!oldChild->isRenderBlock() || !toRenderBlock(oldChild)->inlineContinuation()) &&
    543                                     (!prev || (prev->isAnonymousBlock() && prev->childrenInline())) &&
    544                                     (!prev || (!prev->firstChild() || !prev->firstChild()->isInline() || !prev->firstChild()->isRunIn())) &&
    545                                     (!next || (next->isAnonymousBlock() && next->childrenInline()));
    546     if (canDeleteAnonymousBlocks && prev && next) {
    547         // Take all the children out of the |next| block and put them in
    548         // the |prev| block.
    549         prev->setNeedsLayoutAndPrefWidthsRecalc();
    550         RenderBlock* nextBlock = toRenderBlock(next);
    551         RenderBlock* prevBlock = toRenderBlock(prev);
    552         nextBlock->moveAllChildrenTo(prevBlock, prevBlock->children());
    553         // Delete the now-empty block's lines and nuke it.
    554         nextBlock->deleteLineBoxTree();
    555         nextBlock->destroy();
    556     }
    557 
    558     RenderBox::removeChild(oldChild);
    559 
    560     RenderObject* child = prev ? prev : next;
    561     if (canDeleteAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && !isFlexibleBox()) {
    562         // The removal has knocked us down to containing only a single anonymous
    563         // box.  We can go ahead and pull the content right back up into our
    564         // box.
    565         setNeedsLayoutAndPrefWidthsRecalc();
    566         RenderBlock* anonBlock = toRenderBlock(children()->removeChildNode(this, child, false));
    567         setChildrenInline(true);
    568         anonBlock->moveAllChildrenTo(this, children());
    569         // Delete the now-empty block's lines and nuke it.
    570         anonBlock->deleteLineBoxTree();
    571         anonBlock->destroy();
    572     }
    573 
    574     // If this was our last child be sure to clear out our line boxes.
    575     if (childrenInline() && !firstChild())
    576         lineBoxes()->deleteLineBoxes(renderArena());
    577 }
    578 
    579 bool RenderBlock::isSelfCollapsingBlock() const
    580 {
    581     // We are not self-collapsing if we
    582     // (a) have a non-zero height according to layout (an optimization to avoid wasting time)
    583     // (b) are a table,
    584     // (c) have border/padding,
    585     // (d) have a min-height
    586     // (e) have specified that one of our margins can't collapse using a CSS extension
    587     if (height() > 0 ||
    588         isTable() || (borderBottom() + paddingBottom() + borderTop() + paddingTop()) != 0 ||
    589         style()->minHeight().isPositive() ||
    590         style()->marginTopCollapse() == MSEPARATE || style()->marginBottomCollapse() == MSEPARATE)
    591         return false;
    592 
    593     bool hasAutoHeight = style()->height().isAuto();
    594     if (style()->height().isPercent() && !style()->htmlHacks()) {
    595         hasAutoHeight = true;
    596         for (RenderBlock* cb = containingBlock(); !cb->isRenderView(); cb = cb->containingBlock()) {
    597             if (cb->style()->height().isFixed() || cb->isTableCell())
    598                 hasAutoHeight = false;
    599         }
    600     }
    601 
    602     // If the height is 0 or auto, then whether or not we are a self-collapsing block depends
    603     // on whether we have content that is all self-collapsing or not.
    604     if (hasAutoHeight || ((style()->height().isFixed() || style()->height().isPercent()) && style()->height().isZero())) {
    605         // If the block has inline children, see if we generated any line boxes.  If we have any
    606         // line boxes, then we can't be self-collapsing, since we have content.
    607         if (childrenInline())
    608             return !firstLineBox();
    609 
    610         // Whether or not we collapse is dependent on whether all our normal flow children
    611         // are also self-collapsing.
    612         for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
    613             if (child->isFloatingOrPositioned())
    614                 continue;
    615             if (!child->isSelfCollapsingBlock())
    616                 return false;
    617         }
    618         return true;
    619     }
    620     return false;
    621 }
    622 
    623 void RenderBlock::startDelayUpdateScrollInfo()
    624 {
    625     if (gDelayUpdateScrollInfo == 0) {
    626         ASSERT(!gDelayedUpdateScrollInfoSet);
    627         gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet;
    628     }
    629     ASSERT(gDelayedUpdateScrollInfoSet);
    630     ++gDelayUpdateScrollInfo;
    631 }
    632 
    633 void RenderBlock::finishDelayUpdateScrollInfo()
    634 {
    635     --gDelayUpdateScrollInfo;
    636     ASSERT(gDelayUpdateScrollInfo >= 0);
    637     if (gDelayUpdateScrollInfo == 0) {
    638         ASSERT(gDelayedUpdateScrollInfoSet);
    639 
    640         OwnPtr<DelayedUpdateScrollInfoSet> infoSet(gDelayedUpdateScrollInfoSet);
    641         gDelayedUpdateScrollInfoSet = 0;
    642 
    643         for (DelayedUpdateScrollInfoSet::iterator it = infoSet->begin(); it != infoSet->end(); ++it) {
    644             RenderBlock* block = *it;
    645             if (block->hasOverflowClip()) {
    646                 block->layer()->updateScrollInfoAfterLayout();
    647             }
    648         }
    649     }
    650 }
    651 
    652 void RenderBlock::updateScrollInfoAfterLayout()
    653 {
    654     if (hasOverflowClip()) {
    655         if (gDelayUpdateScrollInfo)
    656             gDelayedUpdateScrollInfoSet->add(this);
    657         else
    658             layer()->updateScrollInfoAfterLayout();
    659     }
    660 }
    661 
    662 void RenderBlock::layout()
    663 {
    664     // Update our first letter info now.
    665     updateFirstLetter();
    666 
    667     // Table cells call layoutBlock directly, so don't add any logic here.  Put code into
    668     // layoutBlock().
    669     layoutBlock(false);
    670 
    671     // It's safe to check for control clip here, since controls can never be table cells.
    672     // If we have a lightweight clip, there can never be any overflow from children.
    673     if (hasControlClip() && m_overflow)
    674         clearLayoutOverflow();
    675 }
    676 
    677 void RenderBlock::layoutBlock(bool relayoutChildren)
    678 {
    679     ASSERT(needsLayout());
    680 
    681     if (isInline() && !isInlineBlockOrInlineTable()) // Inline <form>s inside various table elements can
    682         return;                                      // cause us to come in here.  Just bail.
    683 
    684     if (!relayoutChildren && layoutOnlyPositionedObjects())
    685         return;
    686 
    687     LayoutRepainter repainter(*this, m_everHadLayout && checkForRepaintDuringLayout());
    688     LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection());
    689 
    690     int oldWidth = width();
    691     int oldColumnWidth = desiredColumnWidth();
    692 
    693 #ifdef ANDROID_LAYOUT
    694     int oldVisibleWidth = m_visibleWidth;
    695 #endif
    696 
    697     calcWidth();
    698     calcColumnWidth();
    699 
    700     m_overflow.clear();
    701 
    702     if (oldWidth != width() || oldColumnWidth != desiredColumnWidth())
    703         relayoutChildren = true;
    704 
    705 #ifdef ANDROID_LAYOUT
    706     const Settings* settings = document()->settings();
    707     ASSERT(settings);
    708     if (oldVisibleWidth != m_visibleWidth
    709             && settings->layoutAlgorithm() == Settings::kLayoutFitColumnToScreen)
    710         relayoutChildren = true;
    711 #endif
    712 
    713     clearFloats();
    714 
    715     int previousHeight = height();
    716     setHeight(0);
    717 
    718     // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track
    719     // our current maximal positive and negative margins.  These values are used when we
    720     // are collapsed with adjacent blocks, so for example, if you have block A and B
    721     // collapsing together, then you'd take the maximal positive margin from both A and B
    722     // and subtract it from the maximal negative margin from both A and B to get the
    723     // true collapsed margin.  This algorithm is recursive, so when we finish layout()
    724     // our block knows its current maximal positive/negative values.
    725     //
    726     // Start out by setting our margin values to our current margins.  Table cells have
    727     // no margins, so we don't fill in the values for table cells.
    728     bool isCell = isTableCell();
    729     if (!isCell) {
    730         initMaxMarginValues();
    731 
    732         setTopMarginQuirk(style()->marginTop().quirk());
    733         setBottomMarginQuirk(style()->marginBottom().quirk());
    734 
    735         Node* n = node();
    736         if (n && n->hasTagName(formTag) && static_cast<HTMLFormElement*>(n)->isMalformed()) {
    737             // See if this form is malformed (i.e., unclosed). If so, don't give the form
    738             // a bottom margin.
    739             setMaxBottomMargins(0, 0);
    740         }
    741     }
    742 
    743     // For overflow:scroll blocks, ensure we have both scrollbars in place always.
    744     if (scrollsOverflow()) {
    745         if (style()->overflowX() == OSCROLL)
    746             layer()->setHasHorizontalScrollbar(true);
    747         if (style()->overflowY() == OSCROLL)
    748             layer()->setHasVerticalScrollbar(true);
    749     }
    750 
    751     int repaintTop = 0;
    752     int repaintBottom = 0;
    753     int maxFloatBottom = 0;
    754     if (childrenInline())
    755         layoutInlineChildren(relayoutChildren, repaintTop, repaintBottom);
    756     else
    757         layoutBlockChildren(relayoutChildren, maxFloatBottom);
    758 
    759     // Expand our intrinsic height to encompass floats.
    760     int toAdd = borderBottom() + paddingBottom() + horizontalScrollbarHeight();
    761     if (floatBottom() > (height() - toAdd) && expandsToEncloseOverhangingFloats())
    762         setHeight(floatBottom() + toAdd);
    763 
    764     // Now lay out our columns within this intrinsic height, since they can slightly affect the intrinsic height as
    765     // we adjust for clean column breaks.
    766     int singleColumnBottom = layoutColumns();
    767 
    768     // Calculate our new height.
    769     int oldHeight = height();
    770     calcHeight();
    771     if (oldHeight != height()) {
    772         if (oldHeight > height() && maxFloatBottom > height() && !childrenInline()) {
    773             // One of our children's floats may have become an overhanging float for us. We need to look for it.
    774             for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
    775                 if (child->isBlockFlow() && !child->isFloatingOrPositioned()) {
    776                     RenderBlock* block = toRenderBlock(child);
    777                     if (block->floatBottom() + block->y() > height())
    778                         addOverhangingFloats(block, -block->x(), -block->y(), false);
    779                 }
    780             }
    781         }
    782 
    783         // We have to rebalance columns to the new height.
    784         layoutColumns(singleColumnBottom);
    785     }
    786 
    787     if (previousHeight != height())
    788         relayoutChildren = true;
    789 
    790     // It's weird that we're treating float information as normal flow overflow, but we do this because floatRect() isn't
    791     // able to be propagated up the render tree yet.  Overflow information is however.  This check is designed to catch anyone
    792     // who wasn't going to propagate float information up to the parent and yet could potentially be painted by its ancestor.
    793     if (isRoot() || expandsToEncloseOverhangingFloats())
    794         addOverflowFromFloats();
    795 
    796     // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway).
    797     if (!hasColumns()) {
    798         if (childrenInline())
    799             addOverflowFromInlineChildren();
    800         else
    801             addOverflowFromBlockChildren();
    802     }
    803 
    804     // Add visual overflow from box-shadow and reflections.
    805     addShadowOverflow();
    806 
    807     layoutPositionedObjects(relayoutChildren || isRoot());
    808 
    809     positionListMarker();
    810 
    811     statePusher.pop();
    812 
    813     // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
    814     // we overflow or not.
    815     updateScrollInfoAfterLayout();
    816 
    817     // Repaint with our new bounds if they are different from our old bounds.
    818     bool didFullRepaint = repainter.repaintAfterLayout();
    819     if (!didFullRepaint && repaintTop != repaintBottom && (style()->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) {
    820         int repaintLeft = min(leftVisualOverflow(), leftLayoutOverflow());
    821         int repaintRight = max(rightVisualOverflow(), rightLayoutOverflow());
    822         IntRect repaintRect(repaintLeft, repaintTop, repaintRight - repaintLeft, repaintBottom - repaintTop);
    823 
    824         // FIXME: Deal with multiple column repainting.  We have to split the repaint
    825         // rect up into multiple rects if it spans columns.
    826 
    827         repaintRect.inflate(maximalOutlineSize(PaintPhaseOutline));
    828 
    829         if (hasOverflowClip()) {
    830             // Adjust repaint rect for scroll offset
    831             int x = repaintRect.x();
    832             int y = repaintRect.y();
    833             layer()->subtractScrolledContentOffset(x, y);
    834             repaintRect.setX(x);
    835             repaintRect.setY(y);
    836 
    837             // Don't allow this rect to spill out of our overflow box.
    838             repaintRect.intersect(IntRect(0, 0, width(), height()));
    839         }
    840 
    841         // Make sure the rect is still non-empty after intersecting for overflow above
    842         if (!repaintRect.isEmpty()) {
    843             repaintRectangle(repaintRect); // We need to do a partial repaint of our content.
    844             if (hasReflection())
    845                 repaintRectangle(reflectedRect(repaintRect));
    846         }
    847     }
    848     setNeedsLayout(false);
    849 }
    850 
    851 void RenderBlock::addOverflowFromBlockChildren()
    852 {
    853     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
    854         if (!child->isFloatingOrPositioned())
    855             addOverflowFromChild(child);
    856     }
    857 }
    858 
    859 void RenderBlock::addOverflowFromFloats()
    860 {
    861     IntRect result;
    862     if (!m_floatingObjects)
    863         return;
    864     FloatingObject* r;
    865     DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
    866     for (; (r = it.current()); ++it) {
    867         if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer())
    868             addOverflowFromChild(r->m_renderer, IntSize(r->m_left + r->m_renderer->marginLeft(), r->m_top + r->m_renderer->marginTop()));
    869     }
    870     return;
    871 }
    872 
    873 bool RenderBlock::expandsToEncloseOverhangingFloats() const
    874 {
    875     return isInlineBlockOrInlineTable() || isFloatingOrPositioned() || hasOverflowClip() || (parent() && parent()->isFlexibleBox()) || hasColumns() || isTableCell() || isFieldset();
    876 }
    877 
    878 void RenderBlock::adjustPositionedBlock(RenderBox* child, const MarginInfo& marginInfo)
    879 {
    880     if (child->style()->hasStaticX()) {
    881         if (style()->direction() == LTR)
    882             child->layer()->setStaticX(borderLeft() + paddingLeft());
    883         else
    884             child->layer()->setStaticX(borderRight() + paddingRight());
    885     }
    886 
    887     if (child->style()->hasStaticY()) {
    888         int y = height();
    889         if (!marginInfo.canCollapseWithTop()) {
    890             child->calcVerticalMargins();
    891             int marginTop = child->marginTop();
    892             int collapsedTopPos = marginInfo.posMargin();
    893             int collapsedTopNeg = marginInfo.negMargin();
    894             if (marginTop > 0) {
    895                 if (marginTop > collapsedTopPos)
    896                     collapsedTopPos = marginTop;
    897             } else {
    898                 if (-marginTop > collapsedTopNeg)
    899                     collapsedTopNeg = -marginTop;
    900             }
    901             y += (collapsedTopPos - collapsedTopNeg) - marginTop;
    902         }
    903         RenderLayer* childLayer = child->layer();
    904         if (childLayer->staticY() != y) {
    905             child->layer()->setStaticY(y);
    906             child->setChildNeedsLayout(true, false);
    907         }
    908     }
    909 }
    910 
    911 void RenderBlock::adjustFloatingBlock(const MarginInfo& marginInfo)
    912 {
    913     // The float should be positioned taking into account the bottom margin
    914     // of the previous flow.  We add that margin into the height, get the
    915     // float positioned properly, and then subtract the margin out of the
    916     // height again.  In the case of self-collapsing blocks, we always just
    917     // use the top margins, since the self-collapsing block collapsed its
    918     // own bottom margin into its top margin.
    919     //
    920     // Note also that the previous flow may collapse its margin into the top of
    921     // our block.  If this is the case, then we do not add the margin in to our
    922     // height when computing the position of the float.   This condition can be tested
    923     // for by simply calling canCollapseWithTop.  See
    924     // http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html for
    925     // an example of this scenario.
    926     int marginOffset = marginInfo.canCollapseWithTop() ? 0 : marginInfo.margin();
    927     setHeight(height() + marginOffset);
    928     positionNewFloats();
    929     setHeight(height() - marginOffset);
    930 }
    931 
    932 bool RenderBlock::handleSpecialChild(RenderBox* child, const MarginInfo& marginInfo)
    933 {
    934     // Handle in the given order
    935     return handlePositionedChild(child, marginInfo)
    936         || handleFloatingChild(child, marginInfo)
    937         || handleRunInChild(child);
    938 }
    939 
    940 
    941 bool RenderBlock::handlePositionedChild(RenderBox* child, const MarginInfo& marginInfo)
    942 {
    943     if (child->isPositioned()) {
    944         child->containingBlock()->insertPositionedObject(child);
    945         adjustPositionedBlock(child, marginInfo);
    946         return true;
    947     }
    948     return false;
    949 }
    950 
    951 bool RenderBlock::handleFloatingChild(RenderBox* child, const MarginInfo& marginInfo)
    952 {
    953     if (child->isFloating()) {
    954         insertFloatingObject(child);
    955         adjustFloatingBlock(marginInfo);
    956         return true;
    957     }
    958     return false;
    959 }
    960 
    961 bool RenderBlock::handleRunInChild(RenderBox* child)
    962 {
    963     // See if we have a run-in element with inline children.  If the
    964     // children aren't inline, then just treat the run-in as a normal
    965     // block.
    966     if (!child->isRunIn() || !child->childrenInline())
    967         return false;
    968     // FIXME: We don't handle non-block elements with run-in for now.
    969     if (!child->isRenderBlock())
    970         return false;
    971 
    972     // Get the next non-positioned/non-floating RenderBlock.
    973     RenderBlock* blockRunIn = toRenderBlock(child);
    974     RenderObject* curr = blockRunIn->nextSibling();
    975     while (curr && curr->isFloatingOrPositioned())
    976         curr = curr->nextSibling();
    977 
    978     if (!curr || !curr->isRenderBlock() || !curr->childrenInline() || curr->isRunIn() || curr->isAnonymous())
    979         return false;
    980 
    981     RenderBlock* currBlock = toRenderBlock(curr);
    982 
    983     // Remove the old child.
    984     children()->removeChildNode(this, blockRunIn);
    985 
    986     // Create an inline.
    987     Node* runInNode = blockRunIn->node();
    988     RenderInline* inlineRunIn = new (renderArena()) RenderInline(runInNode ? runInNode : document());
    989     inlineRunIn->setStyle(blockRunIn->style());
    990 
    991     bool runInIsGenerated = child->style()->styleType() == BEFORE || child->style()->styleType() == AFTER;
    992 
    993     // Move the nodes from the old child to the new child, but skip any :before/:after content.  It has already
    994     // been regenerated by the new inline.
    995     for (RenderObject* runInChild = blockRunIn->firstChild(); runInChild; runInChild = runInChild->nextSibling()) {
    996         if (runInIsGenerated || (runInChild->style()->styleType() != BEFORE && runInChild->style()->styleType() != AFTER)) {
    997             blockRunIn->children()->removeChildNode(blockRunIn, runInChild, false);
    998             inlineRunIn->addChild(runInChild); // Use addChild instead of appendChildNode since it handles correct placement of the children relative to :after-generated content.
    999         }
   1000     }
   1001 
   1002     // Now insert the new child under |currBlock|.
   1003     currBlock->children()->insertChildNode(currBlock, inlineRunIn, currBlock->firstChild());
   1004 
   1005     // If the run-in had an element, we need to set the new renderer.
   1006     if (runInNode)
   1007         runInNode->setRenderer(inlineRunIn);
   1008 
   1009     // Destroy the block run-in, which includes deleting its line box tree.
   1010     blockRunIn->deleteLineBoxTree();
   1011     blockRunIn->destroy();
   1012 
   1013     // The block acts like an inline, so just null out its
   1014     // position.
   1015 
   1016     return true;
   1017 }
   1018 
   1019 int RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo)
   1020 {
   1021     // Get our max pos and neg top margins.
   1022     int posTop = child->maxTopMargin(true);
   1023     int negTop = child->maxTopMargin(false);
   1024 
   1025     // For self-collapsing blocks, collapse our bottom margins into our
   1026     // top to get new posTop and negTop values.
   1027     if (child->isSelfCollapsingBlock()) {
   1028         posTop = max(posTop, child->maxBottomMargin(true));
   1029         negTop = max(negTop, child->maxBottomMargin(false));
   1030     }
   1031 
   1032     // See if the top margin is quirky. We only care if this child has
   1033     // margins that will collapse with us.
   1034     bool topQuirk = child->isTopMarginQuirk() || style()->marginTopCollapse() == MDISCARD;
   1035 
   1036     if (marginInfo.canCollapseWithTop()) {
   1037         // This child is collapsing with the top of the
   1038         // block.  If it has larger margin values, then we need to update
   1039         // our own maximal values.
   1040         if (!style()->htmlHacks() || !marginInfo.quirkContainer() || !topQuirk)
   1041             setMaxTopMargins(max(posTop, maxTopPosMargin()), max(negTop, maxTopNegMargin()));
   1042 
   1043         // The minute any of the margins involved isn't a quirk, don't
   1044         // collapse it away, even if the margin is smaller (www.webreference.com
   1045         // has an example of this, a <dt> with 0.8em author-specified inside
   1046         // a <dl> inside a <td>.
   1047         if (!marginInfo.determinedTopQuirk() && !topQuirk && (posTop-negTop)) {
   1048             setTopMarginQuirk(false);
   1049             marginInfo.setDeterminedTopQuirk(true);
   1050         }
   1051 
   1052         if (!marginInfo.determinedTopQuirk() && topQuirk && marginTop() == 0)
   1053             // We have no top margin and our top child has a quirky margin.
   1054             // We will pick up this quirky margin and pass it through.
   1055             // This deals with the <td><div><p> case.
   1056             // Don't do this for a block that split two inlines though.  You do
   1057             // still apply margins in this case.
   1058             setTopMarginQuirk(true);
   1059     }
   1060 
   1061     if (marginInfo.quirkContainer() && marginInfo.atTopOfBlock() && (posTop - negTop))
   1062         marginInfo.setTopQuirk(topQuirk);
   1063 
   1064     int ypos = height();
   1065     if (child->isSelfCollapsingBlock()) {
   1066         // This child has no height.  We need to compute our
   1067         // position before we collapse the child's margins together,
   1068         // so that we can get an accurate position for the zero-height block.
   1069         int collapsedTopPos = max(marginInfo.posMargin(), child->maxTopMargin(true));
   1070         int collapsedTopNeg = max(marginInfo.negMargin(), child->maxTopMargin(false));
   1071         marginInfo.setMargin(collapsedTopPos, collapsedTopNeg);
   1072 
   1073         // Now collapse the child's margins together, which means examining our
   1074         // bottom margin values as well.
   1075         marginInfo.setPosMarginIfLarger(child->maxBottomMargin(true));
   1076         marginInfo.setNegMarginIfLarger(child->maxBottomMargin(false));
   1077 
   1078         if (!marginInfo.canCollapseWithTop())
   1079             // We need to make sure that the position of the self-collapsing block
   1080             // is correct, since it could have overflowing content
   1081             // that needs to be positioned correctly (e.g., a block that
   1082             // had a specified height of 0 but that actually had subcontent).
   1083             ypos = height() + collapsedTopPos - collapsedTopNeg;
   1084     }
   1085     else {
   1086         if (child->style()->marginTopCollapse() == MSEPARATE) {
   1087             setHeight(height() + marginInfo.margin() + child->marginTop());
   1088             ypos = height();
   1089         }
   1090         else if (!marginInfo.atTopOfBlock() ||
   1091             (!marginInfo.canCollapseTopWithChildren()
   1092              && (!style()->htmlHacks() || !marginInfo.quirkContainer() || !marginInfo.topQuirk()))) {
   1093             // We're collapsing with a previous sibling's margins and not
   1094             // with the top of the block.
   1095             setHeight(height() + max(marginInfo.posMargin(), posTop) - max(marginInfo.negMargin(), negTop));
   1096             ypos = height();
   1097         }
   1098 
   1099         marginInfo.setPosMargin(child->maxBottomMargin(true));
   1100         marginInfo.setNegMargin(child->maxBottomMargin(false));
   1101 
   1102         if (marginInfo.margin())
   1103             marginInfo.setBottomQuirk(child->isBottomMarginQuirk() || style()->marginBottomCollapse() == MDISCARD);
   1104     }
   1105 
   1106     return ypos;
   1107 }
   1108 
   1109 int RenderBlock::clearFloatsIfNeeded(RenderBox* child, MarginInfo& marginInfo, int oldTopPosMargin, int oldTopNegMargin, int yPos)
   1110 {
   1111     int heightIncrease = getClearDelta(child, yPos);
   1112     if (!heightIncrease)
   1113         return yPos;
   1114 
   1115     if (child->isSelfCollapsingBlock()) {
   1116         // For self-collapsing blocks that clear, they can still collapse their
   1117         // margins with following siblings.  Reset the current margins to represent
   1118         // the self-collapsing block's margins only.
   1119         // CSS2.1 states:
   1120         // "An element that has had clearance applied to it never collapses its top margin with its parent block's bottom margin.
   1121         // Therefore if we are at the bottom of the block, let's go ahead and reset margins to only include the
   1122         // self-collapsing block's bottom margin.
   1123         bool atBottomOfBlock = true;
   1124         for (RenderBox* curr = child->nextSiblingBox(); curr && atBottomOfBlock; curr = curr->nextSiblingBox()) {
   1125             if (!curr->isFloatingOrPositioned())
   1126                 atBottomOfBlock = false;
   1127         }
   1128         if (atBottomOfBlock) {
   1129             marginInfo.setPosMargin(child->maxBottomMargin(true));
   1130             marginInfo.setNegMargin(child->maxBottomMargin(false));
   1131         } else {
   1132             marginInfo.setPosMargin(max(child->maxTopMargin(true), child->maxBottomMargin(true)));
   1133             marginInfo.setNegMargin(max(child->maxTopMargin(false), child->maxBottomMargin(false)));
   1134         }
   1135 
   1136         // Adjust our height such that we are ready to be collapsed with subsequent siblings (or the bottom
   1137         // of the parent block).
   1138         setHeight(child->y() - max(0, marginInfo.margin()));
   1139     } else
   1140         // Increase our height by the amount we had to clear.
   1141         setHeight(height() + heightIncrease);
   1142 
   1143     if (marginInfo.canCollapseWithTop()) {
   1144         // We can no longer collapse with the top of the block since a clear
   1145         // occurred.  The empty blocks collapse into the cleared block.
   1146         // FIXME: This isn't quite correct.  Need clarification for what to do
   1147         // if the height the cleared block is offset by is smaller than the
   1148         // margins involved.
   1149         setMaxTopMargins(oldTopPosMargin, oldTopNegMargin);
   1150         marginInfo.setAtTopOfBlock(false);
   1151     }
   1152 
   1153     return yPos + heightIncrease;
   1154 }
   1155 
   1156 int RenderBlock::estimateVerticalPosition(RenderBox* child, const MarginInfo& marginInfo)
   1157 {
   1158     // FIXME: We need to eliminate the estimation of vertical position, because when it's wrong we sometimes trigger a pathological
   1159     // relayout if there are intruding floats.
   1160     int yPosEstimate = height();
   1161     if (!marginInfo.canCollapseWithTop()) {
   1162         int childMarginTop = child->selfNeedsLayout() ? child->marginTop() : child->collapsedMarginTop();
   1163         yPosEstimate += max(marginInfo.margin(), childMarginTop);
   1164     }
   1165     yPosEstimate += getClearDelta(child, yPosEstimate);
   1166     return yPosEstimate;
   1167 }
   1168 
   1169 void RenderBlock::determineHorizontalPosition(RenderBox* child)
   1170 {
   1171     if (style()->direction() == LTR) {
   1172         int xPos = borderLeft() + paddingLeft();
   1173 
   1174         // Add in our left margin.
   1175         int chPos = xPos + child->marginLeft();
   1176 
   1177         // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats.  They need
   1178         // to shift over as necessary to dodge any floats that might get in the way.
   1179         if (child->avoidsFloats()) {
   1180             int leftOff = leftOffset(height(), false);
   1181             if (style()->textAlign() != WEBKIT_CENTER && child->style()->marginLeft().type() != Auto) {
   1182                 if (child->marginLeft() < 0)
   1183                     leftOff += child->marginLeft();
   1184                 chPos = max(chPos, leftOff); // Let the float sit in the child's margin if it can fit.
   1185             }
   1186             else if (leftOff != xPos) {
   1187                 // The object is shifting right. The object might be centered, so we need to
   1188                 // recalculate our horizontal margins. Note that the containing block content
   1189                 // width computation will take into account the delta between |leftOff| and |xPos|
   1190                 // so that we can just pass the content width in directly to the |calcHorizontalMargins|
   1191                 // function.
   1192                 child->calcHorizontalMargins(child->style()->marginLeft(), child->style()->marginRight(), lineWidth(child->y(), false));
   1193                 chPos = leftOff + child->marginLeft();
   1194             }
   1195         }
   1196         view()->addLayoutDelta(IntSize(child->x() - chPos, 0));
   1197         child->setLocation(chPos, child->y());
   1198     } else {
   1199         int xPos = width() - borderRight() - paddingRight() - verticalScrollbarWidth();
   1200         int chPos = xPos - (child->width() + child->marginRight());
   1201         if (child->avoidsFloats()) {
   1202             int rightOff = rightOffset(height(), false);
   1203             if (style()->textAlign() != WEBKIT_CENTER && child->style()->marginRight().type() != Auto) {
   1204                 if (child->marginRight() < 0)
   1205                     rightOff -= child->marginRight();
   1206                 chPos = min(chPos, rightOff - child->width()); // Let the float sit in the child's margin if it can fit.
   1207             } else if (rightOff != xPos) {
   1208                 // The object is shifting left. The object might be centered, so we need to
   1209                 // recalculate our horizontal margins. Note that the containing block content
   1210                 // width computation will take into account the delta between |rightOff| and |xPos|
   1211                 // so that we can just pass the content width in directly to the |calcHorizontalMargins|
   1212                 // function.
   1213                 child->calcHorizontalMargins(child->style()->marginLeft(), child->style()->marginRight(), lineWidth(child->y(), false));
   1214                 chPos = rightOff - child->marginRight() - child->width();
   1215             }
   1216         }
   1217         view()->addLayoutDelta(IntSize(child->x() - chPos, 0));
   1218         child->setLocation(chPos, child->y());
   1219     }
   1220 }
   1221 
   1222 void RenderBlock::setCollapsedBottomMargin(const MarginInfo& marginInfo)
   1223 {
   1224     if (marginInfo.canCollapseWithBottom() && !marginInfo.canCollapseWithTop()) {
   1225         // Update our max pos/neg bottom margins, since we collapsed our bottom margins
   1226         // with our children.
   1227         setMaxBottomMargins(max(maxBottomPosMargin(), marginInfo.posMargin()), max(maxBottomNegMargin(), marginInfo.negMargin()));
   1228 
   1229         if (!marginInfo.bottomQuirk())
   1230             setBottomMarginQuirk(false);
   1231 
   1232         if (marginInfo.bottomQuirk() && marginBottom() == 0)
   1233             // We have no bottom margin and our last child has a quirky margin.
   1234             // We will pick up this quirky margin and pass it through.
   1235             // This deals with the <td><div><p> case.
   1236             setBottomMarginQuirk(true);
   1237     }
   1238 }
   1239 
   1240 void RenderBlock::handleBottomOfBlock(int top, int bottom, MarginInfo& marginInfo)
   1241 {
   1242     marginInfo.setAtBottomOfBlock(true);
   1243 
   1244     // If we can't collapse with children then go ahead and add in the bottom margin.
   1245     if (!marginInfo.canCollapseWithBottom() && !marginInfo.canCollapseWithTop()
   1246         && (!style()->htmlHacks() || !marginInfo.quirkContainer() || !marginInfo.bottomQuirk()))
   1247         setHeight(height() + marginInfo.margin());
   1248 
   1249     // Now add in our bottom border/padding.
   1250     setHeight(height() + bottom);
   1251 
   1252     // Negative margins can cause our height to shrink below our minimal height (border/padding).
   1253     // If this happens, ensure that the computed height is increased to the minimal height.
   1254     setHeight(max(height(), top + bottom));
   1255 
   1256     // Update our bottom collapsed margin info.
   1257     setCollapsedBottomMargin(marginInfo);
   1258 }
   1259 
   1260 void RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatBottom)
   1261 {
   1262     if (gPercentHeightDescendantsMap) {
   1263         if (HashSet<RenderBox*>* descendants = gPercentHeightDescendantsMap->get(this)) {
   1264             HashSet<RenderBox*>::iterator end = descendants->end();
   1265             for (HashSet<RenderBox*>::iterator it = descendants->begin(); it != end; ++it) {
   1266                 RenderBox* box = *it;
   1267                 while (box != this) {
   1268                     if (box->normalChildNeedsLayout())
   1269                         break;
   1270                     box->setChildNeedsLayout(true, false);
   1271                     box = box->containingBlock();
   1272                     ASSERT(box);
   1273                     if (!box)
   1274                         break;
   1275                 }
   1276             }
   1277         }
   1278     }
   1279 
   1280     int top = borderTop() + paddingTop();
   1281     int bottom = borderBottom() + paddingBottom() + horizontalScrollbarHeight();
   1282 
   1283     setHeight(top);
   1284 
   1285     // The margin struct caches all our current margin collapsing state.  The compact struct caches state when we encounter compacts,
   1286     MarginInfo marginInfo(this, top, bottom);
   1287 
   1288     // Fieldsets need to find their legend and position it inside the border of the object.
   1289     // The legend then gets skipped during normal layout.
   1290     RenderObject* legend = layoutLegend(relayoutChildren);
   1291 
   1292     int previousFloatBottom = 0;
   1293     maxFloatBottom = 0;
   1294 
   1295     RenderBox* next = firstChildBox();
   1296 
   1297     while (next) {
   1298         RenderBox* child = next;
   1299         next = child->nextSiblingBox();
   1300 
   1301         if (legend == child)
   1302             continue; // Skip the legend, since it has already been positioned up in the fieldset's border.
   1303 
   1304         // Make sure we layout children if they need it.
   1305         // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into
   1306         // an auto value.  Add a method to determine this, so that we can avoid the relayout.
   1307         if (relayoutChildren || ((child->style()->height().isPercent() || child->style()->minHeight().isPercent() || child->style()->maxHeight().isPercent()) && !isRenderView()))
   1308             child->setChildNeedsLayout(true, false);
   1309 
   1310         // If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths.
   1311         if (relayoutChildren && (child->style()->paddingLeft().isPercent() || child->style()->paddingRight().isPercent()))
   1312             child->setPrefWidthsDirty(true, false);
   1313 
   1314         // Handle the four types of special elements first.  These include positioned content, floating content, compacts and
   1315         // run-ins.  When we encounter these four types of objects, we don't actually lay them out as normal flow blocks.
   1316         if (handleSpecialChild(child, marginInfo))
   1317             continue;
   1318 
   1319         // Lay out the child.
   1320         layoutBlockChild(child, marginInfo, previousFloatBottom, maxFloatBottom);
   1321     }
   1322 
   1323     // Now do the handling of the bottom of the block, adding in our bottom border/padding and
   1324     // determining the correct collapsed bottom margin information.
   1325     handleBottomOfBlock(top, bottom, marginInfo);
   1326 }
   1327 
   1328 void RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, int& previousFloatBottom, int& maxFloatBottom)
   1329 {
   1330     int oldTopPosMargin = maxTopPosMargin();
   1331     int oldTopNegMargin = maxTopNegMargin();
   1332 
   1333     // The child is a normal flow object.  Compute its vertical margins now.
   1334     child->calcVerticalMargins();
   1335 
   1336     // Do not allow a collapse if the margin top collapse style is set to SEPARATE.
   1337     if (child->style()->marginTopCollapse() == MSEPARATE) {
   1338         marginInfo.setAtTopOfBlock(false);
   1339         marginInfo.clearMargin();
   1340     }
   1341 
   1342     // Try to guess our correct y position.  In most cases this guess will
   1343     // be correct.  Only if we're wrong (when we compute the real y position)
   1344     // will we have to potentially relayout.
   1345     int yPosEstimate = estimateVerticalPosition(child, marginInfo);
   1346 
   1347     // Cache our old rect so that we can dirty the proper repaint rects if the child moves.
   1348     IntRect oldRect(child->x(), child->y() , child->width(), child->height());
   1349 #ifndef NDEBUG
   1350     IntSize oldLayoutDelta = view()->layoutDelta();
   1351 #endif
   1352     // Go ahead and position the child as though it didn't collapse with the top.
   1353     view()->addLayoutDelta(IntSize(0, child->y() - yPosEstimate));
   1354     child->setLocation(child->x(), yPosEstimate);
   1355 
   1356     bool markDescendantsWithFloats = false;
   1357     if (yPosEstimate != oldRect.y() && !child->avoidsFloats() && child->isBlockFlow() && toRenderBlock(child)->containsFloats())
   1358         markDescendantsWithFloats = true;
   1359     else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) {
   1360         // If an element might be affected by the presence of floats, then always mark it for
   1361         // layout.
   1362         int fb = max(previousFloatBottom, floatBottom());
   1363         if (fb > yPosEstimate)
   1364             markDescendantsWithFloats = true;
   1365     }
   1366 
   1367     if (child->isRenderBlock()) {
   1368         if (markDescendantsWithFloats)
   1369             toRenderBlock(child)->markAllDescendantsWithFloatsForLayout();
   1370 
   1371         previousFloatBottom = max(previousFloatBottom, oldRect.y() + toRenderBlock(child)->floatBottom());
   1372     }
   1373 
   1374     bool childHadLayout = child->m_everHadLayout;
   1375     bool childNeededLayout = child->needsLayout();
   1376     if (childNeededLayout)
   1377         child->layout();
   1378 
   1379     // Now determine the correct ypos based off examination of collapsing margin
   1380     // values.
   1381     int yBeforeClear = collapseMargins(child, marginInfo);
   1382 
   1383     // Now check for clear.
   1384     int yAfterClear = clearFloatsIfNeeded(child, marginInfo, oldTopPosMargin, oldTopNegMargin, yBeforeClear);
   1385 
   1386     view()->addLayoutDelta(IntSize(0, yPosEstimate - yAfterClear));
   1387     child->setLocation(child->x(), yAfterClear);
   1388 
   1389     // Now we have a final y position.  See if it really does end up being different from our estimate.
   1390     if (yAfterClear != yPosEstimate) {
   1391         if (child->shrinkToAvoidFloats()) {
   1392             // The child's width depends on the line width.
   1393             // When the child shifts to clear an item, its width can
   1394             // change (because it has more available line width).
   1395             // So go ahead and mark the item as dirty.
   1396             child->setChildNeedsLayout(true, false);
   1397         }
   1398         if (!child->avoidsFloats() && child->isBlockFlow() && toRenderBlock(child)->containsFloats())
   1399             toRenderBlock(child)->markAllDescendantsWithFloatsForLayout();
   1400         // Our guess was wrong. Make the child lay itself out again.
   1401         child->layoutIfNeeded();
   1402     }
   1403 
   1404     // We are no longer at the top of the block if we encounter a non-empty child.
   1405     // This has to be done after checking for clear, so that margins can be reset if a clear occurred.
   1406     if (marginInfo.atTopOfBlock() && !child->isSelfCollapsingBlock())
   1407         marginInfo.setAtTopOfBlock(false);
   1408 
   1409     // Now place the child in the correct horizontal position
   1410     determineHorizontalPosition(child);
   1411 
   1412     // Update our height now that the child has been placed in the correct position.
   1413     setHeight(height() + child->height());
   1414     if (child->style()->marginBottomCollapse() == MSEPARATE) {
   1415         setHeight(height() + child->marginBottom());
   1416         marginInfo.clearMargin();
   1417     }
   1418     // If the child has overhanging floats that intrude into following siblings (or possibly out
   1419     // of this block), then the parent gets notified of the floats now.
   1420     if (child->isBlockFlow() && toRenderBlock(child)->containsFloats())
   1421         maxFloatBottom = max(maxFloatBottom, addOverhangingFloats(toRenderBlock(child), -child->x(), -child->y(), !childNeededLayout));
   1422 
   1423     IntSize childOffset(child->x() - oldRect.x(), child->y() - oldRect.y());
   1424     if (childOffset.width() || childOffset.height()) {
   1425         view()->addLayoutDelta(childOffset);
   1426 
   1427         // If the child moved, we have to repaint it as well as any floating/positioned
   1428         // descendants.  An exception is if we need a layout.  In this case, we know we're going to
   1429         // repaint ourselves (and the child) anyway.
   1430         if (childHadLayout && !selfNeedsLayout() && child->checkForRepaintDuringLayout())
   1431             child->repaintDuringLayoutIfMoved(oldRect);
   1432     }
   1433 
   1434     if (!childHadLayout && child->checkForRepaintDuringLayout()) {
   1435         child->repaint();
   1436         child->repaintOverhangingFloats(true);
   1437     }
   1438 
   1439     ASSERT(oldLayoutDelta == view()->layoutDelta());
   1440 }
   1441 
   1442 bool RenderBlock::layoutOnlyPositionedObjects()
   1443 {
   1444     if (!posChildNeedsLayout() || normalChildNeedsLayout() || selfNeedsLayout())
   1445         return false;
   1446 
   1447     LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection());
   1448 
   1449     if (needsPositionedMovementLayout()) {
   1450         tryLayoutDoingPositionedMovementOnly();
   1451         if (needsLayout())
   1452             return false;
   1453     }
   1454 
   1455     // All we have to is lay out our positioned objects.
   1456     layoutPositionedObjects(false);
   1457 
   1458     statePusher.pop();
   1459 
   1460     updateScrollInfoAfterLayout();
   1461 
   1462 #ifdef ANDROID_FIX
   1463     // iframe flatten will call FrameView::layout() which calls performPostLayoutTasks,
   1464     // which may make us need to layout again
   1465     if (!posChildNeedsLayout() || normalChildNeedsLayout() || selfNeedsLayout())
   1466         return false;
   1467 #endif
   1468 
   1469     setNeedsLayout(false);
   1470     return true;
   1471 }
   1472 
   1473 void RenderBlock::layoutPositionedObjects(bool relayoutChildren)
   1474 {
   1475     if (m_positionedObjects) {
   1476         RenderBox* r;
   1477         Iterator end = m_positionedObjects->end();
   1478         for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
   1479             r = *it;
   1480             // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the
   1481             // non-positioned block.  Rather than trying to detect all of these movement cases, we just always lay out positioned
   1482             // objects that are positioned implicitly like this.  Such objects are rare, and so in typical DHTML menu usage (where everything is
   1483             // positioned explicitly) this should not incur a performance penalty.
   1484             if (relayoutChildren || (r->style()->hasStaticY() && r->parent() != this && r->parent()->isBlockFlow()))
   1485                 r->setChildNeedsLayout(true, false);
   1486 
   1487             // If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths.
   1488             //if (relayoutChildren && (r->style()->paddingLeft().isPercent() || r->style()->paddingRight().isPercent()))
   1489                 r->setPrefWidthsDirty(true, false);
   1490 
   1491             // We don't have to do a full layout.  We just have to update our position. Try that first. If we have shrink-to-fit width
   1492             // and we hit the available width constraint, the layoutIfNeeded() will catch it and do a full layout.
   1493             if (r->needsPositionedMovementLayoutOnly())
   1494                 r->tryLayoutDoingPositionedMovementOnly();
   1495             r->layoutIfNeeded();
   1496         }
   1497     }
   1498 }
   1499 
   1500 void RenderBlock::markPositionedObjectsForLayout()
   1501 {
   1502     if (m_positionedObjects) {
   1503         RenderBox* r;
   1504         Iterator end = m_positionedObjects->end();
   1505         for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
   1506             r = *it;
   1507             r->setChildNeedsLayout(true);
   1508         }
   1509     }
   1510 }
   1511 
   1512 void RenderBlock::repaintOverhangingFloats(bool paintAllDescendants)
   1513 {
   1514     // Repaint any overhanging floats (if we know we're the one to paint them).
   1515     if (hasOverhangingFloats()) {
   1516         // We think that we must be in a bad state if m_floatingObjects is nil at this point, so
   1517         // we assert on Debug builds and nil-check Release builds.
   1518         ASSERT(m_floatingObjects);
   1519         if (!m_floatingObjects)
   1520             return;
   1521 
   1522         FloatingObject* r;
   1523         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   1524 
   1525         // FIXME: Avoid disabling LayoutState. At the very least, don't disable it for floats originating
   1526         // in this block. Better yet would be to push extra state for the containers of other floats.
   1527         view()->disableLayoutState();
   1528         for ( ; (r = it.current()); ++it) {
   1529             // Only repaint the object if it is overhanging, is not in its own layer, and
   1530             // is our responsibility to paint (m_shouldPaint is set). When paintAllDescendants is true, the latter
   1531             // condition is replaced with being a descendant of us.
   1532             if (r->m_bottom > height() && ((paintAllDescendants && r->m_renderer->isDescendantOf(this)) || r->m_shouldPaint) && !r->m_renderer->hasSelfPaintingLayer()) {
   1533                 r->m_renderer->repaint();
   1534                 r->m_renderer->repaintOverhangingFloats();
   1535             }
   1536         }
   1537         view()->enableLayoutState();
   1538     }
   1539 }
   1540 
   1541 void RenderBlock::paint(PaintInfo& paintInfo, int tx, int ty)
   1542 {
   1543     tx += x();
   1544     ty += y();
   1545 
   1546     PaintPhase phase = paintInfo.phase;
   1547 
   1548     // Check if we need to do anything at all.
   1549     // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
   1550     // paints the root's background.
   1551     if (!isRoot()) {
   1552         IntRect overflowBox = visibleOverflowRect();
   1553         overflowBox.inflate(maximalOutlineSize(paintInfo.phase));
   1554         overflowBox.move(tx, ty);
   1555         if (!overflowBox.intersects(paintInfo.rect))
   1556             return;
   1557     }
   1558 
   1559     bool pushedClip = pushContentsClip(paintInfo, tx, ty);
   1560     paintObject(paintInfo, tx, ty);
   1561     if (pushedClip)
   1562         popContentsClip(paintInfo, phase, tx, ty);
   1563 
   1564     // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
   1565     // z-index.  We paint after we painted the background/border, so that the scrollbars will
   1566     // sit above the background/border.
   1567     if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && shouldPaintWithinRoot(paintInfo))
   1568         layer()->paintOverflowControls(paintInfo.context, tx, ty, paintInfo.rect);
   1569 }
   1570 
   1571 void RenderBlock::paintColumnRules(PaintInfo& paintInfo, int tx, int ty)
   1572 {
   1573     const Color& ruleColor = style()->columnRuleColor();
   1574     bool ruleTransparent = style()->columnRuleIsTransparent();
   1575     EBorderStyle ruleStyle = style()->columnRuleStyle();
   1576     int ruleWidth = style()->columnRuleWidth();
   1577     int colGap = columnGap();
   1578     bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent && ruleWidth <= colGap;
   1579     if (!renderRule)
   1580         return;
   1581 
   1582     // We need to do multiple passes, breaking up our child painting into strips.
   1583     int currXOffset = 0;
   1584     int ruleAdd = borderLeft() + paddingLeft();
   1585     int ruleX = 0;
   1586     Vector<IntRect>* colRects = columnRects();
   1587     unsigned colCount = colRects->size();
   1588     for (unsigned i = 0; i < colCount; i++) {
   1589         // For each rect, we clip to the rect, and then we adjust our coords.
   1590         IntRect colRect = colRects->at(i);
   1591 
   1592         // Move to the next position.
   1593         if (style()->direction() == LTR) {
   1594             ruleX += colRect.width() + colGap / 2;
   1595             currXOffset += colRect.width() + colGap;
   1596         } else {
   1597             ruleX -= (colRect.width() + colGap / 2);
   1598             currXOffset -= (colRect.width() + colGap);
   1599         }
   1600 
   1601         // Now paint the column rule.
   1602         if (i < colCount - 1) {
   1603             int ruleStart = tx + ruleX - ruleWidth / 2 + ruleAdd;
   1604             int ruleEnd = ruleStart + ruleWidth;
   1605             int ruleTop = ty + borderTop() + paddingTop();
   1606             int ruleBottom = ruleTop + contentHeight();
   1607             drawLineForBoxSide(paintInfo.context, ruleStart, ruleTop, ruleEnd, ruleBottom,
   1608                                style()->direction() == LTR ? BSLeft : BSRight, ruleColor, style()->color(), ruleStyle, 0, 0);
   1609         }
   1610 
   1611         ruleX = currXOffset;
   1612     }
   1613 }
   1614 
   1615 void RenderBlock::paintColumnContents(PaintInfo& paintInfo, int tx, int ty, bool paintingFloats)
   1616 {
   1617     // We need to do multiple passes, breaking up our child painting into strips.
   1618     GraphicsContext* context = paintInfo.context;
   1619     int currXOffset = 0;
   1620     int currYOffset = 0;
   1621     int colGap = columnGap();
   1622     Vector<IntRect>* colRects = columnRects();
   1623     unsigned colCount = colRects->size();
   1624     for (unsigned i = 0; i < colCount; i++) {
   1625         // For each rect, we clip to the rect, and then we adjust our coords.
   1626         IntRect colRect = colRects->at(i);
   1627         colRect.move(tx, ty);
   1628         context->save();
   1629 
   1630         // Each strip pushes a clip, since column boxes are specified as being
   1631         // like overflow:hidden.
   1632         context->clip(colRect);
   1633 
   1634         // Adjust tx and ty to change where we paint.
   1635         PaintInfo info(paintInfo);
   1636         info.rect.intersect(colRect);
   1637 
   1638         // Adjust our x and y when painting.
   1639         int finalX = tx + currXOffset;
   1640         int finalY = ty + currYOffset;
   1641         if (paintingFloats)
   1642             paintFloats(info, finalX, finalY, paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip);
   1643         else
   1644             paintContents(info, finalX, finalY);
   1645 
   1646         // Move to the next position.
   1647         if (style()->direction() == LTR)
   1648             currXOffset += colRect.width() + colGap;
   1649         else
   1650             currXOffset -= (colRect.width() + colGap);
   1651 
   1652         currYOffset -= colRect.height();
   1653 
   1654         context->restore();
   1655     }
   1656 }
   1657 
   1658 void RenderBlock::paintContents(PaintInfo& paintInfo, int tx, int ty)
   1659 {
   1660     // Avoid painting descendants of the root element when stylesheets haven't loaded.  This eliminates FOUC.
   1661     // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
   1662     // will do a full repaint().
   1663     if (document()->didLayoutWithPendingStylesheets() && !isRenderView())
   1664         return;
   1665 
   1666     if (childrenInline())
   1667         m_lineBoxes.paint(this, paintInfo, tx, ty);
   1668     else
   1669         paintChildren(paintInfo, tx, ty);
   1670 }
   1671 
   1672 void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
   1673 {
   1674     PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase;
   1675     newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase;
   1676 
   1677     // We don't paint our own background, but we do let the kids paint their backgrounds.
   1678     PaintInfo info(paintInfo);
   1679     info.phase = newPhase;
   1680     info.paintingRoot = paintingRootForChildren(paintInfo);
   1681     bool isPrinting = document()->printing();
   1682 
   1683     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
   1684         // Check for page-break-before: always, and if it's set, break and bail.
   1685         if (isPrinting && !childrenInline() && child->style()->pageBreakBefore() == PBALWAYS &&
   1686             inRootBlockContext() && (ty + child->y()) > paintInfo.rect.y() &&
   1687             (ty + child->y()) < paintInfo.rect.bottom()) {
   1688             view()->setBestTruncatedAt(ty + child->y(), this, true);
   1689             return;
   1690         }
   1691 
   1692         if (!child->hasSelfPaintingLayer() && !child->isFloating())
   1693             child->paint(info, tx, ty);
   1694 
   1695         // Check for page-break-after: always, and if it's set, break and bail.
   1696         if (isPrinting && !childrenInline() && child->style()->pageBreakAfter() == PBALWAYS &&
   1697             inRootBlockContext() && (ty + child->y() + child->height()) > paintInfo.rect.y() &&
   1698             (ty + child->y() + child->height()) < paintInfo.rect.bottom()) {
   1699             view()->setBestTruncatedAt(ty + child->y() + child->height() + max(0, child->collapsedMarginBottom()), this, true);
   1700             return;
   1701         }
   1702     }
   1703 }
   1704 
   1705 void RenderBlock::paintCaret(PaintInfo& paintInfo, int tx, int ty, CaretType type)
   1706 {
   1707     SelectionController* selection = type == CursorCaret ? document()->frame()->selection() : document()->frame()->dragCaretController();
   1708 
   1709     // Paint the caret if the SelectionController says so or if caret browsing is enabled
   1710     bool caretBrowsing = document()->frame()->settings() && document()->frame()->settings()->caretBrowsingEnabled();
   1711     RenderObject* caretPainter = selection->caretRenderer();
   1712     if (caretPainter == this && (selection->isContentEditable() || caretBrowsing)) {
   1713         // Convert the painting offset into the local coordinate system of this renderer,
   1714         // to match the localCaretRect computed by the SelectionController
   1715         offsetForContents(tx, ty);
   1716 
   1717         if (type == CursorCaret)
   1718             document()->frame()->selection()->paintCaret(paintInfo.context, tx, ty, paintInfo.rect);
   1719         else
   1720             document()->frame()->paintDragCaret(paintInfo.context, tx, ty, paintInfo.rect);
   1721     }
   1722 }
   1723 
   1724 void RenderBlock::paintObject(PaintInfo& paintInfo, int tx, int ty)
   1725 {
   1726     PaintPhase paintPhase = paintInfo.phase;
   1727 
   1728     // 1. paint background, borders etc
   1729     if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && style()->visibility() == VISIBLE) {
   1730         if (hasBoxDecorations())
   1731             paintBoxDecorations(paintInfo, tx, ty);
   1732         if (hasColumns())
   1733             paintColumnRules(paintInfo, tx, ty);
   1734     }
   1735 
   1736     if (paintPhase == PaintPhaseMask && style()->visibility() == VISIBLE) {
   1737         paintMask(paintInfo, tx, ty);
   1738         return;
   1739     }
   1740 
   1741     // We're done.  We don't bother painting any children.
   1742     if (paintPhase == PaintPhaseBlockBackground)
   1743         return;
   1744 
   1745     // Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div).s
   1746     int scrolledX = tx;
   1747     int scrolledY = ty;
   1748     if (hasOverflowClip())
   1749         layer()->subtractScrolledContentOffset(scrolledX, scrolledY);
   1750 
   1751     // 2. paint contents
   1752     if (paintPhase != PaintPhaseSelfOutline) {
   1753         if (hasColumns())
   1754             paintColumnContents(paintInfo, scrolledX, scrolledY);
   1755         else
   1756             paintContents(paintInfo, scrolledX, scrolledY);
   1757     }
   1758 
   1759     // 3. paint selection
   1760     // FIXME: Make this work with multi column layouts.  For now don't fill gaps.
   1761     bool isPrinting = document()->printing();
   1762     if (!isPrinting && !hasColumns())
   1763         paintSelection(paintInfo, scrolledX, scrolledY); // Fill in gaps in selection on lines and between blocks.
   1764 
   1765     // 4. paint floats.
   1766     if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip) {
   1767         if (hasColumns())
   1768             paintColumnContents(paintInfo, scrolledX, scrolledY, true);
   1769         else
   1770             paintFloats(paintInfo, scrolledX, scrolledY, paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip);
   1771     }
   1772 
   1773     // 5. paint outline.
   1774     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
   1775         paintOutline(paintInfo.context, tx, ty, width(), height(), style());
   1776 
   1777     // 6. paint continuation outlines.
   1778     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) {
   1779         if (inlineContinuation() && inlineContinuation()->hasOutline() && inlineContinuation()->style()->visibility() == VISIBLE) {
   1780             RenderInline* inlineRenderer = toRenderInline(inlineContinuation()->node()->renderer());
   1781             RenderBlock* cb = containingBlock();
   1782 
   1783             bool inlineEnclosedInSelfPaintingLayer = false;
   1784             for (RenderBoxModelObject* box = inlineRenderer; box != cb; box = box->parent()->enclosingBoxModelObject()) {
   1785                 if (box->hasSelfPaintingLayer()) {
   1786                     inlineEnclosedInSelfPaintingLayer = true;
   1787                     break;
   1788                 }
   1789             }
   1790 
   1791             if (!inlineEnclosedInSelfPaintingLayer)
   1792                 cb->addContinuationWithOutline(inlineRenderer);
   1793             else if (!inlineRenderer->firstLineBox())
   1794                 inlineRenderer->paintOutline(paintInfo.context, tx - x() + inlineRenderer->containingBlock()->x(),
   1795                                              ty - y() + inlineRenderer->containingBlock()->y());
   1796         }
   1797         paintContinuationOutlines(paintInfo, tx, ty);
   1798     }
   1799 
   1800     // 7. paint caret.
   1801     // If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground,
   1802     // then paint the caret.
   1803     if (paintPhase == PaintPhaseForeground) {
   1804         paintCaret(paintInfo, scrolledX, scrolledY, CursorCaret);
   1805         paintCaret(paintInfo, scrolledX, scrolledY, DragCaret);
   1806     }
   1807 }
   1808 
   1809 void RenderBlock::paintFloats(PaintInfo& paintInfo, int tx, int ty, bool preservePhase)
   1810 {
   1811     if (!m_floatingObjects)
   1812         return;
   1813 
   1814     FloatingObject* r;
   1815     DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   1816     for (; (r = it.current()); ++it) {
   1817         // Only paint the object if our m_shouldPaint flag is set.
   1818         if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
   1819             PaintInfo currentPaintInfo(paintInfo);
   1820             currentPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
   1821             int currentTX = tx + r->m_left - r->m_renderer->x() + r->m_renderer->marginLeft();
   1822             int currentTY = ty + r->m_top - r->m_renderer->y() + r->m_renderer->marginTop();
   1823             r->m_renderer->paint(currentPaintInfo, currentTX, currentTY);
   1824             if (!preservePhase) {
   1825                 currentPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
   1826                 r->m_renderer->paint(currentPaintInfo, currentTX, currentTY);
   1827                 currentPaintInfo.phase = PaintPhaseFloat;
   1828                 r->m_renderer->paint(currentPaintInfo, currentTX, currentTY);
   1829                 currentPaintInfo.phase = PaintPhaseForeground;
   1830                 r->m_renderer->paint(currentPaintInfo, currentTX, currentTY);
   1831                 currentPaintInfo.phase = PaintPhaseOutline;
   1832                 r->m_renderer->paint(currentPaintInfo, currentTX, currentTY);
   1833             }
   1834         }
   1835     }
   1836 }
   1837 
   1838 void RenderBlock::paintEllipsisBoxes(PaintInfo& paintInfo, int tx, int ty)
   1839 {
   1840     if (!shouldPaintWithinRoot(paintInfo) || !firstLineBox())
   1841         return;
   1842 
   1843     if (style()->visibility() == VISIBLE && paintInfo.phase == PaintPhaseForeground) {
   1844         // We can check the first box and last box and avoid painting if we don't
   1845         // intersect.
   1846         int yPos = ty + firstLineBox()->y();
   1847         int h = lastLineBox()->y() + lastLineBox()->height() - firstLineBox()->y();
   1848         if (yPos >= paintInfo.rect.bottom() || yPos + h <= paintInfo.rect.y())
   1849             return;
   1850 
   1851         // See if our boxes intersect with the dirty rect.  If so, then we paint
   1852         // them.  Note that boxes can easily overlap, so we can't make any assumptions
   1853         // based off positions of our first line box or our last line box.
   1854         for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
   1855             yPos = ty + curr->y();
   1856             h = curr->height();
   1857             if (curr->ellipsisBox() && yPos < paintInfo.rect.bottom() && yPos + h > paintInfo.rect.y())
   1858                 curr->paintEllipsisBox(paintInfo, tx, ty);
   1859         }
   1860     }
   1861 }
   1862 
   1863 static ContinuationOutlineTableMap* continuationOutlineTable()
   1864 {
   1865     DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ());
   1866     return &table;
   1867 }
   1868 
   1869 void RenderBlock::addContinuationWithOutline(RenderInline* flow)
   1870 {
   1871     // We can't make this work if the inline is in a layer.  We'll just rely on the broken
   1872     // way of painting.
   1873     ASSERT(!flow->layer() && !flow->isInlineContinuation());
   1874 
   1875     ContinuationOutlineTableMap* table = continuationOutlineTable();
   1876     ListHashSet<RenderInline*>* continuations = table->get(this);
   1877     if (!continuations) {
   1878         continuations = new ListHashSet<RenderInline*>;
   1879         table->set(this, continuations);
   1880     }
   1881 
   1882     continuations->add(flow);
   1883 }
   1884 
   1885 void RenderBlock::paintContinuationOutlines(PaintInfo& info, int tx, int ty)
   1886 {
   1887     ContinuationOutlineTableMap* table = continuationOutlineTable();
   1888     if (table->isEmpty())
   1889         return;
   1890 
   1891     ListHashSet<RenderInline*>* continuations = table->get(this);
   1892     if (!continuations)
   1893         return;
   1894 
   1895     // Paint each continuation outline.
   1896     ListHashSet<RenderInline*>::iterator end = continuations->end();
   1897     for (ListHashSet<RenderInline*>::iterator it = continuations->begin(); it != end; ++it) {
   1898         // Need to add in the coordinates of the intervening blocks.
   1899         RenderInline* flow = *it;
   1900         RenderBlock* block = flow->containingBlock();
   1901         for ( ; block && block != this; block = block->containingBlock()) {
   1902             tx += block->x();
   1903             ty += block->y();
   1904         }
   1905         ASSERT(block);
   1906         flow->paintOutline(info.context, tx, ty);
   1907     }
   1908 
   1909     // Delete
   1910     delete continuations;
   1911     table->remove(this);
   1912 }
   1913 
   1914 void RenderBlock::setSelectionState(SelectionState s)
   1915 {
   1916     if (selectionState() == s)
   1917         return;
   1918 
   1919     if (s == SelectionInside && selectionState() != SelectionNone)
   1920         return;
   1921 
   1922     if ((s == SelectionStart && selectionState() == SelectionEnd) ||
   1923         (s == SelectionEnd && selectionState() == SelectionStart))
   1924         RenderBox::setSelectionState(SelectionBoth);
   1925     else
   1926         RenderBox::setSelectionState(s);
   1927 
   1928     RenderBlock* cb = containingBlock();
   1929     if (cb && !cb->isRenderView())
   1930         cb->setSelectionState(s);
   1931 }
   1932 
   1933 bool RenderBlock::shouldPaintSelectionGaps() const
   1934 {
   1935     return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot();
   1936 }
   1937 
   1938 bool RenderBlock::isSelectionRoot() const
   1939 {
   1940     if (!node())
   1941         return false;
   1942 
   1943     // FIXME: Eventually tables should have to learn how to fill gaps between cells, at least in simple non-spanning cases.
   1944     if (isTable())
   1945         return false;
   1946 
   1947     if (isBody() || isRoot() || hasOverflowClip() || isRelPositioned() ||
   1948         isFloatingOrPositioned() || isTableCell() || isInlineBlockOrInlineTable() || hasTransform() ||
   1949         hasReflection() || hasMask())
   1950         return true;
   1951 
   1952     if (view() && view()->selectionStart()) {
   1953         Node* startElement = view()->selectionStart()->node();
   1954         if (startElement && startElement->rootEditableElement() == node())
   1955             return true;
   1956     }
   1957 
   1958     return false;
   1959 }
   1960 
   1961 GapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer)
   1962 {
   1963     ASSERT(!needsLayout());
   1964 
   1965     if (!shouldPaintSelectionGaps())
   1966         return GapRects();
   1967 
   1968     // FIXME: this is broken with transforms
   1969     TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
   1970     mapLocalToContainer(repaintContainer, false, false, transformState);
   1971     FloatPoint offsetFromRepaintContainer = transformState.mappedPoint();
   1972     int x = offsetFromRepaintContainer.x();
   1973     int y = offsetFromRepaintContainer.y();
   1974 
   1975     if (hasOverflowClip())
   1976         layer()->subtractScrolledContentOffset(x, y);
   1977 
   1978     int lastTop = 0;
   1979     int lastLeft = leftSelectionOffset(this, lastTop);
   1980     int lastRight = rightSelectionOffset(this, lastTop);
   1981 
   1982     return fillSelectionGaps(this, x, y, x, y, lastTop, lastLeft, lastRight);
   1983 }
   1984 
   1985 void RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty)
   1986 {
   1987     if (shouldPaintSelectionGaps() && paintInfo.phase == PaintPhaseForeground) {
   1988         int lastTop = 0;
   1989         int lastLeft = leftSelectionOffset(this, lastTop);
   1990         int lastRight = rightSelectionOffset(this, lastTop);
   1991         paintInfo.context->save();
   1992         IntRect gapRectsBounds = fillSelectionGaps(this, tx, ty, tx, ty, lastTop, lastLeft, lastRight, &paintInfo);
   1993         if (!gapRectsBounds.isEmpty()) {
   1994             if (RenderLayer* layer = enclosingLayer()) {
   1995                 gapRectsBounds.move(IntSize(-tx, -ty));
   1996                 if (!hasLayer()) {
   1997                     FloatRect localBounds(gapRectsBounds);
   1998                     gapRectsBounds = localToContainerQuad(localBounds, layer->renderer()).enclosingBoundingBox();
   1999                 }
   2000                 layer->addBlockSelectionGapsBounds(gapRectsBounds);
   2001             }
   2002         }
   2003         paintInfo.context->restore();
   2004     }
   2005 }
   2006 
   2007 #ifndef BUILDING_ON_TIGER
   2008 static void clipOutPositionedObjects(const RenderObject::PaintInfo* paintInfo, int tx, int ty, ListHashSet<RenderBox*>* positionedObjects)
   2009 {
   2010     if (!positionedObjects)
   2011         return;
   2012 
   2013     ListHashSet<RenderBox*>::const_iterator end = positionedObjects->end();
   2014     for (ListHashSet<RenderBox*>::const_iterator it = positionedObjects->begin(); it != end; ++it) {
   2015         RenderBox* r = *it;
   2016         paintInfo->context->clipOut(IntRect(tx + r->x(), ty + r->y(), r->width(), r->height()));
   2017     }
   2018 }
   2019 #endif
   2020 
   2021 GapRects RenderBlock::fillSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty,
   2022                                         int& lastTop, int& lastLeft, int& lastRight, const PaintInfo* paintInfo)
   2023 {
   2024 #ifndef BUILDING_ON_TIGER
   2025     // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore.
   2026     // Clip out floating and positioned objects when painting selection gaps.
   2027     if (paintInfo) {
   2028         // Note that we don't clip out overflow for positioned objects.  We just stick to the border box.
   2029         clipOutPositionedObjects(paintInfo, tx, ty, m_positionedObjects);
   2030         if (isBody() || isRoot()) // The <body> must make sure to examine its containingBlock's positioned objects.
   2031             for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock())
   2032                 clipOutPositionedObjects(paintInfo, cb->x(), cb->y(), cb->m_positionedObjects);
   2033         if (m_floatingObjects) {
   2034             for (DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects); it.current(); ++it) {
   2035                 FloatingObject* r = it.current();
   2036                 paintInfo->context->clipOut(IntRect(tx + r->m_left + r->m_renderer->marginLeft(),
   2037                                                     ty + r->m_top + r->m_renderer->marginTop(),
   2038                                                     r->m_renderer->width(), r->m_renderer->height()));
   2039             }
   2040         }
   2041     }
   2042 #endif
   2043 
   2044     // FIXME: overflow: auto/scroll regions need more math here, since painting in the border box is different from painting in the padding box (one is scrolled, the other is
   2045     // fixed).
   2046     GapRects result;
   2047     if (!isBlockFlow()) // FIXME: Make multi-column selection gap filling work someday.
   2048         return result;
   2049 
   2050     if (hasColumns() || hasTransform()) {
   2051         // FIXME: We should learn how to gap fill multiple columns and transforms eventually.
   2052         lastTop = (ty - blockY) + height();
   2053         lastLeft = leftSelectionOffset(rootBlock, height());
   2054         lastRight = rightSelectionOffset(rootBlock, height());
   2055         return result;
   2056     }
   2057 
   2058     if (childrenInline())
   2059         result = fillInlineSelectionGaps(rootBlock, blockX, blockY, tx, ty, lastTop, lastLeft, lastRight, paintInfo);
   2060     else
   2061         result = fillBlockSelectionGaps(rootBlock, blockX, blockY, tx, ty, lastTop, lastLeft, lastRight, paintInfo);
   2062 
   2063     // Go ahead and fill the vertical gap all the way to the bottom of our block if the selection extends past our block.
   2064     if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd))
   2065         result.uniteCenter(fillVerticalSelectionGap(lastTop, lastLeft, lastRight, ty + height(),
   2066                                                     rootBlock, blockX, blockY, paintInfo));
   2067     return result;
   2068 }
   2069 
   2070 GapRects RenderBlock::fillInlineSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty,
   2071                                               int& lastTop, int& lastLeft, int& lastRight, const PaintInfo* paintInfo)
   2072 {
   2073     GapRects result;
   2074 
   2075     bool containsStart = selectionState() == SelectionStart || selectionState() == SelectionBoth;
   2076 
   2077     if (!firstLineBox()) {
   2078         if (containsStart) {
   2079             // Go ahead and update our lastY to be the bottom of the block.  <hr>s or empty blocks with height can trip this
   2080             // case.
   2081             lastTop = (ty - blockY) + height();
   2082             lastLeft = leftSelectionOffset(rootBlock, height());
   2083             lastRight = rightSelectionOffset(rootBlock, height());
   2084         }
   2085         return result;
   2086     }
   2087 
   2088     RootInlineBox* lastSelectedLine = 0;
   2089     RootInlineBox* curr;
   2090     for (curr = firstRootBox(); curr && !curr->hasSelectedChildren(); curr = curr->nextRootBox()) { }
   2091 
   2092     // Now paint the gaps for the lines.
   2093     for (; curr && curr->hasSelectedChildren(); curr = curr->nextRootBox()) {
   2094         int selTop =  curr->selectionTop();
   2095         int selHeight = curr->selectionHeight();
   2096 
   2097         if (!containsStart && !lastSelectedLine &&
   2098             selectionState() != SelectionStart && selectionState() != SelectionBoth)
   2099             result.uniteCenter(fillVerticalSelectionGap(lastTop, lastLeft, lastRight, ty + selTop,
   2100                                                         rootBlock, blockX, blockY, paintInfo));
   2101 
   2102         if (!paintInfo || (ty + selTop < paintInfo->rect.bottom() && ty + selTop + selHeight > paintInfo->rect.y()))
   2103             result.unite(curr->fillLineSelectionGap(selTop, selHeight, rootBlock, blockX, blockY, tx, ty, paintInfo));
   2104 
   2105         lastSelectedLine = curr;
   2106     }
   2107 
   2108     if (containsStart && !lastSelectedLine)
   2109         // VisibleSelection must start just after our last line.
   2110         lastSelectedLine = lastRootBox();
   2111 
   2112     if (lastSelectedLine && selectionState() != SelectionEnd && selectionState() != SelectionBoth) {
   2113         // Go ahead and update our lastY to be the bottom of the last selected line.
   2114         lastTop = (ty - blockY) + lastSelectedLine->selectionBottom();
   2115         lastLeft = leftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
   2116         lastRight = rightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
   2117     }
   2118     return result;
   2119 }
   2120 
   2121 GapRects RenderBlock::fillBlockSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty,
   2122                                              int& lastTop, int& lastLeft, int& lastRight, const PaintInfo* paintInfo)
   2123 {
   2124     GapRects result;
   2125 
   2126     // Go ahead and jump right to the first block child that contains some selected objects.
   2127     RenderBox* curr;
   2128     for (curr = firstChildBox(); curr && curr->selectionState() == SelectionNone; curr = curr->nextSiblingBox()) { }
   2129 
   2130     for (bool sawSelectionEnd = false; curr && !sawSelectionEnd; curr = curr->nextSiblingBox()) {
   2131         SelectionState childState = curr->selectionState();
   2132         if (childState == SelectionBoth || childState == SelectionEnd)
   2133             sawSelectionEnd = true;
   2134 
   2135         if (curr->isFloatingOrPositioned())
   2136             continue; // We must be a normal flow object in order to even be considered.
   2137 
   2138         if (curr->isRelPositioned() && curr->hasLayer()) {
   2139             // If the relposition offset is anything other than 0, then treat this just like an absolute positioned element.
   2140             // Just disregard it completely.
   2141             IntSize relOffset = curr->layer()->relativePositionOffset();
   2142             if (relOffset.width() || relOffset.height())
   2143                 continue;
   2144         }
   2145 
   2146         bool paintsOwnSelection = curr->shouldPaintSelectionGaps() || curr->isTable(); // FIXME: Eventually we won't special-case table like this.
   2147         bool fillBlockGaps = paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone);
   2148         if (fillBlockGaps) {
   2149             // We need to fill the vertical gap above this object.
   2150             if (childState == SelectionEnd || childState == SelectionInside)
   2151                 // Fill the gap above the object.
   2152                 result.uniteCenter(fillVerticalSelectionGap(lastTop, lastLeft, lastRight,
   2153                                                             ty + curr->y(), rootBlock, blockX, blockY, paintInfo));
   2154 
   2155             // Only fill side gaps for objects that paint their own selection if we know for sure the selection is going to extend all the way *past*
   2156             // our object.  We know this if the selection did not end inside our object.
   2157             if (paintsOwnSelection && (childState == SelectionStart || sawSelectionEnd))
   2158                 childState = SelectionNone;
   2159 
   2160             // Fill side gaps on this object based off its state.
   2161             bool leftGap, rightGap;
   2162             getHorizontalSelectionGapInfo(childState, leftGap, rightGap);
   2163 
   2164             if (leftGap)
   2165                 result.uniteLeft(fillLeftSelectionGap(this, curr->x(), curr->y(), curr->height(), rootBlock, blockX, blockY, tx, ty, paintInfo));
   2166             if (rightGap)
   2167                 result.uniteRight(fillRightSelectionGap(this, curr->x() + curr->width(), curr->y(), curr->height(), rootBlock, blockX, blockY, tx, ty, paintInfo));
   2168 
   2169             // Update lastTop to be just underneath the object.  lastLeft and lastRight extend as far as
   2170             // they can without bumping into floating or positioned objects.  Ideally they will go right up
   2171             // to the border of the root selection block.
   2172             lastTop = (ty - blockY) + (curr->y() + curr->height());
   2173             lastLeft = leftSelectionOffset(rootBlock, curr->y() + curr->height());
   2174             lastRight = rightSelectionOffset(rootBlock, curr->y() + curr->height());
   2175         } else if (childState != SelectionNone)
   2176             // We must be a block that has some selected object inside it.  Go ahead and recur.
   2177             result.unite(toRenderBlock(curr)->fillSelectionGaps(rootBlock, blockX, blockY, tx + curr->x(), ty + curr->y(),
   2178                                                                             lastTop, lastLeft, lastRight, paintInfo));
   2179     }
   2180     return result;
   2181 }
   2182 
   2183 IntRect RenderBlock::fillHorizontalSelectionGap(RenderObject* selObj, int xPos, int yPos, int width, int height, const PaintInfo* paintInfo)
   2184 {
   2185     if (width <= 0 || height <= 0)
   2186         return IntRect();
   2187     IntRect gapRect(xPos, yPos, width, height);
   2188     if (paintInfo && selObj->style()->visibility() == VISIBLE)
   2189         paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
   2190     return gapRect;
   2191 }
   2192 
   2193 IntRect RenderBlock::fillVerticalSelectionGap(int lastTop, int lastLeft, int lastRight, int bottomY, RenderBlock* rootBlock,
   2194                                               int blockX, int blockY, const PaintInfo* paintInfo)
   2195 {
   2196     int top = blockY + lastTop;
   2197     int height = bottomY - top;
   2198     if (height <= 0)
   2199         return IntRect();
   2200 
   2201     // Get the selection offsets for the bottom of the gap
   2202     int left = blockX + max(lastLeft, leftSelectionOffset(rootBlock, bottomY));
   2203     int right = blockX + min(lastRight, rightSelectionOffset(rootBlock, bottomY));
   2204     int width = right - left;
   2205     if (width <= 0)
   2206         return IntRect();
   2207 
   2208     IntRect gapRect(left, top, width, height);
   2209     if (paintInfo)
   2210         paintInfo->context->fillRect(gapRect, selectionBackgroundColor(), style()->colorSpace());
   2211     return gapRect;
   2212 }
   2213 
   2214 IntRect RenderBlock::fillLeftSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock,
   2215                                           int blockX, int /*blockY*/, int tx, int ty, const PaintInfo* paintInfo)
   2216 {
   2217     int top = yPos + ty;
   2218     int left = blockX + max(leftSelectionOffset(rootBlock, yPos), leftSelectionOffset(rootBlock, yPos + height));
   2219     int right = min(xPos + tx, blockX + min(rightSelectionOffset(rootBlock, yPos), rightSelectionOffset(rootBlock, yPos + height)));
   2220     int width = right - left;
   2221     if (width <= 0)
   2222         return IntRect();
   2223 
   2224     IntRect gapRect(left, top, width, height);
   2225     if (paintInfo)
   2226         paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
   2227     return gapRect;
   2228 }
   2229 
   2230 IntRect RenderBlock::fillRightSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock,
   2231                                            int blockX, int /*blockY*/, int tx, int ty, const PaintInfo* paintInfo)
   2232 {
   2233     int left = max(xPos + tx, blockX + max(leftSelectionOffset(rootBlock, yPos), leftSelectionOffset(rootBlock, yPos + height)));
   2234     int top = yPos + ty;
   2235     int right = blockX + min(rightSelectionOffset(rootBlock, yPos), rightSelectionOffset(rootBlock, yPos + height));
   2236     int width = right - left;
   2237     if (width <= 0)
   2238         return IntRect();
   2239 
   2240     IntRect gapRect(left, top, width, height);
   2241     if (paintInfo)
   2242         paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
   2243     return gapRect;
   2244 }
   2245 
   2246 void RenderBlock::getHorizontalSelectionGapInfo(SelectionState state, bool& leftGap, bool& rightGap)
   2247 {
   2248     bool ltr = style()->direction() == LTR;
   2249     leftGap = (state == RenderObject::SelectionInside) ||
   2250               (state == RenderObject::SelectionEnd && ltr) ||
   2251               (state == RenderObject::SelectionStart && !ltr);
   2252     rightGap = (state == RenderObject::SelectionInside) ||
   2253                (state == RenderObject::SelectionStart && ltr) ||
   2254                (state == RenderObject::SelectionEnd && !ltr);
   2255 }
   2256 
   2257 int RenderBlock::leftSelectionOffset(RenderBlock* rootBlock, int yPos)
   2258 {
   2259     int left = leftOffset(yPos, false);
   2260     if (left == borderLeft() + paddingLeft()) {
   2261         if (rootBlock != this)
   2262             // The border can potentially be further extended by our containingBlock().
   2263             return containingBlock()->leftSelectionOffset(rootBlock, yPos + y());
   2264         return left;
   2265     }
   2266     else {
   2267         RenderBlock* cb = this;
   2268         while (cb != rootBlock) {
   2269             left += cb->x();
   2270             cb = cb->containingBlock();
   2271         }
   2272     }
   2273 
   2274     return left;
   2275 }
   2276 
   2277 int RenderBlock::rightSelectionOffset(RenderBlock* rootBlock, int yPos)
   2278 {
   2279     int right = rightOffset(yPos, false);
   2280     if (right == (contentWidth() + (borderLeft() + paddingLeft()))) {
   2281         if (rootBlock != this)
   2282             // The border can potentially be further extended by our containingBlock().
   2283             return containingBlock()->rightSelectionOffset(rootBlock, yPos + y());
   2284         return right;
   2285     }
   2286     else {
   2287         RenderBlock* cb = this;
   2288         while (cb != rootBlock) {
   2289             right += cb->x();
   2290             cb = cb->containingBlock();
   2291         }
   2292     }
   2293     return right;
   2294 }
   2295 
   2296 void RenderBlock::insertPositionedObject(RenderBox* o)
   2297 {
   2298     // Create the list of special objects if we don't aleady have one
   2299     if (!m_positionedObjects)
   2300         m_positionedObjects = new ListHashSet<RenderBox*>;
   2301 
   2302     m_positionedObjects->add(o);
   2303 }
   2304 
   2305 void RenderBlock::removePositionedObject(RenderBox* o)
   2306 {
   2307     if (m_positionedObjects)
   2308         m_positionedObjects->remove(o);
   2309 }
   2310 
   2311 void RenderBlock::removePositionedObjects(RenderBlock* o)
   2312 {
   2313     if (!m_positionedObjects)
   2314         return;
   2315 
   2316     RenderBox* r;
   2317 
   2318     Iterator end = m_positionedObjects->end();
   2319 
   2320     Vector<RenderBox*, 16> deadObjects;
   2321 
   2322     for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
   2323         r = *it;
   2324         if (!o || r->isDescendantOf(o)) {
   2325             if (o)
   2326                 r->setChildNeedsLayout(true, false);
   2327 
   2328             // It is parent blocks job to add positioned child to positioned objects list of its containing block
   2329             // Parent layout needs to be invalidated to ensure this happens.
   2330             RenderObject* p = r->parent();
   2331             while (p && !p->isRenderBlock())
   2332                 p = p->parent();
   2333             if (p)
   2334                 p->setChildNeedsLayout(true);
   2335 
   2336             deadObjects.append(r);
   2337         }
   2338     }
   2339 
   2340     for (unsigned i = 0; i < deadObjects.size(); i++)
   2341         m_positionedObjects->remove(deadObjects.at(i));
   2342 }
   2343 
   2344 void RenderBlock::insertFloatingObject(RenderBox* o)
   2345 {
   2346     ASSERT(o->isFloating());
   2347 
   2348     // Create the list of special objects if we don't aleady have one
   2349     if (!m_floatingObjects) {
   2350         m_floatingObjects = new DeprecatedPtrList<FloatingObject>;
   2351         m_floatingObjects->setAutoDelete(true);
   2352     } else {
   2353         // Don't insert the object again if it's already in the list
   2354         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2355         FloatingObject* f;
   2356         while ( (f = it.current()) ) {
   2357             if (f->m_renderer == o) return;
   2358             ++it;
   2359         }
   2360     }
   2361 
   2362     // Create the special object entry & append it to the list
   2363 
   2364     o->layoutIfNeeded();
   2365 
   2366     FloatingObject* newObj = new FloatingObject(o->style()->floating() == FLEFT ? FloatingObject::FloatLeft : FloatingObject::FloatRight);
   2367 
   2368     newObj->m_top = -1;
   2369     newObj->m_bottom = -1;
   2370     newObj->m_width = o->width() + o->marginLeft() + o->marginRight();
   2371     newObj->m_shouldPaint = !o->hasSelfPaintingLayer(); // If a layer exists, the float will paint itself.  Otherwise someone else will.
   2372     newObj->m_isDescendant = true;
   2373     newObj->m_renderer = o;
   2374 
   2375     m_floatingObjects->append(newObj);
   2376 }
   2377 
   2378 void RenderBlock::removeFloatingObject(RenderBox* o)
   2379 {
   2380     if (m_floatingObjects) {
   2381         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2382         while (it.current()) {
   2383             if (it.current()->m_renderer == o) {
   2384                 if (childrenInline())
   2385                     markLinesDirtyInVerticalRange(0, it.current()->m_bottom);
   2386                 m_floatingObjects->removeRef(it.current());
   2387             }
   2388             ++it;
   2389         }
   2390     }
   2391 }
   2392 
   2393 bool RenderBlock::positionNewFloats()
   2394 {
   2395     if (!m_floatingObjects)
   2396         return false;
   2397 
   2398     FloatingObject* f = m_floatingObjects->last();
   2399 
   2400     // If all floats have already been positioned, then we have no work to do.
   2401     if (!f || f->m_top != -1)
   2402         return false;
   2403 
   2404     // Move backwards through our floating object list until we find a float that has
   2405     // already been positioned.  Then we'll be able to move forward, positioning all of
   2406     // the new floats that need it.
   2407     FloatingObject* lastFloat = m_floatingObjects->getPrev();
   2408     while (lastFloat && lastFloat->m_top == -1) {
   2409         f = m_floatingObjects->prev();
   2410         lastFloat = m_floatingObjects->getPrev();
   2411     }
   2412 
   2413     int y = height();
   2414 
   2415     // The float cannot start above the y position of the last positioned float.
   2416     if (lastFloat)
   2417         y = max(lastFloat->m_top, y);
   2418 
   2419     // Now walk through the set of unpositioned floats and place them.
   2420     while (f) {
   2421         // The containing block is responsible for positioning floats, so if we have floats in our
   2422         // list that come from somewhere else, do not attempt to position them.
   2423         if (f->m_renderer->containingBlock() != this) {
   2424             f = m_floatingObjects->next();
   2425             continue;
   2426         }
   2427 
   2428         RenderBox* o = f->m_renderer;
   2429         int _height = o->height() + o->marginTop() + o->marginBottom();
   2430 
   2431         int ro = rightOffset(); // Constant part of right offset.
   2432         int lo = leftOffset(); // Constat part of left offset.
   2433         int fwidth = f->m_width; // The width we look for.
   2434         if (ro - lo < fwidth)
   2435             fwidth = ro - lo; // Never look for more than what will be available.
   2436 
   2437         IntRect oldRect(o->x(), o->y() , o->width(), o->height());
   2438 
   2439         if (o->style()->clear() & CLEFT)
   2440             y = max(leftBottom(), y);
   2441         if (o->style()->clear() & CRIGHT)
   2442             y = max(rightBottom(), y);
   2443 
   2444         if (o->style()->floating() == FLEFT) {
   2445             int heightRemainingLeft = 1;
   2446             int heightRemainingRight = 1;
   2447             int fx = leftRelOffset(y, lo, false, &heightRemainingLeft);
   2448             while (rightRelOffset(y, ro, false, &heightRemainingRight)-fx < fwidth) {
   2449                 y += min(heightRemainingLeft, heightRemainingRight);
   2450                 fx = leftRelOffset(y, lo, false, &heightRemainingLeft);
   2451             }
   2452             fx = max(0, fx);
   2453             f->m_left = fx;
   2454             o->setLocation(fx + o->marginLeft(), y + o->marginTop());
   2455         } else {
   2456             int heightRemainingLeft = 1;
   2457             int heightRemainingRight = 1;
   2458             int fx = rightRelOffset(y, ro, false, &heightRemainingRight);
   2459             while (fx - leftRelOffset(y, lo, false, &heightRemainingLeft) < fwidth) {
   2460                 y += min(heightRemainingLeft, heightRemainingRight);
   2461                 fx = rightRelOffset(y, ro, false, &heightRemainingRight);
   2462             }
   2463             f->m_left = fx - f->m_width;
   2464             o->setLocation(fx - o->marginRight() - o->width(), y + o->marginTop());
   2465         }
   2466 
   2467         f->m_top = y;
   2468         f->m_bottom = f->m_top + _height;
   2469 
   2470         // If the child moved, we have to repaint it.
   2471         if (o->checkForRepaintDuringLayout())
   2472             o->repaintDuringLayoutIfMoved(oldRect);
   2473 
   2474         f = m_floatingObjects->next();
   2475     }
   2476     return true;
   2477 }
   2478 
   2479 void RenderBlock::newLine(EClear clear)
   2480 {
   2481     positionNewFloats();
   2482     // set y position
   2483     int newY = 0;
   2484     switch (clear)
   2485     {
   2486         case CLEFT:
   2487             newY = leftBottom();
   2488             break;
   2489         case CRIGHT:
   2490             newY = rightBottom();
   2491             break;
   2492         case CBOTH:
   2493             newY = floatBottom();
   2494         default:
   2495             break;
   2496     }
   2497     if (height() < newY)
   2498         setHeight(newY);
   2499 }
   2500 
   2501 void RenderBlock::addPercentHeightDescendant(RenderBox* descendant)
   2502 {
   2503     if (!gPercentHeightDescendantsMap) {
   2504         gPercentHeightDescendantsMap = new PercentHeightDescendantsMap;
   2505         gPercentHeightContainerMap = new PercentHeightContainerMap;
   2506     }
   2507 
   2508     HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(this);
   2509     if (!descendantSet) {
   2510         descendantSet = new HashSet<RenderBox*>;
   2511         gPercentHeightDescendantsMap->set(this, descendantSet);
   2512     }
   2513     bool added = descendantSet->add(descendant).second;
   2514     if (!added) {
   2515         ASSERT(gPercentHeightContainerMap->get(descendant));
   2516         ASSERT(gPercentHeightContainerMap->get(descendant)->contains(this));
   2517         return;
   2518     }
   2519 
   2520     HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->get(descendant);
   2521     if (!containerSet) {
   2522         containerSet = new HashSet<RenderBlock*>;
   2523         gPercentHeightContainerMap->set(descendant, containerSet);
   2524     }
   2525     ASSERT(!containerSet->contains(this));
   2526     containerSet->add(this);
   2527 }
   2528 
   2529 void RenderBlock::removePercentHeightDescendant(RenderBox* descendant)
   2530 {
   2531     if (!gPercentHeightContainerMap)
   2532         return;
   2533 
   2534     HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->take(descendant);
   2535     if (!containerSet)
   2536         return;
   2537 
   2538     HashSet<RenderBlock*>::iterator end = containerSet->end();
   2539     for (HashSet<RenderBlock*>::iterator it = containerSet->begin(); it != end; ++it) {
   2540         RenderBlock* container = *it;
   2541         HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(container);
   2542         ASSERT(descendantSet);
   2543         if (!descendantSet)
   2544             continue;
   2545         ASSERT(descendantSet->contains(descendant));
   2546         descendantSet->remove(descendant);
   2547         if (descendantSet->isEmpty()) {
   2548             gPercentHeightDescendantsMap->remove(container);
   2549             delete descendantSet;
   2550         }
   2551     }
   2552 
   2553     delete containerSet;
   2554 }
   2555 
   2556 HashSet<RenderBox*>* RenderBlock::percentHeightDescendants() const
   2557 {
   2558     return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0;
   2559 }
   2560 
   2561 int RenderBlock::leftOffset() const
   2562 {
   2563     return borderLeft() + paddingLeft();
   2564 }
   2565 
   2566 int RenderBlock::leftRelOffset(int y, int fixedOffset, bool applyTextIndent, int* heightRemaining) const
   2567 {
   2568     int left = fixedOffset;
   2569     if (m_floatingObjects) {
   2570         if ( heightRemaining ) *heightRemaining = 1;
   2571         FloatingObject* r;
   2572         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2573         for ( ; (r = it.current()); ++it )
   2574         {
   2575             if (r->m_top <= y && r->m_bottom > y &&
   2576                 r->type() == FloatingObject::FloatLeft &&
   2577                 r->m_left + r->m_width > left) {
   2578                 left = r->m_left + r->m_width;
   2579                 if ( heightRemaining ) *heightRemaining = r->m_bottom - y;
   2580             }
   2581         }
   2582     }
   2583 
   2584     if (applyTextIndent && style()->direction() == LTR) {
   2585         int cw = 0;
   2586         if (style()->textIndent().isPercent())
   2587             cw = containingBlock()->availableWidth();
   2588         left += style()->textIndent().calcMinValue(cw);
   2589     }
   2590 
   2591     return left;
   2592 }
   2593 
   2594 int RenderBlock::rightOffset() const
   2595 {
   2596     return borderLeft() + paddingLeft() + availableWidth();
   2597 }
   2598 
   2599 int RenderBlock::rightRelOffset(int y, int fixedOffset, bool applyTextIndent, int* heightRemaining) const
   2600 {
   2601     int right = fixedOffset;
   2602 
   2603     if (m_floatingObjects) {
   2604         if (heightRemaining) *heightRemaining = 1;
   2605         FloatingObject* r;
   2606         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2607         for ( ; (r = it.current()); ++it )
   2608         {
   2609             if (r->m_top <= y && r->m_bottom > y &&
   2610                 r->type() == FloatingObject::FloatRight &&
   2611                 r->m_left < right) {
   2612                 right = r->m_left;
   2613                 if ( heightRemaining ) *heightRemaining = r->m_bottom - y;
   2614             }
   2615         }
   2616     }
   2617 
   2618     if (applyTextIndent && style()->direction() == RTL) {
   2619         int cw = 0;
   2620         if (style()->textIndent().isPercent())
   2621             cw = containingBlock()->availableWidth();
   2622         right -= style()->textIndent().calcMinValue(cw);
   2623     }
   2624 
   2625     return right;
   2626 }
   2627 
   2628 int
   2629 RenderBlock::lineWidth(int y, bool firstLine) const
   2630 {
   2631     int result = rightOffset(y, firstLine) - leftOffset(y, firstLine);
   2632     return (result < 0) ? 0 : result;
   2633 }
   2634 
   2635 int RenderBlock::nextFloatBottomBelow(int height) const
   2636 {
   2637     if (!m_floatingObjects)
   2638         return 0;
   2639 
   2640     int bottom = INT_MAX;
   2641     FloatingObject* r;
   2642     DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2643     for ( ; (r = it.current()); ++it) {
   2644         if (r->m_bottom > height)
   2645             bottom = min(r->m_bottom, bottom);
   2646     }
   2647 
   2648     return bottom == INT_MAX ? 0 : bottom;
   2649 }
   2650 
   2651 int
   2652 RenderBlock::floatBottom() const
   2653 {
   2654     if (!m_floatingObjects) return 0;
   2655     int bottom = 0;
   2656     FloatingObject* r;
   2657     DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2658     for ( ; (r = it.current()); ++it )
   2659         if (r->m_bottom>bottom)
   2660             bottom = r->m_bottom;
   2661     return bottom;
   2662 }
   2663 
   2664 IntRect RenderBlock::floatRect() const
   2665 {
   2666     IntRect result;
   2667     if (!m_floatingObjects || hasOverflowClip() || hasColumns())
   2668         return result;
   2669     FloatingObject* r;
   2670     DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2671     for (; (r = it.current()); ++it) {
   2672         if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
   2673             IntRect childRect = r->m_renderer->visibleOverflowRect();
   2674             childRect.move(r->m_left + r->m_renderer->marginLeft(), r->m_top + r->m_renderer->marginTop());
   2675             result.unite(childRect);
   2676         }
   2677     }
   2678 
   2679     return result;
   2680 }
   2681 
   2682 int RenderBlock::lowestPosition(bool includeOverflowInterior, bool includeSelf) const
   2683 {
   2684     int bottom = includeSelf && width() > 0 ? height() : 0;
   2685 
   2686     if (!includeOverflowInterior && (hasOverflowClip() || hasControlClip()))
   2687         return bottom;
   2688 
   2689     if (!firstChild() && (!width() || !height()))
   2690         return bottom;
   2691 
   2692     if (!hasColumns()) {
   2693         // FIXME: Come up with a way to use the layer tree to avoid visiting all the kids.
   2694         // For now, we have to descend into all the children, since we may have a huge abs div inside
   2695         // a tiny rel div buried somewhere deep in our child tree.  In this case we have to get to
   2696         // the abs div.
   2697         // See the last test case in https://bugs.webkit.org/show_bug.cgi?id=9314 for why this is a problem.
   2698         // For inline children, we miss relative positioned boxes that might be buried inside <span>s.
   2699         for (RenderObject* c = firstChild(); c; c = c->nextSibling()) {
   2700             if (!c->isFloatingOrPositioned() && c->isBox()) {
   2701                 RenderBox* childBox = toRenderBox(c);
   2702                 bottom = max(bottom, childBox->y() + childBox->lowestPosition(false));
   2703             }
   2704         }
   2705     }
   2706 
   2707     if (includeSelf && isRelPositioned())
   2708         bottom += relativePositionOffsetY();
   2709     if (!includeOverflowInterior && hasOverflowClip())
   2710         return bottom;
   2711 
   2712     int relativeOffset = includeSelf && isRelPositioned() ? relativePositionOffsetY() : 0;
   2713 
   2714     if (includeSelf)
   2715         bottom = max(bottom, bottomLayoutOverflow() + relativeOffset);
   2716 
   2717     if (m_positionedObjects) {
   2718         RenderBox* r;
   2719         Iterator end = m_positionedObjects->end();
   2720         for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
   2721             r = *it;
   2722             // Fixed positioned objects do not scroll and thus should not constitute
   2723             // part of the lowest position.
   2724             if (r->style()->position() != FixedPosition) {
   2725                 // FIXME: Should work for overflow sections too.
   2726                 // If a positioned object lies completely to the left of the root it will be unreachable via scrolling.
   2727                 // Therefore we should not allow it to contribute to the lowest position.
   2728                 if (!isRenderView() || r->x() + r->width() > 0 || r->x() + r->rightmostPosition(false) > 0) {
   2729                     int lp = r->y() + r->lowestPosition(false);
   2730                     bottom = max(bottom, lp + relativeOffset);
   2731                 }
   2732             }
   2733         }
   2734     }
   2735 
   2736     if (hasColumns()) {
   2737         Vector<IntRect>* colRects = columnRects();
   2738         for (unsigned i = 0; i < colRects->size(); i++)
   2739             bottom = max(bottom, colRects->at(i).bottom() + relativeOffset);
   2740         return bottom;
   2741     }
   2742 
   2743     if (m_floatingObjects) {
   2744         FloatingObject* r;
   2745         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2746         for ( ; (r = it.current()); ++it ) {
   2747             if (r->m_shouldPaint || r->m_renderer->hasSelfPaintingLayer()) {
   2748                 int lp = r->m_top + r->m_renderer->marginTop() + r->m_renderer->lowestPosition(false);
   2749                 bottom = max(bottom, lp + relativeOffset);
   2750             }
   2751         }
   2752     }
   2753 
   2754     if (!includeSelf) {
   2755         bottom = max(bottom, borderTop() + paddingTop() + paddingBottom() + relativeOffset);
   2756         if (childrenInline()) {
   2757             if (lastRootBox()) {
   2758                 int childBottomEdge = lastRootBox()->selectionBottom();
   2759                 bottom = max(bottom, childBottomEdge + paddingBottom() + relativeOffset);
   2760             }
   2761         } else {
   2762             // Find the last normal flow child.
   2763             RenderBox* currBox = lastChildBox();
   2764             while (currBox && currBox->isFloatingOrPositioned())
   2765                 currBox = currBox->previousSiblingBox();
   2766             if (currBox) {
   2767                 int childBottomEdge = currBox->y() + currBox->height() + currBox->collapsedMarginBottom();
   2768                 bottom = max(bottom, childBottomEdge + paddingBottom() + relativeOffset);
   2769             }
   2770         }
   2771     }
   2772 
   2773     return bottom;
   2774 }
   2775 
   2776 int RenderBlock::rightmostPosition(bool includeOverflowInterior, bool includeSelf) const
   2777 {
   2778     int right = includeSelf && height() > 0 ? width() : 0;
   2779 
   2780     if (!includeOverflowInterior && (hasOverflowClip() || hasControlClip()))
   2781         return right;
   2782 
   2783     if (!firstChild() && (!width() || !height()))
   2784         return right;
   2785 
   2786     if (!hasColumns()) {
   2787         // FIXME: Come up with a way to use the layer tree to avoid visiting all the kids.
   2788         // For now, we have to descend into all the children, since we may have a huge abs div inside
   2789         // a tiny rel div buried somewhere deep in our child tree.  In this case we have to get to
   2790         // the abs div.
   2791         for (RenderObject* c = firstChild(); c; c = c->nextSibling()) {
   2792             if (!c->isFloatingOrPositioned() && c->isBox()) {
   2793                 RenderBox* childBox = toRenderBox(c);
   2794                 right = max(right, childBox->x() + childBox->rightmostPosition(false));
   2795             }
   2796         }
   2797     }
   2798 
   2799     if (includeSelf && isRelPositioned())
   2800         right += relativePositionOffsetX();
   2801 
   2802     if (!includeOverflowInterior && hasOverflowClip())
   2803         return right;
   2804 
   2805     int relativeOffset = includeSelf && isRelPositioned() ? relativePositionOffsetX() : 0;
   2806 
   2807     if (includeSelf)
   2808         right = max(right, rightLayoutOverflow() + relativeOffset);
   2809 
   2810     if (m_positionedObjects) {
   2811         RenderBox* r;
   2812         Iterator end = m_positionedObjects->end();
   2813         for (Iterator it = m_positionedObjects->begin() ; it != end; ++it) {
   2814             r = *it;
   2815             // Fixed positioned objects do not scroll and thus should not constitute
   2816             // part of the rightmost position.
   2817             if (r->style()->position() != FixedPosition) {
   2818                 // FIXME: Should work for overflow sections too.
   2819                 // If a positioned object lies completely above the root it will be unreachable via scrolling.
   2820                 // Therefore we should not allow it to contribute to the rightmost position.
   2821                 if (!isRenderView() || r->y() + r->height() > 0 || r->y() + r->lowestPosition(false) > 0) {
   2822                     int rp = r->x() + r->rightmostPosition(false);
   2823                     right = max(right, rp + relativeOffset);
   2824                 }
   2825             }
   2826         }
   2827     }
   2828 
   2829     if (hasColumns()) {
   2830         // This only matters for LTR
   2831         if (style()->direction() == LTR)
   2832             right = max(columnRects()->last().right() + relativeOffset, right);
   2833         return right;
   2834     }
   2835 
   2836     if (m_floatingObjects) {
   2837         FloatingObject* r;
   2838         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2839         for ( ; (r = it.current()); ++it ) {
   2840             if (r->m_shouldPaint || r->m_renderer->hasSelfPaintingLayer()) {
   2841                 int rp = r->m_left + r->m_renderer->marginLeft() + r->m_renderer->rightmostPosition(false);
   2842                 right = max(right, rp + relativeOffset);
   2843             }
   2844         }
   2845     }
   2846 
   2847     if (!includeSelf) {
   2848         right = max(right, borderLeft() + paddingLeft() + paddingRight() + relativeOffset);
   2849         if (childrenInline()) {
   2850             for (InlineRunBox* currBox = firstLineBox(); currBox; currBox = currBox->nextLineBox()) {
   2851                 int childRightEdge = currBox->x() + currBox->width();
   2852 
   2853                 // If this node is a root editable element, then the rightmostPosition should account for a caret at the end.
   2854                 // FIXME: Need to find another way to do this, since scrollbars could show when we don't want them to.
   2855                 if (node() && node()->isContentEditable() && node() == node()->rootEditableElement() && style()->direction() == LTR && !paddingRight())
   2856                     childRightEdge += 1;
   2857                 right = max(right, childRightEdge + paddingRight() + relativeOffset);
   2858             }
   2859         } else {
   2860             // Walk all normal flow children.
   2861             for (RenderBox* currBox = firstChildBox(); currBox; currBox = currBox->nextSiblingBox()) {
   2862                 if (currBox->isFloatingOrPositioned())
   2863                     continue;
   2864                 int childRightEdge = currBox->x() + currBox->width() + currBox->marginRight();
   2865                 right = max(right, childRightEdge + paddingRight() + relativeOffset);
   2866             }
   2867         }
   2868     }
   2869 
   2870     return right;
   2871 }
   2872 
   2873 int RenderBlock::leftmostPosition(bool includeOverflowInterior, bool includeSelf) const
   2874 {
   2875     int left = includeSelf && height() > 0 ? 0 : width();
   2876 
   2877     if (!includeOverflowInterior && (hasOverflowClip() || hasControlClip()))
   2878         return left;
   2879 
   2880     if (!firstChild() && (!width() || !height()))
   2881         return left;
   2882 
   2883     if (!hasColumns()) {
   2884         // FIXME: Come up with a way to use the layer tree to avoid visiting all the kids.
   2885         // For now, we have to descend into all the children, since we may have a huge abs div inside
   2886         // a tiny rel div buried somewhere deep in our child tree.  In this case we have to get to
   2887         // the abs div.
   2888         for (RenderObject* c = firstChild(); c; c = c->nextSibling()) {
   2889             if (!c->isFloatingOrPositioned() && c->isBox()) {
   2890                 RenderBox* childBox = toRenderBox(c);
   2891                 left = min(left, childBox->x() + childBox->leftmostPosition(false));
   2892             }
   2893         }
   2894     }
   2895 
   2896     if (includeSelf && isRelPositioned())
   2897         left += relativePositionOffsetX();
   2898 
   2899     if (!includeOverflowInterior && hasOverflowClip())
   2900         return left;
   2901 
   2902     int relativeOffset = includeSelf && isRelPositioned() ? relativePositionOffsetX() : 0;
   2903 
   2904     if (includeSelf)
   2905         left = min(left, leftLayoutOverflow() + relativeOffset);
   2906 
   2907     if (m_positionedObjects) {
   2908         RenderBox* r;
   2909         Iterator end = m_positionedObjects->end();
   2910         for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
   2911             r = *it;
   2912             // Fixed positioned objects do not scroll and thus should not constitute
   2913             // part of the leftmost position.
   2914             if (r->style()->position() != FixedPosition) {
   2915                 // FIXME: Should work for overflow sections too.
   2916                 // If a positioned object lies completely above the root it will be unreachable via scrolling.
   2917                 // Therefore we should not allow it to contribute to the leftmost position.
   2918                 if (!isRenderView() || r->y() + r->height() > 0 || r->y() + r->lowestPosition(false) > 0) {
   2919                     int lp = r->x() + r->leftmostPosition(false);
   2920                     left = min(left, lp + relativeOffset);
   2921                 }
   2922             }
   2923         }
   2924     }
   2925 
   2926     if (hasColumns()) {
   2927         // This only matters for RTL
   2928         if (style()->direction() == RTL)
   2929             left = min(columnRects()->last().x() + relativeOffset, left);
   2930         return left;
   2931     }
   2932 
   2933     if (m_floatingObjects) {
   2934         FloatingObject* r;
   2935         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2936         for ( ; (r = it.current()); ++it ) {
   2937             if (r->m_shouldPaint || r->m_renderer->hasSelfPaintingLayer()) {
   2938                 int lp = r->m_left + r->m_renderer->marginLeft() + r->m_renderer->leftmostPosition(false);
   2939                 left = min(left, lp + relativeOffset);
   2940             }
   2941         }
   2942     }
   2943 
   2944     if (!includeSelf && firstLineBox()) {
   2945         for (InlineRunBox* currBox = firstLineBox(); currBox; currBox = currBox->nextLineBox())
   2946             left = min(left, (int)currBox->x() + relativeOffset);
   2947     }
   2948 
   2949     return left;
   2950 }
   2951 
   2952 int
   2953 RenderBlock::leftBottom()
   2954 {
   2955     if (!m_floatingObjects) return 0;
   2956     int bottom = 0;
   2957     FloatingObject* r;
   2958     DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2959     for ( ; (r = it.current()); ++it )
   2960         if (r->m_bottom > bottom && r->type() == FloatingObject::FloatLeft)
   2961             bottom = r->m_bottom;
   2962 
   2963     return bottom;
   2964 }
   2965 
   2966 int
   2967 RenderBlock::rightBottom()
   2968 {
   2969     if (!m_floatingObjects) return 0;
   2970     int bottom = 0;
   2971     FloatingObject* r;
   2972     DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   2973     for ( ; (r = it.current()); ++it )
   2974         if (r->m_bottom>bottom && r->type() == FloatingObject::FloatRight)
   2975             bottom = r->m_bottom;
   2976 
   2977     return bottom;
   2978 }
   2979 
   2980 void RenderBlock::markLinesDirtyInVerticalRange(int top, int bottom, RootInlineBox* highest)
   2981 {
   2982     if (top >= bottom)
   2983         return;
   2984 
   2985     RootInlineBox* lowestDirtyLine = lastRootBox();
   2986     RootInlineBox* afterLowest = lowestDirtyLine;
   2987     while (lowestDirtyLine && lowestDirtyLine->blockHeight() >= bottom) {
   2988         afterLowest = lowestDirtyLine;
   2989         lowestDirtyLine = lowestDirtyLine->prevRootBox();
   2990     }
   2991 
   2992     while (afterLowest && afterLowest != highest && afterLowest->blockHeight() >= top) {
   2993         afterLowest->markDirty();
   2994         afterLowest = afterLowest->prevRootBox();
   2995     }
   2996 }
   2997 
   2998 void RenderBlock::clearFloats()
   2999 {
   3000     // Inline blocks are covered by the isReplaced() check in the avoidFloats method.
   3001     if (avoidsFloats() || isRoot() || isRenderView() || isFloatingOrPositioned() || isTableCell()) {
   3002         if (m_floatingObjects)
   3003             m_floatingObjects->clear();
   3004         return;
   3005     }
   3006 
   3007     typedef HashMap<RenderObject*, FloatingObject*> RendererToFloatInfoMap;
   3008     RendererToFloatInfoMap floatMap;
   3009 
   3010     if (m_floatingObjects) {
   3011         if (childrenInline()) {
   3012             m_floatingObjects->first();
   3013             while (FloatingObject* f = m_floatingObjects->take())
   3014                 floatMap.add(f->m_renderer, f);
   3015         } else
   3016             m_floatingObjects->clear();
   3017     }
   3018 
   3019     // Attempt to locate a previous sibling with overhanging floats.  We skip any elements that are
   3020     // out of flow (like floating/positioned elements), and we also skip over any objects that may have shifted
   3021     // to avoid floats.
   3022     bool parentHasFloats = false;
   3023     RenderObject* prev = previousSibling();
   3024     while (prev && (prev->isFloatingOrPositioned() || !prev->isBox() || !prev->isRenderBlock() || toRenderBlock(prev)->avoidsFloats())) {
   3025         if (prev->isFloating())
   3026             parentHasFloats = true;
   3027          prev = prev->previousSibling();
   3028     }
   3029 
   3030     // First add in floats from the parent.
   3031     int offset = y();
   3032     if (parentHasFloats) {
   3033         RenderBlock* parentBlock = toRenderBlock(parent());
   3034         addIntrudingFloats(parentBlock, parentBlock->borderLeft() + parentBlock->paddingLeft(), offset);
   3035     }
   3036 
   3037     int xoffset = 0;
   3038     if (prev)
   3039         offset -= toRenderBox(prev)->y();
   3040     else if (parent()->isBox()) {
   3041         prev = parent();
   3042         xoffset += toRenderBox(prev)->borderLeft() + toRenderBox(prev)->paddingLeft();
   3043     }
   3044 
   3045     // Add overhanging floats from the previous RenderBlock, but only if it has a float that intrudes into our space.
   3046     if (!prev || !prev->isRenderBlock())
   3047         return;
   3048 
   3049     RenderBlock* block = toRenderBlock(prev);
   3050     if (block->m_floatingObjects && block->floatBottom() > offset)
   3051         addIntrudingFloats(block, xoffset, offset);
   3052 
   3053     if (childrenInline()) {
   3054         int changeTop = INT_MAX;
   3055         int changeBottom = INT_MIN;
   3056         if (m_floatingObjects) {
   3057             for (FloatingObject* f = m_floatingObjects->first(); f; f = m_floatingObjects->next()) {
   3058                 FloatingObject* oldFloatingObject = floatMap.get(f->m_renderer);
   3059                 if (oldFloatingObject) {
   3060                     if (f->m_width != oldFloatingObject->m_width || f->m_left != oldFloatingObject->m_left) {
   3061                         changeTop = 0;
   3062                         changeBottom = max(changeBottom, max(f->m_bottom, oldFloatingObject->m_bottom));
   3063                     } else if (f->m_bottom != oldFloatingObject->m_bottom) {
   3064                         changeTop = min(changeTop, min(f->m_bottom, oldFloatingObject->m_bottom));
   3065                         changeBottom = max(changeBottom, max(f->m_bottom, oldFloatingObject->m_bottom));
   3066                     }
   3067 
   3068                     floatMap.remove(f->m_renderer);
   3069                     delete oldFloatingObject;
   3070                 } else {
   3071                     changeTop = 0;
   3072                     changeBottom = max(changeBottom, f->m_bottom);
   3073                 }
   3074             }
   3075         }
   3076 
   3077         RendererToFloatInfoMap::iterator end = floatMap.end();
   3078         for (RendererToFloatInfoMap::iterator it = floatMap.begin(); it != end; ++it) {
   3079             FloatingObject* floatingObject = (*it).second;
   3080             if (!floatingObject->m_isDescendant) {
   3081                 changeTop = 0;
   3082                 changeBottom = max(changeBottom, floatingObject->m_bottom);
   3083             }
   3084         }
   3085         deleteAllValues(floatMap);
   3086 
   3087         markLinesDirtyInVerticalRange(changeTop, changeBottom);
   3088     }
   3089 }
   3090 
   3091 int RenderBlock::addOverhangingFloats(RenderBlock* child, int xoff, int yoff, bool makeChildPaintOtherFloats)
   3092 {
   3093     // Prevent floats from being added to the canvas by the root element, e.g., <html>.
   3094     if (child->hasOverflowClip() || !child->containsFloats() || child->isRoot())
   3095         return 0;
   3096 
   3097     int lowestFloatBottom = 0;
   3098 
   3099     // Floats that will remain the child's responsibility to paint should factor into its
   3100     // overflow.
   3101     DeprecatedPtrListIterator<FloatingObject> it(*child->m_floatingObjects);
   3102     for (FloatingObject* r; (r = it.current()); ++it) {
   3103         int bottom = child->y() + r->m_bottom;
   3104         lowestFloatBottom = max(lowestFloatBottom, bottom);
   3105 
   3106         if (bottom > height()) {
   3107             // If the object is not in the list, we add it now.
   3108             if (!containsFloat(r->m_renderer)) {
   3109                 FloatingObject *floatingObj = new FloatingObject(r->type());
   3110                 floatingObj->m_top = r->m_top - yoff;
   3111                 floatingObj->m_bottom = r->m_bottom - yoff;
   3112                 floatingObj->m_left = r->m_left - xoff;
   3113                 floatingObj->m_width = r->m_width;
   3114                 floatingObj->m_renderer = r->m_renderer;
   3115 
   3116                 // The nearest enclosing layer always paints the float (so that zindex and stacking
   3117                 // behaves properly).  We always want to propagate the desire to paint the float as
   3118                 // far out as we can, to the outermost block that overlaps the float, stopping only
   3119                 // if we hit a self-painting layer boundary.
   3120                 if (r->m_renderer->enclosingSelfPaintingLayer() == enclosingSelfPaintingLayer())
   3121                     r->m_shouldPaint = false;
   3122                 else
   3123                     floatingObj->m_shouldPaint = false;
   3124 
   3125                 // We create the floating object list lazily.
   3126                 if (!m_floatingObjects) {
   3127                     m_floatingObjects = new DeprecatedPtrList<FloatingObject>;
   3128                     m_floatingObjects->setAutoDelete(true);
   3129                 }
   3130                 m_floatingObjects->append(floatingObj);
   3131             }
   3132         } else if (makeChildPaintOtherFloats && !r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer() &&
   3133                    r->m_renderer->isDescendantOf(child) && r->m_renderer->enclosingLayer() == child->enclosingLayer())
   3134             // The float is not overhanging from this block, so if it is a descendant of the child, the child should
   3135             // paint it (the other case is that it is intruding into the child), unless it has its own layer or enclosing
   3136             // layer.
   3137             // If makeChildPaintOtherFloats is false, it means that the child must already know about all the floats
   3138             // it should paint.
   3139             r->m_shouldPaint = true;
   3140 
   3141         if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer())
   3142             child->addOverflowFromChild(r->m_renderer, IntSize(r->m_left + r->m_renderer->marginLeft(), r->m_top + r->m_renderer->marginTop()));
   3143     }
   3144     return lowestFloatBottom;
   3145 }
   3146 
   3147 void RenderBlock::addIntrudingFloats(RenderBlock* prev, int xoff, int yoff)
   3148 {
   3149     // If the parent or previous sibling doesn't have any floats to add, don't bother.
   3150     if (!prev->m_floatingObjects)
   3151         return;
   3152 
   3153     DeprecatedPtrListIterator<FloatingObject> it(*prev->m_floatingObjects);
   3154     for (FloatingObject *r; (r = it.current()); ++it) {
   3155         if (r->m_bottom > yoff) {
   3156             // The object may already be in our list. Check for it up front to avoid
   3157             // creating duplicate entries.
   3158             FloatingObject* f = 0;
   3159             if (m_floatingObjects) {
   3160                 DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   3161                 while ((f = it.current())) {
   3162                     if (f->m_renderer == r->m_renderer) break;
   3163                     ++it;
   3164                 }
   3165             }
   3166             if (!f) {
   3167                 FloatingObject *floatingObj = new FloatingObject(r->type());
   3168                 floatingObj->m_top = r->m_top - yoff;
   3169                 floatingObj->m_bottom = r->m_bottom - yoff;
   3170                 floatingObj->m_left = r->m_left - xoff;
   3171                 // Applying the child's margin makes no sense in the case where the child was passed in.
   3172                 // since his own margin was added already through the subtraction of the |xoff| variable
   3173                 // above.  |xoff| will equal -flow->marginLeft() in this case, so it's already been taken
   3174                 // into account.  Only apply this code if |child| is false, since otherwise the left margin
   3175                 // will get applied twice.
   3176                 if (prev != parent())
   3177                     floatingObj->m_left += prev->marginLeft();
   3178                 floatingObj->m_left -= marginLeft();
   3179                 floatingObj->m_shouldPaint = false;  // We are not in the direct inheritance chain for this float. We will never paint it.
   3180                 floatingObj->m_width = r->m_width;
   3181                 floatingObj->m_renderer = r->m_renderer;
   3182 
   3183                 // We create the floating object list lazily.
   3184                 if (!m_floatingObjects) {
   3185                     m_floatingObjects = new DeprecatedPtrList<FloatingObject>;
   3186                     m_floatingObjects->setAutoDelete(true);
   3187                 }
   3188                 m_floatingObjects->append(floatingObj);
   3189             }
   3190         }
   3191     }
   3192 }
   3193 
   3194 bool RenderBlock::avoidsFloats() const
   3195 {
   3196     // Floats can't intrude into our box if we have a non-auto column count or width.
   3197     return RenderBox::avoidsFloats() || !style()->hasAutoColumnCount() || !style()->hasAutoColumnWidth();
   3198 }
   3199 
   3200 bool RenderBlock::containsFloat(RenderObject* o)
   3201 {
   3202     if (m_floatingObjects) {
   3203         DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   3204         while (it.current()) {
   3205             if (it.current()->m_renderer == o)
   3206                 return true;
   3207             ++it;
   3208         }
   3209     }
   3210     return false;
   3211 }
   3212 
   3213 void RenderBlock::markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove, bool inLayout)
   3214 {
   3215     setChildNeedsLayout(true, !inLayout);
   3216 
   3217     if (floatToRemove)
   3218         removeFloatingObject(floatToRemove);
   3219 
   3220     // Iterate over our children and mark them as needed.
   3221     if (!childrenInline()) {
   3222         for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
   3223             if ((!floatToRemove && child->isFloatingOrPositioned()) || !child->isRenderBlock())
   3224                 continue;
   3225             RenderBlock* childBlock = toRenderBlock(child);
   3226             if ((floatToRemove ? childBlock->containsFloat(floatToRemove) : childBlock->containsFloats()) || childBlock->shrinkToAvoidFloats())
   3227                 childBlock->markAllDescendantsWithFloatsForLayout(floatToRemove, inLayout);
   3228         }
   3229     }
   3230 }
   3231 
   3232 int RenderBlock::getClearDelta(RenderBox* child, int yPos)
   3233 {
   3234     // There is no need to compute clearance if we have no floats.
   3235     if (!containsFloats())
   3236         return 0;
   3237 
   3238     // At least one float is present.  We need to perform the clearance computation.
   3239     bool clearSet = child->style()->clear() != CNONE;
   3240     int bottom = 0;
   3241     switch (child->style()->clear()) {
   3242         case CNONE:
   3243             break;
   3244         case CLEFT:
   3245             bottom = leftBottom();
   3246             break;
   3247         case CRIGHT:
   3248             bottom = rightBottom();
   3249             break;
   3250         case CBOTH:
   3251             bottom = floatBottom();
   3252             break;
   3253     }
   3254 
   3255     // We also clear floats if we are too big to sit on the same line as a float (and wish to avoid floats by default).
   3256     int result = clearSet ? max(0, bottom - yPos) : 0;
   3257     if (!result && child->avoidsFloats()) {
   3258         int availableWidth = this->availableWidth();
   3259         if (child->minPrefWidth() > availableWidth)
   3260             return 0;
   3261 
   3262         int y = yPos;
   3263         while (true) {
   3264             int widthAtY = lineWidth(y, false);
   3265             if (widthAtY == availableWidth)
   3266                 return y - yPos;
   3267 
   3268             int oldChildY = child->y();
   3269             int oldChildWidth = child->width();
   3270             child->setY(y);
   3271             child->calcWidth();
   3272             int childWidthAtY = child->width();
   3273             child->setY(oldChildY);
   3274             child->setWidth(oldChildWidth);
   3275 
   3276             if (childWidthAtY <= widthAtY)
   3277                 return y - yPos;
   3278 
   3279             y = nextFloatBottomBelow(y);
   3280             ASSERT(y >= yPos);
   3281             if (y < yPos)
   3282                 break;
   3283         }
   3284         ASSERT_NOT_REACHED();
   3285     }
   3286     return result;
   3287 }
   3288 
   3289 bool RenderBlock::isPointInOverflowControl(HitTestResult& result, int _x, int _y, int _tx, int _ty)
   3290 {
   3291     if (!scrollsOverflow())
   3292         return false;
   3293 
   3294     return layer()->hitTestOverflowControls(result, IntPoint(_x - _tx, _y - _ty));
   3295 }
   3296 
   3297 bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction)
   3298 {
   3299     int tx = _tx + x();
   3300     int ty = _ty + y();
   3301 
   3302     if (!isRenderView()) {
   3303         // Check if we need to do anything at all.
   3304         IntRect overflowBox = visibleOverflowRect();
   3305         overflowBox.move(tx, ty);
   3306         if (!overflowBox.contains(_x, _y))
   3307             return false;
   3308     }
   3309 
   3310     if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) && isPointInOverflowControl(result, _x, _y, tx, ty)) {
   3311         updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
   3312         return true;
   3313     }
   3314 
   3315     // If we have clipping, then we can't have any spillout.
   3316     bool useOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer();
   3317     bool useClip = (hasControlClip() || useOverflowClip);
   3318     bool checkChildren = !useClip || (hasControlClip() ? controlClipRect(tx, ty).contains(_x, _y) : overflowClipRect(tx, ty).contains(_x, _y));
   3319     if (checkChildren) {
   3320         // Hit test descendants first.
   3321         int scrolledX = tx;
   3322         int scrolledY = ty;
   3323         if (hasOverflowClip())
   3324             layer()->subtractScrolledContentOffset(scrolledX, scrolledY);
   3325 
   3326         // Hit test contents if we don't have columns.
   3327         if (!hasColumns() && hitTestContents(request, result, _x, _y, scrolledX, scrolledY, hitTestAction))
   3328             return true;
   3329 
   3330         // Hit test our columns if we do have them.
   3331         if (hasColumns() && hitTestColumns(request, result, _x, _y, scrolledX, scrolledY, hitTestAction))
   3332             return true;
   3333 
   3334         // Hit test floats.
   3335         if (hitTestAction == HitTestFloat && m_floatingObjects) {
   3336             if (isRenderView()) {
   3337                 scrolledX += toRenderView(this)->frameView()->scrollX();
   3338                 scrolledY += toRenderView(this)->frameView()->scrollY();
   3339             }
   3340 
   3341             FloatingObject* o;
   3342             DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   3343             for (it.toLast(); (o = it.current()); --it) {
   3344                 if (o->m_shouldPaint && !o->m_renderer->hasSelfPaintingLayer()) {
   3345                     int xoffset = scrolledX + o->m_left + o->m_renderer->marginLeft() - o->m_renderer->x();
   3346                     int yoffset =  scrolledY + o->m_top + o->m_renderer->marginTop() - o->m_renderer->y();
   3347                     if (o->m_renderer->hitTest(request, result, IntPoint(_x, _y), xoffset, yoffset)) {
   3348                         updateHitTestResult(result, IntPoint(_x - xoffset, _y - yoffset));
   3349                         return true;
   3350                     }
   3351                 }
   3352             }
   3353         }
   3354     }
   3355 
   3356     // Now hit test our background
   3357     if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) {
   3358         IntRect boundsRect(tx, ty, width(), height());
   3359         if (visibleToHitTesting() && boundsRect.contains(_x, _y)) {
   3360             updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
   3361             return true;
   3362         }
   3363     }
   3364 
   3365     return false;
   3366 }
   3367 
   3368 bool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
   3369 {
   3370     // We need to do multiple passes, breaking up our hit testing into strips.
   3371     // We can always go left to right, since column contents are clipped (meaning that there
   3372     // can't be any overlap).
   3373     int currXOffset = 0;
   3374     int currYOffset = 0;
   3375     int colGap = columnGap();
   3376     Vector<IntRect>* colRects = columnRects();
   3377     for (unsigned i = 0; i < colRects->size(); i++) {
   3378         IntRect colRect = colRects->at(i);
   3379         colRect.move(tx, ty);
   3380 
   3381         if (colRect.contains(x, y)) {
   3382             // The point is inside this column.
   3383             // Adjust tx and ty to change where we hit test.
   3384 
   3385             int finalX = tx + currXOffset;
   3386             int finalY = ty + currYOffset;
   3387             return hitTestContents(request, result, x, y, finalX, finalY, hitTestAction);
   3388         }
   3389 
   3390         // Move to the next position.
   3391         if (style()->direction() == LTR)
   3392             currXOffset += colRect.width() + colGap;
   3393         else
   3394             currXOffset -= (colRect.width() + colGap);
   3395 
   3396         currYOffset -= colRect.height();
   3397     }
   3398 
   3399     return false;
   3400 }
   3401 
   3402 bool RenderBlock::hitTestContents(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
   3403 {
   3404     if (childrenInline() && !isTable()) {
   3405         // We have to hit-test our line boxes.
   3406         if (m_lineBoxes.hitTest(this, request, result, x, y, tx, ty, hitTestAction)) {
   3407             updateHitTestResult(result, IntPoint(x - tx, y - ty));
   3408             return true;
   3409         }
   3410     } else {
   3411         // Hit test our children.
   3412         HitTestAction childHitTest = hitTestAction;
   3413         if (hitTestAction == HitTestChildBlockBackgrounds)
   3414             childHitTest = HitTestChildBlockBackground;
   3415         for (RenderBox* child = lastChildBox(); child; child = child->previousSiblingBox()) {
   3416             if (!child->hasSelfPaintingLayer() && !child->isFloating() && child->nodeAtPoint(request, result, x, y, tx, ty, childHitTest)) {
   3417                 updateHitTestResult(result, IntPoint(x - tx, y - ty));
   3418                 return true;
   3419             }
   3420         }
   3421     }
   3422 
   3423     return false;
   3424 }
   3425 
   3426 Position RenderBlock::positionForBox(InlineBox *box, bool start) const
   3427 {
   3428     if (!box)
   3429         return Position();
   3430 
   3431     if (!box->renderer()->node())
   3432         return Position(node(), start ? caretMinOffset() : caretMaxOffset());
   3433 
   3434     if (!box->isInlineTextBox())
   3435         return Position(box->renderer()->node(), start ? box->renderer()->caretMinOffset() : box->renderer()->caretMaxOffset());
   3436 
   3437     InlineTextBox *textBox = static_cast<InlineTextBox *>(box);
   3438     return Position(box->renderer()->node(), start ? textBox->start() : textBox->start() + textBox->len());
   3439 }
   3440 
   3441 Position RenderBlock::positionForRenderer(RenderObject* renderer, bool start) const
   3442 {
   3443     if (!renderer)
   3444         return Position(node(), 0);
   3445 
   3446     Node* n = renderer->node() ? renderer->node() : node();
   3447     if (!n)
   3448         return Position();
   3449 
   3450     ASSERT(renderer == n->renderer());
   3451 
   3452     int offset = start ? renderer->caretMinOffset() : renderer->caretMaxOffset();
   3453 
   3454     // FIXME: This was a runtime check that seemingly couldn't fail; changed it to an assertion for now.
   3455     ASSERT(!n->isCharacterDataNode() || renderer->isText());
   3456 
   3457     return Position(n, offset);
   3458 }
   3459 
   3460 // FIXME: This function should go on RenderObject as an instance method. Then
   3461 // all cases in which positionForPoint recurs could call this instead to
   3462 // prevent crossing editable boundaries. This would require many tests.
   3463 static VisiblePosition positionForPointRespectingEditingBoundaries(RenderBox* parent, RenderBox* child, const IntPoint& pointInParentCoordinates)
   3464 {
   3465     IntPoint pointInChildCoordinates(pointInParentCoordinates - child->location());
   3466 
   3467     // If this is an anonymous renderer, we just recur normally
   3468     Node* childNode = child->node();
   3469     if (!childNode)
   3470         return child->positionForPoint(pointInChildCoordinates);
   3471 
   3472     // Otherwise, first make sure that the editability of the parent and child agree.
   3473     // If they don't agree, then we return a visible position just before or after the child
   3474     RenderObject* ancestor = parent;
   3475     while (ancestor && !ancestor->node())
   3476         ancestor = ancestor->parent();
   3477 
   3478     // If we can't find an ancestor to check editability on, or editability is unchanged, we recur like normal
   3479     if (!ancestor || ancestor->node()->isContentEditable() == childNode->isContentEditable())
   3480         return child->positionForPoint(pointInChildCoordinates);
   3481 
   3482     // Otherwise return before or after the child, depending on if the click was left or right of the child
   3483     int childMidX = child->width() / 2;
   3484     if (pointInChildCoordinates.x() < childMidX)
   3485         return ancestor->createVisiblePosition(childNode->nodeIndex(), DOWNSTREAM);
   3486     return ancestor->createVisiblePosition(childNode->nodeIndex() + 1, UPSTREAM);
   3487 }
   3488 
   3489 VisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint& pointInContents)
   3490 {
   3491     ASSERT(childrenInline());
   3492 
   3493     if (!firstRootBox())
   3494         return createVisiblePosition(0, DOWNSTREAM);
   3495 
   3496     // look for the closest line box in the root box which is at the passed-in y coordinate
   3497     InlineBox* closestBox = 0;
   3498     RootInlineBox* firstRootBoxWithChildren = 0;
   3499     RootInlineBox* lastRootBoxWithChildren = 0;
   3500     for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
   3501         if (!root->firstLeafChild())
   3502             continue;
   3503         if (!firstRootBoxWithChildren)
   3504             firstRootBoxWithChildren = root;
   3505         lastRootBoxWithChildren = root;
   3506 
   3507         // set the bottom based on whether there is a next root box
   3508         // FIXME: This will consider nextRootBox even if it has no children, and maybe it shouldn't.
   3509         int bottom;
   3510         if (root->nextRootBox()) {
   3511             // FIXME: We would prefer to make the break point halfway between the bottom
   3512             // of the previous root box and the top of the next root box.
   3513             bottom = root->nextRootBox()->lineTop();
   3514         } else
   3515             bottom = root->lineBottom() + verticalLineClickFudgeFactor;
   3516 
   3517         // check if this root line box is located at this y coordinate
   3518         if (pointInContents.y() < bottom) {
   3519             closestBox = root->closestLeafChildForXPos(pointInContents.x());
   3520             if (closestBox)
   3521                 break;
   3522         }
   3523     }
   3524 
   3525     Settings* settings = document()->settings();
   3526     bool useWindowsBehavior = settings && settings->editingBehavior() == EditingWindowsBehavior;
   3527 
   3528     if (useWindowsBehavior && !closestBox && lastRootBoxWithChildren) {
   3529         // y coordinate is below last root line box, pretend we hit it
   3530         closestBox = lastRootBoxWithChildren->closestLeafChildForXPos(pointInContents.x());
   3531     }
   3532 
   3533     if (closestBox) {
   3534         if (!useWindowsBehavior && pointInContents.y() < firstRootBoxWithChildren->lineTop() - verticalLineClickFudgeFactor) {
   3535             // y coordinate is above first root line box, so return the start of the first
   3536             return VisiblePosition(positionForBox(firstRootBoxWithChildren->firstLeafChild(), true), DOWNSTREAM);
   3537         }
   3538 
   3539         // pass the box a y position that is inside it
   3540         return closestBox->renderer()->positionForPoint(IntPoint(pointInContents.x(), closestBox->m_y));
   3541     }
   3542 
   3543     if (lastRootBoxWithChildren) {
   3544         // We hit this case for Mac behavior when the Y coordinate is below the last box.
   3545         ASSERT(!useWindowsBehavior);
   3546         return VisiblePosition(positionForBox(lastRootBoxWithChildren->lastLeafChild(), false), DOWNSTREAM);
   3547     }
   3548 
   3549     // Can't reach this. We have a root line box, but it has no kids.
   3550     // FIXME: This should ASSERT_NOT_REACHED(), but clicking on placeholder text
   3551     // seems to hit this code path.
   3552     return createVisiblePosition(0, DOWNSTREAM);
   3553 }
   3554 
   3555 static inline bool isChildHitTestCandidate(RenderBox* box)
   3556 {
   3557     return box->height() && box->style()->visibility() == VISIBLE && !box->isFloatingOrPositioned();
   3558 }
   3559 
   3560 VisiblePosition RenderBlock::positionForPoint(const IntPoint& point)
   3561 {
   3562     if (isTable())
   3563         return RenderBox::positionForPoint(point);
   3564 
   3565     if (isReplaced()) {
   3566         if (point.y() < 0 || (point.y() < height() && point.x() < 0))
   3567             return createVisiblePosition(caretMinOffset(), DOWNSTREAM);
   3568         if (point.y() >= height() || (point.y() >= 0 && point.x() >= width()))
   3569             return createVisiblePosition(caretMaxOffset(), DOWNSTREAM);
   3570     }
   3571 
   3572     int contentsX = point.x();
   3573     int contentsY = point.y();
   3574     offsetForContents(contentsX, contentsY);
   3575     IntPoint pointInContents(contentsX, contentsY);
   3576 
   3577     if (childrenInline())
   3578         return positionForPointWithInlineChildren(pointInContents);
   3579 
   3580     if (lastChildBox() && contentsY > lastChildBox()->y()) {
   3581         for (RenderBox* childBox = lastChildBox(); childBox; childBox = childBox->previousSiblingBox()) {
   3582             if (isChildHitTestCandidate(childBox))
   3583                 return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents);
   3584         }
   3585     } else {
   3586         for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
   3587             // We hit child if our click is above the bottom of its padding box (like IE6/7 and FF3).
   3588             if (isChildHitTestCandidate(childBox) && contentsY < childBox->frameRect().bottom())
   3589                 return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents);
   3590         }
   3591     }
   3592 
   3593     // We only get here if there are no hit test candidate children below the click.
   3594     return RenderBox::positionForPoint(point);
   3595 }
   3596 
   3597 void RenderBlock::offsetForContents(int& tx, int& ty) const
   3598 {
   3599     if (hasOverflowClip())
   3600         layer()->addScrolledContentOffset(tx, ty);
   3601 
   3602     if (hasColumns()) {
   3603         IntPoint contentsPoint(tx, ty);
   3604         adjustPointToColumnContents(contentsPoint);
   3605         tx = contentsPoint.x();
   3606         ty = contentsPoint.y();
   3607     }
   3608 }
   3609 
   3610 int RenderBlock::availableWidth() const
   3611 {
   3612     // If we have multiple columns, then the available width is reduced to our column width.
   3613     if (hasColumns())
   3614         return desiredColumnWidth();
   3615     return contentWidth();
   3616 }
   3617 
   3618 int RenderBlock::columnGap() const
   3619 {
   3620     if (style()->hasNormalColumnGap())
   3621         return style()->fontDescription().computedPixelSize(); // "1em" is recommended as the normal gap setting. Matches <p> margins.
   3622     return static_cast<int>(style()->columnGap());
   3623 }
   3624 
   3625 void RenderBlock::calcColumnWidth()
   3626 {
   3627     // Calculate our column width and column count.
   3628     unsigned desiredColumnCount = 1;
   3629     int desiredColumnWidth = contentWidth();
   3630 
   3631     // For now, we don't support multi-column layouts when printing, since we have to do a lot of work for proper pagination.
   3632     if (document()->printing() || (style()->hasAutoColumnCount() && style()->hasAutoColumnWidth())) {
   3633         setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
   3634         return;
   3635     }
   3636 
   3637     int availWidth = desiredColumnWidth;
   3638     int colGap = columnGap();
   3639     int colWidth = max(1, static_cast<int>(style()->columnWidth()));
   3640     int colCount = max(1, static_cast<int>(style()->columnCount()));
   3641 
   3642     if (style()->hasAutoColumnWidth()) {
   3643         if ((colCount - 1) * colGap < availWidth) {
   3644             desiredColumnCount = colCount;
   3645             desiredColumnWidth = (availWidth - (desiredColumnCount - 1) * colGap) / desiredColumnCount;
   3646         } else if (colGap < availWidth) {
   3647             desiredColumnCount = availWidth / colGap;
   3648             if (desiredColumnCount < 1)
   3649                 desiredColumnCount = 1;
   3650             desiredColumnWidth = (availWidth - (desiredColumnCount - 1) * colGap) / desiredColumnCount;
   3651         }
   3652     } else if (style()->hasAutoColumnCount()) {
   3653         if (colWidth < availWidth) {
   3654             desiredColumnCount = (availWidth + colGap) / (colWidth + colGap);
   3655             if (desiredColumnCount < 1)
   3656                 desiredColumnCount = 1;
   3657             desiredColumnWidth = (availWidth - (desiredColumnCount - 1) * colGap) / desiredColumnCount;
   3658         }
   3659     } else {
   3660         // Both are set.
   3661         if (colCount * colWidth + (colCount - 1) * colGap <= availWidth) {
   3662             desiredColumnCount = colCount;
   3663             desiredColumnWidth = colWidth;
   3664         } else if (colWidth < availWidth) {
   3665             desiredColumnCount = (availWidth + colGap) / (colWidth + colGap);
   3666             if (desiredColumnCount < 1)
   3667                 desiredColumnCount = 1;
   3668             desiredColumnWidth = (availWidth - (desiredColumnCount - 1) * colGap) / desiredColumnCount;
   3669         }
   3670     }
   3671     setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
   3672 }
   3673 
   3674 void RenderBlock::setDesiredColumnCountAndWidth(int count, int width)
   3675 {
   3676     if (count == 1 && style()->hasAutoColumnWidth()) {
   3677         if (hasColumns()) {
   3678             delete gColumnInfoMap->take(this);
   3679             setHasColumns(false);
   3680         }
   3681     } else {
   3682         ColumnInfo* info;
   3683         if (hasColumns())
   3684             info = gColumnInfoMap->get(this);
   3685         else {
   3686             if (!gColumnInfoMap)
   3687                 gColumnInfoMap = new ColumnInfoMap;
   3688             info = new ColumnInfo;
   3689             gColumnInfoMap->add(this, info);
   3690             setHasColumns(true);
   3691         }
   3692         info->m_desiredColumnCount = count;
   3693         info->m_desiredColumnWidth = width;
   3694     }
   3695 }
   3696 
   3697 int RenderBlock::desiredColumnWidth() const
   3698 {
   3699     if (!hasColumns())
   3700         return contentWidth();
   3701     return gColumnInfoMap->get(this)->m_desiredColumnWidth;
   3702 }
   3703 
   3704 unsigned RenderBlock::desiredColumnCount() const
   3705 {
   3706     if (!hasColumns())
   3707         return 1;
   3708     return gColumnInfoMap->get(this)->m_desiredColumnCount;
   3709 }
   3710 
   3711 Vector<IntRect>* RenderBlock::columnRects() const
   3712 {
   3713     if (!hasColumns())
   3714         return 0;
   3715     return &gColumnInfoMap->get(this)->m_columnRects;
   3716 }
   3717 
   3718 int RenderBlock::layoutColumns(int endOfContent, int requestedColumnHeight)
   3719 {
   3720     // Don't do anything if we have no columns
   3721     if (!hasColumns())
   3722         return -1;
   3723 
   3724     ColumnInfo* info = gColumnInfoMap->get(this);
   3725     int desiredColumnWidth = info->m_desiredColumnWidth;
   3726     int desiredColumnCount = info->m_desiredColumnCount;
   3727     Vector<IntRect>* columnRects = &info->m_columnRects;
   3728 
   3729     bool computeIntrinsicHeight = (endOfContent == -1);
   3730 
   3731     // Fill the columns in to the available height.  Attempt to balance the height of the columns.
   3732     // Add in half our line-height to help with best-guess initial balancing.
   3733     int columnSlop = lineHeight(false) / 2;
   3734     int remainingSlopSpace = columnSlop * desiredColumnCount;
   3735     int availableHeight = contentHeight();
   3736     int colHeight;
   3737     if (computeIntrinsicHeight && requestedColumnHeight >= 0)
   3738         colHeight = requestedColumnHeight;
   3739     else if (computeIntrinsicHeight)
   3740         colHeight = availableHeight / desiredColumnCount + columnSlop;
   3741     else
   3742         colHeight = availableHeight;
   3743     int originalColHeight = colHeight;
   3744 
   3745     int colGap = columnGap();
   3746 
   3747     // Compute a collection of column rects.
   3748     columnRects->clear();
   3749 
   3750     // Then we do a simulated "paint" into the column slices and allow the content to slightly adjust our individual column rects.
   3751     // FIXME: We need to take into account layers that are affected by the columns as well here so that they can have an opportunity
   3752     // to adjust column rects also.
   3753     RenderView* v = view();
   3754     int left = borderLeft() + paddingLeft();
   3755     int top = borderTop() + paddingTop();
   3756     int currX = style()->direction() == LTR ? borderLeft() + paddingLeft() : borderLeft() + paddingLeft() + contentWidth() - desiredColumnWidth;
   3757     int currY = top;
   3758     unsigned colCount = desiredColumnCount;
   3759     int maxColBottom = borderTop() + paddingTop();
   3760     int contentBottom = top + availableHeight;
   3761     int minimumColumnHeight = -1;
   3762     for (unsigned i = 0; i < colCount; i++) {
   3763         // If we aren't constrained, then the last column can just get all the remaining space.
   3764         if (computeIntrinsicHeight && i == colCount - 1)
   3765             colHeight = availableHeight;
   3766 
   3767         // This represents the real column position.
   3768         IntRect colRect(currX, top, desiredColumnWidth, colHeight);
   3769 
   3770         // For the simulated paint, we pretend like everything is in one long strip.
   3771         IntRect pageRect(left, currY, desiredColumnWidth, colHeight);
   3772         v->setPrintRect(pageRect);
   3773         v->setTruncatedAt(currY + colHeight);
   3774         GraphicsContext context((PlatformGraphicsContext*)0);
   3775         RenderObject::PaintInfo paintInfo(&context, pageRect, PaintPhaseForeground, false, 0, 0);
   3776 
   3777         setHasColumns(false);
   3778         paintObject(paintInfo, 0, 0);
   3779         setHasColumns(true);
   3780 
   3781         if (computeIntrinsicHeight && v->minimumColumnHeight() > originalColHeight) {
   3782             // The initial column height was too small to contain one line of text.
   3783             minimumColumnHeight = max(minimumColumnHeight, v->minimumColumnHeight());
   3784         }
   3785 
   3786         int adjustedBottom = v->bestTruncatedAt();
   3787         if (adjustedBottom <= currY)
   3788             adjustedBottom = currY + colHeight;
   3789 
   3790         colRect.setHeight(adjustedBottom - currY);
   3791 
   3792         // Add in the lost space to the subsequent columns.
   3793         // FIXME: This will create a "staircase" effect if there are enough columns, but the effect should be pretty subtle.
   3794         if (computeIntrinsicHeight) {
   3795             int lostSpace = colHeight - colRect.height();
   3796             if (lostSpace > remainingSlopSpace) {
   3797                 // Redestribute the space among the remaining columns.
   3798                 int spaceToRedistribute = lostSpace - remainingSlopSpace;
   3799                 int remainingColumns = colCount - i + 1;
   3800                 colHeight += spaceToRedistribute / remainingColumns;
   3801             }
   3802             remainingSlopSpace = max(0, remainingSlopSpace - lostSpace);
   3803         }
   3804 
   3805         if (style()->direction() == LTR)
   3806             currX += desiredColumnWidth + colGap;
   3807         else
   3808             currX -= (desiredColumnWidth + colGap);
   3809 
   3810         currY += colRect.height();
   3811         availableHeight -= colRect.height();
   3812 
   3813         maxColBottom = max(colRect.bottom(), maxColBottom);
   3814 
   3815         columnRects->append(colRect);
   3816 
   3817         // Start adding in more columns as long as there's still content left.
   3818         if (currY < endOfContent && i == colCount - 1 && (computeIntrinsicHeight || contentHeight()))
   3819             colCount++;
   3820     }
   3821 
   3822     if (minimumColumnHeight >= 0) {
   3823         // If originalColHeight was too small, we need to try to layout again.
   3824         return layoutColumns(endOfContent, minimumColumnHeight);
   3825     }
   3826 
   3827     int overflowRight = max(width(), currX - colGap);
   3828     int overflowLeft = min(0, currX + desiredColumnWidth + colGap);
   3829     int overflowHeight = maxColBottom;
   3830     int toAdd = borderBottom() + paddingBottom() + horizontalScrollbarHeight();
   3831 
   3832     if (computeIntrinsicHeight)
   3833         setHeight(maxColBottom + toAdd);
   3834 
   3835     m_overflow.clear();
   3836     addLayoutOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight));
   3837 
   3838     v->setPrintRect(IntRect());
   3839     v->setTruncatedAt(0);
   3840 
   3841     ASSERT(colCount == columnRects->size());
   3842 
   3843     return contentBottom;
   3844 }
   3845 
   3846 void RenderBlock::adjustPointToColumnContents(IntPoint& point) const
   3847 {
   3848     // Just bail if we have no columns.
   3849     if (!hasColumns())
   3850         return;
   3851 
   3852     Vector<IntRect>* colRects = columnRects();
   3853 
   3854     // Determine which columns we intersect.
   3855     int colGap = columnGap();
   3856     int leftGap = colGap / 2;
   3857     IntPoint columnPoint(colRects->at(0).location());
   3858     int yOffset = 0;
   3859     for (unsigned i = 0; i < colRects->size(); i++) {
   3860         // Add in half the column gap to the left and right of the rect.
   3861         IntRect colRect = colRects->at(i);
   3862         IntRect gapAndColumnRect(colRect.x() - leftGap, colRect.y(), colRect.width() + colGap, colRect.height());
   3863 
   3864         if (gapAndColumnRect.contains(point)) {
   3865             // We're inside the column.  Translate the x and y into our column coordinate space.
   3866             point.move(columnPoint.x() - colRect.x(), yOffset);
   3867             return;
   3868         }
   3869 
   3870         // Move to the next position.
   3871         yOffset += colRect.height();
   3872     }
   3873 }
   3874 
   3875 void RenderBlock::adjustRectForColumns(IntRect& r) const
   3876 {
   3877     // Just bail if we have no columns.
   3878     if (!hasColumns())
   3879         return;
   3880 
   3881     Vector<IntRect>* colRects = columnRects();
   3882 
   3883     // Begin with a result rect that is empty.
   3884     IntRect result;
   3885 
   3886     // Determine which columns we intersect.
   3887     int currXOffset = 0;
   3888     int currYOffset = 0;
   3889     int colGap = columnGap();
   3890     for (unsigned i = 0; i < colRects->size(); i++) {
   3891         IntRect colRect = colRects->at(i);
   3892 
   3893         IntRect repaintRect = r;
   3894         repaintRect.move(currXOffset, currYOffset);
   3895 
   3896         repaintRect.intersect(colRect);
   3897 
   3898         result.unite(repaintRect);
   3899 
   3900         // Move to the next position.
   3901         if (style()->direction() == LTR)
   3902             currXOffset += colRect.width() + colGap;
   3903         else
   3904             currXOffset -= (colRect.width() + colGap);
   3905 
   3906         currYOffset -= colRect.height();
   3907     }
   3908 
   3909     r = result;
   3910 }
   3911 
   3912 void RenderBlock::calcPrefWidths()
   3913 {
   3914     ASSERT(prefWidthsDirty());
   3915 
   3916     updateFirstLetter();
   3917 
   3918     if (!isTableCell() && style()->width().isFixed() && style()->width().value() > 0)
   3919         m_minPrefWidth = m_maxPrefWidth = calcContentBoxWidth(style()->width().value());
   3920     else {
   3921         m_minPrefWidth = 0;
   3922         m_maxPrefWidth = 0;
   3923 
   3924         if (childrenInline())
   3925             calcInlinePrefWidths();
   3926         else
   3927             calcBlockPrefWidths();
   3928 
   3929         m_maxPrefWidth = max(m_minPrefWidth, m_maxPrefWidth);
   3930 
   3931         if (!style()->autoWrap() && childrenInline()) {
   3932             m_minPrefWidth = m_maxPrefWidth;
   3933 
   3934             // A horizontal marquee with inline children has no minimum width.
   3935             if (layer() && layer()->marquee() && layer()->marquee()->isHorizontal())
   3936                 m_minPrefWidth = 0;
   3937         }
   3938 
   3939         if (isTableCell()) {
   3940             Length w = toRenderTableCell(this)->styleOrColWidth();
   3941             if (w.isFixed() && w.value() > 0)
   3942                 m_maxPrefWidth = max(m_minPrefWidth, calcContentBoxWidth(w.value()));
   3943         }
   3944     }
   3945 
   3946     if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) {
   3947         m_maxPrefWidth = max(m_maxPrefWidth, calcContentBoxWidth(style()->minWidth().value()));
   3948         m_minPrefWidth = max(m_minPrefWidth, calcContentBoxWidth(style()->minWidth().value()));
   3949     }
   3950 
   3951     if (style()->maxWidth().isFixed() && style()->maxWidth().value() != undefinedLength) {
   3952         m_maxPrefWidth = min(m_maxPrefWidth, calcContentBoxWidth(style()->maxWidth().value()));
   3953         m_minPrefWidth = min(m_minPrefWidth, calcContentBoxWidth(style()->maxWidth().value()));
   3954     }
   3955 
   3956     int toAdd = 0;
   3957     toAdd = borderLeft() + borderRight() + paddingLeft() + paddingRight();
   3958 
   3959     if (hasOverflowClip() && style()->overflowY() == OSCROLL)
   3960         toAdd += verticalScrollbarWidth();
   3961 
   3962     m_minPrefWidth += toAdd;
   3963     m_maxPrefWidth += toAdd;
   3964 
   3965     setPrefWidthsDirty(false);
   3966 }
   3967 
   3968 struct InlineMinMaxIterator {
   3969 /* InlineMinMaxIterator is a class that will iterate over all render objects that contribute to
   3970    inline min/max width calculations.  Note the following about the way it walks:
   3971    (1) Positioned content is skipped (since it does not contribute to min/max width of a block)
   3972    (2) We do not drill into the children of floats or replaced elements, since you can't break
   3973        in the middle of such an element.
   3974    (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side can have
   3975        distinct borders/margin/padding that contribute to the min/max width.
   3976 */
   3977     RenderObject* parent;
   3978     RenderObject* current;
   3979     bool endOfInline;
   3980 
   3981     InlineMinMaxIterator(RenderObject* p, bool end = false)
   3982         :parent(p), current(p), endOfInline(end) {}
   3983 
   3984     RenderObject* next();
   3985 };
   3986 
   3987 RenderObject* InlineMinMaxIterator::next()
   3988 {
   3989     RenderObject* result = 0;
   3990     bool oldEndOfInline = endOfInline;
   3991     endOfInline = false;
   3992     while (current || current == parent) {
   3993         if (!oldEndOfInline &&
   3994             (current == parent ||
   3995              (!current->isFloating() && !current->isReplaced() && !current->isPositioned())))
   3996             result = current->firstChild();
   3997         if (!result) {
   3998             // We hit the end of our inline. (It was empty, e.g., <span></span>.)
   3999             if (!oldEndOfInline && current->isRenderInline()) {
   4000                 result = current;
   4001                 endOfInline = true;
   4002                 break;
   4003             }
   4004 
   4005             while (current && current != parent) {
   4006                 result = current->nextSibling();
   4007                 if (result) break;
   4008                 current = current->parent();
   4009                 if (current && current != parent && current->isRenderInline()) {
   4010                     result = current;
   4011                     endOfInline = true;
   4012                     break;
   4013                 }
   4014             }
   4015         }
   4016 
   4017         if (!result)
   4018             break;
   4019 
   4020         if (!result->isPositioned() && (result->isText() || result->isFloating() || result->isReplaced() || result->isRenderInline()))
   4021              break;
   4022 
   4023         current = result;
   4024         result = 0;
   4025     }
   4026 
   4027     // Update our position.
   4028     current = result;
   4029     return current;
   4030 }
   4031 
   4032 static int getBPMWidth(int childValue, Length cssUnit)
   4033 {
   4034     if (cssUnit.type() != Auto)
   4035         return (cssUnit.isFixed() ? cssUnit.value() : childValue);
   4036     return 0;
   4037 }
   4038 
   4039 static int getBorderPaddingMargin(const RenderBoxModelObject* child, bool endOfInline)
   4040 {
   4041     RenderStyle* cstyle = child->style();
   4042     int result = 0;
   4043     bool leftSide = (cstyle->direction() == LTR) ? !endOfInline : endOfInline;
   4044     result += getBPMWidth((leftSide ? child->marginLeft() : child->marginRight()),
   4045                           (leftSide ? cstyle->marginLeft() :
   4046                                       cstyle->marginRight()));
   4047     result += getBPMWidth((leftSide ? child->paddingLeft() : child->paddingRight()),
   4048                           (leftSide ? cstyle->paddingLeft() :
   4049                                       cstyle->paddingRight()));
   4050     result += leftSide ? child->borderLeft() : child->borderRight();
   4051     return result;
   4052 }
   4053 
   4054 static inline void stripTrailingSpace(int& inlineMax, int& inlineMin,
   4055                                       RenderObject* trailingSpaceChild)
   4056 {
   4057     if (trailingSpaceChild && trailingSpaceChild->isText()) {
   4058         // Collapse away the trailing space at the end of a block.
   4059         RenderText* t = toRenderText(trailingSpaceChild);
   4060         const UChar space = ' ';
   4061         const Font& font = t->style()->font(); // FIXME: This ignores first-line.
   4062         int spaceWidth = font.width(TextRun(&space, 1));
   4063         inlineMax -= spaceWidth + font.wordSpacing();
   4064         if (inlineMin > inlineMax)
   4065             inlineMin = inlineMax;
   4066     }
   4067 }
   4068 
   4069 void RenderBlock::calcInlinePrefWidths()
   4070 {
   4071     int inlineMax = 0;
   4072     int inlineMin = 0;
   4073 
   4074     int cw = containingBlock()->contentWidth();
   4075 
   4076     // If we are at the start of a line, we want to ignore all white-space.
   4077     // Also strip spaces if we previously had text that ended in a trailing space.
   4078     bool stripFrontSpaces = true;
   4079     RenderObject* trailingSpaceChild = 0;
   4080 
   4081     // Firefox and Opera will allow a table cell to grow to fit an image inside it under
   4082     // very specific cirucumstances (in order to match common WinIE renderings).
   4083     // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
   4084     bool allowImagesToBreak = !style()->htmlHacks() || !isTableCell() || !style()->width().isIntrinsicOrAuto();
   4085 
   4086     bool autoWrap, oldAutoWrap;
   4087     autoWrap = oldAutoWrap = style()->autoWrap();
   4088 
   4089     InlineMinMaxIterator childIterator(this);
   4090     bool addedTextIndent = false; // Only gets added in once.
   4091     RenderObject* prevFloat = 0;
   4092     RenderObject* previousLeaf = 0;
   4093     while (RenderObject* child = childIterator.next()) {
   4094         autoWrap = child->isReplaced() ? child->parent()->style()->autoWrap() :
   4095             child->style()->autoWrap();
   4096 
   4097         if (!child->isBR()) {
   4098             // Step One: determine whether or not we need to go ahead and
   4099             // terminate our current line.  Each discrete chunk can become
   4100             // the new min-width, if it is the widest chunk seen so far, and
   4101             // it can also become the max-width.
   4102 
   4103             // Children fall into three categories:
   4104             // (1) An inline flow object.  These objects always have a min/max of 0,
   4105             // and are included in the iteration solely so that their margins can
   4106             // be added in.
   4107             //
   4108             // (2) An inline non-text non-flow object, e.g., an inline replaced element.
   4109             // These objects can always be on a line by themselves, so in this situation
   4110             // we need to go ahead and break the current line, and then add in our own
   4111             // margins and min/max width on its own line, and then terminate the line.
   4112             //
   4113             // (3) A text object.  Text runs can have breakable characters at the start,
   4114             // the middle or the end.  They may also lose whitespace off the front if
   4115             // we're already ignoring whitespace.  In order to compute accurate min-width
   4116             // information, we need three pieces of information.
   4117             // (a) the min-width of the first non-breakable run.  Should be 0 if the text string
   4118             // starts with whitespace.
   4119             // (b) the min-width of the last non-breakable run. Should be 0 if the text string
   4120             // ends with whitespace.
   4121             // (c) the min/max width of the string (trimmed for whitespace).
   4122             //
   4123             // If the text string starts with whitespace, then we need to go ahead and
   4124             // terminate our current line (unless we're already in a whitespace stripping
   4125             // mode.
   4126             //
   4127             // If the text string has a breakable character in the middle, but didn't start
   4128             // with whitespace, then we add the width of the first non-breakable run and
   4129             // then end the current line.  We then need to use the intermediate min/max width
   4130             // values (if any of them are larger than our current min/max).  We then look at
   4131             // the width of the last non-breakable run and use that to start a new line
   4132             // (unless we end in whitespace).
   4133             RenderStyle* cstyle = child->style();
   4134             int childMin = 0;
   4135             int childMax = 0;
   4136 
   4137             if (!child->isText()) {
   4138                 // Case (1) and (2).  Inline replaced and inline flow elements.
   4139                 if (child->isRenderInline()) {
   4140                     // Add in padding/border/margin from the appropriate side of
   4141                     // the element.
   4142                     int bpm = getBorderPaddingMargin(toRenderInline(child), childIterator.endOfInline);
   4143                     childMin += bpm;
   4144                     childMax += bpm;
   4145 
   4146                     inlineMin += childMin;
   4147                     inlineMax += childMax;
   4148 
   4149                     child->setPrefWidthsDirty(false);
   4150                 } else {
   4151                     // Inline replaced elts add in their margins to their min/max values.
   4152                     int margins = 0;
   4153                     Length leftMargin = cstyle->marginLeft();
   4154                     Length rightMargin = cstyle->marginRight();
   4155                     if (leftMargin.isFixed())
   4156                         margins += leftMargin.value();
   4157                     if (rightMargin.isFixed())
   4158                         margins += rightMargin.value();
   4159                     childMin += margins;
   4160                     childMax += margins;
   4161                 }
   4162             }
   4163 
   4164             if (!child->isRenderInline() && !child->isText()) {
   4165                 // Case (2). Inline replaced elements and floats.
   4166                 // Go ahead and terminate the current line as far as
   4167                 // minwidth is concerned.
   4168                 childMin += child->minPrefWidth();
   4169                 childMax += child->maxPrefWidth();
   4170 
   4171                 bool clearPreviousFloat;
   4172                 if (child->isFloating()) {
   4173                     clearPreviousFloat = (prevFloat
   4174                         && ((prevFloat->style()->floating() == FLEFT && (child->style()->clear() & CLEFT))
   4175                             || (prevFloat->style()->floating() == FRIGHT && (child->style()->clear() & CRIGHT))));
   4176                     prevFloat = child;
   4177                 } else
   4178                     clearPreviousFloat = false;
   4179 
   4180                 bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak;
   4181                 if ((canBreakReplacedElement && (autoWrap || oldAutoWrap)) || clearPreviousFloat) {
   4182                     m_minPrefWidth = max(inlineMin, m_minPrefWidth);
   4183                     inlineMin = 0;
   4184                 }
   4185 
   4186                 // If we're supposed to clear the previous float, then terminate maxwidth as well.
   4187                 if (clearPreviousFloat) {
   4188                     m_maxPrefWidth = max(inlineMax, m_maxPrefWidth);
   4189                     inlineMax = 0;
   4190                 }
   4191 
   4192                 // Add in text-indent.  This is added in only once.
   4193                 int ti = 0;
   4194                 if (!addedTextIndent) {
   4195                     addedTextIndent = true;
   4196                     ti = style()->textIndent().calcMinValue(cw);
   4197                     childMin+=ti;
   4198                     childMax+=ti;
   4199                 }
   4200 
   4201                 // Add our width to the max.
   4202                 inlineMax += childMax;
   4203 
   4204                 if (!autoWrap || !canBreakReplacedElement) {
   4205                     if (child->isFloating())
   4206                         m_minPrefWidth = max(childMin, m_minPrefWidth);
   4207                     else
   4208                         inlineMin += childMin;
   4209                 } else {
   4210                     // Now check our line.
   4211                     m_minPrefWidth = max(childMin, m_minPrefWidth);
   4212 
   4213                     // Now start a new line.
   4214                     inlineMin = 0;
   4215                 }
   4216 
   4217                 // We are no longer stripping whitespace at the start of
   4218                 // a line.
   4219                 if (!child->isFloating()) {
   4220                     stripFrontSpaces = false;
   4221                     trailingSpaceChild = 0;
   4222                 }
   4223             } else if (child->isText()) {
   4224                 // Case (3). Text.
   4225                 RenderText* t = toRenderText(child);
   4226 
   4227                 if (t->isWordBreak()) {
   4228                     m_minPrefWidth = max(inlineMin, m_minPrefWidth);
   4229                     inlineMin = 0;
   4230                     continue;
   4231                 }
   4232 
   4233                 // Determine if we have a breakable character.  Pass in
   4234                 // whether or not we should ignore any spaces at the front
   4235                 // of the string.  If those are going to be stripped out,
   4236                 // then they shouldn't be considered in the breakable char
   4237                 // check.
   4238                 bool hasBreakableChar, hasBreak;
   4239                 int beginMin, endMin;
   4240                 bool beginWS, endWS;
   4241                 int beginMax, endMax;
   4242                 t->trimmedPrefWidths(inlineMax, beginMin, beginWS, endMin, endWS,
   4243                                      hasBreakableChar, hasBreak, beginMax, endMax,
   4244                                      childMin, childMax, stripFrontSpaces);
   4245 
   4246                 // This text object will not be rendered, but it may still provide a breaking opportunity.
   4247                 if (!hasBreak && childMax == 0) {
   4248                     if (autoWrap && (beginWS || endWS)) {
   4249                         m_minPrefWidth = max(inlineMin, m_minPrefWidth);
   4250                         inlineMin = 0;
   4251                     }
   4252                     continue;
   4253                 }
   4254 
   4255                 if (stripFrontSpaces)
   4256                     trailingSpaceChild = child;
   4257                 else
   4258                     trailingSpaceChild = 0;
   4259 
   4260                 // Add in text-indent.  This is added in only once.
   4261                 int ti = 0;
   4262                 if (!addedTextIndent) {
   4263                     addedTextIndent = true;
   4264                     ti = style()->textIndent().calcMinValue(cw);
   4265                     childMin+=ti; beginMin += ti;
   4266                     childMax+=ti; beginMax += ti;
   4267                 }
   4268 
   4269                 // If we have no breakable characters at all,
   4270                 // then this is the easy case. We add ourselves to the current
   4271                 // min and max and continue.
   4272                 if (!hasBreakableChar) {
   4273                     inlineMin += childMin;
   4274                 } else {
   4275                     // We have a breakable character.  Now we need to know if
   4276                     // we start and end with whitespace.
   4277                     if (beginWS)
   4278                         // Go ahead and end the current line.
   4279                         m_minPrefWidth = max(inlineMin, m_minPrefWidth);
   4280                     else {
   4281                         inlineMin += beginMin;
   4282                         m_minPrefWidth = max(inlineMin, m_minPrefWidth);
   4283                         childMin -= ti;
   4284                     }
   4285 
   4286                     inlineMin = childMin;
   4287 
   4288                     if (endWS) {
   4289                         // We end in whitespace, which means we can go ahead
   4290                         // and end our current line.
   4291                         m_minPrefWidth = max(inlineMin, m_minPrefWidth);
   4292                         inlineMin = 0;
   4293                     } else {
   4294                         m_minPrefWidth = max(inlineMin, m_minPrefWidth);
   4295                         inlineMin = endMin;
   4296                     }
   4297                 }
   4298 
   4299                 if (hasBreak) {
   4300                     inlineMax += beginMax;
   4301                     m_maxPrefWidth = max(inlineMax, m_maxPrefWidth);
   4302                     m_maxPrefWidth = max(childMax, m_maxPrefWidth);
   4303                     inlineMax = endMax;
   4304                 } else
   4305                     inlineMax += childMax;
   4306             }
   4307 
   4308             // Ignore spaces after a list marker.
   4309             if (child->isListMarker())
   4310                 stripFrontSpaces = true;
   4311         } else {
   4312             m_minPrefWidth = max(inlineMin, m_minPrefWidth);
   4313             m_maxPrefWidth = max(inlineMax, m_maxPrefWidth);
   4314             inlineMin = inlineMax = 0;
   4315             stripFrontSpaces = true;
   4316             trailingSpaceChild = 0;
   4317         }
   4318 
   4319         oldAutoWrap = autoWrap;
   4320         if (!child->isRenderInline())
   4321             previousLeaf = child;
   4322     }
   4323 
   4324     if (style()->collapseWhiteSpace())
   4325         stripTrailingSpace(inlineMax, inlineMin, trailingSpaceChild);
   4326 
   4327     m_minPrefWidth = max(inlineMin, m_minPrefWidth);
   4328     m_maxPrefWidth = max(inlineMax, m_maxPrefWidth);
   4329 }
   4330 
   4331 // Use a very large value (in effect infinite).
   4332 #define BLOCK_MAX_WIDTH 15000
   4333 
   4334 void RenderBlock::calcBlockPrefWidths()
   4335 {
   4336     bool nowrap = style()->whiteSpace() == NOWRAP;
   4337 
   4338     RenderObject *child = firstChild();
   4339     int floatLeftWidth = 0, floatRightWidth = 0;
   4340     while (child) {
   4341         // Positioned children don't affect the min/max width
   4342         if (child->isPositioned()) {
   4343             child = child->nextSibling();
   4344             continue;
   4345         }
   4346 
   4347         if (child->isFloating() || (child->isBox() && toRenderBox(child)->avoidsFloats())) {
   4348             int floatTotalWidth = floatLeftWidth + floatRightWidth;
   4349             if (child->style()->clear() & CLEFT) {
   4350                 m_maxPrefWidth = max(floatTotalWidth, m_maxPrefWidth);
   4351                 floatLeftWidth = 0;
   4352             }
   4353             if (child->style()->clear() & CRIGHT) {
   4354                 m_maxPrefWidth = max(floatTotalWidth, m_maxPrefWidth);
   4355                 floatRightWidth = 0;
   4356             }
   4357         }
   4358 
   4359         // A margin basically has three types: fixed, percentage, and auto (variable).
   4360         // Auto and percentage margins simply become 0 when computing min/max width.
   4361         // Fixed margins can be added in as is.
   4362         Length ml = child->style()->marginLeft();
   4363         Length mr = child->style()->marginRight();
   4364         int margin = 0, marginLeft = 0, marginRight = 0;
   4365         if (ml.isFixed())
   4366             marginLeft += ml.value();
   4367         if (mr.isFixed())
   4368             marginRight += mr.value();
   4369         margin = marginLeft + marginRight;
   4370 
   4371         int w = child->minPrefWidth() + margin;
   4372         m_minPrefWidth = max(w, m_minPrefWidth);
   4373 
   4374         // IE ignores tables for calculation of nowrap. Makes some sense.
   4375         if (nowrap && !child->isTable())
   4376             m_maxPrefWidth = max(w, m_maxPrefWidth);
   4377 
   4378         w = child->maxPrefWidth() + margin;
   4379 
   4380         if (!child->isFloating()) {
   4381             if (child->isBox() && toRenderBox(child)->avoidsFloats()) {
   4382                 // Determine a left and right max value based off whether or not the floats can fit in the
   4383                 // margins of the object.  For negative margins, we will attempt to overlap the float if the negative margin
   4384                 // is smaller than the float width.
   4385                 int maxLeft = marginLeft > 0 ? max(floatLeftWidth, marginLeft) : floatLeftWidth + marginLeft;
   4386                 int maxRight = marginRight > 0 ? max(floatRightWidth, marginRight) : floatRightWidth + marginRight;
   4387                 w = child->maxPrefWidth() + maxLeft + maxRight;
   4388                 w = max(w, floatLeftWidth + floatRightWidth);
   4389             }
   4390             else
   4391                 m_maxPrefWidth = max(floatLeftWidth + floatRightWidth, m_maxPrefWidth);
   4392             floatLeftWidth = floatRightWidth = 0;
   4393         }
   4394 
   4395         if (child->isFloating()) {
   4396             if (style()->floating() == FLEFT)
   4397                 floatLeftWidth += w;
   4398             else
   4399                 floatRightWidth += w;
   4400         } else
   4401             m_maxPrefWidth = max(w, m_maxPrefWidth);
   4402 
   4403         // A very specific WinIE quirk.
   4404         // Example:
   4405         /*
   4406            <div style="position:absolute; width:100px; top:50px;">
   4407               <div style="position:absolute;left:0px;top:50px;height:50px;background-color:green">
   4408                 <table style="width:100%"><tr><td></table>
   4409               </div>
   4410            </div>
   4411         */
   4412         // In the above example, the inner absolute positioned block should have a computed width
   4413         // of 100px because of the table.
   4414         // We can achieve this effect by making the maxwidth of blocks that contain tables
   4415         // with percentage widths be infinite (as long as they are not inside a table cell).
   4416         if (style()->htmlHacks() && child->style()->width().isPercent() &&
   4417             !isTableCell() && child->isTable() && m_maxPrefWidth < BLOCK_MAX_WIDTH) {
   4418             RenderBlock* cb = containingBlock();
   4419             while (!cb->isRenderView() && !cb->isTableCell())
   4420                 cb = cb->containingBlock();
   4421             if (!cb->isTableCell())
   4422                 m_maxPrefWidth = BLOCK_MAX_WIDTH;
   4423         }
   4424 
   4425         child = child->nextSibling();
   4426     }
   4427 
   4428     // Always make sure these values are non-negative.
   4429     m_minPrefWidth = max(0, m_minPrefWidth);
   4430     m_maxPrefWidth = max(0, m_maxPrefWidth);
   4431 
   4432     m_maxPrefWidth = max(floatLeftWidth + floatRightWidth, m_maxPrefWidth);
   4433 }
   4434 
   4435 bool RenderBlock::hasLineIfEmpty() const
   4436 {
   4437     if (!node())
   4438         return false;
   4439 
   4440     if (node()->isContentEditable() && node()->rootEditableElement() == node())
   4441         return true;
   4442 
   4443     if (node()->isShadowNode() && (node()->shadowParentNode()->hasTagName(inputTag) || node()->shadowParentNode()->hasTagName(textareaTag)))
   4444         return true;
   4445 
   4446     return false;
   4447 }
   4448 
   4449 int RenderBlock::lineHeight(bool firstLine, bool isRootLineBox) const
   4450 {
   4451     // Inline blocks are replaced elements. Otherwise, just pass off to
   4452     // the base class.  If we're being queried as though we're the root line
   4453     // box, then the fact that we're an inline-block is irrelevant, and we behave
   4454     // just like a block.
   4455     if (isReplaced() && !isRootLineBox)
   4456         return height() + marginTop() + marginBottom();
   4457 
   4458     if (firstLine && document()->usesFirstLineRules()) {
   4459         RenderStyle* s = style(firstLine);
   4460         if (s != style())
   4461             return s->computedLineHeight();
   4462     }
   4463 
   4464     if (m_lineHeight == -1)
   4465         m_lineHeight = style()->computedLineHeight();
   4466 
   4467     return m_lineHeight;
   4468 }
   4469 
   4470 int RenderBlock::baselinePosition(bool b, bool isRootLineBox) const
   4471 {
   4472     // Inline blocks are replaced elements. Otherwise, just pass off to
   4473     // the base class.  If we're being queried as though we're the root line
   4474     // box, then the fact that we're an inline-block is irrelevant, and we behave
   4475     // just like a block.
   4476     if (isReplaced() && !isRootLineBox) {
   4477         // For "leaf" theme objects, let the theme decide what the baseline position is.
   4478         // FIXME: Might be better to have a custom CSS property instead, so that if the theme
   4479         // is turned off, checkboxes/radios will still have decent baselines.
   4480         if (style()->hasAppearance() && !theme()->isControlContainer(style()->appearance()))
   4481             return theme()->baselinePosition(this);
   4482 
   4483         // CSS2.1 states that the baseline of an inline block is the baseline of the last line box in
   4484         // the normal flow.  We make an exception for marquees, since their baselines are meaningless
   4485         // (the content inside them moves).  This matches WinIE as well, which just bottom-aligns them.
   4486         // We also give up on finding a baseline if we have a vertical scrollbar, or if we are scrolled
   4487         // vertically (e.g., an overflow:hidden block that has had scrollTop moved) or if the baseline is outside
   4488         // of our content box.
   4489         int baselinePos = (layer() && (layer()->marquee() || layer()->verticalScrollbar() || layer()->scrollYOffset() != 0)) ? -1 : lastLineBoxBaseline();
   4490         if (baselinePos != -1 && baselinePos <= borderTop() + paddingTop() + contentHeight())
   4491             return marginTop() + baselinePos;
   4492         return height() + marginTop() + marginBottom();
   4493     }
   4494     return RenderBox::baselinePosition(b, isRootLineBox);
   4495 }
   4496 
   4497 int RenderBlock::firstLineBoxBaseline() const
   4498 {
   4499     if (!isBlockFlow())
   4500         return -1;
   4501 
   4502     if (childrenInline()) {
   4503         if (firstLineBox())
   4504             return firstLineBox()->y() + style(true)->font().ascent();
   4505         else
   4506             return -1;
   4507     }
   4508     else {
   4509         for (RenderBox* curr = firstChildBox(); curr; curr = curr->nextSiblingBox()) {
   4510             if (!curr->isFloatingOrPositioned()) {
   4511                 int result = curr->firstLineBoxBaseline();
   4512                 if (result != -1)
   4513                     return curr->y() + result; // Translate to our coordinate space.
   4514             }
   4515         }
   4516     }
   4517 
   4518     return -1;
   4519 }
   4520 
   4521 int RenderBlock::lastLineBoxBaseline() const
   4522 {
   4523     if (!isBlockFlow())
   4524         return -1;
   4525 
   4526     if (childrenInline()) {
   4527         if (!firstLineBox() && hasLineIfEmpty())
   4528             return RenderBox::baselinePosition(true, true) + borderTop() + paddingTop();
   4529         if (lastLineBox())
   4530             return lastLineBox()->y() + style(lastLineBox() == firstLineBox())->font().ascent();
   4531         return -1;
   4532     }
   4533     else {
   4534         bool haveNormalFlowChild = false;
   4535         for (RenderBox* curr = lastChildBox(); curr; curr = curr->previousSiblingBox()) {
   4536             if (!curr->isFloatingOrPositioned()) {
   4537                 haveNormalFlowChild = true;
   4538                 int result = curr->lastLineBoxBaseline();
   4539                 if (result != -1)
   4540                     return curr->y() + result; // Translate to our coordinate space.
   4541             }
   4542         }
   4543         if (!haveNormalFlowChild && hasLineIfEmpty())
   4544             return RenderBox::baselinePosition(true, true) + borderTop() + paddingTop();
   4545     }
   4546 
   4547     return -1;
   4548 }
   4549 
   4550 bool RenderBlock::containsNonZeroBidiLevel() const
   4551 {
   4552     for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
   4553         for (InlineBox* box = root->firstLeafChild(); box; box = box->nextLeafChild()) {
   4554             if (box->bidiLevel())
   4555                 return true;
   4556         }
   4557     }
   4558     return false;
   4559 }
   4560 
   4561 RenderBlock* RenderBlock::firstLineBlock() const
   4562 {
   4563     RenderBlock* firstLineBlock = const_cast<RenderBlock*>(this);
   4564     bool hasPseudo = false;
   4565     while (true) {
   4566         hasPseudo = firstLineBlock->style()->hasPseudoStyle(FIRST_LINE);
   4567         if (hasPseudo)
   4568             break;
   4569         RenderObject* parentBlock = firstLineBlock->parent();
   4570         if (firstLineBlock->isReplaced() || firstLineBlock->isFloating() ||
   4571             !parentBlock || parentBlock->firstChild() != firstLineBlock || !parentBlock->isBlockFlow())
   4572             break;
   4573         ASSERT(parentBlock->isRenderBlock());
   4574         firstLineBlock = toRenderBlock(parentBlock);
   4575     }
   4576 
   4577     if (!hasPseudo)
   4578         return 0;
   4579 
   4580     return firstLineBlock;
   4581 }
   4582 
   4583 void RenderBlock::updateFirstLetter()
   4584 {
   4585     if (!document()->usesFirstLetterRules())
   4586         return;
   4587     // Don't recur
   4588     if (style()->styleType() == FIRST_LETTER)
   4589         return;
   4590 
   4591     // FIXME: We need to destroy the first-letter object if it is no longer the first child.  Need to find
   4592     // an efficient way to check for that situation though before implementing anything.
   4593     RenderObject* firstLetterBlock = this;
   4594     bool hasPseudoStyle = false;
   4595     while (true) {
   4596         // We only honor first-letter if the firstLetterBlock can have children in the DOM. This correctly
   4597         // prevents form controls from honoring first-letter.
   4598         hasPseudoStyle = firstLetterBlock->style()->hasPseudoStyle(FIRST_LETTER)
   4599             && firstLetterBlock->canHaveChildren();
   4600         if (hasPseudoStyle)
   4601             break;
   4602         RenderObject* parentBlock = firstLetterBlock->parent();
   4603         if (firstLetterBlock->isReplaced() || !parentBlock || parentBlock->firstChild() != firstLetterBlock ||
   4604             !parentBlock->isBlockFlow())
   4605             break;
   4606         firstLetterBlock = parentBlock;
   4607     }
   4608 
   4609     if (!hasPseudoStyle)
   4610         return;
   4611 
   4612     // Drill into inlines looking for our first text child.
   4613     RenderObject* currChild = firstLetterBlock->firstChild();
   4614     while (currChild && currChild->needsLayout() && (!currChild->isReplaced() || currChild->isFloatingOrPositioned()) && !currChild->isText()) {
   4615         if (currChild->isFloatingOrPositioned()) {
   4616             if (currChild->style()->styleType() == FIRST_LETTER)
   4617                 break;
   4618             currChild = currChild->nextSibling();
   4619         } else
   4620             currChild = currChild->firstChild();
   4621     }
   4622 
   4623     // Get list markers out of the way.
   4624     while (currChild && currChild->isListMarker())
   4625         currChild = currChild->nextSibling();
   4626 
   4627     if (!currChild)
   4628         return;
   4629 
   4630     RenderObject* firstLetterContainer = currChild->parent();
   4631 
   4632     // If the child already has style, then it has already been created, so we just want
   4633     // to update it.
   4634     if (currChild->style()->styleType() == FIRST_LETTER) {
   4635         RenderStyle* pseudo = firstLetterBlock->getCachedPseudoStyle(FIRST_LETTER,
   4636                                                                      firstLetterContainer->firstLineStyle());
   4637         currChild->setStyle(pseudo);
   4638         for (RenderObject* genChild = currChild->firstChild(); genChild; genChild = genChild->nextSibling()) {
   4639             if (genChild->isText())
   4640                 genChild->setStyle(pseudo);
   4641         }
   4642         return;
   4643     }
   4644 
   4645     // If the child does not already have style, we create it here.
   4646     if (currChild->isText() && !currChild->isBR() && currChild->parent()->style()->styleType() != FIRST_LETTER) {
   4647         // Our layout state is not valid for the repaints we are going to trigger by
   4648         // adding and removing children of firstLetterContainer.
   4649         view()->disableLayoutState();
   4650 
   4651         RenderText* textObj = toRenderText(currChild);
   4652 
   4653         // Create our pseudo style now that we have our firstLetterContainer determined.
   4654         RenderStyle* pseudoStyle = firstLetterBlock->getCachedPseudoStyle(FIRST_LETTER,
   4655                                                                           firstLetterContainer->firstLineStyle());
   4656 
   4657         // Force inline display (except for floating first-letters)
   4658         pseudoStyle->setDisplay(pseudoStyle->isFloating() ? BLOCK : INLINE);
   4659         pseudoStyle->setPosition(StaticPosition); // CSS2 says first-letter can't be positioned.
   4660 
   4661         RenderObject* firstLetter = 0;
   4662         if (pseudoStyle->display() == INLINE)
   4663             firstLetter = new (renderArena()) RenderInline(document());
   4664         else
   4665             firstLetter = new (renderArena()) RenderBlock(document());
   4666         firstLetter->setStyle(pseudoStyle);
   4667         firstLetterContainer->addChild(firstLetter, currChild);
   4668 
   4669         // The original string is going to be either a generated content string or a DOM node's
   4670         // string.  We want the original string before it got transformed in case first-letter has
   4671         // no text-transform or a different text-transform applied to it.
   4672         RefPtr<StringImpl> oldText = textObj->originalText();
   4673         ASSERT(oldText);
   4674 
   4675         if (oldText && oldText->length() > 0) {
   4676             unsigned int length = 0;
   4677 
   4678             // account for leading spaces and punctuation
   4679             while (length < oldText->length() && (isSpaceOrNewline((*oldText)[length]) || Unicode::isPunct((*oldText)[length])))
   4680                 length++;
   4681 
   4682             // account for first letter
   4683             length++;
   4684 
   4685             // construct text fragment for the text after the first letter
   4686             // NOTE: this might empty
   4687             RenderTextFragment* remainingText =
   4688                 new (renderArena()) RenderTextFragment(textObj->node() ? textObj->node() : textObj->document(), oldText.get(), length, oldText->length() - length);
   4689             remainingText->setStyle(textObj->style());
   4690             if (remainingText->node())
   4691                 remainingText->node()->setRenderer(remainingText);
   4692 
   4693             RenderObject* nextObj = textObj->nextSibling();
   4694             firstLetterContainer->removeChild(textObj);
   4695             firstLetterContainer->addChild(remainingText, nextObj);
   4696             remainingText->setFirstLetter(firstLetter);
   4697 
   4698             // construct text fragment for the first letter
   4699             RenderTextFragment* letter =
   4700                 new (renderArena()) RenderTextFragment(remainingText->node() ? remainingText->node() : remainingText->document(), oldText.get(), 0, length);
   4701             RefPtr<RenderStyle> newStyle = RenderStyle::create();
   4702             newStyle->inheritFrom(pseudoStyle);
   4703             letter->setStyle(newStyle.release());
   4704             firstLetter->addChild(letter);
   4705 
   4706             textObj->destroy();
   4707         }
   4708         view()->enableLayoutState();
   4709     }
   4710 }
   4711 
   4712 bool RenderBlock::inRootBlockContext() const
   4713 {
   4714     if (isTableCell() || isFloatingOrPositioned() || hasOverflowClip())
   4715         return false;
   4716 
   4717     if (isRoot() || isRenderView())
   4718         return true;
   4719 
   4720     return containingBlock()->inRootBlockContext();
   4721 }
   4722 
   4723 // Helper methods for obtaining the last line, computing line counts and heights for line counts
   4724 // (crawling into blocks).
   4725 static bool shouldCheckLines(RenderObject* obj)
   4726 {
   4727     return !obj->isFloatingOrPositioned() && !obj->isRunIn() &&
   4728             obj->isBlockFlow() && obj->style()->height().isAuto() &&
   4729             (!obj->isFlexibleBox() || obj->style()->boxOrient() == VERTICAL);
   4730 }
   4731 
   4732 static RootInlineBox* getLineAtIndex(RenderBlock* block, int i, int& count)
   4733 {
   4734     if (block->style()->visibility() == VISIBLE) {
   4735         if (block->childrenInline()) {
   4736             for (RootInlineBox* box = block->firstRootBox(); box; box = box->nextRootBox()) {
   4737                 if (count++ == i)
   4738                     return box;
   4739             }
   4740         }
   4741         else {
   4742             for (RenderObject* obj = block->firstChild(); obj; obj = obj->nextSibling()) {
   4743                 if (shouldCheckLines(obj)) {
   4744                     RootInlineBox *box = getLineAtIndex(toRenderBlock(obj), i, count);
   4745                     if (box)
   4746                         return box;
   4747                 }
   4748             }
   4749         }
   4750     }
   4751     return 0;
   4752 }
   4753 
   4754 static int getHeightForLineCount(RenderBlock* block, int l, bool includeBottom, int& count)
   4755 {
   4756     if (block->style()->visibility() == VISIBLE) {
   4757         if (block->childrenInline()) {
   4758             for (RootInlineBox* box = block->firstRootBox(); box; box = box->nextRootBox()) {
   4759                 if (++count == l)
   4760                     return box->lineBottom() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : 0);
   4761             }
   4762         }
   4763         else {
   4764             RenderBox* normalFlowChildWithoutLines = 0;
   4765             for (RenderBox* obj = block->firstChildBox(); obj; obj = obj->nextSiblingBox()) {
   4766                 if (shouldCheckLines(obj)) {
   4767                     int result = getHeightForLineCount(toRenderBlock(obj), l, false, count);
   4768                     if (result != -1)
   4769                         return result + obj->y() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : 0);
   4770                 }
   4771                 else if (!obj->isFloatingOrPositioned() && !obj->isRunIn())
   4772                     normalFlowChildWithoutLines = obj;
   4773             }
   4774             if (normalFlowChildWithoutLines && l == 0)
   4775                 return normalFlowChildWithoutLines->y() + normalFlowChildWithoutLines->height();
   4776         }
   4777     }
   4778 
   4779     return -1;
   4780 }
   4781 
   4782 RootInlineBox* RenderBlock::lineAtIndex(int i)
   4783 {
   4784     int count = 0;
   4785     return getLineAtIndex(this, i, count);
   4786 }
   4787 
   4788 int RenderBlock::lineCount()
   4789 {
   4790     int count = 0;
   4791     if (style()->visibility() == VISIBLE) {
   4792         if (childrenInline())
   4793             for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
   4794                 count++;
   4795         else
   4796             for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling())
   4797                 if (shouldCheckLines(obj))
   4798                     count += toRenderBlock(obj)->lineCount();
   4799     }
   4800     return count;
   4801 }
   4802 
   4803 int RenderBlock::heightForLineCount(int l)
   4804 {
   4805     int count = 0;
   4806     return getHeightForLineCount(this, l, true, count);
   4807 }
   4808 
   4809 void RenderBlock::adjustForBorderFit(int x, int& left, int& right) const
   4810 {
   4811     // We don't deal with relative positioning.  Our assumption is that you shrink to fit the lines without accounting
   4812     // for either overflow or translations via relative positioning.
   4813     if (style()->visibility() == VISIBLE) {
   4814         if (childrenInline()) {
   4815             for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) {
   4816                 if (box->firstChild())
   4817                     left = min(left, x + box->firstChild()->x());
   4818                 if (box->lastChild())
   4819                     right = max(right, x + box->lastChild()->x() + box->lastChild()->width());
   4820             }
   4821         }
   4822         else {
   4823             for (RenderBox* obj = firstChildBox(); obj; obj = obj->nextSiblingBox()) {
   4824                 if (!obj->isFloatingOrPositioned()) {
   4825                     if (obj->isBlockFlow() && !obj->hasOverflowClip())
   4826                         toRenderBlock(obj)->adjustForBorderFit(x + obj->x(), left, right);
   4827                     else if (obj->style()->visibility() == VISIBLE) {
   4828                         // We are a replaced element or some kind of non-block-flow object.
   4829                         left = min(left, x + obj->x());
   4830                         right = max(right, x + obj->x() + obj->width());
   4831                     }
   4832                 }
   4833             }
   4834         }
   4835 
   4836         if (m_floatingObjects) {
   4837             FloatingObject* r;
   4838             DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
   4839             for (; (r = it.current()); ++it) {
   4840                 // Only examine the object if our m_shouldPaint flag is set.
   4841                 if (r->m_shouldPaint) {
   4842                     int floatLeft = r->m_left - r->m_renderer->x() + r->m_renderer->marginLeft();
   4843                     int floatRight = floatLeft + r->m_renderer->width();
   4844                     left = min(left, floatLeft);
   4845                     right = max(right, floatRight);
   4846                 }
   4847             }
   4848         }
   4849     }
   4850 }
   4851 
   4852 void RenderBlock::borderFitAdjust(int& x, int& w) const
   4853 {
   4854     if (style()->borderFit() == BorderFitBorder)
   4855         return;
   4856 
   4857     // Walk any normal flow lines to snugly fit.
   4858     int left = INT_MAX;
   4859     int right = INT_MIN;
   4860     int oldWidth = w;
   4861     adjustForBorderFit(0, left, right);
   4862     if (left != INT_MAX) {
   4863         left -= (borderLeft() + paddingLeft());
   4864         if (left > 0) {
   4865             x += left;
   4866             w -= left;
   4867         }
   4868     }
   4869     if (right != INT_MIN) {
   4870         right += (borderRight() + paddingRight());
   4871         if (right < oldWidth)
   4872             w -= (oldWidth - right);
   4873     }
   4874 }
   4875 
   4876 void RenderBlock::clearTruncation()
   4877 {
   4878     if (style()->visibility() == VISIBLE) {
   4879         if (childrenInline() && hasMarkupTruncation()) {
   4880             setHasMarkupTruncation(false);
   4881             for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
   4882                 box->clearTruncation();
   4883         }
   4884         else
   4885             for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling())
   4886                 if (shouldCheckLines(obj))
   4887                     toRenderBlock(obj)->clearTruncation();
   4888     }
   4889 }
   4890 
   4891 void RenderBlock::setMaxTopMargins(int pos, int neg)
   4892 {
   4893     if (!m_maxMargin) {
   4894         if (pos == MaxMargin::topPosDefault(this) && neg == MaxMargin::topNegDefault(this))
   4895             return;
   4896         m_maxMargin = new MaxMargin(this);
   4897     }
   4898     m_maxMargin->m_topPos = pos;
   4899     m_maxMargin->m_topNeg = neg;
   4900 }
   4901 
   4902 void RenderBlock::setMaxBottomMargins(int pos, int neg)
   4903 {
   4904     if (!m_maxMargin) {
   4905         if (pos == MaxMargin::bottomPosDefault(this) && neg == MaxMargin::bottomNegDefault(this))
   4906             return;
   4907         m_maxMargin = new MaxMargin(this);
   4908     }
   4909     m_maxMargin->m_bottomPos = pos;
   4910     m_maxMargin->m_bottomNeg = neg;
   4911 }
   4912 
   4913 void RenderBlock::absoluteRects(Vector<IntRect>& rects, int tx, int ty)
   4914 {
   4915     // For blocks inside inlines, we go ahead and include margins so that we run right up to the
   4916     // inline boxes above and below us (thus getting merged with them to form a single irregular
   4917     // shape).
   4918     if (inlineContinuation()) {
   4919         rects.append(IntRect(tx, ty - collapsedMarginTop(),
   4920                              width(), height() + collapsedMarginTop() + collapsedMarginBottom()));
   4921         inlineContinuation()->absoluteRects(rects,
   4922                                             tx - x() + inlineContinuation()->containingBlock()->x(),
   4923                                             ty - y() + inlineContinuation()->containingBlock()->y());
   4924     } else
   4925         rects.append(IntRect(tx, ty, width(), height()));
   4926 }
   4927 
   4928 void RenderBlock::absoluteQuads(Vector<FloatQuad>& quads)
   4929 {
   4930     // For blocks inside inlines, we go ahead and include margins so that we run right up to the
   4931     // inline boxes above and below us (thus getting merged with them to form a single irregular
   4932     // shape).
   4933     if (inlineContinuation()) {
   4934         FloatRect localRect(0, -collapsedMarginTop(),
   4935                             width(), height() + collapsedMarginTop() + collapsedMarginBottom());
   4936         quads.append(localToAbsoluteQuad(localRect));
   4937         inlineContinuation()->absoluteQuads(quads);
   4938     } else
   4939         quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width(), height())));
   4940 }
   4941 
   4942 IntRect RenderBlock::rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth)
   4943 {
   4944     IntRect r(RenderBox::rectWithOutlineForRepaint(repaintContainer, outlineWidth));
   4945     if (inlineContinuation())
   4946         r.inflateY(collapsedMarginTop());
   4947     return r;
   4948 }
   4949 
   4950 RenderObject* RenderBlock::hoverAncestor() const
   4951 {
   4952     return inlineContinuation() ? inlineContinuation() : RenderBox::hoverAncestor();
   4953 }
   4954 
   4955 void RenderBlock::updateDragState(bool dragOn)
   4956 {
   4957     RenderBox::updateDragState(dragOn);
   4958     if (inlineContinuation())
   4959         inlineContinuation()->updateDragState(dragOn);
   4960 }
   4961 
   4962 RenderStyle* RenderBlock::outlineStyleForRepaint() const
   4963 {
   4964     return inlineContinuation() ? inlineContinuation()->style() : style();
   4965 }
   4966 
   4967 void RenderBlock::childBecameNonInline(RenderObject*)
   4968 {
   4969     makeChildrenNonInline();
   4970     if (isAnonymousBlock() && parent() && parent()->isRenderBlock())
   4971         toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
   4972     // |this| may be dead here
   4973 }
   4974 
   4975 void RenderBlock::updateHitTestResult(HitTestResult& result, const IntPoint& point)
   4976 {
   4977     if (result.innerNode())
   4978         return;
   4979 
   4980     Node* n = node();
   4981     if (inlineContinuation())
   4982         // We are in the margins of block elements that are part of a continuation.  In
   4983         // this case we're actually still inside the enclosing inline element that was
   4984         // split.  Go ahead and set our inner node accordingly.
   4985         n = inlineContinuation()->node();
   4986 
   4987     if (n) {
   4988         result.setInnerNode(n);
   4989         if (!result.innerNonSharedNode())
   4990             result.setInnerNonSharedNode(n);
   4991         result.setLocalPoint(point);
   4992     }
   4993 }
   4994 
   4995 IntRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, int* extraWidthToEndOfLine)
   4996 {
   4997     // Do the normal calculation in most cases.
   4998     if (firstChild())
   4999         return RenderBox::localCaretRect(inlineBox, caretOffset, extraWidthToEndOfLine);
   5000 
   5001     // This is a special case:
   5002     // The element is not an inline element, and it's empty. So we have to
   5003     // calculate a fake position to indicate where objects are to be inserted.
   5004 
   5005     // FIXME: This does not take into account either :first-line or :first-letter
   5006     // However, as soon as some content is entered, the line boxes will be
   5007     // constructed and this kludge is not called any more. So only the caret size
   5008     // of an empty :first-line'd block is wrong. I think we can live with that.
   5009     RenderStyle* currentStyle = firstLineStyle();
   5010     int height = lineHeight(true);
   5011 
   5012     enum CaretAlignment { alignLeft, alignRight, alignCenter };
   5013 
   5014     CaretAlignment alignment = alignLeft;
   5015 
   5016     switch (currentStyle->textAlign()) {
   5017         case TAAUTO:
   5018         case JUSTIFY:
   5019             if (currentStyle->direction() == RTL)
   5020                 alignment = alignRight;
   5021             break;
   5022         case LEFT:
   5023         case WEBKIT_LEFT:
   5024             break;
   5025         case CENTER:
   5026         case WEBKIT_CENTER:
   5027             alignment = alignCenter;
   5028             break;
   5029         case RIGHT:
   5030         case WEBKIT_RIGHT:
   5031             alignment = alignRight;
   5032             break;
   5033     }
   5034 
   5035     int x = borderLeft() + paddingLeft();
   5036     int w = width();
   5037 
   5038     switch (alignment) {
   5039         case alignLeft:
   5040             break;
   5041         case alignCenter:
   5042             x = (x + w - (borderRight() + paddingRight())) / 2;
   5043             break;
   5044         case alignRight:
   5045             x = w - (borderRight() + paddingRight()) - caretWidth;
   5046             break;
   5047     }
   5048 
   5049     if (extraWidthToEndOfLine) {
   5050         if (isRenderBlock()) {
   5051             *extraWidthToEndOfLine = w - (x + caretWidth);
   5052         } else {
   5053             // FIXME: This code looks wrong.
   5054             // myRight and containerRight are set up, but then clobbered.
   5055             // So *extraWidthToEndOfLine will always be 0 here.
   5056 
   5057             int myRight = x + caretWidth;
   5058             // FIXME: why call localToAbsoluteForContent() twice here, too?
   5059             FloatPoint absRightPoint = localToAbsolute(FloatPoint(myRight, 0));
   5060 
   5061             int containerRight = containingBlock()->x() + containingBlockWidthForContent();
   5062             FloatPoint absContainerPoint = localToAbsolute(FloatPoint(containerRight, 0));
   5063 
   5064             *extraWidthToEndOfLine = absContainerPoint.x() - absRightPoint.x();
   5065         }
   5066     }
   5067 
   5068     int y = paddingTop() + borderTop();
   5069 
   5070     return IntRect(x, y, caretWidth, height);
   5071 }
   5072 
   5073 void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
   5074 {
   5075     // For blocks inside inlines, we go ahead and include margins so that we run right up to the
   5076     // inline boxes above and below us (thus getting merged with them to form a single irregular
   5077     // shape).
   5078     if (inlineContinuation()) {
   5079         // FIXME: This check really isn't accurate.
   5080         bool nextInlineHasLineBox = inlineContinuation()->firstLineBox();
   5081         // FIXME: This is wrong. The principal renderer may not be the continuation preceding this block.
   5082         bool prevInlineHasLineBox = toRenderInline(inlineContinuation()->node()->renderer())->firstLineBox();
   5083         int topMargin = prevInlineHasLineBox ? collapsedMarginTop() : 0;
   5084         int bottomMargin = nextInlineHasLineBox ? collapsedMarginBottom() : 0;
   5085         IntRect rect(tx, ty - topMargin, width(), height() + topMargin + bottomMargin);
   5086         if (!rect.isEmpty())
   5087             rects.append(rect);
   5088     } else if (width() && height())
   5089         rects.append(IntRect(tx, ty, width(), height()));
   5090 
   5091     if (!hasOverflowClip() && !hasControlClip()) {
   5092         for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
   5093             int top = max(curr->lineTop(), curr->y());
   5094             int bottom = min(curr->lineBottom(), curr->y() + curr->height());
   5095             IntRect rect(tx + curr->x(), ty + top, curr->width(), bottom - top);
   5096             if (!rect.isEmpty())
   5097                 rects.append(rect);
   5098         }
   5099 
   5100         for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
   5101             if (!curr->isText() && !curr->isListMarker() && curr->isBox()) {
   5102                 RenderBox* box = toRenderBox(curr);
   5103                 FloatPoint pos;
   5104                 // FIXME: This doesn't work correctly with transforms.
   5105                 if (box->layer())
   5106                     pos = curr->localToAbsolute();
   5107                 else
   5108                     pos = FloatPoint(tx + box->x(), ty + box->y());
   5109                 box->addFocusRingRects(rects, pos.x(), pos.y());
   5110             }
   5111         }
   5112     }
   5113 
   5114     if (inlineContinuation())
   5115         inlineContinuation()->addFocusRingRects(rects,
   5116                                                 tx - x() + inlineContinuation()->containingBlock()->x(),
   5117                                                 ty - y() + inlineContinuation()->containingBlock()->y());
   5118 }
   5119 
   5120 RenderBlock* RenderBlock::createAnonymousBlock(bool isFlexibleBox) const
   5121 {
   5122     RefPtr<RenderStyle> newStyle = RenderStyle::create();
   5123     newStyle->inheritFrom(style());
   5124 
   5125     RenderBlock* newBox = 0;
   5126     if (isFlexibleBox) {
   5127         newStyle->setDisplay(BOX);
   5128         newBox = new (renderArena()) RenderFlexibleBox(document() /* anonymous box */);
   5129     } else {
   5130         newStyle->setDisplay(BLOCK);
   5131         newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
   5132     }
   5133 
   5134     newBox->setStyle(newStyle.release());
   5135     return newBox;
   5136 }
   5137 
   5138 const char* RenderBlock::renderName() const
   5139 {
   5140     if (isBody())
   5141         return "RenderBody"; // FIXME: Temporary hack until we know that the regression tests pass.
   5142 
   5143     if (isFloating())
   5144         return "RenderBlock (floating)";
   5145     if (isPositioned())
   5146         return "RenderBlock (positioned)";
   5147     if (isAnonymousBlock())
   5148         return "RenderBlock (anonymous)";
   5149     else if (isAnonymous())
   5150         return "RenderBlock (generated)";
   5151     if (isRelPositioned())
   5152         return "RenderBlock (relative positioned)";
   5153     if (isRunIn())
   5154         return "RenderBlock (run-in)";
   5155     return "RenderBlock";
   5156 }
   5157 
   5158 } // namespace WebCore
   5159