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  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
      7  *
      8  * This library is free software; you can redistribute it and/or
      9  * modify it under the terms of the GNU Library General Public
     10  * License as published by the Free Software Foundation; either
     11  * version 2 of the License, or (at your option) any later version.
     12  *
     13  * This library is distributed in the hope that it will be useful,
     14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     16  * Library General Public License for more details.
     17  *
     18  * You should have received a copy of the GNU Library General Public License
     19  * along with this library; see the file COPYING.LIB.  If not, write to
     20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     21  * Boston, MA 02110-1301, USA.
     22  */
     23 
     24 #include "config.h"
     25 #include "RenderBlock.h"
     26 
     27 #include "ColumnInfo.h"
     28 #include "Document.h"
     29 #include "Element.h"
     30 #include "FloatQuad.h"
     31 #include "Frame.h"
     32 #include "FrameView.h"
     33 #include "GraphicsContext.h"
     34 #include "HTMLFormElement.h"
     35 #include "HTMLNames.h"
     36 #include "HitTestResult.h"
     37 #include "InlineIterator.h"
     38 #include "InlineTextBox.h"
     39 #include "PaintInfo.h"
     40 #include "RenderCombineText.h"
     41 #include "RenderFlexibleBox.h"
     42 #include "RenderImage.h"
     43 #include "RenderInline.h"
     44 #include "RenderLayer.h"
     45 #include "RenderMarquee.h"
     46 #include "RenderReplica.h"
     47 #include "RenderTableCell.h"
     48 #include "RenderTextFragment.h"
     49 #include "RenderTheme.h"
     50 #include "RenderView.h"
     51 #include "SelectionController.h"
     52 #include "Settings.h"
     53 #include "TextRun.h"
     54 #include "TransformState.h"
     55 #include <wtf/StdLibExtras.h>
     56 
     57 #ifdef ANDROID_LAYOUT
     58 #include "Settings.h"
     59 #endif
     60 
     61 using namespace std;
     62 using namespace WTF;
     63 using namespace Unicode;
     64 
     65 namespace WebCore {
     66 
     67 using namespace HTMLNames;
     68 
     69 typedef WTF::HashMap<const RenderBox*, ColumnInfo*> ColumnInfoMap;
     70 static ColumnInfoMap* gColumnInfoMap = 0;
     71 
     72 typedef WTF::HashMap<const RenderBlock*, HashSet<RenderBox*>*> PercentHeightDescendantsMap;
     73 static PercentHeightDescendantsMap* gPercentHeightDescendantsMap = 0;
     74 
     75 typedef WTF::HashMap<const RenderBox*, HashSet<RenderBlock*>*> PercentHeightContainerMap;
     76 static PercentHeightContainerMap* gPercentHeightContainerMap = 0;
     77 
     78 typedef WTF::HashMap<RenderBlock*, ListHashSet<RenderInline*>*> ContinuationOutlineTableMap;
     79 
     80 typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet;
     81 static int gDelayUpdateScrollInfo = 0;
     82 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0;
     83 
     84 bool RenderBlock::s_canPropagateFloatIntoSibling = false;
     85 
     86 // Our MarginInfo state used when laying out block children.
     87 RenderBlock::MarginInfo::MarginInfo(RenderBlock* block, int beforeBorderPadding, int afterBorderPadding)
     88     : m_atBeforeSideOfBlock(true)
     89     , m_atAfterSideOfBlock(false)
     90     , m_marginBeforeQuirk(false)
     91     , m_marginAfterQuirk(false)
     92     , m_determinedMarginBeforeQuirk(false)
     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         && !block->isWritingModeRoot();
    100 
    101     m_canCollapseMarginBeforeWithChildren = m_canCollapseWithChildren && (beforeBorderPadding == 0) && block->style()->marginBeforeCollapse() != MSEPARATE;
    102 
    103     // If any height other than auto is specified in CSS, then we don't collapse our bottom
    104     // margins with our children's margins.  To do otherwise would be to risk odd visual
    105     // effects when the children overflow out of the parent block and yet still collapse
    106     // with it.  We also don't collapse if we have any bottom border/padding.
    107     m_canCollapseMarginAfterWithChildren = m_canCollapseWithChildren && (afterBorderPadding == 0) &&
    108         (block->style()->logicalHeight().isAuto() && block->style()->logicalHeight().value() == 0) && block->style()->marginAfterCollapse() != MSEPARATE;
    109 
    110     m_quirkContainer = block->isTableCell() || block->isBody() || block->style()->marginBeforeCollapse() == MDISCARD ||
    111         block->style()->marginAfterCollapse() == MDISCARD;
    112 
    113     m_positiveMargin = m_canCollapseMarginBeforeWithChildren ? block->maxPositiveMarginBefore() : 0;
    114     m_negativeMargin = m_canCollapseMarginBeforeWithChildren ? block->maxNegativeMarginBefore() : 0;
    115 }
    116 
    117 // -------------------------------------------------------------------------------------------------------
    118 
    119 RenderBlock::RenderBlock(Node* node)
    120       : RenderBox(node)
    121       , m_floatingObjects(0)
    122       , m_positionedObjects(0)
    123       , m_rareData(0)
    124       , m_lineHeight(-1)
    125       , m_beingDestroyed(false)
    126 {
    127     setChildrenInline(true);
    128 }
    129 
    130 RenderBlock::~RenderBlock()
    131 {
    132     if (m_floatingObjects)
    133         deleteAllValues(m_floatingObjects->set());
    134 
    135     if (hasColumns())
    136         delete gColumnInfoMap->take(this);
    137 
    138     if (gPercentHeightDescendantsMap) {
    139         if (HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->take(this)) {
    140             HashSet<RenderBox*>::iterator end = descendantSet->end();
    141             for (HashSet<RenderBox*>::iterator descendant = descendantSet->begin(); descendant != end; ++descendant) {
    142                 HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->get(*descendant);
    143                 ASSERT(containerSet);
    144                 if (!containerSet)
    145                     continue;
    146                 ASSERT(containerSet->contains(this));
    147                 containerSet->remove(this);
    148                 if (containerSet->isEmpty()) {
    149                     gPercentHeightContainerMap->remove(*descendant);
    150                     delete containerSet;
    151                 }
    152             }
    153             delete descendantSet;
    154         }
    155     }
    156 }
    157 
    158 void RenderBlock::destroy()
    159 {
    160     // Mark as being destroyed to avoid trouble with merges in removeChild().
    161     m_beingDestroyed = true;
    162 
    163     // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
    164     // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
    165     children()->destroyLeftoverChildren();
    166 
    167     // Destroy our continuation before anything other than anonymous children.
    168     // The reason we don't destroy it before anonymous children is that they may
    169     // have continuations of their own that are anonymous children of our continuation.
    170     RenderBoxModelObject* continuation = this->continuation();
    171     if (continuation) {
    172         continuation->destroy();
    173         setContinuation(0);
    174     }
    175 
    176     if (!documentBeingDestroyed()) {
    177         if (firstLineBox()) {
    178             // We can't wait for RenderBox::destroy to clear the selection,
    179             // because by then we will have nuked the line boxes.
    180             // FIXME: The SelectionController should be responsible for this when it
    181             // is notified of DOM mutations.
    182             if (isSelectionBorder())
    183                 view()->clearSelection();
    184 
    185             // If we are an anonymous block, then our line boxes might have children
    186             // that will outlast this block. In the non-anonymous block case those
    187             // children will be destroyed by the time we return from this function.
    188             if (isAnonymousBlock()) {
    189                 for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox()) {
    190                     while (InlineBox* childBox = box->firstChild())
    191                         childBox->remove();
    192                 }
    193             }
    194         } else if (parent())
    195             parent()->dirtyLinesFromChangedChild(this);
    196     }
    197 
    198     m_lineBoxes.deleteLineBoxes(renderArena());
    199 
    200     RenderBox::destroy();
    201 }
    202 
    203 void RenderBlock::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
    204 {
    205     s_canPropagateFloatIntoSibling = style() ? !isFloatingOrPositioned() && !avoidsFloats() : false;
    206 
    207     setReplaced(newStyle->isDisplayInlineType());
    208 
    209     if (style() && parent() && diff == StyleDifferenceLayout && style()->position() != newStyle->position()) {
    210         if (newStyle->position() == StaticPosition)
    211             // Clear our positioned objects list. Our absolutely positioned descendants will be
    212             // inserted into our containing block's positioned objects list during layout.
    213             removePositionedObjects(0);
    214         else if (style()->position() == StaticPosition) {
    215             // Remove our absolutely positioned descendants from their current containing block.
    216             // They will be inserted into our positioned objects list during layout.
    217             RenderObject* cb = parent();
    218             while (cb && (cb->style()->position() == StaticPosition || (cb->isInline() && !cb->isReplaced())) && !cb->isRenderView()) {
    219                 if (cb->style()->position() == RelativePosition && cb->isInline() && !cb->isReplaced()) {
    220                     cb = cb->containingBlock();
    221                     break;
    222                 }
    223                 cb = cb->parent();
    224             }
    225 
    226             if (cb->isRenderBlock())
    227                 toRenderBlock(cb)->removePositionedObjects(this);
    228         }
    229 
    230         if (containsFloats() && !isFloating() && !isPositioned() && (newStyle->position() == AbsolutePosition || newStyle->position() == FixedPosition))
    231             markAllDescendantsWithFloatsForLayout();
    232     }
    233 
    234     RenderBox::styleWillChange(diff, newStyle);
    235 }
    236 
    237 void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
    238 {
    239     RenderBox::styleDidChange(diff, oldStyle);
    240 
    241     if (!isAnonymousBlock()) {
    242         // Ensure that all of our continuation blocks pick up the new style.
    243         for (RenderBlock* currCont = blockElementContinuation(); currCont; currCont = currCont->blockElementContinuation()) {
    244             RenderBoxModelObject* nextCont = currCont->continuation();
    245             currCont->setContinuation(0);
    246             currCont->setStyle(style());
    247             currCont->setContinuation(nextCont);
    248         }
    249     }
    250 
    251     // FIXME: We could save this call when the change only affected non-inherited properties
    252     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
    253         if (child->isAnonymousBlock()) {
    254             RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
    255             if (style()->specifiesColumns()) {
    256                 if (child->style()->specifiesColumns())
    257                     newStyle->inheritColumnPropertiesFrom(style());
    258                 if (child->style()->columnSpan())
    259                     newStyle->setColumnSpan(true);
    260             }
    261             newStyle->setDisplay(BLOCK);
    262             child->setStyle(newStyle.release());
    263         }
    264     }
    265 
    266     m_lineHeight = -1;
    267 
    268     // Update pseudos for :before and :after now.
    269     if (!isAnonymous() && document()->usesBeforeAfterRules() && canHaveChildren()) {
    270         updateBeforeAfterContent(BEFORE);
    271         updateBeforeAfterContent(AFTER);
    272     }
    273 
    274     // After our style changed, if we lose our ability to propagate floats into next sibling
    275     // blocks, then we need to find the top most parent containing that overhanging float and
    276     // then mark its descendants with floats for layout and clear all floats from its next
    277     // sibling blocks that exist in our floating objects list. See bug 56299 and 62875.
    278     bool canPropagateFloatIntoSibling = !isFloatingOrPositioned() && !avoidsFloats();
    279     if (diff == StyleDifferenceLayout && s_canPropagateFloatIntoSibling && !canPropagateFloatIntoSibling && hasOverhangingFloats()) {
    280         RenderBlock* parentBlock = this;
    281         FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
    282         FloatingObjectSetIterator end = floatingObjectSet.end();
    283 
    284         for (RenderObject* curr = parent(); curr && !curr->isRenderView(); curr = curr->parent()) {
    285             if (curr->isRenderBlock()) {
    286                 RenderBlock* currBlock = toRenderBlock(curr);
    287 
    288                 if (currBlock->hasOverhangingFloats()) {
    289                     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
    290                         RenderBox* renderer = (*it)->renderer();
    291                         if (currBlock->hasOverhangingFloat(renderer)) {
    292                             parentBlock = currBlock;
    293                             break;
    294                         }
    295                     }
    296                 }
    297             }
    298         }
    299 
    300         parentBlock->markAllDescendantsWithFloatsForLayout();
    301         parentBlock->markSiblingsWithFloatsForLayout();
    302     }
    303 }
    304 
    305 void RenderBlock::updateBeforeAfterContent(PseudoId pseudoId)
    306 {
    307     // If this is an anonymous wrapper, then the parent applies its own pseudo-element style to it.
    308     if (parent() && parent()->createsAnonymousWrapper())
    309         return;
    310     return children()->updateBeforeAfterContent(this, pseudoId);
    311 }
    312 
    313 RenderBlock* RenderBlock::continuationBefore(RenderObject* beforeChild)
    314 {
    315     if (beforeChild && beforeChild->parent() == this)
    316         return this;
    317 
    318     RenderBlock* curr = toRenderBlock(continuation());
    319     RenderBlock* nextToLast = this;
    320     RenderBlock* last = this;
    321     while (curr) {
    322         if (beforeChild && beforeChild->parent() == curr) {
    323             if (curr->firstChild() == beforeChild)
    324                 return last;
    325             return curr;
    326         }
    327 
    328         nextToLast = last;
    329         last = curr;
    330         curr = toRenderBlock(curr->continuation());
    331     }
    332 
    333     if (!beforeChild && !last->firstChild())
    334         return nextToLast;
    335     return last;
    336 }
    337 
    338 void RenderBlock::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild)
    339 {
    340     RenderBlock* flow = continuationBefore(beforeChild);
    341     ASSERT(!beforeChild || beforeChild->parent()->isAnonymousColumnSpanBlock() || beforeChild->parent()->isRenderBlock());
    342     RenderBoxModelObject* beforeChildParent = 0;
    343     if (beforeChild)
    344         beforeChildParent = toRenderBoxModelObject(beforeChild->parent());
    345     else {
    346         RenderBoxModelObject* cont = flow->continuation();
    347         if (cont)
    348             beforeChildParent = cont;
    349         else
    350             beforeChildParent = flow;
    351     }
    352 
    353     if (newChild->isFloatingOrPositioned())
    354         return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
    355 
    356     // A continuation always consists of two potential candidates: a block or an anonymous
    357     // column span box holding column span children.
    358     bool childIsNormal = newChild->isInline() || !newChild->style()->columnSpan();
    359     bool bcpIsNormal = beforeChildParent->isInline() || !beforeChildParent->style()->columnSpan();
    360     bool flowIsNormal = flow->isInline() || !flow->style()->columnSpan();
    361 
    362     if (flow == beforeChildParent)
    363         return flow->addChildIgnoringContinuation(newChild, beforeChild);
    364 
    365     // The goal here is to match up if we can, so that we can coalesce and create the
    366     // minimal # of continuations needed for the inline.
    367     if (childIsNormal == bcpIsNormal)
    368         return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
    369     if (flowIsNormal == childIsNormal)
    370         return flow->addChildIgnoringContinuation(newChild, 0); // Just treat like an append.
    371     return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
    372 }
    373 
    374 
    375 void RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
    376 {
    377     ASSERT(!continuation()); // We don't yet support column spans that aren't immediate children of the multi-column block.
    378 
    379     // The goal is to locate a suitable box in which to place our child.
    380     RenderBlock* beforeChildParent = toRenderBlock(beforeChild && beforeChild->parent()->isRenderBlock() ? beforeChild->parent() : lastChild());
    381 
    382     // If the new child is floating or positioned it can just go in that block.
    383     if (newChild->isFloatingOrPositioned())
    384         return beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
    385 
    386     // See if the child can be placed in the box.
    387     bool newChildHasColumnSpan = newChild->style()->columnSpan() && !newChild->isInline();
    388     bool beforeChildParentHoldsColumnSpans = beforeChildParent->isAnonymousColumnSpanBlock();
    389 
    390     if (newChildHasColumnSpan == beforeChildParentHoldsColumnSpans)
    391         return beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
    392 
    393     if (!beforeChild) {
    394         // Create a new block of the correct type.
    395         RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
    396         children()->appendChildNode(this, newBox);
    397         newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
    398         return;
    399     }
    400 
    401     RenderObject* immediateChild = beforeChild;
    402     bool isPreviousBlockViable = true;
    403     while (immediateChild->parent() != this) {
    404         if (isPreviousBlockViable)
    405             isPreviousBlockViable = !immediateChild->previousSibling();
    406         immediateChild = immediateChild->parent();
    407     }
    408     if (isPreviousBlockViable && immediateChild->previousSibling())
    409         return toRenderBlock(immediateChild->previousSibling())->addChildIgnoringAnonymousColumnBlocks(newChild, 0); // Treat like an append.
    410 
    411     // Split our anonymous blocks.
    412     RenderObject* newBeforeChild = splitAnonymousBlocksAroundChild(beforeChild);
    413 
    414     // Create a new anonymous box of the appropriate type.
    415     RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
    416     children()->insertChildNode(this, newBox, newBeforeChild);
    417     newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
    418     return;
    419 }
    420 
    421 RenderBlock* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBlock)
    422 {
    423     RenderBlock* firstChildIgnoringAnonymousWrappers = 0;
    424     for (RenderObject* curr = this; curr; curr = curr->parent()) {
    425         if (!curr->isRenderBlock() || curr->isFloatingOrPositioned() || curr->isTableCell() || curr->isRoot() || curr->isRenderView() || curr->hasOverflowClip()
    426             || curr->isInlineBlockOrInlineTable())
    427             return 0;
    428 
    429         RenderBlock* currBlock = toRenderBlock(curr);
    430         if (!currBlock->createsAnonymousWrapper())
    431             firstChildIgnoringAnonymousWrappers = currBlock;
    432 
    433         if (currBlock->style()->specifiesColumns() && (allowAnonymousColumnBlock || !currBlock->isAnonymousColumnsBlock()))
    434             return firstChildIgnoringAnonymousWrappers;
    435 
    436         if (currBlock->isAnonymousColumnSpanBlock())
    437             return 0;
    438     }
    439     return 0;
    440 }
    441 
    442 RenderBlock* RenderBlock::clone() const
    443 {
    444     RenderBlock* cloneBlock;
    445     if (isAnonymousBlock())
    446         cloneBlock = createAnonymousBlock();
    447     else {
    448         cloneBlock = new (renderArena()) RenderBlock(node());
    449         cloneBlock->setStyle(style());
    450         if (!childrenInline() && cloneBlock->firstChild() && cloneBlock->firstChild()->isInline())
    451             cloneBlock->makeChildrenNonInline();
    452     }
    453     cloneBlock->setChildrenInline(childrenInline());
    454     return cloneBlock;
    455 }
    456 
    457 void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
    458                               RenderBlock* middleBlock,
    459                               RenderObject* beforeChild, RenderBoxModelObject* oldCont)
    460 {
    461     // Create a clone of this inline.
    462     RenderBlock* cloneBlock = clone();
    463     if (!isAnonymousBlock())
    464         cloneBlock->setContinuation(oldCont);
    465 
    466     // Now take all of the children from beforeChild to the end and remove
    467     // them from |this| and place them in the clone.
    468     if (!beforeChild && isAfterContent(lastChild()))
    469         beforeChild = lastChild();
    470     moveChildrenTo(cloneBlock, beforeChild, 0);
    471 
    472     // Hook |clone| up as the continuation of the middle block.
    473     if (!cloneBlock->isAnonymousBlock())
    474         middleBlock->setContinuation(cloneBlock);
    475 
    476     // We have been reparented and are now under the fromBlock.  We need
    477     // to walk up our block parent chain until we hit the containing anonymous columns block.
    478     // Once we hit the anonymous columns block we're done.
    479     RenderBoxModelObject* curr = toRenderBoxModelObject(parent());
    480     RenderBoxModelObject* currChild = this;
    481 
    482     while (curr && curr != fromBlock) {
    483         ASSERT(curr->isRenderBlock());
    484 
    485         RenderBlock* blockCurr = toRenderBlock(curr);
    486 
    487         // Create a new clone.
    488         RenderBlock* cloneChild = cloneBlock;
    489         cloneBlock = blockCurr->clone();
    490 
    491         // Insert our child clone as the first child.
    492         cloneBlock->children()->appendChildNode(cloneBlock, cloneChild);
    493 
    494         // Hook the clone up as a continuation of |curr|.  Note we do encounter
    495         // anonymous blocks possibly as we walk up the block chain.  When we split an
    496         // anonymous block, there's no need to do any continuation hookup, since we haven't
    497         // actually split a real element.
    498         if (!blockCurr->isAnonymousBlock()) {
    499             oldCont = blockCurr->continuation();
    500             blockCurr->setContinuation(cloneBlock);
    501             cloneBlock->setContinuation(oldCont);
    502         }
    503 
    504         // Someone may have indirectly caused a <q> to split.  When this happens, the :after content
    505         // has to move into the inline continuation.  Call updateBeforeAfterContent to ensure that the inline's :after
    506         // content gets properly destroyed.
    507         if (document()->usesBeforeAfterRules())
    508             blockCurr->children()->updateBeforeAfterContent(blockCurr, AFTER);
    509 
    510         // Now we need to take all of the children starting from the first child
    511         // *after* currChild and append them all to the clone.
    512         RenderObject* afterContent = isAfterContent(cloneBlock->lastChild()) ? cloneBlock->lastChild() : 0;
    513         blockCurr->moveChildrenTo(cloneBlock, currChild->nextSibling(), 0, afterContent);
    514 
    515         // Keep walking up the chain.
    516         currChild = curr;
    517         curr = toRenderBoxModelObject(curr->parent());
    518     }
    519 
    520     // Now we are at the columns block level. We need to put the clone into the toBlock.
    521     toBlock->children()->appendChildNode(toBlock, cloneBlock);
    522 
    523     // Now take all the children after currChild and remove them from the fromBlock
    524     // and put them in the toBlock.
    525     fromBlock->moveChildrenTo(toBlock, currChild->nextSibling(), 0);
    526 }
    527 
    528 void RenderBlock::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
    529                             RenderObject* newChild, RenderBoxModelObject* oldCont)
    530 {
    531     RenderBlock* pre = 0;
    532     RenderBlock* block = containingColumnsBlock();
    533 
    534     // Delete our line boxes before we do the inline split into continuations.
    535     block->deleteLineBoxTree();
    536 
    537     bool madeNewBeforeBlock = false;
    538     if (block->isAnonymousColumnsBlock()) {
    539         // We can reuse this block and make it the preBlock of the next continuation.
    540         pre = block;
    541         pre->removePositionedObjects(0);
    542         block = toRenderBlock(block->parent());
    543     } else {
    544         // No anonymous block available for use.  Make one.
    545         pre = block->createAnonymousColumnsBlock();
    546         pre->setChildrenInline(false);
    547         madeNewBeforeBlock = true;
    548     }
    549 
    550     RenderBlock* post = block->createAnonymousColumnsBlock();
    551     post->setChildrenInline(false);
    552 
    553     RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
    554     if (madeNewBeforeBlock)
    555         block->children()->insertChildNode(block, pre, boxFirst);
    556     block->children()->insertChildNode(block, newBlockBox, boxFirst);
    557     block->children()->insertChildNode(block, post, boxFirst);
    558     block->setChildrenInline(false);
    559 
    560     if (madeNewBeforeBlock)
    561         block->moveChildrenTo(pre, boxFirst, 0);
    562 
    563     splitBlocks(pre, post, newBlockBox, beforeChild, oldCont);
    564 
    565     // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
    566     // time in makeChildrenNonInline by just setting this explicitly up front.
    567     newBlockBox->setChildrenInline(false);
    568 
    569     // We delayed adding the newChild until now so that the |newBlockBox| would be fully
    570     // connected, thus allowing newChild access to a renderArena should it need
    571     // to wrap itself in additional boxes (e.g., table construction).
    572     newBlockBox->addChild(newChild);
    573 
    574     // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
    575     // get deleted properly.  Because objects moves from the pre block into the post block, we want to
    576     // make new line boxes instead of leaving the old line boxes around.
    577     pre->setNeedsLayoutAndPrefWidthsRecalc();
    578     block->setNeedsLayoutAndPrefWidthsRecalc();
    579     post->setNeedsLayoutAndPrefWidthsRecalc();
    580 }
    581 
    582 RenderObject* RenderBlock::splitAnonymousBlocksAroundChild(RenderObject* beforeChild)
    583 {
    584     while (beforeChild->parent() != this) {
    585         RenderBlock* blockToSplit = toRenderBlock(beforeChild->parent());
    586         if (blockToSplit->firstChild() != beforeChild) {
    587             // We have to split the parentBlock into two blocks.
    588             RenderBlock* post = createAnonymousBlockWithSameTypeAs(blockToSplit);
    589             post->setChildrenInline(blockToSplit->childrenInline());
    590             RenderBlock* parentBlock = toRenderBlock(blockToSplit->parent());
    591             parentBlock->children()->insertChildNode(parentBlock, post, blockToSplit->nextSibling());
    592             blockToSplit->moveChildrenTo(post, beforeChild, 0, blockToSplit->hasLayer());
    593             post->setNeedsLayoutAndPrefWidthsRecalc();
    594             blockToSplit->setNeedsLayoutAndPrefWidthsRecalc();
    595             beforeChild = post;
    596         } else
    597             beforeChild = blockToSplit;
    598     }
    599     return beforeChild;
    600 }
    601 
    602 void RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlock* newBlockBox, RenderObject* newChild)
    603 {
    604     RenderBlock* pre = 0;
    605     RenderBlock* post = 0;
    606     RenderBlock* block = this; // Eventually block will not just be |this|, but will also be a block nested inside |this|.  Assign to a variable
    607                                // so that we don't have to patch all of the rest of the code later on.
    608 
    609     // Delete the block's line boxes before we do the split.
    610     block->deleteLineBoxTree();
    611 
    612     if (beforeChild && beforeChild->parent() != this)
    613         beforeChild = splitAnonymousBlocksAroundChild(beforeChild);
    614 
    615     if (beforeChild != firstChild()) {
    616         pre = block->createAnonymousColumnsBlock();
    617         pre->setChildrenInline(block->childrenInline());
    618     }
    619 
    620     if (beforeChild) {
    621         post = block->createAnonymousColumnsBlock();
    622         post->setChildrenInline(block->childrenInline());
    623     }
    624 
    625     RenderObject* boxFirst = block->firstChild();
    626     if (pre)
    627         block->children()->insertChildNode(block, pre, boxFirst);
    628     block->children()->insertChildNode(block, newBlockBox, boxFirst);
    629     if (post)
    630         block->children()->insertChildNode(block, post, boxFirst);
    631     block->setChildrenInline(false);
    632 
    633     // The pre/post blocks always have layers, so we know to always do a full insert/remove (so we pass true as the last argument).
    634     block->moveChildrenTo(pre, boxFirst, beforeChild, true);
    635     block->moveChildrenTo(post, beforeChild, 0, true);
    636 
    637     // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
    638     // time in makeChildrenNonInline by just setting this explicitly up front.
    639     newBlockBox->setChildrenInline(false);
    640 
    641     // We delayed adding the newChild until now so that the |newBlockBox| would be fully
    642     // connected, thus allowing newChild access to a renderArena should it need
    643     // to wrap itself in additional boxes (e.g., table construction).
    644     newBlockBox->addChild(newChild);
    645 
    646     // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
    647     // get deleted properly.  Because objects moved from the pre block into the post block, we want to
    648     // make new line boxes instead of leaving the old line boxes around.
    649     if (pre)
    650         pre->setNeedsLayoutAndPrefWidthsRecalc();
    651     block->setNeedsLayoutAndPrefWidthsRecalc();
    652     if (post)
    653         post->setNeedsLayoutAndPrefWidthsRecalc();
    654 }
    655 
    656 RenderBlock* RenderBlock::columnsBlockForSpanningElement(RenderObject* newChild)
    657 {
    658     // FIXME: This function is the gateway for the addition of column-span support.  It will
    659     // be added to in three stages:
    660     // (1) Immediate children of a multi-column block can span.
    661     // (2) Nested block-level children with only block-level ancestors between them and the multi-column block can span.
    662     // (3) Nested children with block or inline ancestors between them and the multi-column block can span (this is when we
    663     // cross the streams and have to cope with both types of continuations mixed together).
    664     // This function currently supports (1) and (2).
    665     RenderBlock* columnsBlockAncestor = 0;
    666     if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isBeforeOrAfterContent()
    667         && !newChild->isFloatingOrPositioned() && !newChild->isInline() && !isAnonymousColumnSpanBlock()) {
    668         columnsBlockAncestor = containingColumnsBlock(false);
    669         if (columnsBlockAncestor) {
    670             // Make sure that none of the parent ancestors have a continuation.
    671             // If yes, we do not want split the block into continuations.
    672             RenderObject* curr = this;
    673             while (curr && curr != columnsBlockAncestor) {
    674                 if (curr->isRenderBlock() && toRenderBlock(curr)->continuation()) {
    675                     columnsBlockAncestor = 0;
    676                     break;
    677                 }
    678                 curr = curr->parent();
    679             }
    680         }
    681     }
    682     return columnsBlockAncestor;
    683 }
    684 
    685 void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
    686 {
    687     // Make sure we don't append things after :after-generated content if we have it.
    688     if (!beforeChild) {
    689         RenderObject* lastRenderer = lastChild();
    690         if (isAfterContent(lastRenderer))
    691             beforeChild = lastRenderer;
    692         else if (lastRenderer && lastRenderer->isAnonymousBlock() && isAfterContent(lastRenderer->lastChild()))
    693             beforeChild = lastRenderer->lastChild();
    694     }
    695 
    696     // If the requested beforeChild is not one of our children, then this is because
    697     // there is an anonymous container within this object that contains the beforeChild.
    698     if (beforeChild && beforeChild->parent() != this) {
    699         RenderObject* anonymousChild = beforeChild->parent();
    700         ASSERT(anonymousChild);
    701 
    702         while (anonymousChild->parent() != this)
    703             anonymousChild = anonymousChild->parent();
    704 
    705         ASSERT(anonymousChild->isAnonymous());
    706 
    707         if (anonymousChild->isAnonymousBlock()) {
    708             // Insert the child into the anonymous block box instead of here.
    709             if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)
    710                 beforeChild->parent()->addChild(newChild, beforeChild);
    711             else
    712                 addChild(newChild, beforeChild->parent());
    713             return;
    714         }
    715 
    716         ASSERT(anonymousChild->isTable());
    717         if ((newChild->isTableCol() && newChild->style()->display() == TABLE_COLUMN_GROUP)
    718                 || (newChild->isRenderBlock() && newChild->style()->display() == TABLE_CAPTION)
    719                 || newChild->isTableSection()
    720                 || newChild->isTableRow()
    721                 || newChild->isTableCell()) {
    722             // Insert into the anonymous table.
    723             anonymousChild->addChild(newChild, beforeChild);
    724             return;
    725         }
    726 
    727         // Go on to insert before the anonymous table.
    728         beforeChild = anonymousChild;
    729     }
    730 
    731     // Check for a spanning element in columns.
    732     RenderBlock* columnsBlockAncestor = columnsBlockForSpanningElement(newChild);
    733     if (columnsBlockAncestor) {
    734         // We are placing a column-span element inside a block.
    735         RenderBlock* newBox = createAnonymousColumnSpanBlock();
    736 
    737         if (columnsBlockAncestor != this) {
    738             // We are nested inside a multi-column element and are being split by the span.  We have to break up
    739             // our block into continuations.
    740             RenderBoxModelObject* oldContinuation = continuation();
    741             setContinuation(newBox);
    742 
    743             // Someone may have put a <p> inside a <q>, causing a split.  When this happens, the :after content
    744             // has to move into the inline continuation.  Call updateBeforeAfterContent to ensure that our :after
    745             // content gets properly destroyed.
    746             bool isLastChild = (beforeChild == lastChild());
    747             if (document()->usesBeforeAfterRules())
    748                 children()->updateBeforeAfterContent(this, AFTER);
    749             if (isLastChild && beforeChild != lastChild())
    750                 beforeChild = 0; // We destroyed the last child, so now we need to update our insertion
    751                                  // point to be 0.  It's just a straight append now.
    752 
    753             splitFlow(beforeChild, newBox, newChild, oldContinuation);
    754             return;
    755         }
    756 
    757         // We have to perform a split of this block's children.  This involves creating an anonymous block box to hold
    758         // the column-spanning |newChild|.  We take all of the children from before |newChild| and put them into
    759         // one anonymous columns block, and all of the children after |newChild| go into another anonymous block.
    760         makeChildrenAnonymousColumnBlocks(beforeChild, newBox, newChild);
    761         return;
    762     }
    763 
    764     bool madeBoxesNonInline = false;
    765 
    766     // A block has to either have all of its children inline, or all of its children as blocks.
    767     // So, if our children are currently inline and a block child has to be inserted, we move all our
    768     // inline children into anonymous block boxes.
    769     if (childrenInline() && !newChild->isInline() && !newChild->isFloatingOrPositioned()) {
    770         // This is a block with inline content. Wrap the inline content in anonymous blocks.
    771         makeChildrenNonInline(beforeChild);
    772         madeBoxesNonInline = true;
    773 
    774         if (beforeChild && beforeChild->parent() != this) {
    775             beforeChild = beforeChild->parent();
    776             ASSERT(beforeChild->isAnonymousBlock());
    777             ASSERT(beforeChild->parent() == this);
    778         }
    779     } else if (!childrenInline() && (newChild->isFloatingOrPositioned() || newChild->isInline())) {
    780         // If we're inserting an inline child but all of our children are blocks, then we have to make sure
    781         // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise
    782         // a new one is created and inserted into our list of children in the appropriate position.
    783         RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();
    784 
    785         if (afterChild && afterChild->isAnonymousBlock()) {
    786             afterChild->addChild(newChild);
    787             return;
    788         }
    789 
    790         if (newChild->isInline()) {
    791             // No suitable existing anonymous box - create a new one.
    792             RenderBlock* newBox = createAnonymousBlock();
    793             RenderBox::addChild(newBox, beforeChild);
    794             newBox->addChild(newChild);
    795             return;
    796         }
    797     }
    798 
    799     RenderBox::addChild(newChild, beforeChild);
    800 
    801     if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRenderBlock())
    802         toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
    803     // this object may be dead here
    804 }
    805 
    806 void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
    807 {
    808     if (continuation() && !isAnonymousBlock())
    809         return addChildToContinuation(newChild, beforeChild);
    810     return addChildIgnoringContinuation(newChild, beforeChild);
    811 }
    812 
    813 void RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild)
    814 {
    815     if (!isAnonymousBlock() && firstChild() && (firstChild()->isAnonymousColumnsBlock() || firstChild()->isAnonymousColumnSpanBlock()))
    816         return addChildToAnonymousColumnBlocks(newChild, beforeChild);
    817     return addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
    818 }
    819 
    820 static void getInlineRun(RenderObject* start, RenderObject* boundary,
    821                          RenderObject*& inlineRunStart,
    822                          RenderObject*& inlineRunEnd)
    823 {
    824     // Beginning at |start| we find the largest contiguous run of inlines that
    825     // we can.  We denote the run with start and end points, |inlineRunStart|
    826     // and |inlineRunEnd|.  Note that these two values may be the same if
    827     // we encounter only one inline.
    828     //
    829     // We skip any non-inlines we encounter as long as we haven't found any
    830     // inlines yet.
    831     //
    832     // |boundary| indicates a non-inclusive boundary point.  Regardless of whether |boundary|
    833     // is inline or not, we will not include it in a run with inlines before it.  It's as though we encountered
    834     // a non-inline.
    835 
    836     // Start by skipping as many non-inlines as we can.
    837     RenderObject * curr = start;
    838     bool sawInline;
    839     do {
    840         while (curr && !(curr->isInline() || curr->isFloatingOrPositioned()))
    841             curr = curr->nextSibling();
    842 
    843         inlineRunStart = inlineRunEnd = curr;
    844 
    845         if (!curr)
    846             return; // No more inline children to be found.
    847 
    848         sawInline = curr->isInline();
    849 
    850         curr = curr->nextSibling();
    851         while (curr && (curr->isInline() || curr->isFloatingOrPositioned()) && (curr != boundary)) {
    852             inlineRunEnd = curr;
    853             if (curr->isInline())
    854                 sawInline = true;
    855             curr = curr->nextSibling();
    856         }
    857     } while (!sawInline);
    858 }
    859 
    860 void RenderBlock::deleteLineBoxTree()
    861 {
    862     m_lineBoxes.deleteLineBoxTree(renderArena());
    863 }
    864 
    865 RootInlineBox* RenderBlock::createRootInlineBox()
    866 {
    867     return new (renderArena()) RootInlineBox(this);
    868 }
    869 
    870 RootInlineBox* RenderBlock::createAndAppendRootInlineBox()
    871 {
    872     RootInlineBox* rootBox = createRootInlineBox();
    873     m_lineBoxes.appendLineBox(rootBox);
    874     return rootBox;
    875 }
    876 
    877 void RenderBlock::moveChildTo(RenderBlock* to, RenderObject* child, RenderObject* beforeChild, bool fullRemoveInsert)
    878 {
    879     ASSERT(this == child->parent());
    880     ASSERT(!beforeChild || to == beforeChild->parent());
    881     to->children()->insertChildNode(to, children()->removeChildNode(this, child, fullRemoveInsert), beforeChild, fullRemoveInsert);
    882 }
    883 
    884 void RenderBlock::moveChildrenTo(RenderBlock* to, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert)
    885 {
    886     ASSERT(!beforeChild || to == beforeChild->parent());
    887     RenderObject* nextChild = startChild;
    888     while (nextChild && nextChild != endChild) {
    889         RenderObject* child = nextChild;
    890         nextChild = child->nextSibling();
    891         to->children()->insertChildNode(to, children()->removeChildNode(this, child, fullRemoveInsert), beforeChild, fullRemoveInsert);
    892         if (child == endChild)
    893             return;
    894     }
    895 }
    896 
    897 void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
    898 {
    899     // makeChildrenNonInline takes a block whose children are *all* inline and it
    900     // makes sure that inline children are coalesced under anonymous
    901     // blocks.  If |insertionPoint| is defined, then it represents the insertion point for
    902     // the new block child that is causing us to have to wrap all the inlines.  This
    903     // means that we cannot coalesce inlines before |insertionPoint| with inlines following
    904     // |insertionPoint|, because the new child is going to be inserted in between the inlines,
    905     // splitting them.
    906     ASSERT(isInlineBlockOrInlineTable() || !isInline());
    907     ASSERT(!insertionPoint || insertionPoint->parent() == this);
    908 
    909     setChildrenInline(false);
    910 
    911     RenderObject *child = firstChild();
    912     if (!child)
    913         return;
    914 
    915     deleteLineBoxTree();
    916 
    917     while (child) {
    918         RenderObject *inlineRunStart, *inlineRunEnd;
    919         getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);
    920 
    921         if (!inlineRunStart)
    922             break;
    923 
    924         child = inlineRunEnd->nextSibling();
    925 
    926         RenderBlock* block = createAnonymousBlock();
    927         children()->insertChildNode(this, block, inlineRunStart);
    928         moveChildrenTo(block, inlineRunStart, child);
    929     }
    930 
    931 #ifndef NDEBUG
    932     for (RenderObject *c = firstChild(); c; c = c->nextSibling())
    933         ASSERT(!c->isInline());
    934 #endif
    935 
    936     repaint();
    937 }
    938 
    939 void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
    940 {
    941     ASSERT(child->isAnonymousBlock());
    942     ASSERT(!child->childrenInline());
    943 
    944     if (child->continuation() || (child->firstChild() && (child->isAnonymousColumnSpanBlock() || child->isAnonymousColumnsBlock())))
    945         return;
    946 
    947     RenderObject* firstAnChild = child->m_children.firstChild();
    948     RenderObject* lastAnChild = child->m_children.lastChild();
    949     if (firstAnChild) {
    950         RenderObject* o = firstAnChild;
    951         while (o) {
    952             o->setParent(this);
    953             o = o->nextSibling();
    954         }
    955         firstAnChild->setPreviousSibling(child->previousSibling());
    956         lastAnChild->setNextSibling(child->nextSibling());
    957         if (child->previousSibling())
    958             child->previousSibling()->setNextSibling(firstAnChild);
    959         if (child->nextSibling())
    960             child->nextSibling()->setPreviousSibling(lastAnChild);
    961 
    962         if (child == m_children.firstChild())
    963             m_children.setFirstChild(firstAnChild);
    964         if (child == m_children.lastChild())
    965             m_children.setLastChild(lastAnChild);
    966     } else {
    967         if (child == m_children.firstChild())
    968             m_children.setFirstChild(child->nextSibling());
    969         if (child == m_children.lastChild())
    970             m_children.setLastChild(child->previousSibling());
    971 
    972         if (child->previousSibling())
    973             child->previousSibling()->setNextSibling(child->nextSibling());
    974         if (child->nextSibling())
    975             child->nextSibling()->setPreviousSibling(child->previousSibling());
    976     }
    977     child->setParent(0);
    978     child->setPreviousSibling(0);
    979     child->setNextSibling(0);
    980 
    981     child->children()->setFirstChild(0);
    982     child->m_next = 0;
    983 
    984     child->destroy();
    985 }
    986 
    987 static bool canMergeContiguousAnonymousBlocks(RenderObject* oldChild, RenderObject* prev, RenderObject* next)
    988 {
    989     if (oldChild->documentBeingDestroyed() || oldChild->isInline() || oldChild->virtualContinuation())
    990         return false;
    991 
    992     if (oldChild->parent() && oldChild->parent()->isDetails())
    993         return false;
    994 
    995     if ((prev && (!prev->isAnonymousBlock() || toRenderBlock(prev)->continuation() || toRenderBlock(prev)->beingDestroyed()))
    996         || (next && (!next->isAnonymousBlock() || toRenderBlock(next)->continuation() || toRenderBlock(next)->beingDestroyed())))
    997         return false;
    998 
    999     // FIXME: This check isn't required when inline run-ins can't be split into continuations.
   1000     if (prev && prev->firstChild() && prev->firstChild()->isInline() && prev->firstChild()->isRunIn())
   1001         return false;
   1002 
   1003     if ((prev && (prev->isRubyRun() || prev->isRubyBase()))
   1004         || (next && (next->isRubyRun() || next->isRubyBase())))
   1005         return false;
   1006 
   1007     if (!prev || !next)
   1008         return true;
   1009 
   1010     // Make sure the types of the anonymous blocks match up.
   1011     return prev->isAnonymousColumnsBlock() == next->isAnonymousColumnsBlock()
   1012            && prev->isAnonymousColumnSpanBlock() == next->isAnonymousColumnSpanBlock();
   1013 }
   1014 
   1015 void RenderBlock::removeChild(RenderObject* oldChild)
   1016 {
   1017     // If this child is a block, and if our previous and next siblings are
   1018     // both anonymous blocks with inline content, then we can go ahead and
   1019     // fold the inline content back together.
   1020     RenderObject* prev = oldChild->previousSibling();
   1021     RenderObject* next = oldChild->nextSibling();
   1022     bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, prev, next);
   1023     if (canMergeAnonymousBlocks && prev && next) {
   1024         prev->setNeedsLayoutAndPrefWidthsRecalc();
   1025         RenderBlock* nextBlock = toRenderBlock(next);
   1026         RenderBlock* prevBlock = toRenderBlock(prev);
   1027 
   1028         if (prev->childrenInline() != next->childrenInline()) {
   1029             RenderBlock* inlineChildrenBlock = prev->childrenInline() ? prevBlock : nextBlock;
   1030             RenderBlock* blockChildrenBlock = prev->childrenInline() ? nextBlock : prevBlock;
   1031 
   1032             // Place the inline children block inside of the block children block instead of deleting it.
   1033             // In order to reuse it, we have to reset it to just be a generic anonymous block.  Make sure
   1034             // to clear out inherited column properties by just making a new style, and to also clear the
   1035             // column span flag if it is set.
   1036             ASSERT(!inlineChildrenBlock->continuation());
   1037             RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
   1038             children()->removeChildNode(this, inlineChildrenBlock, inlineChildrenBlock->hasLayer());
   1039             inlineChildrenBlock->setStyle(newStyle);
   1040 
   1041             // Now just put the inlineChildrenBlock inside the blockChildrenBlock.
   1042             blockChildrenBlock->children()->insertChildNode(blockChildrenBlock, inlineChildrenBlock, prev == inlineChildrenBlock ? blockChildrenBlock->firstChild() : 0,
   1043                                                             inlineChildrenBlock->hasLayer() || blockChildrenBlock->hasLayer());
   1044             next->setNeedsLayoutAndPrefWidthsRecalc();
   1045 
   1046             // inlineChildrenBlock got reparented to blockChildrenBlock, so it is no longer a child
   1047             // of "this". we null out prev or next so that is not used later in the function.
   1048             if (inlineChildrenBlock == prevBlock)
   1049                 prev = 0;
   1050             else
   1051                 next = 0;
   1052         } else {
   1053             // Take all the children out of the |next| block and put them in
   1054             // the |prev| block.
   1055             nextBlock->moveAllChildrenTo(prevBlock, nextBlock->hasLayer() || prevBlock->hasLayer());
   1056 
   1057             // Delete the now-empty block's lines and nuke it.
   1058             nextBlock->deleteLineBoxTree();
   1059             nextBlock->destroy();
   1060             next = 0;
   1061         }
   1062     }
   1063 
   1064     RenderBox::removeChild(oldChild);
   1065 
   1066     RenderObject* child = prev ? prev : next;
   1067     if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && !isFlexibleBox()) {
   1068         // The removal has knocked us down to containing only a single anonymous
   1069         // box.  We can go ahead and pull the content right back up into our
   1070         // box.
   1071         setNeedsLayoutAndPrefWidthsRecalc();
   1072         setChildrenInline(child->childrenInline());
   1073         RenderBlock* anonBlock = toRenderBlock(children()->removeChildNode(this, child, child->hasLayer()));
   1074         anonBlock->moveAllChildrenTo(this, child->hasLayer());
   1075         // Delete the now-empty block's lines and nuke it.
   1076         anonBlock->deleteLineBoxTree();
   1077         anonBlock->destroy();
   1078     }
   1079 
   1080     if (!firstChild() && !documentBeingDestroyed()) {
   1081         // If this was our last child be sure to clear out our line boxes.
   1082         if (childrenInline())
   1083             lineBoxes()->deleteLineBoxes(renderArena());
   1084     }
   1085 }
   1086 
   1087 bool RenderBlock::isSelfCollapsingBlock() const
   1088 {
   1089     // We are not self-collapsing if we
   1090     // (a) have a non-zero height according to layout (an optimization to avoid wasting time)
   1091     // (b) are a table,
   1092     // (c) have border/padding,
   1093     // (d) have a min-height
   1094     // (e) have specified that one of our margins can't collapse using a CSS extension
   1095     if (logicalHeight() > 0
   1096         || isTable() || borderAndPaddingLogicalHeight()
   1097         || style()->logicalMinHeight().isPositive()
   1098         || style()->marginBeforeCollapse() == MSEPARATE || style()->marginAfterCollapse() == MSEPARATE)
   1099         return false;
   1100 
   1101     Length logicalHeightLength = style()->logicalHeight();
   1102     bool hasAutoHeight = logicalHeightLength.isAuto();
   1103     if (logicalHeightLength.isPercent() && !document()->inQuirksMode()) {
   1104         hasAutoHeight = true;
   1105         for (RenderBlock* cb = containingBlock(); !cb->isRenderView(); cb = cb->containingBlock()) {
   1106             if (cb->style()->logicalHeight().isFixed() || cb->isTableCell())
   1107                 hasAutoHeight = false;
   1108         }
   1109     }
   1110 
   1111     // If the height is 0 or auto, then whether or not we are a self-collapsing block depends
   1112     // on whether we have content that is all self-collapsing or not.
   1113     if (hasAutoHeight || ((logicalHeightLength.isFixed() || logicalHeightLength.isPercent()) && logicalHeightLength.isZero())) {
   1114         // If the block has inline children, see if we generated any line boxes.  If we have any
   1115         // line boxes, then we can't be self-collapsing, since we have content.
   1116         if (childrenInline())
   1117             return !firstLineBox();
   1118 
   1119         // Whether or not we collapse is dependent on whether all our normal flow children
   1120         // are also self-collapsing.
   1121         for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
   1122             if (child->isFloatingOrPositioned())
   1123                 continue;
   1124             if (!child->isSelfCollapsingBlock())
   1125                 return false;
   1126         }
   1127         return true;
   1128     }
   1129     return false;
   1130 }
   1131 
   1132 void RenderBlock::startDelayUpdateScrollInfo()
   1133 {
   1134     if (gDelayUpdateScrollInfo == 0) {
   1135         ASSERT(!gDelayedUpdateScrollInfoSet);
   1136         gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet;
   1137     }
   1138     ASSERT(gDelayedUpdateScrollInfoSet);
   1139     ++gDelayUpdateScrollInfo;
   1140 }
   1141 
   1142 void RenderBlock::finishDelayUpdateScrollInfo()
   1143 {
   1144     --gDelayUpdateScrollInfo;
   1145     ASSERT(gDelayUpdateScrollInfo >= 0);
   1146     if (gDelayUpdateScrollInfo == 0) {
   1147         ASSERT(gDelayedUpdateScrollInfoSet);
   1148 
   1149         OwnPtr<DelayedUpdateScrollInfoSet> infoSet(gDelayedUpdateScrollInfoSet);
   1150         gDelayedUpdateScrollInfoSet = 0;
   1151 
   1152         for (DelayedUpdateScrollInfoSet::iterator it = infoSet->begin(); it != infoSet->end(); ++it) {
   1153             RenderBlock* block = *it;
   1154             if (block->hasOverflowClip()) {
   1155                 block->layer()->updateScrollInfoAfterLayout();
   1156             }
   1157         }
   1158     }
   1159 }
   1160 
   1161 void RenderBlock::updateScrollInfoAfterLayout()
   1162 {
   1163     if (hasOverflowClip()) {
   1164         if (gDelayUpdateScrollInfo)
   1165             gDelayedUpdateScrollInfoSet->add(this);
   1166         else
   1167             layer()->updateScrollInfoAfterLayout();
   1168     }
   1169 }
   1170 
   1171 void RenderBlock::layout()
   1172 {
   1173     // Update our first letter info now.
   1174     updateFirstLetter();
   1175 
   1176     // Table cells call layoutBlock directly, so don't add any logic here.  Put code into
   1177     // layoutBlock().
   1178     layoutBlock(false);
   1179 
   1180     // It's safe to check for control clip here, since controls can never be table cells.
   1181     // If we have a lightweight clip, there can never be any overflow from children.
   1182     if (hasControlClip() && m_overflow)
   1183         clearLayoutOverflow();
   1184 }
   1185 
   1186 void RenderBlock::layoutBlock(bool relayoutChildren, int pageLogicalHeight)
   1187 {
   1188     ASSERT(needsLayout());
   1189 
   1190     if (isInline() && !isInlineBlockOrInlineTable()) // Inline <form>s inside various table elements can
   1191         return;                                      // cause us to come in here.  Just bail.
   1192 
   1193     if (!relayoutChildren && simplifiedLayout())
   1194         return;
   1195 
   1196     LayoutRepainter repainter(*this, m_everHadLayout && checkForRepaintDuringLayout());
   1197 
   1198     int oldWidth = logicalWidth();
   1199     int oldColumnWidth = desiredColumnWidth();
   1200 
   1201     computeLogicalWidth();
   1202     calcColumnWidth();
   1203 
   1204     m_overflow.clear();
   1205 
   1206     if (oldWidth != logicalWidth() || oldColumnWidth != desiredColumnWidth())
   1207         relayoutChildren = true;
   1208 
   1209 #ifdef ANDROID_LAYOUT
   1210     checkAndSetRelayoutChildren(&relayoutChildren);
   1211 #endif
   1212 
   1213     clearFloats();
   1214 
   1215     int previousHeight = logicalHeight();
   1216     setLogicalHeight(0);
   1217     bool hasSpecifiedPageLogicalHeight = false;
   1218     bool pageLogicalHeightChanged = false;
   1219     ColumnInfo* colInfo = columnInfo();
   1220     if (hasColumns()) {
   1221         if (!pageLogicalHeight) {
   1222             // We need to go ahead and set our explicit page height if one exists, so that we can
   1223             // avoid doing two layout passes.
   1224             computeLogicalHeight();
   1225             int columnHeight = contentLogicalHeight();
   1226             if (columnHeight > 0) {
   1227                 pageLogicalHeight = columnHeight;
   1228                 hasSpecifiedPageLogicalHeight = true;
   1229             }
   1230             setLogicalHeight(0);
   1231         }
   1232         if (colInfo->columnHeight() != pageLogicalHeight && m_everHadLayout) {
   1233             colInfo->setColumnHeight(pageLogicalHeight);
   1234             pageLogicalHeightChanged = true;
   1235         }
   1236 
   1237         if (!hasSpecifiedPageLogicalHeight && !pageLogicalHeight)
   1238             colInfo->clearForcedBreaks();
   1239     }
   1240 
   1241     LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode(), pageLogicalHeight, pageLogicalHeightChanged, colInfo);
   1242 
   1243     // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track
   1244     // our current maximal positive and negative margins.  These values are used when we
   1245     // are collapsed with adjacent blocks, so for example, if you have block A and B
   1246     // collapsing together, then you'd take the maximal positive margin from both A and B
   1247     // and subtract it from the maximal negative margin from both A and B to get the
   1248     // true collapsed margin.  This algorithm is recursive, so when we finish layout()
   1249     // our block knows its current maximal positive/negative values.
   1250     //
   1251     // Start out by setting our margin values to our current margins.  Table cells have
   1252     // no margins, so we don't fill in the values for table cells.
   1253     bool isCell = isTableCell();
   1254     if (!isCell) {
   1255         initMaxMarginValues();
   1256 
   1257         setMarginBeforeQuirk(style()->marginBefore().quirk());
   1258         setMarginAfterQuirk(style()->marginAfter().quirk());
   1259 
   1260         Node* n = node();
   1261         if (n && n->hasTagName(formTag) && static_cast<HTMLFormElement*>(n)->isMalformed()) {
   1262             // See if this form is malformed (i.e., unclosed). If so, don't give the form
   1263             // a bottom margin.
   1264             setMaxMarginAfterValues(0, 0);
   1265         }
   1266 
   1267         setPaginationStrut(0);
   1268     }
   1269 
   1270     // For overflow:scroll blocks, ensure we have both scrollbars in place always.
   1271     if (scrollsOverflow()) {
   1272         if (style()->overflowX() == OSCROLL)
   1273             layer()->setHasHorizontalScrollbar(true);
   1274         if (style()->overflowY() == OSCROLL)
   1275             layer()->setHasVerticalScrollbar(true);
   1276     }
   1277 
   1278     int repaintLogicalTop = 0;
   1279     int repaintLogicalBottom = 0;
   1280     int maxFloatLogicalBottom = 0;
   1281     if (!firstChild() && !isAnonymousBlock())
   1282         setChildrenInline(true);
   1283     if (childrenInline())
   1284         layoutInlineChildren(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
   1285     else
   1286         layoutBlockChildren(relayoutChildren, maxFloatLogicalBottom);
   1287 
   1288     // Expand our intrinsic height to encompass floats.
   1289     int toAdd = borderAfter() + paddingAfter() + scrollbarLogicalHeight();
   1290     if (lowestFloatLogicalBottom() > (logicalHeight() - toAdd) && expandsToEncloseOverhangingFloats())
   1291         setLogicalHeight(lowestFloatLogicalBottom() + toAdd);
   1292 
   1293     if (layoutColumns(hasSpecifiedPageLogicalHeight, pageLogicalHeight, statePusher))
   1294         return;
   1295 
   1296     // Calculate our new height.
   1297     int oldHeight = logicalHeight();
   1298     int oldClientAfterEdge = clientLogicalBottom();
   1299     computeLogicalHeight();
   1300     int newHeight = logicalHeight();
   1301     if (oldHeight != newHeight) {
   1302         if (oldHeight > newHeight && maxFloatLogicalBottom > newHeight && !childrenInline()) {
   1303             // One of our children's floats may have become an overhanging float for us. We need to look for it.
   1304             for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
   1305                 if (child->isBlockFlow() && !child->isFloatingOrPositioned()) {
   1306                     RenderBlock* block = toRenderBlock(child);
   1307                     if (block->lowestFloatLogicalBottom() + block->logicalTop() > newHeight)
   1308                         addOverhangingFloats(block, -block->logicalLeft(), -block->logicalTop(), false);
   1309                 }
   1310             }
   1311         }
   1312     }
   1313 
   1314     if (previousHeight != newHeight)
   1315         relayoutChildren = true;
   1316 
   1317     layoutPositionedObjects(relayoutChildren || isRoot());
   1318 
   1319     // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway).
   1320     computeOverflow(oldClientAfterEdge);
   1321 
   1322     statePusher.pop();
   1323 
   1324     if (view()->layoutState()->m_pageLogicalHeight)
   1325         setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(logicalTop()));
   1326 
   1327     updateLayerTransform();
   1328 
   1329     // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
   1330     // we overflow or not.
   1331     updateScrollInfoAfterLayout();
   1332 
   1333     // Repaint with our new bounds if they are different from our old bounds.
   1334     bool didFullRepaint = repainter.repaintAfterLayout();
   1335     if (!didFullRepaint && repaintLogicalTop != repaintLogicalBottom && (style()->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) {
   1336         // FIXME: We could tighten up the left and right invalidation points if we let layoutInlineChildren fill them in based off the particular lines
   1337         // it had to lay out.  We wouldn't need the hasOverflowClip() hack in that case either.
   1338         int repaintLogicalLeft = logicalLeftVisualOverflow();
   1339         int repaintLogicalRight = logicalRightVisualOverflow();
   1340         if (hasOverflowClip()) {
   1341             // If we have clipped overflow, we should use layout overflow as well, since visual overflow from lines didn't propagate to our block's overflow.
   1342             // Note the old code did this as well but even for overflow:visible.  The addition of hasOverflowClip() at least tightens up the hack a bit.
   1343             // layoutInlineChildren should be patched to compute the entire repaint rect.
   1344             repaintLogicalLeft = min(repaintLogicalLeft, logicalLeftLayoutOverflow());
   1345             repaintLogicalRight = max(repaintLogicalRight, logicalRightLayoutOverflow());
   1346         }
   1347 
   1348         IntRect repaintRect;
   1349         if (isHorizontalWritingMode())
   1350             repaintRect = IntRect(repaintLogicalLeft, repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop);
   1351         else
   1352             repaintRect = IntRect(repaintLogicalTop, repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft);
   1353 
   1354         // The repaint rect may be split across columns, in which case adjustRectForColumns() will return the union.
   1355         adjustRectForColumns(repaintRect);
   1356 
   1357         repaintRect.inflate(maximalOutlineSize(PaintPhaseOutline));
   1358 
   1359         if (hasOverflowClip()) {
   1360             // Adjust repaint rect for scroll offset
   1361             repaintRect.move(-layer()->scrolledContentOffset());
   1362 
   1363             // Don't allow this rect to spill out of our overflow box.
   1364             repaintRect.intersect(IntRect(0, 0, width(), height()));
   1365         }
   1366 
   1367         // Make sure the rect is still non-empty after intersecting for overflow above
   1368         if (!repaintRect.isEmpty()) {
   1369             repaintRectangle(repaintRect); // We need to do a partial repaint of our content.
   1370             if (hasReflection())
   1371                 repaintRectangle(reflectedRect(repaintRect));
   1372         }
   1373     }
   1374     setNeedsLayout(false);
   1375 }
   1376 
   1377 void RenderBlock::addOverflowFromChildren()
   1378 {
   1379     if (!hasColumns()) {
   1380         if (childrenInline())
   1381             addOverflowFromInlineChildren();
   1382         else
   1383             addOverflowFromBlockChildren();
   1384     } else {
   1385         ColumnInfo* colInfo = columnInfo();
   1386         if (columnCount(colInfo)) {
   1387             IntRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
   1388             if (isHorizontalWritingMode()) {
   1389                 int overflowLeft = !style()->isLeftToRightDirection() ? min(0, lastRect.x()) : 0;
   1390                 int overflowRight = style()->isLeftToRightDirection() ? max(width(), lastRect.maxX()) : 0;
   1391                 int overflowHeight = borderBefore() + paddingBefore() + colInfo->columnHeight();
   1392                 addLayoutOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight));
   1393                 if (!hasOverflowClip())
   1394                     addVisualOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight));
   1395             } else {
   1396                 IntRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
   1397                 int overflowTop = !style()->isLeftToRightDirection() ? min(0, lastRect.y()) : 0;
   1398                 int overflowBottom = style()->isLeftToRightDirection() ? max(height(), lastRect.maxY()) : 0;
   1399                 int overflowWidth = borderBefore() + paddingBefore() + colInfo->columnHeight();
   1400                 addLayoutOverflow(IntRect(0, overflowTop, overflowWidth, overflowBottom - overflowTop));
   1401                 if (!hasOverflowClip())
   1402                     addVisualOverflow(IntRect(0, overflowTop, overflowWidth, overflowBottom - overflowTop));
   1403             }
   1404         }
   1405     }
   1406 }
   1407 
   1408 void RenderBlock::computeOverflow(int oldClientAfterEdge, bool recomputeFloats)
   1409 {
   1410     // Add overflow from children.
   1411     addOverflowFromChildren();
   1412 
   1413     if (!hasColumns() && (recomputeFloats || isRoot() || expandsToEncloseOverhangingFloats() || hasSelfPaintingLayer()))
   1414         addOverflowFromFloats();
   1415 
   1416     // Add in the overflow from positioned objects.
   1417     addOverflowFromPositionedObjects();
   1418 
   1419     if (hasOverflowClip()) {
   1420         // When we have overflow clip, propagate the original spillout since it will include collapsed bottom margins
   1421         // and bottom padding.  Set the axis we don't care about to be 1, since we want this overflow to always
   1422         // be considered reachable.
   1423         IntRect clientRect(clientBoxRect());
   1424         IntRect rectToApply;
   1425         if (isHorizontalWritingMode())
   1426             rectToApply = IntRect(clientRect.x(), clientRect.y(), 1, max(0, oldClientAfterEdge - clientRect.y()));
   1427         else
   1428             rectToApply = IntRect(clientRect.x(), clientRect.y(), max(0, oldClientAfterEdge - clientRect.x()), 1);
   1429         addLayoutOverflow(rectToApply);
   1430     }
   1431 
   1432     // Add visual overflow from box-shadow and reflections.
   1433     addShadowOverflow();
   1434 }
   1435 
   1436 void RenderBlock::addOverflowFromBlockChildren()
   1437 {
   1438     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
   1439         if (!child->isFloatingOrPositioned())
   1440             addOverflowFromChild(child);
   1441     }
   1442 }
   1443 
   1444 void RenderBlock::addOverflowFromFloats()
   1445 {
   1446     if (!m_floatingObjects)
   1447         return;
   1448 
   1449     FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   1450     FloatingObjectSetIterator end = floatingObjectSet.end();
   1451     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   1452         FloatingObject* r = *it;
   1453         if (r->m_isDescendant)
   1454             addOverflowFromChild(r->m_renderer, IntSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r)));
   1455     }
   1456     return;
   1457 }
   1458 
   1459 void RenderBlock::addOverflowFromPositionedObjects()
   1460 {
   1461     if (!m_positionedObjects)
   1462         return;
   1463 
   1464     RenderBox* positionedObject;
   1465     Iterator end = m_positionedObjects->end();
   1466     for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
   1467         positionedObject = *it;
   1468 
   1469         // Fixed positioned elements don't contribute to layout overflow, since they don't scroll with the content.
   1470         if (positionedObject->style()->position() != FixedPosition)
   1471             addOverflowFromChild(positionedObject);
   1472     }
   1473 }
   1474 
   1475 bool RenderBlock::expandsToEncloseOverhangingFloats() const
   1476 {
   1477     return isInlineBlockOrInlineTable() || isFloatingOrPositioned() || hasOverflowClip() || (parent() && parent()->isFlexibleBox())
   1478            || hasColumns() || isTableCell() || isFieldset() || isWritingModeRoot();
   1479 }
   1480 
   1481 void RenderBlock::adjustPositionedBlock(RenderBox* child, const MarginInfo& marginInfo)
   1482 {
   1483     bool isHorizontal = isHorizontalWritingMode();
   1484     bool hasStaticBlockPosition = child->style()->hasStaticBlockPosition(isHorizontal);
   1485     RenderLayer* childLayer = child->layer();
   1486 
   1487     childLayer->setStaticInlinePosition(borderAndPaddingStart());
   1488 
   1489     int logicalTop = logicalHeight();
   1490     if (!marginInfo.canCollapseWithMarginBefore()) {
   1491         child->computeBlockDirectionMargins(this);
   1492         int marginBefore = marginBeforeForChild(child);
   1493         int collapsedBeforePos = marginInfo.positiveMargin();
   1494         int collapsedBeforeNeg = marginInfo.negativeMargin();
   1495         if (marginBefore > 0) {
   1496             if (marginBefore > collapsedBeforePos)
   1497                 collapsedBeforePos = marginBefore;
   1498         } else {
   1499             if (-marginBefore > collapsedBeforeNeg)
   1500                 collapsedBeforeNeg = -marginBefore;
   1501         }
   1502         logicalTop += (collapsedBeforePos - collapsedBeforeNeg) - marginBefore;
   1503     }
   1504     if (childLayer->staticBlockPosition() != logicalTop) {
   1505         childLayer->setStaticBlockPosition(logicalTop);
   1506         if (hasStaticBlockPosition)
   1507             child->setChildNeedsLayout(true, false);
   1508     }
   1509 }
   1510 
   1511 void RenderBlock::adjustFloatingBlock(const MarginInfo& marginInfo)
   1512 {
   1513     // The float should be positioned taking into account the bottom margin
   1514     // of the previous flow.  We add that margin into the height, get the
   1515     // float positioned properly, and then subtract the margin out of the
   1516     // height again.  In the case of self-collapsing blocks, we always just
   1517     // use the top margins, since the self-collapsing block collapsed its
   1518     // own bottom margin into its top margin.
   1519     //
   1520     // Note also that the previous flow may collapse its margin into the top of
   1521     // our block.  If this is the case, then we do not add the margin in to our
   1522     // height when computing the position of the float.   This condition can be tested
   1523     // for by simply calling canCollapseWithMarginBefore.  See
   1524     // http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html for
   1525     // an example of this scenario.
   1526     int marginOffset = marginInfo.canCollapseWithMarginBefore() ? 0 : marginInfo.margin();
   1527     setLogicalHeight(logicalHeight() + marginOffset);
   1528     positionNewFloats();
   1529     setLogicalHeight(logicalHeight() - marginOffset);
   1530 }
   1531 
   1532 bool RenderBlock::handleSpecialChild(RenderBox* child, const MarginInfo& marginInfo)
   1533 {
   1534     // Handle in the given order
   1535     return handlePositionedChild(child, marginInfo)
   1536         || handleFloatingChild(child, marginInfo)
   1537         || handleRunInChild(child);
   1538 }
   1539 
   1540 
   1541 bool RenderBlock::handlePositionedChild(RenderBox* child, const MarginInfo& marginInfo)
   1542 {
   1543     if (child->isPositioned()) {
   1544         child->containingBlock()->insertPositionedObject(child);
   1545         adjustPositionedBlock(child, marginInfo);
   1546         return true;
   1547     }
   1548     return false;
   1549 }
   1550 
   1551 bool RenderBlock::handleFloatingChild(RenderBox* child, const MarginInfo& marginInfo)
   1552 {
   1553     if (child->isFloating()) {
   1554         insertFloatingObject(child);
   1555         adjustFloatingBlock(marginInfo);
   1556         return true;
   1557     }
   1558     return false;
   1559 }
   1560 
   1561 bool RenderBlock::handleRunInChild(RenderBox* child)
   1562 {
   1563     // See if we have a run-in element with inline children.  If the
   1564     // children aren't inline, then just treat the run-in as a normal
   1565     // block.
   1566     if (!child->isRunIn() || !child->childrenInline())
   1567         return false;
   1568     // FIXME: We don't handle non-block elements with run-in for now.
   1569     if (!child->isRenderBlock())
   1570         return false;
   1571 
   1572     RenderBlock* blockRunIn = toRenderBlock(child);
   1573     RenderObject* curr = blockRunIn->nextSibling();
   1574     if (!curr || !curr->isRenderBlock() || !curr->childrenInline() || curr->isRunIn() || curr->isAnonymous() || curr->isFloatingOrPositioned())
   1575         return false;
   1576 
   1577     RenderBlock* currBlock = toRenderBlock(curr);
   1578 
   1579     // First we destroy any :before/:after content. It will be regenerated by the new inline.
   1580     // Exception is if the run-in itself is generated.
   1581     if (child->style()->styleType() != BEFORE && child->style()->styleType() != AFTER) {
   1582         RenderObject* generatedContent;
   1583         if (child->getCachedPseudoStyle(BEFORE) && (generatedContent = child->beforePseudoElementRenderer()))
   1584             generatedContent->destroy();
   1585         if (child->getCachedPseudoStyle(AFTER) && (generatedContent = child->afterPseudoElementRenderer()))
   1586             generatedContent->destroy();
   1587     }
   1588 
   1589     // Remove the old child.
   1590     children()->removeChildNode(this, blockRunIn);
   1591 
   1592     // Create an inline.
   1593     Node* runInNode = blockRunIn->node();
   1594     RenderInline* inlineRunIn = new (renderArena()) RenderInline(runInNode ? runInNode : document());
   1595     inlineRunIn->setStyle(blockRunIn->style());
   1596 
   1597     // Move the nodes from the old child to the new child
   1598     for (RenderObject* runInChild = blockRunIn->firstChild(); runInChild;) {
   1599         RenderObject* nextSibling = runInChild->nextSibling();
   1600         blockRunIn->children()->removeChildNode(blockRunIn, runInChild, false);
   1601         inlineRunIn->addChild(runInChild); // Use addChild instead of appendChildNode since it handles correct placement of the children relative to :after-generated content.
   1602         runInChild = nextSibling;
   1603     }
   1604 
   1605     // Now insert the new child under |currBlock|. Use addChild instead of insertChildNode since it handles correct placement of the children, esp where we cannot insert
   1606     // anything before the first child. e.g. details tag. See https://bugs.webkit.org/show_bug.cgi?id=58228.
   1607     currBlock->addChild(inlineRunIn, currBlock->firstChild());
   1608 
   1609     // If the run-in had an element, we need to set the new renderer.
   1610     if (runInNode)
   1611         runInNode->setRenderer(inlineRunIn);
   1612 
   1613     // Destroy the block run-in, which includes deleting its line box tree.
   1614     blockRunIn->deleteLineBoxTree();
   1615     blockRunIn->destroy();
   1616 
   1617     // The block acts like an inline, so just null out its
   1618     // position.
   1619 
   1620     return true;
   1621 }
   1622 
   1623 int RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo)
   1624 {
   1625     // Get the four margin values for the child and cache them.
   1626     const MarginValues childMargins = marginValuesForChild(child);
   1627 
   1628     // Get our max pos and neg top margins.
   1629     int posTop = childMargins.positiveMarginBefore();
   1630     int negTop = childMargins.negativeMarginBefore();
   1631 
   1632     // For self-collapsing blocks, collapse our bottom margins into our
   1633     // top to get new posTop and negTop values.
   1634     if (child->isSelfCollapsingBlock()) {
   1635         posTop = max(posTop, childMargins.positiveMarginAfter());
   1636         negTop = max(negTop, childMargins.negativeMarginAfter());
   1637     }
   1638 
   1639     // See if the top margin is quirky. We only care if this child has
   1640     // margins that will collapse with us.
   1641     bool topQuirk = child->isMarginBeforeQuirk() || style()->marginBeforeCollapse() == MDISCARD;
   1642 
   1643     if (marginInfo.canCollapseWithMarginBefore()) {
   1644         // This child is collapsing with the top of the
   1645         // block.  If it has larger margin values, then we need to update
   1646         // our own maximal values.
   1647         if (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !topQuirk)
   1648             setMaxMarginBeforeValues(max(posTop, maxPositiveMarginBefore()), max(negTop, maxNegativeMarginBefore()));
   1649 
   1650         // The minute any of the margins involved isn't a quirk, don't
   1651         // collapse it away, even if the margin is smaller (www.webreference.com
   1652         // has an example of this, a <dt> with 0.8em author-specified inside
   1653         // a <dl> inside a <td>.
   1654         if (!marginInfo.determinedMarginBeforeQuirk() && !topQuirk && (posTop - negTop)) {
   1655             setMarginBeforeQuirk(false);
   1656             marginInfo.setDeterminedMarginBeforeQuirk(true);
   1657         }
   1658 
   1659         if (!marginInfo.determinedMarginBeforeQuirk() && topQuirk && !marginBefore())
   1660             // We have no top margin and our top child has a quirky margin.
   1661             // We will pick up this quirky margin and pass it through.
   1662             // This deals with the <td><div><p> case.
   1663             // Don't do this for a block that split two inlines though.  You do
   1664             // still apply margins in this case.
   1665             setMarginBeforeQuirk(true);
   1666     }
   1667 
   1668     if (marginInfo.quirkContainer() && marginInfo.atBeforeSideOfBlock() && (posTop - negTop))
   1669         marginInfo.setMarginBeforeQuirk(topQuirk);
   1670 
   1671     int beforeCollapseLogicalTop = logicalHeight();
   1672     int logicalTop = beforeCollapseLogicalTop;
   1673     if (child->isSelfCollapsingBlock()) {
   1674         // This child has no height.  We need to compute our
   1675         // position before we collapse the child's margins together,
   1676         // so that we can get an accurate position for the zero-height block.
   1677         int collapsedBeforePos = max(marginInfo.positiveMargin(), childMargins.positiveMarginBefore());
   1678         int collapsedBeforeNeg = max(marginInfo.negativeMargin(), childMargins.negativeMarginBefore());
   1679         marginInfo.setMargin(collapsedBeforePos, collapsedBeforeNeg);
   1680 
   1681         // Now collapse the child's margins together, which means examining our
   1682         // bottom margin values as well.
   1683         marginInfo.setPositiveMarginIfLarger(childMargins.positiveMarginAfter());
   1684         marginInfo.setNegativeMarginIfLarger(childMargins.negativeMarginAfter());
   1685 
   1686         if (!marginInfo.canCollapseWithMarginBefore())
   1687             // We need to make sure that the position of the self-collapsing block
   1688             // is correct, since it could have overflowing content
   1689             // that needs to be positioned correctly (e.g., a block that
   1690             // had a specified height of 0 but that actually had subcontent).
   1691             logicalTop = logicalHeight() + collapsedBeforePos - collapsedBeforeNeg;
   1692     }
   1693     else {
   1694         if (child->style()->marginBeforeCollapse() == MSEPARATE) {
   1695             setLogicalHeight(logicalHeight() + marginInfo.margin() + marginBeforeForChild(child));
   1696             logicalTop = logicalHeight();
   1697         }
   1698         else if (!marginInfo.atBeforeSideOfBlock() ||
   1699             (!marginInfo.canCollapseMarginBeforeWithChildren()
   1700              && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.marginBeforeQuirk()))) {
   1701             // We're collapsing with a previous sibling's margins and not
   1702             // with the top of the block.
   1703             setLogicalHeight(logicalHeight() + max(marginInfo.positiveMargin(), posTop) - max(marginInfo.negativeMargin(), negTop));
   1704             logicalTop = logicalHeight();
   1705         }
   1706 
   1707         marginInfo.setPositiveMargin(childMargins.positiveMarginAfter());
   1708         marginInfo.setNegativeMargin(childMargins.negativeMarginAfter());
   1709 
   1710         if (marginInfo.margin())
   1711             marginInfo.setMarginAfterQuirk(child->isMarginAfterQuirk() || style()->marginAfterCollapse() == MDISCARD);
   1712     }
   1713 
   1714     // If margins would pull us past the top of the next page, then we need to pull back and pretend like the margins
   1715     // collapsed into the page edge.
   1716     bool paginated = view()->layoutState()->isPaginated();
   1717     if (paginated && logicalTop > beforeCollapseLogicalTop) {
   1718         int oldLogicalTop = logicalTop;
   1719         logicalTop = min(logicalTop, nextPageLogicalTop(beforeCollapseLogicalTop));
   1720         setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop));
   1721     }
   1722     return logicalTop;
   1723 }
   1724 
   1725 int RenderBlock::clearFloatsIfNeeded(RenderBox* child, MarginInfo& marginInfo, int oldTopPosMargin, int oldTopNegMargin, int yPos)
   1726 {
   1727     int heightIncrease = getClearDelta(child, yPos);
   1728     if (!heightIncrease)
   1729         return yPos;
   1730 
   1731     if (child->isSelfCollapsingBlock()) {
   1732         // For self-collapsing blocks that clear, they can still collapse their
   1733         // margins with following siblings.  Reset the current margins to represent
   1734         // the self-collapsing block's margins only.
   1735         // CSS2.1 states:
   1736         // "An element that has had clearance applied to it never collapses its top margin with its parent block's bottom margin.
   1737         // Therefore if we are at the bottom of the block, let's go ahead and reset margins to only include the
   1738         // self-collapsing block's bottom margin.
   1739         bool atBottomOfBlock = true;
   1740         for (RenderBox* curr = child->nextSiblingBox(); curr && atBottomOfBlock; curr = curr->nextSiblingBox()) {
   1741             if (!curr->isFloatingOrPositioned())
   1742                 atBottomOfBlock = false;
   1743         }
   1744 
   1745         MarginValues childMargins = marginValuesForChild(child);
   1746         if (atBottomOfBlock) {
   1747             marginInfo.setPositiveMargin(childMargins.positiveMarginAfter());
   1748             marginInfo.setNegativeMargin(childMargins.negativeMarginAfter());
   1749         } else {
   1750             marginInfo.setPositiveMargin(max(childMargins.positiveMarginBefore(), childMargins.positiveMarginAfter()));
   1751             marginInfo.setNegativeMargin(max(childMargins.negativeMarginBefore(), childMargins.negativeMarginAfter()));
   1752         }
   1753 
   1754         // Adjust our height such that we are ready to be collapsed with subsequent siblings (or the bottom
   1755         // of the parent block).
   1756         setLogicalHeight(child->y() - max(0, marginInfo.margin()));
   1757     } else
   1758         // Increase our height by the amount we had to clear.
   1759         setLogicalHeight(height() + heightIncrease);
   1760 
   1761     if (marginInfo.canCollapseWithMarginBefore()) {
   1762         // We can no longer collapse with the top of the block since a clear
   1763         // occurred.  The empty blocks collapse into the cleared block.
   1764         // FIXME: This isn't quite correct.  Need clarification for what to do
   1765         // if the height the cleared block is offset by is smaller than the
   1766         // margins involved.
   1767         setMaxMarginBeforeValues(oldTopPosMargin, oldTopNegMargin);
   1768         marginInfo.setAtBeforeSideOfBlock(false);
   1769     }
   1770 
   1771     return yPos + heightIncrease;
   1772 }
   1773 
   1774 int RenderBlock::estimateLogicalTopPosition(RenderBox* child, const MarginInfo& marginInfo)
   1775 {
   1776     // FIXME: We need to eliminate the estimation of vertical position, because when it's wrong we sometimes trigger a pathological
   1777     // relayout if there are intruding floats.
   1778     int logicalTopEstimate = logicalHeight();
   1779     if (!marginInfo.canCollapseWithMarginBefore()) {
   1780         int childMarginBefore = child->selfNeedsLayout() ? marginBeforeForChild(child) : collapsedMarginBeforeForChild(child);
   1781         logicalTopEstimate += max(marginInfo.margin(), childMarginBefore);
   1782     }
   1783 
   1784     bool paginated = view()->layoutState()->isPaginated();
   1785 
   1786     // Adjust logicalTopEstimate down to the next page if the margins are so large that we don't fit on the current
   1787     // page.
   1788     if (paginated && logicalTopEstimate > logicalHeight())
   1789         logicalTopEstimate = min(logicalTopEstimate, nextPageLogicalTop(logicalHeight()));
   1790 
   1791     logicalTopEstimate += getClearDelta(child, logicalTopEstimate);
   1792 
   1793     if (paginated) {
   1794         // If the object has a page or column break value of "before", then we should shift to the top of the next page.
   1795         logicalTopEstimate = applyBeforeBreak(child, logicalTopEstimate);
   1796 
   1797         // For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one.
   1798         logicalTopEstimate = adjustForUnsplittableChild(child, logicalTopEstimate);
   1799 
   1800         if (!child->selfNeedsLayout() && child->isRenderBlock())
   1801             logicalTopEstimate += toRenderBlock(child)->paginationStrut();
   1802     }
   1803 
   1804     return logicalTopEstimate;
   1805 }
   1806 
   1807 void RenderBlock::determineLogicalLeftPositionForChild(RenderBox* child)
   1808 {
   1809     int startPosition = borderStart() + paddingStart();
   1810     int totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + availableLogicalWidth();
   1811 
   1812     // Add in our start margin.
   1813     int childMarginStart = marginStartForChild(child);
   1814     int newPosition = startPosition + childMarginStart;
   1815 
   1816     // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats.  They need
   1817     // to shift over as necessary to dodge any floats that might get in the way.
   1818     if (child->avoidsFloats()) {
   1819         int startOff = style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(logicalHeight(), false) : totalAvailableLogicalWidth - logicalRightOffsetForLine(logicalHeight(), false);
   1820         if (style()->textAlign() != WEBKIT_CENTER && !child->style()->marginStartUsing(style()).isAuto()) {
   1821             if (childMarginStart < 0)
   1822                 startOff += childMarginStart;
   1823             newPosition = max(newPosition, startOff); // Let the float sit in the child's margin if it can fit.
   1824         } else if (startOff != startPosition) {
   1825             // The object is shifting to the "end" side of the block. The object might be centered, so we need to
   1826             // recalculate our inline direction margins. Note that the containing block content
   1827             // width computation will take into account the delta between |startOff| and |startPosition|
   1828             // so that we can just pass the content width in directly to the |computeMarginsInContainingBlockInlineDirection|
   1829             // function.
   1830             child->computeInlineDirectionMargins(this, availableLogicalWidthForLine(logicalTopForChild(child), false), logicalWidthForChild(child));
   1831             newPosition = startOff + marginStartForChild(child);
   1832         }
   1833     }
   1834 
   1835     setLogicalLeftForChild(child, style()->isLeftToRightDirection() ? newPosition : totalAvailableLogicalWidth - newPosition - logicalWidthForChild(child), ApplyLayoutDelta);
   1836 }
   1837 
   1838 void RenderBlock::setCollapsedBottomMargin(const MarginInfo& marginInfo)
   1839 {
   1840     if (marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()) {
   1841         // Update our max pos/neg bottom margins, since we collapsed our bottom margins
   1842         // with our children.
   1843         setMaxMarginAfterValues(max(maxPositiveMarginAfter(), marginInfo.positiveMargin()), max(maxNegativeMarginAfter(), marginInfo.negativeMargin()));
   1844 
   1845         if (!marginInfo.marginAfterQuirk())
   1846             setMarginAfterQuirk(false);
   1847 
   1848         if (marginInfo.marginAfterQuirk() && marginAfter() == 0)
   1849             // We have no bottom margin and our last child has a quirky margin.
   1850             // We will pick up this quirky margin and pass it through.
   1851             // This deals with the <td><div><p> case.
   1852             setMarginAfterQuirk(true);
   1853     }
   1854 }
   1855 
   1856 void RenderBlock::handleAfterSideOfBlock(int beforeSide, int afterSide, MarginInfo& marginInfo)
   1857 {
   1858     marginInfo.setAtAfterSideOfBlock(true);
   1859 
   1860     // If we can't collapse with children then go ahead and add in the bottom margin.
   1861     if (!marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()
   1862         && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.marginAfterQuirk()))
   1863         setLogicalHeight(logicalHeight() + marginInfo.margin());
   1864 
   1865     // Now add in our bottom border/padding.
   1866     setLogicalHeight(logicalHeight() + afterSide);
   1867 
   1868     // Negative margins can cause our height to shrink below our minimal height (border/padding).
   1869     // If this happens, ensure that the computed height is increased to the minimal height.
   1870     setLogicalHeight(max(logicalHeight(), beforeSide + afterSide));
   1871 
   1872     // Update our bottom collapsed margin info.
   1873     setCollapsedBottomMargin(marginInfo);
   1874 }
   1875 
   1876 void RenderBlock::setLogicalLeftForChild(RenderBox* child, int logicalLeft, ApplyLayoutDeltaMode applyDelta)
   1877 {
   1878     if (isHorizontalWritingMode()) {
   1879         if (applyDelta == ApplyLayoutDelta)
   1880             view()->addLayoutDelta(IntSize(child->x() - logicalLeft, 0));
   1881         child->setX(logicalLeft);
   1882     } else {
   1883         if (applyDelta == ApplyLayoutDelta)
   1884             view()->addLayoutDelta(IntSize(0, child->y() - logicalLeft));
   1885         child->setY(logicalLeft);
   1886     }
   1887 }
   1888 
   1889 void RenderBlock::setLogicalTopForChild(RenderBox* child, int logicalTop, ApplyLayoutDeltaMode applyDelta)
   1890 {
   1891     if (isHorizontalWritingMode()) {
   1892         if (applyDelta == ApplyLayoutDelta)
   1893             view()->addLayoutDelta(IntSize(0, child->y() - logicalTop));
   1894         child->setY(logicalTop);
   1895     } else {
   1896         if (applyDelta == ApplyLayoutDelta)
   1897             view()->addLayoutDelta(IntSize(child->x() - logicalTop, 0));
   1898         child->setX(logicalTop);
   1899     }
   1900 }
   1901 
   1902 void RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatLogicalBottom)
   1903 {
   1904     if (gPercentHeightDescendantsMap) {
   1905         if (HashSet<RenderBox*>* descendants = gPercentHeightDescendantsMap->get(this)) {
   1906             HashSet<RenderBox*>::iterator end = descendants->end();
   1907             for (HashSet<RenderBox*>::iterator it = descendants->begin(); it != end; ++it) {
   1908                 RenderBox* box = *it;
   1909                 while (box != this) {
   1910                     if (box->normalChildNeedsLayout())
   1911                         break;
   1912                     box->setChildNeedsLayout(true, false);
   1913                     box = box->containingBlock();
   1914                     ASSERT(box);
   1915                     if (!box)
   1916                         break;
   1917                 }
   1918             }
   1919         }
   1920     }
   1921 
   1922     int beforeEdge = borderBefore() + paddingBefore();
   1923     int afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeight();
   1924 
   1925     setLogicalHeight(beforeEdge);
   1926 
   1927     // The margin struct caches all our current margin collapsing state.  The compact struct caches state when we encounter compacts,
   1928     MarginInfo marginInfo(this, beforeEdge, afterEdge);
   1929 
   1930     // Fieldsets need to find their legend and position it inside the border of the object.
   1931     // The legend then gets skipped during normal layout.  The same is true for ruby text.
   1932     // It doesn't get included in the normal layout process but is instead skipped.
   1933     RenderObject* childToExclude = layoutSpecialExcludedChild(relayoutChildren);
   1934 
   1935     int previousFloatLogicalBottom = 0;
   1936     maxFloatLogicalBottom = 0;
   1937 
   1938     RenderBox* next = firstChildBox();
   1939 
   1940     while (next) {
   1941         RenderBox* child = next;
   1942         next = child->nextSiblingBox();
   1943 
   1944         if (childToExclude == child)
   1945             continue; // Skip this child, since it will be positioned by the specialized subclass (fieldsets and ruby runs).
   1946 
   1947         // Make sure we layout children if they need it.
   1948         // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into
   1949         // an auto value.  Add a method to determine this, so that we can avoid the relayout.
   1950         if (relayoutChildren || ((child->style()->logicalHeight().isPercent() || child->style()->logicalMinHeight().isPercent() || child->style()->logicalMaxHeight().isPercent()) && !isRenderView()))
   1951             child->setChildNeedsLayout(true, false);
   1952 
   1953         // If relayoutChildren is set and the child has percentage padding, we also need to invalidate the child's pref widths.
   1954         if (relayoutChildren && (child->style()->paddingStart().isPercent() || child->style()->paddingEnd().isPercent()))
   1955             child->setPreferredLogicalWidthsDirty(true, false);
   1956 
   1957         // Handle the four types of special elements first.  These include positioned content, floating content, compacts and
   1958         // run-ins.  When we encounter these four types of objects, we don't actually lay them out as normal flow blocks.
   1959         if (handleSpecialChild(child, marginInfo))
   1960             continue;
   1961 
   1962         // Lay out the child.
   1963         layoutBlockChild(child, marginInfo, previousFloatLogicalBottom, maxFloatLogicalBottom);
   1964     }
   1965 
   1966     // Now do the handling of the bottom of the block, adding in our bottom border/padding and
   1967     // determining the correct collapsed bottom margin information.
   1968     handleAfterSideOfBlock(beforeEdge, afterEdge, marginInfo);
   1969 }
   1970 
   1971 void RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, int& previousFloatLogicalBottom, int& maxFloatLogicalBottom)
   1972 {
   1973     int oldPosMarginBefore = maxPositiveMarginBefore();
   1974     int oldNegMarginBefore = maxNegativeMarginBefore();
   1975 
   1976     // The child is a normal flow object.  Compute the margins we will use for collapsing now.
   1977     child->computeBlockDirectionMargins(this);
   1978 
   1979     // Do not allow a collapse if the margin-before-collapse style is set to SEPARATE.
   1980     if (child->style()->marginBeforeCollapse() == MSEPARATE) {
   1981         marginInfo.setAtBeforeSideOfBlock(false);
   1982         marginInfo.clearMargin();
   1983     }
   1984 
   1985     // Try to guess our correct logical top position.  In most cases this guess will
   1986     // be correct.  Only if we're wrong (when we compute the real logical top position)
   1987     // will we have to potentially relayout.
   1988     int logicalTopEstimate = estimateLogicalTopPosition(child, marginInfo);
   1989 
   1990     // Cache our old rect so that we can dirty the proper repaint rects if the child moves.
   1991     IntRect oldRect(child->x(), child->y() , child->width(), child->height());
   1992     int oldLogicalTop = logicalTopForChild(child);
   1993 
   1994 #ifndef NDEBUG
   1995     IntSize oldLayoutDelta = view()->layoutDelta();
   1996 #endif
   1997     // Go ahead and position the child as though it didn't collapse with the top.
   1998     setLogicalTopForChild(child, logicalTopEstimate, ApplyLayoutDelta);
   1999 
   2000     RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0;
   2001     bool markDescendantsWithFloats = false;
   2002     if (logicalTopEstimate != oldLogicalTop && !child->avoidsFloats() && childRenderBlock && childRenderBlock->containsFloats())
   2003         markDescendantsWithFloats = true;
   2004     else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) {
   2005         // If an element might be affected by the presence of floats, then always mark it for
   2006         // layout.
   2007         int fb = max(previousFloatLogicalBottom, lowestFloatLogicalBottom());
   2008         if (fb > logicalTopEstimate)
   2009             markDescendantsWithFloats = true;
   2010     }
   2011 
   2012     if (childRenderBlock) {
   2013         if (markDescendantsWithFloats)
   2014             childRenderBlock->markAllDescendantsWithFloatsForLayout();
   2015         if (!child->isWritingModeRoot())
   2016             previousFloatLogicalBottom = max(previousFloatLogicalBottom, oldLogicalTop + childRenderBlock->lowestFloatLogicalBottom());
   2017     }
   2018 
   2019     if (!child->needsLayout())
   2020         child->markForPaginationRelayoutIfNeeded();
   2021 
   2022     bool childHadLayout = child->m_everHadLayout;
   2023     bool childNeededLayout = child->needsLayout();
   2024     if (childNeededLayout)
   2025         child->layout();
   2026 
   2027     // Cache if we are at the top of the block right now.
   2028     bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock();
   2029 
   2030     // Now determine the correct ypos based off examination of collapsing margin
   2031     // values.
   2032     int logicalTopBeforeClear = collapseMargins(child, marginInfo);
   2033 
   2034     // Now check for clear.
   2035     int logicalTopAfterClear = clearFloatsIfNeeded(child, marginInfo, oldPosMarginBefore, oldNegMarginBefore, logicalTopBeforeClear);
   2036 
   2037     bool paginated = view()->layoutState()->isPaginated();
   2038     if (paginated) {
   2039         int oldTop = logicalTopAfterClear;
   2040 
   2041         // If the object has a page or column break value of "before", then we should shift to the top of the next page.
   2042         logicalTopAfterClear = applyBeforeBreak(child, logicalTopAfterClear);
   2043 
   2044         // For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one.
   2045         int logicalTopBeforeUnsplittableAdjustment = logicalTopAfterClear;
   2046         int logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChild(child, logicalTopAfterClear);
   2047 
   2048         int paginationStrut = 0;
   2049         int unsplittableAdjustmentDelta = logicalTopAfterUnsplittableAdjustment - logicalTopBeforeUnsplittableAdjustment;
   2050         if (unsplittableAdjustmentDelta)
   2051             paginationStrut = unsplittableAdjustmentDelta;
   2052         else if (childRenderBlock && childRenderBlock->paginationStrut())
   2053             paginationStrut = childRenderBlock->paginationStrut();
   2054 
   2055         if (paginationStrut) {
   2056             // We are willing to propagate out to our parent block as long as we were at the top of the block prior
   2057             // to collapsing our margins, and as long as we didn't clear or move as a result of other pagination.
   2058             if (atBeforeSideOfBlock && oldTop == logicalTopBeforeClear && !isPositioned() && !isTableCell()) {
   2059                 // FIXME: Should really check if we're exceeding the page height before propagating the strut, but we don't
   2060                 // have all the information to do so (the strut only has the remaining amount to push).  Gecko gets this wrong too
   2061                 // and pushes to the next page anyway, so not too concerned about it.
   2062                 setPaginationStrut(logicalTopAfterClear + paginationStrut);
   2063                 if (childRenderBlock)
   2064                     childRenderBlock->setPaginationStrut(0);
   2065             } else
   2066                 logicalTopAfterClear += paginationStrut;
   2067         }
   2068 
   2069         // Similar to how we apply clearance.  Go ahead and boost height() to be the place where we're going to position the child.
   2070         setLogicalHeight(logicalHeight() + (logicalTopAfterClear - oldTop));
   2071     }
   2072 
   2073     setLogicalTopForChild(child, logicalTopAfterClear, ApplyLayoutDelta);
   2074 
   2075     // Now we have a final top position.  See if it really does end up being different from our estimate.
   2076     if (logicalTopAfterClear != logicalTopEstimate) {
   2077         if (child->shrinkToAvoidFloats()) {
   2078             // The child's width depends on the line width.
   2079             // When the child shifts to clear an item, its width can
   2080             // change (because it has more available line width).
   2081             // So go ahead and mark the item as dirty.
   2082             child->setChildNeedsLayout(true, false);
   2083         }
   2084         if (childRenderBlock) {
   2085             if (!child->avoidsFloats() && childRenderBlock->containsFloats())
   2086                 childRenderBlock->markAllDescendantsWithFloatsForLayout();
   2087             if (!child->needsLayout())
   2088                 child->markForPaginationRelayoutIfNeeded();
   2089         }
   2090 
   2091         // Our guess was wrong. Make the child lay itself out again.
   2092         child->layoutIfNeeded();
   2093     }
   2094 
   2095     // We are no longer at the top of the block if we encounter a non-empty child.
   2096     // This has to be done after checking for clear, so that margins can be reset if a clear occurred.
   2097     if (marginInfo.atBeforeSideOfBlock() && !child->isSelfCollapsingBlock())
   2098         marginInfo.setAtBeforeSideOfBlock(false);
   2099 
   2100     // Now place the child in the correct left position
   2101     determineLogicalLeftPositionForChild(child);
   2102 
   2103     // Update our height now that the child has been placed in the correct position.
   2104     setLogicalHeight(logicalHeight() + logicalHeightForChild(child));
   2105     if (child->style()->marginAfterCollapse() == MSEPARATE) {
   2106         setLogicalHeight(logicalHeight() + marginAfterForChild(child));
   2107         marginInfo.clearMargin();
   2108     }
   2109     // If the child has overhanging floats that intrude into following siblings (or possibly out
   2110     // of this block), then the parent gets notified of the floats now.
   2111     if (childRenderBlock && childRenderBlock->containsFloats())
   2112         maxFloatLogicalBottom = max(maxFloatLogicalBottom, addOverhangingFloats(toRenderBlock(child), -child->logicalLeft(), -child->logicalTop(), !childNeededLayout));
   2113 
   2114     IntSize childOffset(child->x() - oldRect.x(), child->y() - oldRect.y());
   2115     if (childOffset.width() || childOffset.height()) {
   2116         view()->addLayoutDelta(childOffset);
   2117 
   2118         // If the child moved, we have to repaint it as well as any floating/positioned
   2119         // descendants.  An exception is if we need a layout.  In this case, we know we're going to
   2120         // repaint ourselves (and the child) anyway.
   2121         if (childHadLayout && !selfNeedsLayout() && child->checkForRepaintDuringLayout())
   2122             child->repaintDuringLayoutIfMoved(oldRect);
   2123     }
   2124 
   2125     if (!childHadLayout && child->checkForRepaintDuringLayout()) {
   2126         child->repaint();
   2127         child->repaintOverhangingFloats(true);
   2128     }
   2129 
   2130     if (paginated) {
   2131         // Check for an after page/column break.
   2132         int newHeight = applyAfterBreak(child, logicalHeight(), marginInfo);
   2133         if (newHeight != height())
   2134             setLogicalHeight(newHeight);
   2135     }
   2136 
   2137     ASSERT(oldLayoutDelta == view()->layoutDelta());
   2138 }
   2139 
   2140 void RenderBlock::simplifiedNormalFlowLayout()
   2141 {
   2142     if (childrenInline()) {
   2143         ListHashSet<RootInlineBox*> lineBoxes;
   2144         bool endOfInline = false;
   2145         RenderObject* o = bidiFirst(this, 0, false);
   2146         while (o) {
   2147             if (!o->isPositioned() && (o->isReplaced() || o->isFloating())) {
   2148                 o->layoutIfNeeded();
   2149                 if (toRenderBox(o)->inlineBoxWrapper()) {
   2150                     RootInlineBox* box = toRenderBox(o)->inlineBoxWrapper()->root();
   2151                     lineBoxes.add(box);
   2152                 }
   2153             } else if (o->isText() || (o->isRenderInline() && !endOfInline))
   2154                 o->setNeedsLayout(false);
   2155             o = bidiNext(this, o, 0, false, &endOfInline);
   2156         }
   2157 
   2158         // FIXME: Glyph overflow will get lost in this case, but not really a big deal.
   2159         GlyphOverflowAndFallbackFontsMap textBoxDataMap;
   2160         for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it != lineBoxes.end(); ++it) {
   2161             RootInlineBox* box = *it;
   2162             box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap);
   2163         }
   2164     } else {
   2165         for (RenderBox* box = firstChildBox(); box; box = box->nextSiblingBox()) {
   2166             if (!box->isPositioned())
   2167                 box->layoutIfNeeded();
   2168         }
   2169     }
   2170 }
   2171 
   2172 bool RenderBlock::simplifiedLayout()
   2173 {
   2174     if ((!posChildNeedsLayout() && !needsSimplifiedNormalFlowLayout()) || normalChildNeedsLayout() || selfNeedsLayout())
   2175         return false;
   2176 
   2177     LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
   2178 
   2179     if (needsPositionedMovementLayout() && !tryLayoutDoingPositionedMovementOnly())
   2180         return false;
   2181 
   2182     // Lay out positioned descendants or objects that just need to recompute overflow.
   2183     if (needsSimplifiedNormalFlowLayout())
   2184         simplifiedNormalFlowLayout();
   2185 
   2186     // Lay out our positioned objects if our positioned child bit is set.
   2187     if (posChildNeedsLayout())
   2188         layoutPositionedObjects(false);
   2189 
   2190     // Recompute our overflow information.
   2191     // FIXME: We could do better here by computing a temporary overflow object from layoutPositionedObjects and only
   2192     // updating our overflow if we either used to have overflow or if the new temporary object has overflow.
   2193     // For now just always recompute overflow.  This is no worse performance-wise than the old code that called rightmostPosition and
   2194     // lowestPosition on every relayout so it's not a regression.
   2195     m_overflow.clear();
   2196     computeOverflow(clientLogicalBottom(), true);
   2197 
   2198     statePusher.pop();
   2199 
   2200     updateLayerTransform();
   2201 
   2202     updateScrollInfoAfterLayout();
   2203 
   2204     setNeedsLayout(false);
   2205     return true;
   2206 }
   2207 
   2208 void RenderBlock::layoutPositionedObjects(bool relayoutChildren)
   2209 {
   2210     if (!m_positionedObjects)
   2211         return;
   2212 
   2213     if (hasColumns())
   2214         view()->layoutState()->clearPaginationInformation(); // Positioned objects are not part of the column flow, so they don't paginate with the columns.
   2215 
   2216     RenderBox* r;
   2217     Iterator end = m_positionedObjects->end();
   2218     for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
   2219         r = *it;
   2220         // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the
   2221         // non-positioned block.  Rather than trying to detect all of these movement cases, we just always lay out positioned
   2222         // objects that are positioned implicitly like this.  Such objects are rare, and so in typical DHTML menu usage (where everything is
   2223         // positioned explicitly) this should not incur a performance penalty.
   2224         if (relayoutChildren || (r->style()->hasStaticBlockPosition(isHorizontalWritingMode()) && r->parent() != this && r->parent()->isBlockFlow()))
   2225             r->setChildNeedsLayout(true, false);
   2226 
   2227         // If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths.
   2228         if (relayoutChildren && (r->style()->paddingStart().isPercent() || r->style()->paddingEnd().isPercent()))
   2229             r->setPreferredLogicalWidthsDirty(true, false);
   2230 
   2231         if (!r->needsLayout())
   2232             r->markForPaginationRelayoutIfNeeded();
   2233 
   2234         // 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
   2235         // and we hit the available width constraint, the layoutIfNeeded() will catch it and do a full layout.
   2236         if (r->needsPositionedMovementLayoutOnly() && r->tryLayoutDoingPositionedMovementOnly())
   2237             r->setNeedsLayout(false);
   2238         r->layoutIfNeeded();
   2239     }
   2240 
   2241     if (hasColumns())
   2242         view()->layoutState()->m_columnInfo = columnInfo(); // FIXME: Kind of gross. We just put this back into the layout state so that pop() will work.
   2243 }
   2244 
   2245 void RenderBlock::markPositionedObjectsForLayout()
   2246 {
   2247     if (m_positionedObjects) {
   2248         RenderBox* r;
   2249         Iterator end = m_positionedObjects->end();
   2250         for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
   2251             r = *it;
   2252             r->setChildNeedsLayout(true);
   2253         }
   2254     }
   2255 }
   2256 
   2257 void RenderBlock::markForPaginationRelayoutIfNeeded()
   2258 {
   2259     ASSERT(!needsLayout());
   2260     if (needsLayout())
   2261         return;
   2262 
   2263     if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(logicalTop()) != pageLogicalOffset()))
   2264         setChildNeedsLayout(true, false);
   2265 }
   2266 
   2267 void RenderBlock::repaintOverhangingFloats(bool paintAllDescendants)
   2268 {
   2269     // Repaint any overhanging floats (if we know we're the one to paint them).
   2270     // Otherwise, bail out.
   2271     if (!hasOverhangingFloats())
   2272         return;
   2273 
   2274     // FIXME: Avoid disabling LayoutState. At the very least, don't disable it for floats originating
   2275     // in this block. Better yet would be to push extra state for the containers of other floats.
   2276     view()->disableLayoutState();
   2277     FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   2278     FloatingObjectSetIterator end = floatingObjectSet.end();
   2279     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   2280         FloatingObject* r = *it;
   2281         // Only repaint the object if it is overhanging, is not in its own layer, and
   2282         // is our responsibility to paint (m_shouldPaint is set). When paintAllDescendants is true, the latter
   2283         // condition is replaced with being a descendant of us.
   2284         if (logicalBottomForFloat(r) > logicalHeight() && ((paintAllDescendants && r->m_renderer->isDescendantOf(this)) || r->m_shouldPaint) && !r->m_renderer->hasSelfPaintingLayer()) {
   2285             r->m_renderer->repaint();
   2286             r->m_renderer->repaintOverhangingFloats();
   2287         }
   2288     }
   2289     view()->enableLayoutState();
   2290 }
   2291 
   2292 void RenderBlock::paint(PaintInfo& paintInfo, int tx, int ty)
   2293 {
   2294     tx += x();
   2295     ty += y();
   2296 
   2297     PaintPhase phase = paintInfo.phase;
   2298 
   2299     // Check if we need to do anything at all.
   2300     // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
   2301     // paints the root's background.
   2302     if (!isRoot()) {
   2303         IntRect overflowBox = visualOverflowRect();
   2304         flipForWritingMode(overflowBox);
   2305         overflowBox.inflate(maximalOutlineSize(paintInfo.phase));
   2306         overflowBox.move(tx, ty);
   2307         if (!overflowBox.intersects(paintInfo.rect))
   2308             return;
   2309     }
   2310 
   2311     bool pushedClip = pushContentsClip(paintInfo, tx, ty);
   2312     paintObject(paintInfo, tx, ty);
   2313     if (pushedClip)
   2314         popContentsClip(paintInfo, phase, tx, ty);
   2315 
   2316     // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
   2317     // z-index.  We paint after we painted the background/border, so that the scrollbars will
   2318     // sit above the background/border.
   2319     if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && paintInfo.shouldPaintWithinRoot(this))
   2320         layer()->paintOverflowControls(paintInfo.context, tx, ty, paintInfo.rect);
   2321 }
   2322 
   2323 void RenderBlock::paintColumnRules(PaintInfo& paintInfo, int tx, int ty)
   2324 {
   2325     const Color& ruleColor = style()->visitedDependentColor(CSSPropertyWebkitColumnRuleColor);
   2326     bool ruleTransparent = style()->columnRuleIsTransparent();
   2327     EBorderStyle ruleStyle = style()->columnRuleStyle();
   2328     int ruleWidth = style()->columnRuleWidth();
   2329     int colGap = columnGap();
   2330     bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent && ruleWidth <= colGap;
   2331     if (!renderRule)
   2332         return;
   2333 
   2334     // We need to do multiple passes, breaking up our child painting into strips.
   2335     ColumnInfo* colInfo = columnInfo();
   2336     unsigned colCount = columnCount(colInfo);
   2337     int currLogicalLeftOffset = style()->isLeftToRightDirection() ? 0 : contentLogicalWidth();
   2338     int ruleAdd = logicalLeftOffsetForContent();
   2339     int ruleLogicalLeft = style()->isLeftToRightDirection() ? 0 : contentLogicalWidth();
   2340     for (unsigned i = 0; i < colCount; i++) {
   2341         IntRect colRect = columnRectAt(colInfo, i);
   2342 
   2343         int inlineDirectionSize = isHorizontalWritingMode() ? colRect.width() : colRect.height();
   2344 
   2345         // Move to the next position.
   2346         if (style()->isLeftToRightDirection()) {
   2347             ruleLogicalLeft += inlineDirectionSize + colGap / 2;
   2348             currLogicalLeftOffset += inlineDirectionSize + colGap;
   2349         } else {
   2350             ruleLogicalLeft -= (inlineDirectionSize + colGap / 2);
   2351             currLogicalLeftOffset -= (inlineDirectionSize + colGap);
   2352         }
   2353 
   2354         // Now paint the column rule.
   2355         if (i < colCount - 1) {
   2356             int ruleLeft = isHorizontalWritingMode() ? tx + ruleLogicalLeft - ruleWidth / 2 + ruleAdd : tx + borderBefore() + paddingBefore();
   2357             int ruleRight = isHorizontalWritingMode() ? ruleLeft + ruleWidth : ruleLeft + contentWidth();
   2358             int ruleTop = isHorizontalWritingMode() ? ty + borderTop() + paddingTop() : ty + ruleLogicalLeft - ruleWidth / 2 + ruleAdd;
   2359             int ruleBottom = isHorizontalWritingMode() ? ruleTop + contentHeight() : ruleTop + ruleWidth;
   2360             drawLineForBoxSide(paintInfo.context, ruleLeft, ruleTop, ruleRight, ruleBottom,
   2361                                style()->isLeftToRightDirection() ? BSLeft : BSRight, ruleColor, ruleStyle, 0, 0);
   2362         }
   2363 
   2364         ruleLogicalLeft = currLogicalLeftOffset;
   2365     }
   2366 }
   2367 
   2368 void RenderBlock::paintColumnContents(PaintInfo& paintInfo, int tx, int ty, bool paintingFloats)
   2369 {
   2370     // We need to do multiple passes, breaking up our child painting into strips.
   2371     GraphicsContext* context = paintInfo.context;
   2372     ColumnInfo* colInfo = columnInfo();
   2373     unsigned colCount = columnCount(colInfo);
   2374     if (!colCount)
   2375         return;
   2376     int currLogicalTopOffset = 0;
   2377     for (unsigned i = 0; i < colCount; i++) {
   2378         // For each rect, we clip to the rect, and then we adjust our coords.
   2379         IntRect colRect = columnRectAt(colInfo, i);
   2380         flipForWritingMode(colRect);
   2381         int logicalLeftOffset = (isHorizontalWritingMode() ? colRect.x() : colRect.y()) - logicalLeftOffsetForContent();
   2382         IntSize offset = isHorizontalWritingMode() ? IntSize(logicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, logicalLeftOffset);
   2383         colRect.move(tx, ty);
   2384         PaintInfo info(paintInfo);
   2385         info.rect.intersect(colRect);
   2386 
   2387         if (!info.rect.isEmpty()) {
   2388             context->save();
   2389 
   2390             // Each strip pushes a clip, since column boxes are specified as being
   2391             // like overflow:hidden.
   2392             context->clip(colRect);
   2393 
   2394             // Adjust our x and y when painting.
   2395             int finalX = tx + offset.width();
   2396             int finalY = ty + offset.height();
   2397             if (paintingFloats)
   2398                 paintFloats(info, finalX, finalY, paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip);
   2399             else
   2400                 paintContents(info, finalX, finalY);
   2401 
   2402             context->restore();
   2403         }
   2404 
   2405         int blockDelta = (isHorizontalWritingMode() ? colRect.height() : colRect.width());
   2406         if (style()->isFlippedBlocksWritingMode())
   2407             currLogicalTopOffset += blockDelta;
   2408         else
   2409             currLogicalTopOffset -= blockDelta;
   2410     }
   2411 }
   2412 
   2413 void RenderBlock::paintContents(PaintInfo& paintInfo, int tx, int ty)
   2414 {
   2415     // Avoid painting descendants of the root element when stylesheets haven't loaded.  This eliminates FOUC.
   2416     // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
   2417     // will do a full repaint().
   2418     if (document()->didLayoutWithPendingStylesheets() && !isRenderView())
   2419         return;
   2420 
   2421     if (childrenInline())
   2422         m_lineBoxes.paint(this, paintInfo, tx, ty);
   2423     else
   2424         paintChildren(paintInfo, tx, ty);
   2425 }
   2426 
   2427 void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
   2428 {
   2429     PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase;
   2430     newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase;
   2431 
   2432     // We don't paint our own background, but we do let the kids paint their backgrounds.
   2433     PaintInfo info(paintInfo);
   2434     info.phase = newPhase;
   2435     info.updatePaintingRootForChildren(this);
   2436 
   2437     // FIXME: Paint-time pagination is obsolete and is now only used by embedded WebViews inside AppKit
   2438     // NSViews.  Do not add any more code for this.
   2439     RenderView* renderView = view();
   2440     bool usePrintRect = !renderView->printRect().isEmpty();
   2441 
   2442     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
   2443         // Check for page-break-before: always, and if it's set, break and bail.
   2444         bool checkBeforeAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakBefore() == PBALWAYS);
   2445         if (checkBeforeAlways
   2446             && (ty + child->y()) > paintInfo.rect.y()
   2447             && (ty + child->y()) < paintInfo.rect.maxY()) {
   2448             view()->setBestTruncatedAt(ty + child->y(), this, true);
   2449             return;
   2450         }
   2451 
   2452         if (!child->isFloating() && child->isReplaced() && usePrintRect && child->height() <= renderView->printRect().height()) {
   2453             // Paginate block-level replaced elements.
   2454             if (ty + child->y() + child->height() > renderView->printRect().maxY()) {
   2455                 if (ty + child->y() < renderView->truncatedAt())
   2456                     renderView->setBestTruncatedAt(ty + child->y(), child);
   2457                 // If we were able to truncate, don't paint.
   2458                 if (ty + child->y() >= renderView->truncatedAt())
   2459                     break;
   2460             }
   2461         }
   2462 
   2463         IntPoint childPoint = flipForWritingMode(child, IntPoint(tx, ty), ParentToChildFlippingAdjustment);
   2464         if (!child->hasSelfPaintingLayer() && !child->isFloating())
   2465             child->paint(info, childPoint.x(), childPoint.y());
   2466 
   2467         // Check for page-break-after: always, and if it's set, break and bail.
   2468         bool checkAfterAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakAfter() == PBALWAYS);
   2469         if (checkAfterAlways
   2470             && (ty + child->y() + child->height()) > paintInfo.rect.y()
   2471             && (ty + child->y() + child->height()) < paintInfo.rect.maxY()) {
   2472             view()->setBestTruncatedAt(ty + child->y() + child->height() + max(0, child->collapsedMarginAfter()), this, true);
   2473             return;
   2474         }
   2475     }
   2476 }
   2477 
   2478 void RenderBlock::paintCaret(PaintInfo& paintInfo, int tx, int ty, CaretType type)
   2479 {
   2480     SelectionController* selection = type == CursorCaret ? frame()->selection() : frame()->page()->dragCaretController();
   2481 
   2482     // Paint the caret if the SelectionController says so or if caret browsing is enabled
   2483     bool caretBrowsing = frame()->settings() && frame()->settings()->caretBrowsingEnabled();
   2484     RenderObject* caretPainter = selection->caretRenderer();
   2485     if (caretPainter == this && (selection->isContentEditable() || caretBrowsing)) {
   2486         // Convert the painting offset into the local coordinate system of this renderer,
   2487         // to match the localCaretRect computed by the SelectionController
   2488         offsetForContents(tx, ty);
   2489 
   2490         if (type == CursorCaret)
   2491             frame()->selection()->paintCaret(paintInfo.context, tx, ty, paintInfo.rect);
   2492         else
   2493             frame()->selection()->paintDragCaret(paintInfo.context, tx, ty, paintInfo.rect);
   2494     }
   2495 }
   2496 
   2497 void RenderBlock::paintObject(PaintInfo& paintInfo, int tx, int ty)
   2498 {
   2499     PaintPhase paintPhase = paintInfo.phase;
   2500 
   2501     // 1. paint background, borders etc
   2502     if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground
   2503 #if PLATFORM(ANDROID)
   2504          || paintPhase == PaintPhaseBlockBackgroundDecorations
   2505 #endif
   2506         ) && style()->visibility() == VISIBLE) {
   2507         if (hasBoxDecorations())
   2508             paintBoxDecorations(paintInfo, tx, ty);
   2509         if (hasColumns())
   2510             paintColumnRules(paintInfo, tx, ty);
   2511     }
   2512 
   2513     if (paintPhase == PaintPhaseMask && style()->visibility() == VISIBLE) {
   2514         paintMask(paintInfo, tx, ty);
   2515         return;
   2516     }
   2517 
   2518     // We're done.  We don't bother painting any children.
   2519     if (paintPhase == PaintPhaseBlockBackground)
   2520         return;
   2521 
   2522     // Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div).
   2523     int scrolledX = tx;
   2524     int scrolledY = ty;
   2525     if (hasOverflowClip()) {
   2526         IntSize offset = layer()->scrolledContentOffset();
   2527         scrolledX -= offset.width();
   2528         scrolledY -= offset.height();
   2529     }
   2530 
   2531     // 2. paint contents
   2532     if (paintPhase != PaintPhaseSelfOutline) {
   2533         if (hasColumns())
   2534             paintColumnContents(paintInfo, scrolledX, scrolledY);
   2535         else
   2536             paintContents(paintInfo, scrolledX, scrolledY);
   2537     }
   2538 
   2539     // 3. paint selection
   2540     // FIXME: Make this work with multi column layouts.  For now don't fill gaps.
   2541     bool isPrinting = document()->printing();
   2542     if (!isPrinting && !hasColumns())
   2543         paintSelection(paintInfo, scrolledX, scrolledY); // Fill in gaps in selection on lines and between blocks.
   2544 
   2545     // 4. paint floats.
   2546     if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip) {
   2547         if (hasColumns())
   2548             paintColumnContents(paintInfo, scrolledX, scrolledY, true);
   2549         else
   2550             paintFloats(paintInfo, scrolledX, scrolledY, paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip);
   2551     }
   2552 
   2553     // 5. paint outline.
   2554     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
   2555         paintOutline(paintInfo.context, tx, ty, width(), height());
   2556 
   2557     // 6. paint continuation outlines.
   2558     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) {
   2559         RenderInline* inlineCont = inlineElementContinuation();
   2560         if (inlineCont && inlineCont->hasOutline() && inlineCont->style()->visibility() == VISIBLE) {
   2561             RenderInline* inlineRenderer = toRenderInline(inlineCont->node()->renderer());
   2562             RenderBlock* cb = containingBlock();
   2563 
   2564             bool inlineEnclosedInSelfPaintingLayer = false;
   2565             for (RenderBoxModelObject* box = inlineRenderer; box != cb; box = box->parent()->enclosingBoxModelObject()) {
   2566                 if (box->hasSelfPaintingLayer()) {
   2567                     inlineEnclosedInSelfPaintingLayer = true;
   2568                     break;
   2569                 }
   2570             }
   2571 
   2572             if (!inlineEnclosedInSelfPaintingLayer)
   2573                 cb->addContinuationWithOutline(inlineRenderer);
   2574             else if (!inlineRenderer->firstLineBox())
   2575                 inlineRenderer->paintOutline(paintInfo.context, tx - x() + inlineRenderer->containingBlock()->x(),
   2576                                              ty - y() + inlineRenderer->containingBlock()->y());
   2577         }
   2578         paintContinuationOutlines(paintInfo, tx, ty);
   2579     }
   2580 
   2581     // 7. paint caret.
   2582     // If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground,
   2583     // then paint the caret.
   2584     if (paintPhase == PaintPhaseForeground) {
   2585         paintCaret(paintInfo, scrolledX, scrolledY, CursorCaret);
   2586         paintCaret(paintInfo, scrolledX, scrolledY, DragCaret);
   2587     }
   2588 }
   2589 
   2590 IntPoint RenderBlock::flipFloatForWritingMode(const FloatingObject* child, const IntPoint& point) const
   2591 {
   2592     if (!style()->isFlippedBlocksWritingMode())
   2593         return point;
   2594 
   2595     // This is similar to the ParentToChildFlippingAdjustment in RenderBox::flipForWritingMode.  We have to subtract out our left/top offsets twice, since
   2596     // it's going to get added back in.  We hide this complication here so that the calling code looks normal for the unflipped
   2597     // case.
   2598     if (isHorizontalWritingMode())
   2599         return IntPoint(point.x(), point.y() + height() - child->renderer()->height() - 2 * yPositionForFloatIncludingMargin(child));
   2600     return IntPoint(point.x() + width() - child->width() - 2 * xPositionForFloatIncludingMargin(child), point.y());
   2601 }
   2602 
   2603 void RenderBlock::paintFloats(PaintInfo& paintInfo, int tx, int ty, bool preservePhase)
   2604 {
   2605     if (!m_floatingObjects)
   2606         return;
   2607 
   2608     FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   2609     FloatingObjectSetIterator end = floatingObjectSet.end();
   2610     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   2611         FloatingObject* r = *it;
   2612         // Only paint the object if our m_shouldPaint flag is set.
   2613         if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
   2614             PaintInfo currentPaintInfo(paintInfo);
   2615             currentPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
   2616             IntPoint childPoint = flipFloatForWritingMode(r, IntPoint(tx + xPositionForFloatIncludingMargin(r) - r->m_renderer->x(), ty + yPositionForFloatIncludingMargin(r) - r->m_renderer->y()));
   2617             r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
   2618             if (!preservePhase) {
   2619                 currentPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
   2620                 r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
   2621                 currentPaintInfo.phase = PaintPhaseFloat;
   2622                 r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
   2623                 currentPaintInfo.phase = PaintPhaseForeground;
   2624                 r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
   2625                 currentPaintInfo.phase = PaintPhaseOutline;
   2626                 r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
   2627             }
   2628         }
   2629     }
   2630 }
   2631 
   2632 void RenderBlock::paintEllipsisBoxes(PaintInfo& paintInfo, int tx, int ty)
   2633 {
   2634     if (!paintInfo.shouldPaintWithinRoot(this) || !firstLineBox())
   2635         return;
   2636 
   2637     if (style()->visibility() == VISIBLE && paintInfo.phase == PaintPhaseForeground) {
   2638         // We can check the first box and last box and avoid painting if we don't
   2639         // intersect.
   2640         int yPos = ty + firstLineBox()->y();
   2641         int h = lastLineBox()->y() + lastLineBox()->logicalHeight() - firstLineBox()->y();
   2642         if (yPos >= paintInfo.rect.maxY() || yPos + h <= paintInfo.rect.y())
   2643             return;
   2644 
   2645         // See if our boxes intersect with the dirty rect.  If so, then we paint
   2646         // them.  Note that boxes can easily overlap, so we can't make any assumptions
   2647         // based off positions of our first line box or our last line box.
   2648         for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
   2649             yPos = ty + curr->y();
   2650             h = curr->logicalHeight();
   2651             if (curr->ellipsisBox() && yPos < paintInfo.rect.maxY() && yPos + h > paintInfo.rect.y())
   2652                 curr->paintEllipsisBox(paintInfo, tx, ty, curr->lineTop(), curr->lineBottom());
   2653         }
   2654     }
   2655 }
   2656 
   2657 RenderInline* RenderBlock::inlineElementContinuation() const
   2658 {
   2659     RenderBoxModelObject* continuation = this->continuation();
   2660     return continuation && continuation->isInline() ? toRenderInline(continuation) : 0;
   2661 }
   2662 
   2663 RenderBlock* RenderBlock::blockElementContinuation() const
   2664 {
   2665     RenderBoxModelObject* currentContinuation = continuation();
   2666     if (!currentContinuation || currentContinuation->isInline())
   2667         return 0;
   2668     RenderBlock* nextContinuation = toRenderBlock(currentContinuation);
   2669     if (nextContinuation->isAnonymousBlock())
   2670         return nextContinuation->blockElementContinuation();
   2671     return nextContinuation;
   2672 }
   2673 
   2674 static ContinuationOutlineTableMap* continuationOutlineTable()
   2675 {
   2676     DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ());
   2677     return &table;
   2678 }
   2679 
   2680 void RenderBlock::addContinuationWithOutline(RenderInline* flow)
   2681 {
   2682     // We can't make this work if the inline is in a layer.  We'll just rely on the broken
   2683     // way of painting.
   2684     ASSERT(!flow->layer() && !flow->isInlineElementContinuation());
   2685 
   2686     ContinuationOutlineTableMap* table = continuationOutlineTable();
   2687     ListHashSet<RenderInline*>* continuations = table->get(this);
   2688     if (!continuations) {
   2689         continuations = new ListHashSet<RenderInline*>;
   2690         table->set(this, continuations);
   2691     }
   2692 
   2693     continuations->add(flow);
   2694 }
   2695 
   2696 bool RenderBlock::paintsContinuationOutline(RenderInline* flow)
   2697 {
   2698     ContinuationOutlineTableMap* table = continuationOutlineTable();
   2699     if (table->isEmpty())
   2700         return false;
   2701 
   2702     ListHashSet<RenderInline*>* continuations = table->get(this);
   2703     if (!continuations)
   2704         return false;
   2705 
   2706     return continuations->contains(flow);
   2707 }
   2708 
   2709 void RenderBlock::paintContinuationOutlines(PaintInfo& info, int tx, int ty)
   2710 {
   2711     ContinuationOutlineTableMap* table = continuationOutlineTable();
   2712     if (table->isEmpty())
   2713         return;
   2714 
   2715     ListHashSet<RenderInline*>* continuations = table->get(this);
   2716     if (!continuations)
   2717         return;
   2718 
   2719     // Paint each continuation outline.
   2720     ListHashSet<RenderInline*>::iterator end = continuations->end();
   2721     for (ListHashSet<RenderInline*>::iterator it = continuations->begin(); it != end; ++it) {
   2722         // Need to add in the coordinates of the intervening blocks.
   2723         RenderInline* flow = *it;
   2724         RenderBlock* block = flow->containingBlock();
   2725         for ( ; block && block != this; block = block->containingBlock()) {
   2726             tx += block->x();
   2727             ty += block->y();
   2728         }
   2729         ASSERT(block);
   2730         flow->paintOutline(info.context, tx, ty);
   2731     }
   2732 
   2733     // Delete
   2734     delete continuations;
   2735     table->remove(this);
   2736 }
   2737 
   2738 bool RenderBlock::shouldPaintSelectionGaps() const
   2739 {
   2740     return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot();
   2741 }
   2742 
   2743 bool RenderBlock::isSelectionRoot() const
   2744 {
   2745     if (!node())
   2746         return false;
   2747 
   2748     // FIXME: Eventually tables should have to learn how to fill gaps between cells, at least in simple non-spanning cases.
   2749     if (isTable())
   2750         return false;
   2751 
   2752     if (isBody() || isRoot() || hasOverflowClip() || isRelPositioned() ||
   2753         isFloatingOrPositioned() || isTableCell() || isInlineBlockOrInlineTable() || hasTransform() ||
   2754         hasReflection() || hasMask() || isWritingModeRoot())
   2755         return true;
   2756 
   2757     if (view() && view()->selectionStart()) {
   2758         Node* startElement = view()->selectionStart()->node();
   2759         if (startElement && startElement->rootEditableElement() == node())
   2760             return true;
   2761     }
   2762 
   2763     return false;
   2764 }
   2765 
   2766 GapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer)
   2767 {
   2768     ASSERT(!needsLayout());
   2769 
   2770     if (!shouldPaintSelectionGaps())
   2771         return GapRects();
   2772 
   2773     // FIXME: this is broken with transforms
   2774     TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
   2775     mapLocalToContainer(repaintContainer, false, false, transformState);
   2776     IntPoint offsetFromRepaintContainer = roundedIntPoint(transformState.mappedPoint());
   2777 
   2778     if (hasOverflowClip())
   2779         offsetFromRepaintContainer -= layer()->scrolledContentOffset();
   2780 
   2781     int lastTop = 0;
   2782     int lastLeft = logicalLeftSelectionOffset(this, lastTop);
   2783     int lastRight = logicalRightSelectionOffset(this, lastTop);
   2784 
   2785     return selectionGaps(this, offsetFromRepaintContainer, IntSize(), lastTop, lastLeft, lastRight);
   2786 }
   2787 
   2788 void RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty)
   2789 {
   2790     if (shouldPaintSelectionGaps() && paintInfo.phase == PaintPhaseForeground) {
   2791         int lastTop = 0;
   2792         int lastLeft = logicalLeftSelectionOffset(this, lastTop);
   2793         int lastRight = logicalRightSelectionOffset(this, lastTop);
   2794         paintInfo.context->save();
   2795         IntRect gapRectsBounds = selectionGaps(this, IntPoint(tx, ty), IntSize(), lastTop, lastLeft, lastRight, &paintInfo);
   2796         if (!gapRectsBounds.isEmpty()) {
   2797             if (RenderLayer* layer = enclosingLayer()) {
   2798                 gapRectsBounds.move(IntSize(-tx, -ty));
   2799                 if (!hasLayer()) {
   2800                     IntRect localBounds(gapRectsBounds);
   2801                     flipForWritingMode(localBounds);
   2802                     gapRectsBounds = localToContainerQuad(FloatRect(localBounds), layer->renderer()).enclosingBoundingBox();
   2803                     gapRectsBounds.move(layer->scrolledContentOffset());
   2804                 }
   2805                 layer->addBlockSelectionGapsBounds(gapRectsBounds);
   2806             }
   2807         }
   2808         paintInfo.context->restore();
   2809     }
   2810 }
   2811 
   2812 static void clipOutPositionedObjects(const PaintInfo* paintInfo, const IntPoint& offset, RenderBlock::PositionedObjectsListHashSet* positionedObjects)
   2813 {
   2814     if (!positionedObjects)
   2815         return;
   2816 
   2817     RenderBlock::PositionedObjectsListHashSet::const_iterator end = positionedObjects->end();
   2818     for (RenderBlock::PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
   2819         RenderBox* r = *it;
   2820         paintInfo->context->clipOut(IntRect(offset.x() + r->x(), offset.y() + r->y(), r->width(), r->height()));
   2821     }
   2822 }
   2823 
   2824 static int blockDirectionOffset(RenderBlock* rootBlock, const IntSize& offsetFromRootBlock)
   2825 {
   2826     return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.height() : offsetFromRootBlock.width();
   2827 }
   2828 
   2829 static int inlineDirectionOffset(RenderBlock* rootBlock, const IntSize& offsetFromRootBlock)
   2830 {
   2831     return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.width() : offsetFromRootBlock.height();
   2832 }
   2833 
   2834 IntRect RenderBlock::logicalRectToPhysicalRect(const IntPoint& rootBlockPhysicalPosition, const IntRect& logicalRect)
   2835 {
   2836     IntRect result;
   2837     if (isHorizontalWritingMode())
   2838         result = logicalRect;
   2839     else
   2840         result = IntRect(logicalRect.y(), logicalRect.x(), logicalRect.height(), logicalRect.width());
   2841     flipForWritingMode(result);
   2842     result.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
   2843     return result;
   2844 }
   2845 
   2846 GapRects RenderBlock::selectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
   2847                                     int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo)
   2848 {
   2849     // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore.
   2850     // Clip out floating and positioned objects when painting selection gaps.
   2851     if (paintInfo) {
   2852         // Note that we don't clip out overflow for positioned objects.  We just stick to the border box.
   2853         IntRect flippedBlockRect = IntRect(offsetFromRootBlock.width(), offsetFromRootBlock.height(), width(), height());
   2854         rootBlock->flipForWritingMode(flippedBlockRect);
   2855         flippedBlockRect.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
   2856         clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), m_positionedObjects.get());
   2857         if (isBody() || isRoot()) // The <body> must make sure to examine its containingBlock's positioned objects.
   2858             for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock())
   2859                 clipOutPositionedObjects(paintInfo, IntPoint(cb->x(), cb->y()), cb->m_positionedObjects.get()); // FIXME: Not right for flipped writing modes.
   2860         if (m_floatingObjects) {
   2861             FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   2862             FloatingObjectSetIterator end = floatingObjectSet.end();
   2863             for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   2864                 FloatingObject* r = *it;
   2865                 IntRect floatBox = IntRect(offsetFromRootBlock.width() + xPositionForFloatIncludingMargin(r),
   2866                                            offsetFromRootBlock.height() + yPositionForFloatIncludingMargin(r),
   2867                                            r->m_renderer->width(), r->m_renderer->height());
   2868                 rootBlock->flipForWritingMode(floatBox);
   2869                 floatBox.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
   2870                 paintInfo->context->clipOut(floatBox);
   2871             }
   2872         }
   2873     }
   2874 
   2875     // 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
   2876     // fixed).
   2877     GapRects result;
   2878     if (!isBlockFlow()) // FIXME: Make multi-column selection gap filling work someday.
   2879         return result;
   2880 
   2881     if (hasColumns() || hasTransform() || style()->columnSpan()) {
   2882         // FIXME: We should learn how to gap fill multiple columns and transforms eventually.
   2883         lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
   2884         lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight());
   2885         lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight());
   2886         return result;
   2887     }
   2888 
   2889     if (childrenInline())
   2890         result = inlineSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
   2891     else
   2892         result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
   2893 
   2894     // Go ahead and fill the vertical gap all the way to the bottom of our block if the selection extends past our block.
   2895     if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd))
   2896         result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
   2897                                              logicalHeight(), paintInfo));
   2898     return result;
   2899 }
   2900 
   2901 GapRects RenderBlock::inlineSelectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
   2902                                           int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo)
   2903 {
   2904     GapRects result;
   2905 
   2906     bool containsStart = selectionState() == SelectionStart || selectionState() == SelectionBoth;
   2907 
   2908     if (!firstLineBox()) {
   2909         if (containsStart) {
   2910             // Go ahead and update our lastLogicalTop to be the bottom of the block.  <hr>s or empty blocks with height can trip this
   2911             // case.
   2912             lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
   2913             lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight());
   2914             lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight());
   2915         }
   2916         return result;
   2917     }
   2918 
   2919     RootInlineBox* lastSelectedLine = 0;
   2920     RootInlineBox* curr;
   2921     for (curr = firstRootBox(); curr && !curr->hasSelectedChildren(); curr = curr->nextRootBox()) { }
   2922 
   2923     // Now paint the gaps for the lines.
   2924     for (; curr && curr->hasSelectedChildren(); curr = curr->nextRootBox()) {
   2925         int selTop =  curr->selectionTop();
   2926         int selHeight = curr->selectionHeight();
   2927 
   2928         if (!containsStart && !lastSelectedLine &&
   2929             selectionState() != SelectionStart && selectionState() != SelectionBoth)
   2930             result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
   2931                                                  selTop, paintInfo));
   2932 
   2933         IntRect logicalRect(curr->logicalLeft(), selTop, curr->logicalWidth(), selTop + selHeight);
   2934         logicalRect.move(isHorizontalWritingMode() ? offsetFromRootBlock : IntSize(offsetFromRootBlock.height(), offsetFromRootBlock.width()));
   2935         IntRect physicalRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect);
   2936         if (!paintInfo || (isHorizontalWritingMode() && physicalRect.y() < paintInfo->rect.maxY() && physicalRect.maxY() > paintInfo->rect.y())
   2937             || (!isHorizontalWritingMode() && physicalRect.x() < paintInfo->rect.maxX() && physicalRect.maxX() > paintInfo->rect.x()))
   2938             result.unite(curr->lineSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, selTop, selHeight, paintInfo));
   2939 
   2940         lastSelectedLine = curr;
   2941     }
   2942 
   2943     if (containsStart && !lastSelectedLine)
   2944         // VisibleSelection must start just after our last line.
   2945         lastSelectedLine = lastRootBox();
   2946 
   2947     if (lastSelectedLine && selectionState() != SelectionEnd && selectionState() != SelectionBoth) {
   2948         // Go ahead and update our lastY to be the bottom of the last selected line.
   2949         lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + lastSelectedLine->selectionBottom();
   2950         lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
   2951         lastLogicalRight = logicalRightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
   2952     }
   2953     return result;
   2954 }
   2955 
   2956 GapRects RenderBlock::blockSelectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
   2957                                          int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo)
   2958 {
   2959     GapRects result;
   2960 
   2961     // Go ahead and jump right to the first block child that contains some selected objects.
   2962     RenderBox* curr;
   2963     for (curr = firstChildBox(); curr && curr->selectionState() == SelectionNone; curr = curr->nextSiblingBox()) { }
   2964 
   2965     for (bool sawSelectionEnd = false; curr && !sawSelectionEnd; curr = curr->nextSiblingBox()) {
   2966         SelectionState childState = curr->selectionState();
   2967         if (childState == SelectionBoth || childState == SelectionEnd)
   2968             sawSelectionEnd = true;
   2969 
   2970         if (curr->isFloatingOrPositioned())
   2971             continue; // We must be a normal flow object in order to even be considered.
   2972 
   2973         if (curr->isRelPositioned() && curr->hasLayer()) {
   2974             // If the relposition offset is anything other than 0, then treat this just like an absolute positioned element.
   2975             // Just disregard it completely.
   2976             IntSize relOffset = curr->layer()->relativePositionOffset();
   2977             if (relOffset.width() || relOffset.height())
   2978                 continue;
   2979         }
   2980 
   2981         bool paintsOwnSelection = curr->shouldPaintSelectionGaps() || curr->isTable(); // FIXME: Eventually we won't special-case table like this.
   2982         bool fillBlockGaps = paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone);
   2983         if (fillBlockGaps) {
   2984             // We need to fill the vertical gap above this object.
   2985             if (childState == SelectionEnd || childState == SelectionInside)
   2986                 // Fill the gap above the object.
   2987                 result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
   2988                                                      curr->logicalTop(), paintInfo));
   2989 
   2990             // 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*
   2991             // our object.  We know this if the selection did not end inside our object.
   2992             if (paintsOwnSelection && (childState == SelectionStart || sawSelectionEnd))
   2993                 childState = SelectionNone;
   2994 
   2995             // Fill side gaps on this object based off its state.
   2996             bool leftGap, rightGap;
   2997             getSelectionGapInfo(childState, leftGap, rightGap);
   2998 
   2999             if (leftGap)
   3000                 result.uniteLeft(logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalLeft(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
   3001             if (rightGap)
   3002                 result.uniteRight(logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalRight(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
   3003 
   3004             // Update lastLogicalTop to be just underneath the object.  lastLogicalLeft and lastLogicalRight extend as far as
   3005             // they can without bumping into floating or positioned objects.  Ideally they will go right up
   3006             // to the border of the root selection block.
   3007             lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + curr->logicalBottom();
   3008             lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, curr->logicalBottom());
   3009             lastLogicalRight = logicalRightSelectionOffset(rootBlock, curr->logicalBottom());
   3010         } else if (childState != SelectionNone)
   3011             // We must be a block that has some selected object inside it.  Go ahead and recur.
   3012             result.unite(toRenderBlock(curr)->selectionGaps(rootBlock, rootBlockPhysicalPosition, IntSize(offsetFromRootBlock.width() + curr->x(), offsetFromRootBlock.height() + curr->y()),
   3013                                                             lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo));
   3014     }
   3015     return result;
   3016 }
   3017 
   3018 IntRect RenderBlock::blockSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
   3019                                        int lastLogicalTop, int lastLogicalLeft, int lastLogicalRight, int logicalBottom, const PaintInfo* paintInfo)
   3020 {
   3021     int logicalTop = lastLogicalTop;
   3022     int logicalHeight = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalBottom - logicalTop;
   3023     if (logicalHeight <= 0)
   3024         return IntRect();
   3025 
   3026     // Get the selection offsets for the bottom of the gap
   3027     int logicalLeft = max(lastLogicalLeft, logicalLeftSelectionOffset(rootBlock, logicalBottom));
   3028     int logicalRight = min(lastLogicalRight, logicalRightSelectionOffset(rootBlock, logicalBottom));
   3029     int logicalWidth = logicalRight - logicalLeft;
   3030     if (logicalWidth <= 0)
   3031         return IntRect();
   3032 
   3033     IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(logicalLeft, logicalTop, logicalWidth, logicalHeight));
   3034     if (paintInfo)
   3035         paintInfo->context->fillRect(gapRect, selectionBackgroundColor(), style()->colorSpace());
   3036     return gapRect;
   3037 }
   3038 
   3039 IntRect RenderBlock::logicalLeftSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
   3040                                              RenderObject* selObj, int logicalLeft, int logicalTop, int logicalHeight, const PaintInfo* paintInfo)
   3041 {
   3042     int rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
   3043     int rootBlockLogicalLeft = max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight));
   3044     int rootBlockLogicalRight = min(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalLeft, min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight)));
   3045     int rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
   3046     if (rootBlockLogicalWidth <= 0)
   3047         return IntRect();
   3048 
   3049     IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
   3050     if (paintInfo)
   3051         paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
   3052     return gapRect;
   3053 }
   3054 
   3055 IntRect RenderBlock::logicalRightSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
   3056                                               RenderObject* selObj, int logicalRight, int logicalTop, int logicalHeight, const PaintInfo* paintInfo)
   3057 {
   3058     int rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
   3059     int rootBlockLogicalLeft = max(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalRight, max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight)));
   3060     int rootBlockLogicalRight = min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight));
   3061     int rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
   3062     if (rootBlockLogicalWidth <= 0)
   3063         return IntRect();
   3064 
   3065     IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
   3066     if (paintInfo)
   3067         paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
   3068     return gapRect;
   3069 }
   3070 
   3071 void RenderBlock::getSelectionGapInfo(SelectionState state, bool& leftGap, bool& rightGap)
   3072 {
   3073     bool ltr = style()->isLeftToRightDirection();
   3074     leftGap = (state == RenderObject::SelectionInside) ||
   3075               (state == RenderObject::SelectionEnd && ltr) ||
   3076               (state == RenderObject::SelectionStart && !ltr);
   3077     rightGap = (state == RenderObject::SelectionInside) ||
   3078                (state == RenderObject::SelectionStart && ltr) ||
   3079                (state == RenderObject::SelectionEnd && !ltr);
   3080 }
   3081 
   3082 int RenderBlock::logicalLeftSelectionOffset(RenderBlock* rootBlock, int position)
   3083 {
   3084     int logicalLeft = logicalLeftOffsetForLine(position, false);
   3085     if (logicalLeft == logicalLeftOffsetForContent()) {
   3086         if (rootBlock != this)
   3087             // The border can potentially be further extended by our containingBlock().
   3088             return containingBlock()->logicalLeftSelectionOffset(rootBlock, position + logicalTop());
   3089         return logicalLeft;
   3090     } else {
   3091         RenderBlock* cb = this;
   3092         while (cb != rootBlock) {
   3093             logicalLeft += cb->logicalLeft();
   3094             cb = cb->containingBlock();
   3095         }
   3096     }
   3097     return logicalLeft;
   3098 }
   3099 
   3100 int RenderBlock::logicalRightSelectionOffset(RenderBlock* rootBlock, int position)
   3101 {
   3102     int logicalRight = logicalRightOffsetForLine(position, false);
   3103     if (logicalRight == logicalRightOffsetForContent()) {
   3104         if (rootBlock != this)
   3105             // The border can potentially be further extended by our containingBlock().
   3106             return containingBlock()->logicalRightSelectionOffset(rootBlock, position + logicalTop());
   3107         return logicalRight;
   3108     } else {
   3109         RenderBlock* cb = this;
   3110         while (cb != rootBlock) {
   3111             logicalRight += cb->logicalLeft();
   3112             cb = cb->containingBlock();
   3113         }
   3114     }
   3115     return logicalRight;
   3116 }
   3117 
   3118 void RenderBlock::insertPositionedObject(RenderBox* o)
   3119 {
   3120     // Create the list of special objects if we don't aleady have one
   3121     if (!m_positionedObjects)
   3122         m_positionedObjects = adoptPtr(new PositionedObjectsListHashSet);
   3123 
   3124     m_positionedObjects->add(o);
   3125 }
   3126 
   3127 void RenderBlock::removePositionedObject(RenderBox* o)
   3128 {
   3129     if (m_positionedObjects)
   3130         m_positionedObjects->remove(o);
   3131 }
   3132 
   3133 void RenderBlock::removePositionedObjects(RenderBlock* o)
   3134 {
   3135     if (!m_positionedObjects)
   3136         return;
   3137 
   3138     RenderBox* r;
   3139 
   3140     Iterator end = m_positionedObjects->end();
   3141 
   3142     Vector<RenderBox*, 16> deadObjects;
   3143 
   3144     for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
   3145         r = *it;
   3146         if (!o || r->isDescendantOf(o)) {
   3147             if (o)
   3148                 r->setChildNeedsLayout(true, false);
   3149 
   3150             // It is parent blocks job to add positioned child to positioned objects list of its containing block
   3151             // Parent layout needs to be invalidated to ensure this happens.
   3152             RenderObject* p = r->parent();
   3153             while (p && !p->isRenderBlock())
   3154                 p = p->parent();
   3155             if (p)
   3156                 p->setChildNeedsLayout(true);
   3157 
   3158             deadObjects.append(r);
   3159         }
   3160     }
   3161 
   3162     for (unsigned i = 0; i < deadObjects.size(); i++)
   3163         m_positionedObjects->remove(deadObjects.at(i));
   3164 }
   3165 
   3166 RenderBlock::FloatingObject* RenderBlock::insertFloatingObject(RenderBox* o)
   3167 {
   3168     ASSERT(o->isFloating());
   3169 
   3170     // Create the list of special objects if we don't aleady have one
   3171     if (!m_floatingObjects)
   3172         m_floatingObjects = adoptPtr(new FloatingObjects);
   3173     else {
   3174         // Don't insert the object again if it's already in the list
   3175         FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3176         FloatingObjectSetIterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(o);
   3177         if (it != floatingObjectSet.end())
   3178             return *it;
   3179     }
   3180 
   3181     // Create the special object entry & append it to the list
   3182 
   3183     FloatingObject* newObj = new FloatingObject(o->style()->floating() == FLEFT ? FloatingObject::FloatLeft : FloatingObject::FloatRight);
   3184 
   3185     // Our location is irrelevant if we're unsplittable or no pagination is in effect.
   3186     // Just go ahead and lay out the float.
   3187     bool isChildRenderBlock = o->isRenderBlock();
   3188     if (isChildRenderBlock && !o->needsLayout() && view()->layoutState()->pageLogicalHeightChanged())
   3189         o->setChildNeedsLayout(true, false);
   3190 
   3191     bool affectedByPagination = isChildRenderBlock && view()->layoutState()->m_pageLogicalHeight;
   3192     if (!affectedByPagination || isWritingModeRoot()) // We are unsplittable if we're a block flow root.
   3193         o->layoutIfNeeded();
   3194     else {
   3195         o->computeLogicalWidth();
   3196         o->computeBlockDirectionMargins(this);
   3197     }
   3198     setLogicalWidthForFloat(newObj, logicalWidthForChild(o) + marginStartForChild(o) + marginEndForChild(o));
   3199 
   3200     newObj->m_shouldPaint = !o->hasSelfPaintingLayer(); // If a layer exists, the float will paint itself.  Otherwise someone else will.
   3201     newObj->m_isDescendant = true;
   3202     newObj->m_renderer = o;
   3203 
   3204     m_floatingObjects->increaseObjectsCount(newObj->type());
   3205     m_floatingObjects->set().add(newObj);
   3206 
   3207     return newObj;
   3208 }
   3209 
   3210 void RenderBlock::removeFloatingObject(RenderBox* o)
   3211 {
   3212     if (m_floatingObjects) {
   3213         FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3214         FloatingObjectSet::iterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(o);
   3215         if (it != floatingObjectSet.end()) {
   3216             FloatingObject* r = *it;
   3217             if (childrenInline()) {
   3218                 int logicalTop = logicalTopForFloat(r);
   3219                 int logicalBottom = logicalBottomForFloat(r);
   3220 
   3221                 // Fix for https://bugs.webkit.org/show_bug.cgi?id=54995.
   3222                 if (logicalBottom < 0 || logicalBottom < logicalTop || logicalTop == numeric_limits<int>::max())
   3223                     logicalBottom = numeric_limits<int>::max();
   3224                 else {
   3225                     // Special-case zero- and less-than-zero-height floats: those don't touch
   3226                     // the line that they're on, but it still needs to be dirtied. This is
   3227                     // accomplished by pretending they have a height of 1.
   3228                     logicalBottom = max(logicalBottom, logicalTop + 1);
   3229                 }
   3230                 if (r->m_originatingLine) {
   3231                     ASSERT(r->m_originatingLine->renderer() == this);
   3232                     r->m_originatingLine->markDirty();
   3233 #if !ASSERT_DISABLED
   3234                     r->m_originatingLine = 0;
   3235 #endif
   3236                 }
   3237                 markLinesDirtyInBlockRange(0, logicalBottom);
   3238             }
   3239             m_floatingObjects->decreaseObjectsCount(r->type());
   3240             floatingObjectSet.remove(it);
   3241             ASSERT(!r->m_originatingLine);
   3242             delete r;
   3243         }
   3244     }
   3245 }
   3246 
   3247 void RenderBlock::removeFloatingObjectsBelow(FloatingObject* lastFloat, int logicalOffset)
   3248 {
   3249     if (!m_floatingObjects)
   3250         return;
   3251 
   3252     FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3253     FloatingObject* curr = floatingObjectSet.last();
   3254     while (curr != lastFloat && (!curr->isPlaced() || logicalTopForFloat(curr) >= logicalOffset)) {
   3255         m_floatingObjects->decreaseObjectsCount(curr->type());
   3256         floatingObjectSet.removeLast();
   3257         ASSERT(!curr->m_originatingLine);
   3258         delete curr;
   3259         curr = floatingObjectSet.last();
   3260     }
   3261 }
   3262 
   3263 bool RenderBlock::positionNewFloats()
   3264 {
   3265     if (!m_floatingObjects)
   3266         return false;
   3267 
   3268     FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3269     if (floatingObjectSet.isEmpty())
   3270         return false;
   3271 
   3272     // If all floats have already been positioned, then we have no work to do.
   3273     if (floatingObjectSet.last()->isPlaced())
   3274         return false;
   3275 
   3276     // Move backwards through our floating object list until we find a float that has
   3277     // already been positioned.  Then we'll be able to move forward, positioning all of
   3278     // the new floats that need it.
   3279     FloatingObjectSetIterator it = floatingObjectSet.end();
   3280     --it; // Go to last item.
   3281     FloatingObjectSetIterator begin = floatingObjectSet.begin();
   3282     FloatingObject* lastPlacedFloatingObject = 0;
   3283     while (it != begin) {
   3284         --it;
   3285         if ((*it)->isPlaced()) {
   3286             lastPlacedFloatingObject = *it;
   3287             ++it;
   3288             break;
   3289         }
   3290     }
   3291 
   3292     int logicalTop = logicalHeight();
   3293 
   3294     // The float cannot start above the top position of the last positioned float.
   3295     if (lastPlacedFloatingObject)
   3296         logicalTop = max(logicalTopForFloat(lastPlacedFloatingObject), logicalTop);
   3297 
   3298     FloatingObjectSetIterator end = floatingObjectSet.end();
   3299     // Now walk through the set of unpositioned floats and place them.
   3300     for (; it != end; ++it) {
   3301          FloatingObject* floatingObject = *it;
   3302         // The containing block is responsible for positioning floats, so if we have floats in our
   3303         // list that come from somewhere else, do not attempt to position them.
   3304         if (floatingObject->renderer()->containingBlock() != this)
   3305             continue;
   3306 
   3307         RenderBox* childBox = floatingObject->renderer();
   3308         int childLogicalLeftMargin = style()->isLeftToRightDirection() ? marginStartForChild(childBox) : marginEndForChild(childBox);
   3309 
   3310         int rightOffset = logicalRightOffsetForContent(); // Constant part of right offset.
   3311         int leftOffset = logicalLeftOffsetForContent(); // Constant part of left offset.
   3312         int floatLogicalWidth = logicalWidthForFloat(floatingObject); // The width we look for.
   3313         if (rightOffset - leftOffset < floatLogicalWidth)
   3314             floatLogicalWidth = rightOffset - leftOffset; // Never look for more than what will be available.
   3315 
   3316         IntRect oldRect(childBox->x(), childBox->y() , childBox->width(), childBox->height());
   3317 
   3318         if (childBox->style()->clear() & CLEFT)
   3319             logicalTop = max(lowestFloatLogicalBottom(FloatingObject::FloatLeft), logicalTop);
   3320         if (childBox->style()->clear() & CRIGHT)
   3321             logicalTop = max(lowestFloatLogicalBottom(FloatingObject::FloatRight), logicalTop);
   3322 
   3323         int floatLogicalLeft;
   3324         if (childBox->style()->floating() == FLEFT) {
   3325             int heightRemainingLeft = 1;
   3326             int heightRemainingRight = 1;
   3327             floatLogicalLeft = logicalLeftOffsetForLine(logicalTop, leftOffset, false, &heightRemainingLeft);
   3328             while (logicalRightOffsetForLine(logicalTop, rightOffset, false, &heightRemainingRight) - floatLogicalLeft < floatLogicalWidth) {
   3329                 logicalTop += min(heightRemainingLeft, heightRemainingRight);
   3330                 floatLogicalLeft = logicalLeftOffsetForLine(logicalTop, leftOffset, false, &heightRemainingLeft);
   3331             }
   3332             floatLogicalLeft = max(0, floatLogicalLeft);
   3333         } else {
   3334             int heightRemainingLeft = 1;
   3335             int heightRemainingRight = 1;
   3336             floatLogicalLeft = logicalRightOffsetForLine(logicalTop, rightOffset, false, &heightRemainingRight);
   3337             while (floatLogicalLeft - logicalLeftOffsetForLine(logicalTop, leftOffset, false, &heightRemainingLeft) < floatLogicalWidth) {
   3338                 logicalTop += min(heightRemainingLeft, heightRemainingRight);
   3339                 floatLogicalLeft = logicalRightOffsetForLine(logicalTop, rightOffset, false, &heightRemainingRight);
   3340             }
   3341             floatLogicalLeft -= logicalWidthForFloat(floatingObject); // Use the original width of the float here, since the local variable
   3342                                                                       // |floatLogicalWidth| was capped to the available line width.
   3343                                                                       // See fast/block/float/clamped-right-float.html.
   3344         }
   3345 
   3346         setLogicalLeftForFloat(floatingObject, floatLogicalLeft);
   3347         setLogicalLeftForChild(childBox, floatLogicalLeft + childLogicalLeftMargin);
   3348         setLogicalTopForChild(childBox, logicalTop + marginBeforeForChild(childBox));
   3349 
   3350         if (view()->layoutState()->isPaginated()) {
   3351             RenderBlock* childBlock = childBox->isRenderBlock() ? toRenderBlock(childBox) : 0;
   3352 
   3353             if (!childBox->needsLayout())
   3354                 childBox->markForPaginationRelayoutIfNeeded();;
   3355             childBox->layoutIfNeeded();
   3356 
   3357             // If we are unsplittable and don't fit, then we need to move down.
   3358             // We include our margins as part of the unsplittable area.
   3359             int newLogicalTop = adjustForUnsplittableChild(childBox, logicalTop, true);
   3360 
   3361             // See if we have a pagination strut that is making us move down further.
   3362             // Note that an unsplittable child can't also have a pagination strut, so this is
   3363             // exclusive with the case above.
   3364             if (childBlock && childBlock->paginationStrut()) {
   3365                 newLogicalTop += childBlock->paginationStrut();
   3366                 childBlock->setPaginationStrut(0);
   3367             }
   3368 
   3369             if (newLogicalTop != logicalTop) {
   3370                 floatingObject->m_paginationStrut = newLogicalTop - logicalTop;
   3371                 logicalTop = newLogicalTop;
   3372                 setLogicalTopForChild(childBox, logicalTop + marginBeforeForChild(childBox));
   3373                 if (childBlock)
   3374                     childBlock->setChildNeedsLayout(true, false);
   3375                 childBox->layoutIfNeeded();
   3376             }
   3377         }
   3378 
   3379         setLogicalTopForFloat(floatingObject, logicalTop);
   3380         setLogicalHeightForFloat(floatingObject, logicalHeightForChild(childBox) + marginBeforeForChild(childBox) + marginAfterForChild(childBox));
   3381 
   3382         floatingObject->setIsPlaced();
   3383 
   3384         // If the child moved, we have to repaint it.
   3385         if (childBox->checkForRepaintDuringLayout())
   3386             childBox->repaintDuringLayoutIfMoved(oldRect);
   3387     }
   3388     return true;
   3389 }
   3390 
   3391 void RenderBlock::newLine(EClear clear)
   3392 {
   3393     positionNewFloats();
   3394     // set y position
   3395     int newY = 0;
   3396     switch (clear)
   3397     {
   3398         case CLEFT:
   3399             newY = lowestFloatLogicalBottom(FloatingObject::FloatLeft);
   3400             break;
   3401         case CRIGHT:
   3402             newY = lowestFloatLogicalBottom(FloatingObject::FloatRight);
   3403             break;
   3404         case CBOTH:
   3405             newY = lowestFloatLogicalBottom();
   3406         default:
   3407             break;
   3408     }
   3409     if (height() < newY)
   3410         setLogicalHeight(newY);
   3411 }
   3412 
   3413 void RenderBlock::addPercentHeightDescendant(RenderBox* descendant)
   3414 {
   3415     if (!gPercentHeightDescendantsMap) {
   3416         gPercentHeightDescendantsMap = new PercentHeightDescendantsMap;
   3417         gPercentHeightContainerMap = new PercentHeightContainerMap;
   3418     }
   3419 
   3420     HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(this);
   3421     if (!descendantSet) {
   3422         descendantSet = new HashSet<RenderBox*>;
   3423         gPercentHeightDescendantsMap->set(this, descendantSet);
   3424     }
   3425     bool added = descendantSet->add(descendant).second;
   3426     if (!added) {
   3427         ASSERT(gPercentHeightContainerMap->get(descendant));
   3428         ASSERT(gPercentHeightContainerMap->get(descendant)->contains(this));
   3429         return;
   3430     }
   3431 
   3432     HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->get(descendant);
   3433     if (!containerSet) {
   3434         containerSet = new HashSet<RenderBlock*>;
   3435         gPercentHeightContainerMap->set(descendant, containerSet);
   3436     }
   3437     ASSERT(!containerSet->contains(this));
   3438     containerSet->add(this);
   3439 }
   3440 
   3441 void RenderBlock::removePercentHeightDescendant(RenderBox* descendant)
   3442 {
   3443     if (!gPercentHeightContainerMap)
   3444         return;
   3445 
   3446     HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->take(descendant);
   3447     if (!containerSet)
   3448         return;
   3449 
   3450     HashSet<RenderBlock*>::iterator end = containerSet->end();
   3451     for (HashSet<RenderBlock*>::iterator it = containerSet->begin(); it != end; ++it) {
   3452         RenderBlock* container = *it;
   3453         HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(container);
   3454         ASSERT(descendantSet);
   3455         if (!descendantSet)
   3456             continue;
   3457         ASSERT(descendantSet->contains(descendant));
   3458         descendantSet->remove(descendant);
   3459         if (descendantSet->isEmpty()) {
   3460             gPercentHeightDescendantsMap->remove(container);
   3461             delete descendantSet;
   3462         }
   3463     }
   3464 
   3465     delete containerSet;
   3466 }
   3467 
   3468 HashSet<RenderBox*>* RenderBlock::percentHeightDescendants() const
   3469 {
   3470     return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0;
   3471 }
   3472 
   3473 // FIXME: The logicalLeftOffsetForLine/logicalRightOffsetForLine functions are very slow if there are many floats
   3474 // present. We need to add a structure to floating objects to represent "lines" of floats.  Then instead of checking
   3475 // each float individually, we'd just walk backwards through the "lines" and stop when we hit a line that is fully above
   3476 // the vertical offset that we'd like to check.  Computing the "lines" would be rather complicated, but could replace the left
   3477 // objects and right objects count hack that is currently used here.
   3478 int RenderBlock::logicalLeftOffsetForLine(int logicalTop, int fixedOffset, bool applyTextIndent, int* heightRemaining) const
   3479 {
   3480     int left = fixedOffset;
   3481     if (m_floatingObjects && m_floatingObjects->hasLeftObjects()) {
   3482         if (heightRemaining)
   3483             *heightRemaining = 1;
   3484 
   3485         // We know the list is non-empty, since we have "left" objects to search for.
   3486         // Therefore we can assume that begin != end, and that we can do at least one
   3487         // decrement.
   3488         FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3489         FloatingObjectSetIterator begin = floatingObjectSet.begin();
   3490         FloatingObjectSetIterator it = floatingObjectSet.end();
   3491         do {
   3492             --it;
   3493             FloatingObject* r = *it;
   3494             if (r->isPlaced() && logicalTopForFloat(r) <= logicalTop && logicalBottomForFloat(r) > logicalTop
   3495                 && r->type() == FloatingObject::FloatLeft
   3496                 && logicalRightForFloat(r) > left) {
   3497                 left = max(left, logicalRightForFloat(r));
   3498                 if (heightRemaining)
   3499                     *heightRemaining = logicalBottomForFloat(r) - logicalTop;
   3500             }
   3501         } while (it != begin);
   3502     }
   3503 
   3504     if (applyTextIndent && style()->isLeftToRightDirection()) {
   3505         int cw = 0;
   3506         if (style()->textIndent().isPercent())
   3507             cw = containingBlock()->availableLogicalWidth();
   3508         left += style()->textIndent().calcMinValue(cw);
   3509     }
   3510 
   3511     return left;
   3512 }
   3513 
   3514 int RenderBlock::logicalRightOffsetForLine(int logicalTop, int fixedOffset, bool applyTextIndent, int* heightRemaining) const
   3515 {
   3516     int right = fixedOffset;
   3517 
   3518     if (m_floatingObjects && m_floatingObjects->hasRightObjects()) {
   3519         if (heightRemaining)
   3520             *heightRemaining = 1;
   3521 
   3522         // We know the list is non-empty, since we have "right" objects to search for.
   3523         // Therefore we can assume that begin != end, and that we can do at least one
   3524         // decrement.
   3525         FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3526         FloatingObjectSetIterator begin = floatingObjectSet.begin();
   3527         FloatingObjectSetIterator it = floatingObjectSet.end();
   3528         do {
   3529             --it;
   3530             FloatingObject* r = *it;
   3531             if (r->isPlaced() && logicalTopForFloat(r) <= logicalTop && logicalBottomForFloat(r) > logicalTop
   3532                 && r->type() == FloatingObject::FloatRight
   3533                 && logicalLeftForFloat(r) < right) {
   3534                 right = min(right, logicalLeftForFloat(r));
   3535                 if (heightRemaining)
   3536                     *heightRemaining = logicalBottomForFloat(r) - logicalTop;
   3537             }
   3538         } while (it != begin);
   3539     }
   3540 
   3541     if (applyTextIndent && !style()->isLeftToRightDirection()) {
   3542         int cw = 0;
   3543         if (style()->textIndent().isPercent())
   3544             cw = containingBlock()->availableLogicalWidth();
   3545         right -= style()->textIndent().calcMinValue(cw);
   3546     }
   3547 
   3548     return right;
   3549 }
   3550 
   3551 int RenderBlock::availableLogicalWidthForLine(int position, bool firstLine) const
   3552 {
   3553     int result = logicalRightOffsetForLine(position, firstLine) - logicalLeftOffsetForLine(position, firstLine);
   3554     return (result < 0) ? 0 : result;
   3555 }
   3556 
   3557 int RenderBlock::nextFloatLogicalBottomBelow(int logicalHeight) const
   3558 {
   3559     if (!m_floatingObjects)
   3560         return 0;
   3561 
   3562     int bottom = INT_MAX;
   3563     FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3564     FloatingObjectSetIterator end = floatingObjectSet.end();
   3565     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   3566         FloatingObject* r = *it;
   3567         int floatBottom = logicalBottomForFloat(r);
   3568         if (floatBottom > logicalHeight)
   3569             bottom = min(floatBottom, bottom);
   3570     }
   3571 
   3572     return bottom == INT_MAX ? 0 : bottom;
   3573 }
   3574 
   3575 int RenderBlock::lowestFloatLogicalBottom(FloatingObject::Type floatType) const
   3576 {
   3577     if (!m_floatingObjects)
   3578         return 0;
   3579     int lowestFloatBottom = 0;
   3580     FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3581     FloatingObjectSetIterator end = floatingObjectSet.end();
   3582     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   3583         FloatingObject* r = *it;
   3584         if (r->isPlaced() && r->type() & floatType)
   3585             lowestFloatBottom = max(lowestFloatBottom, logicalBottomForFloat(r));
   3586     }
   3587     return lowestFloatBottom;
   3588 }
   3589 
   3590 void RenderBlock::markLinesDirtyInBlockRange(int logicalTop, int logicalBottom, RootInlineBox* highest)
   3591 {
   3592     if (logicalTop >= logicalBottom)
   3593         return;
   3594 
   3595     RootInlineBox* lowestDirtyLine = lastRootBox();
   3596     RootInlineBox* afterLowest = lowestDirtyLine;
   3597     while (lowestDirtyLine && lowestDirtyLine->blockLogicalHeight() >= logicalBottom && logicalBottom < numeric_limits<int>::max()) {
   3598         afterLowest = lowestDirtyLine;
   3599         lowestDirtyLine = lowestDirtyLine->prevRootBox();
   3600     }
   3601 
   3602     while (afterLowest && afterLowest != highest && (afterLowest->blockLogicalHeight() >= logicalTop || afterLowest->blockLogicalHeight() < 0)) {
   3603         afterLowest->markDirty();
   3604         afterLowest = afterLowest->prevRootBox();
   3605     }
   3606 }
   3607 
   3608 void RenderBlock::clearFloats()
   3609 {
   3610     // Inline blocks are covered by the isReplaced() check in the avoidFloats method.
   3611     if (avoidsFloats() || isRoot() || isRenderView() || isFloatingOrPositioned() || isTableCell()) {
   3612         if (m_floatingObjects) {
   3613             deleteAllValues(m_floatingObjects->set());
   3614             m_floatingObjects->clear();
   3615         }
   3616         return;
   3617     }
   3618 
   3619     typedef HashMap<RenderObject*, FloatingObject*> RendererToFloatInfoMap;
   3620     RendererToFloatInfoMap floatMap;
   3621 
   3622     if (m_floatingObjects) {
   3623         FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3624         if (childrenInline()) {
   3625             FloatingObjectSet::iterator end = floatingObjectSet.end();
   3626             for (FloatingObjectSet::iterator it = floatingObjectSet.begin(); it != end; ++it) {
   3627                 FloatingObject* f = *it;
   3628                 floatMap.add(f->m_renderer, f);
   3629             }
   3630         } else
   3631             deleteAllValues(floatingObjectSet);
   3632         m_floatingObjects->clear();
   3633     }
   3634 
   3635     // We should not process floats if the parent node is not a RenderBlock. Otherwise, we will add
   3636     // floats in an invalid context. This will cause a crash arising from a bad cast on the parent.
   3637     // See <rdar://problem/8049753>, where float property is applied on a text node in a SVG.
   3638     if (!parent() || !parent()->isRenderBlock())
   3639         return;
   3640 
   3641     // Attempt to locate a previous sibling with overhanging floats.  We skip any elements that are
   3642     // out of flow (like floating/positioned elements), and we also skip over any objects that may have shifted
   3643     // to avoid floats.
   3644     bool parentHasFloats = false;
   3645     RenderBlock* parentBlock = toRenderBlock(parent());
   3646     RenderObject* prev = previousSibling();
   3647     while (prev && (prev->isFloatingOrPositioned() || !prev->isBox() || !prev->isRenderBlock() || toRenderBlock(prev)->avoidsFloats())) {
   3648         if (prev->isFloating())
   3649             parentHasFloats = true;
   3650          prev = prev->previousSibling();
   3651     }
   3652 
   3653     // First add in floats from the parent.
   3654     int logicalTopOffset = logicalTop();
   3655     if (parentHasFloats)
   3656         addIntrudingFloats(parentBlock, parentBlock->logicalLeftOffsetForContent(), logicalTopOffset);
   3657 
   3658     int logicalLeftOffset = 0;
   3659     if (prev)
   3660         logicalTopOffset -= toRenderBox(prev)->logicalTop();
   3661     else {
   3662         prev = parentBlock;
   3663         logicalLeftOffset += parentBlock->logicalLeftOffsetForContent();
   3664     }
   3665 
   3666     // Add overhanging floats from the previous RenderBlock, but only if it has a float that intrudes into our space.
   3667     if (!prev || !prev->isRenderBlock())
   3668         return;
   3669 
   3670     RenderBlock* block = toRenderBlock(prev);
   3671     if (block->m_floatingObjects && block->lowestFloatLogicalBottom() > logicalTopOffset)
   3672         addIntrudingFloats(block, logicalLeftOffset, logicalTopOffset);
   3673 
   3674     if (childrenInline()) {
   3675         int changeLogicalTop = numeric_limits<int>::max();
   3676         int changeLogicalBottom = numeric_limits<int>::min();
   3677         if (m_floatingObjects) {
   3678             FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3679             FloatingObjectSetIterator end = floatingObjectSet.end();
   3680             for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   3681                 FloatingObject* f = *it;
   3682                 FloatingObject* oldFloatingObject = floatMap.get(f->m_renderer);
   3683                 int logicalBottom = logicalBottomForFloat(f);
   3684                 if (oldFloatingObject) {
   3685                     int oldLogicalBottom = logicalBottomForFloat(oldFloatingObject);
   3686                     if (logicalWidthForFloat(f) != logicalWidthForFloat(oldFloatingObject) || logicalLeftForFloat(f) != logicalLeftForFloat(oldFloatingObject)) {
   3687                         changeLogicalTop = 0;
   3688                         changeLogicalBottom = max(changeLogicalBottom, max(logicalBottom, oldLogicalBottom));
   3689                     } else if (logicalBottom != oldLogicalBottom) {
   3690                         changeLogicalTop = min(changeLogicalTop, min(logicalBottom, oldLogicalBottom));
   3691                         changeLogicalBottom = max(changeLogicalBottom, max(logicalBottom, oldLogicalBottom));
   3692                     }
   3693 
   3694                     floatMap.remove(f->m_renderer);
   3695                     if (oldFloatingObject->m_originatingLine) {
   3696                         ASSERT(oldFloatingObject->m_originatingLine->renderer() == this);
   3697                         oldFloatingObject->m_originatingLine->markDirty();
   3698                     }
   3699                     delete oldFloatingObject;
   3700                 } else {
   3701                     changeLogicalTop = 0;
   3702                     changeLogicalBottom = max(changeLogicalBottom, logicalBottom);
   3703                 }
   3704             }
   3705         }
   3706 
   3707         RendererToFloatInfoMap::iterator end = floatMap.end();
   3708         for (RendererToFloatInfoMap::iterator it = floatMap.begin(); it != end; ++it) {
   3709             FloatingObject* floatingObject = (*it).second;
   3710             if (!floatingObject->m_isDescendant) {
   3711                 changeLogicalTop = 0;
   3712                 changeLogicalBottom = max(changeLogicalBottom, logicalBottomForFloat(floatingObject));
   3713             }
   3714         }
   3715         deleteAllValues(floatMap);
   3716 
   3717         markLinesDirtyInBlockRange(changeLogicalTop, changeLogicalBottom);
   3718     }
   3719 }
   3720 
   3721 int RenderBlock::addOverhangingFloats(RenderBlock* child, int logicalLeftOffset, int logicalTopOffset, bool makeChildPaintOtherFloats)
   3722 {
   3723     // Prevent floats from being added to the canvas by the root element, e.g., <html>.
   3724     if (child->hasOverflowClip() || !child->containsFloats() || child->isRoot() || child->hasColumns() || child->isWritingModeRoot())
   3725         return 0;
   3726 
   3727     int childLogicalTop = child->logicalTop();
   3728     int lowestFloatLogicalBottom = 0;
   3729 
   3730     // Floats that will remain the child's responsibility to paint should factor into its
   3731     // overflow.
   3732     FloatingObjectSetIterator childEnd = child->m_floatingObjects->set().end();
   3733     for (FloatingObjectSetIterator childIt = child->m_floatingObjects->set().begin(); childIt != childEnd; ++childIt) {
   3734         FloatingObject* r = *childIt;
   3735         int logicalBottomForFloat = min(this->logicalBottomForFloat(r), numeric_limits<int>::max() - childLogicalTop);
   3736         int logicalBottom = childLogicalTop + logicalBottomForFloat;
   3737         lowestFloatLogicalBottom = max(lowestFloatLogicalBottom, logicalBottom);
   3738 
   3739         if (logicalBottom > logicalHeight()) {
   3740             // If the object is not in the list, we add it now.
   3741             if (!containsFloat(r->m_renderer)) {
   3742                 int leftOffset = isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset;
   3743                 int topOffset = isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset;
   3744                 FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->x() - leftOffset, r->y() - topOffset, r->width(), r->height()));
   3745                 floatingObj->m_renderer = r->m_renderer;
   3746 
   3747                 // The nearest enclosing layer always paints the float (so that zindex and stacking
   3748                 // behaves properly).  We always want to propagate the desire to paint the float as
   3749                 // far out as we can, to the outermost block that overlaps the float, stopping only
   3750                 // if we hit a self-painting layer boundary.
   3751                 if (r->m_renderer->enclosingFloatPaintingLayer() == enclosingFloatPaintingLayer())
   3752                     r->m_shouldPaint = false;
   3753                 else
   3754                     floatingObj->m_shouldPaint = false;
   3755 
   3756                 floatingObj->m_isDescendant = true;
   3757 
   3758                 // We create the floating object list lazily.
   3759                 if (!m_floatingObjects)
   3760                     m_floatingObjects = adoptPtr(new FloatingObjects);
   3761 
   3762                 m_floatingObjects->increaseObjectsCount(floatingObj->type());
   3763                 m_floatingObjects->set().add(floatingObj);
   3764             }
   3765         } else {
   3766             if (makeChildPaintOtherFloats && !r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer() &&
   3767                 r->m_renderer->isDescendantOf(child) && r->m_renderer->enclosingFloatPaintingLayer() == child->enclosingFloatPaintingLayer()) {
   3768                 // The float is not overhanging from this block, so if it is a descendant of the child, the child should
   3769                 // paint it (the other case is that it is intruding into the child), unless it has its own layer or enclosing
   3770                 // layer.
   3771                 // If makeChildPaintOtherFloats is false, it means that the child must already know about all the floats
   3772                 // it should paint.
   3773                 r->m_shouldPaint = true;
   3774             }
   3775 
   3776             // Since the float doesn't overhang, it didn't get put into our list.  We need to go ahead and add its overflow in to the
   3777             // child now.
   3778             if (r->m_isDescendant)
   3779                 child->addOverflowFromChild(r->m_renderer, IntSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r)));
   3780         }
   3781     }
   3782     return lowestFloatLogicalBottom;
   3783 }
   3784 
   3785 bool RenderBlock::hasOverhangingFloat(RenderBox* renderer)
   3786 {
   3787     if (!m_floatingObjects || hasColumns() || !parent())
   3788         return false;
   3789 
   3790     FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3791     FloatingObjectSetIterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(renderer);
   3792     if (it == floatingObjectSet.end())
   3793         return false;
   3794 
   3795     return logicalBottomForFloat(*it) > logicalHeight();
   3796 }
   3797 
   3798 void RenderBlock::addIntrudingFloats(RenderBlock* prev, int logicalLeftOffset, int logicalTopOffset)
   3799 {
   3800     // If the parent or previous sibling doesn't have any floats to add, don't bother.
   3801     if (!prev->m_floatingObjects)
   3802         return;
   3803 
   3804     logicalLeftOffset += (isHorizontalWritingMode() ? marginLeft() : marginTop());
   3805 
   3806     FloatingObjectSet& prevSet = prev->m_floatingObjects->set();
   3807     FloatingObjectSetIterator prevEnd = prevSet.end();
   3808     for (FloatingObjectSetIterator prevIt = prevSet.begin(); prevIt != prevEnd; ++prevIt) {
   3809         FloatingObject* r = *prevIt;
   3810         if (logicalBottomForFloat(r) > logicalTopOffset) {
   3811             if (!m_floatingObjects || !m_floatingObjects->set().contains(r)) {
   3812                 int leftOffset = isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset;
   3813                 int topOffset = isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset;
   3814 
   3815                 FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->x() - leftOffset, r->y() - topOffset, r->width(), r->height()));
   3816 
   3817                 // Applying the child's margin makes no sense in the case where the child was passed in.
   3818                 // since this margin was added already through the modification of the |logicalLeftOffset| variable
   3819                 // above.  |logicalLeftOffset| will equal the margin in this case, so it's already been taken
   3820                 // into account.  Only apply this code if prev is the parent, since otherwise the left margin
   3821                 // will get applied twice.
   3822                 if (prev != parent()) {
   3823                     if (isHorizontalWritingMode())
   3824                         floatingObj->setX(floatingObj->x() + prev->marginLeft());
   3825                     else
   3826                         floatingObj->setY(floatingObj->y() + prev->marginTop());
   3827                 }
   3828 
   3829                 floatingObj->m_shouldPaint = false;  // We are not in the direct inheritance chain for this float. We will never paint it.
   3830                 floatingObj->m_renderer = r->m_renderer;
   3831 
   3832                 // We create the floating object list lazily.
   3833                 if (!m_floatingObjects)
   3834                     m_floatingObjects = adoptPtr(new FloatingObjects);