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