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