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);
   3835                 m_floatingObjects->increaseObjectsCount(floatingObj->type());
   3836                 m_floatingObjects->set().add(floatingObj);
   3837             }
   3838         }
   3839     }
   3840 }
   3841 
   3842 bool RenderBlock::avoidsFloats() const
   3843 {
   3844     // Floats can't intrude into our box if we have a non-auto column count or width.
   3845     return RenderBox::avoidsFloats() || !style()->hasAutoColumnCount() || !style()->hasAutoColumnWidth();
   3846 }
   3847 
   3848 bool RenderBlock::containsFloat(RenderBox* renderer)
   3849 {
   3850     return m_floatingObjects && m_floatingObjects->set().contains<RenderBox*, FloatingObjectHashTranslator>(renderer);
   3851 }
   3852 
   3853 void RenderBlock::markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove, bool inLayout)
   3854 {
   3855     if (!m_everHadLayout)
   3856         return;
   3857 
   3858     setChildNeedsLayout(true, !inLayout);
   3859 
   3860     if (floatToRemove)
   3861         removeFloatingObject(floatToRemove);
   3862 
   3863     // Iterate over our children and mark them as needed.
   3864     if (!childrenInline()) {
   3865         for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
   3866             if ((!floatToRemove && child->isFloatingOrPositioned()) || !child->isRenderBlock())
   3867                 continue;
   3868             RenderBlock* childBlock = toRenderBlock(child);
   3869             if ((floatToRemove ? childBlock->containsFloat(floatToRemove) : childBlock->containsFloats()) || childBlock->shrinkToAvoidFloats())
   3870                 childBlock->markAllDescendantsWithFloatsForLayout(floatToRemove, inLayout);
   3871         }
   3872     }
   3873 }
   3874 
   3875 void RenderBlock::markSiblingsWithFloatsForLayout()
   3876 {
   3877     FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3878     FloatingObjectSetIterator end = floatingObjectSet.end();
   3879     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   3880         if (logicalBottomForFloat(*it) > logicalHeight()) {
   3881             RenderBox* floatingBox = (*it)->renderer();
   3882 
   3883             RenderObject* next = nextSibling();
   3884             while (next) {
   3885                 if (next->isRenderBlock() && !next->isFloatingOrPositioned() && !toRenderBlock(next)->avoidsFloats()) {
   3886                     RenderBlock* nextBlock = toRenderBlock(next);
   3887                     if (nextBlock->containsFloat(floatingBox))
   3888                         nextBlock->markAllDescendantsWithFloatsForLayout(floatingBox);
   3889                     else
   3890                         break;
   3891                 }
   3892 
   3893                 next = next->nextSibling();
   3894             }
   3895         }
   3896     }
   3897 }
   3898 
   3899 int RenderBlock::getClearDelta(RenderBox* child, int yPos)
   3900 {
   3901     // There is no need to compute clearance if we have no floats.
   3902     if (!containsFloats())
   3903         return 0;
   3904 
   3905     // At least one float is present.  We need to perform the clearance computation.
   3906     bool clearSet = child->style()->clear() != CNONE;
   3907     int bottom = 0;
   3908     switch (child->style()->clear()) {
   3909         case CNONE:
   3910             break;
   3911         case CLEFT:
   3912             bottom = lowestFloatLogicalBottom(FloatingObject::FloatLeft);
   3913             break;
   3914         case CRIGHT:
   3915             bottom = lowestFloatLogicalBottom(FloatingObject::FloatRight);
   3916             break;
   3917         case CBOTH:
   3918             bottom = lowestFloatLogicalBottom();
   3919             break;
   3920     }
   3921 
   3922     // We also clear floats if we are too big to sit on the same line as a float (and wish to avoid floats by default).
   3923     int result = clearSet ? max(0, bottom - yPos) : 0;
   3924     if (!result && child->avoidsFloats()) {
   3925         int y = yPos;
   3926         while (true) {
   3927             int widthAtY = availableLogicalWidthForLine(y, false);
   3928             if (widthAtY == availableLogicalWidth())
   3929                 return y - yPos;
   3930 
   3931             int oldChildY = child->y();
   3932             int oldChildWidth = child->width();
   3933             child->setY(y);
   3934             child->computeLogicalWidth();
   3935             int childWidthAtY = child->width();
   3936             child->setY(oldChildY);
   3937             child->setWidth(oldChildWidth);
   3938 
   3939             if (childWidthAtY <= widthAtY)
   3940                 return y - yPos;
   3941 
   3942             y = nextFloatLogicalBottomBelow(y);
   3943             ASSERT(y >= yPos);
   3944             if (y < yPos)
   3945                 break;
   3946         }
   3947         ASSERT_NOT_REACHED();
   3948     }
   3949     return result;
   3950 }
   3951 
   3952 bool RenderBlock::isPointInOverflowControl(HitTestResult& result, int _x, int _y, int _tx, int _ty)
   3953 {
   3954     if (!scrollsOverflow())
   3955         return false;
   3956 
   3957     return layer()->hitTestOverflowControls(result, IntPoint(_x - _tx, _y - _ty));
   3958 }
   3959 
   3960 bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction)
   3961 {
   3962     int tx = _tx + x();
   3963     int ty = _ty + y();
   3964 
   3965     if (!isRenderView()) {
   3966         // Check if we need to do anything at all.
   3967         IntRect overflowBox = visualOverflowRect();
   3968         overflowBox.move(tx, ty);
   3969         if (!overflowBox.intersects(result.rectForPoint(_x, _y)))
   3970             return false;
   3971     }
   3972 
   3973     if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) && isPointInOverflowControl(result, _x, _y, tx, ty)) {
   3974         updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
   3975         // FIXME: isPointInOverflowControl() doesn't handle rect-based tests yet.
   3976         if (!result.addNodeToRectBasedTestResult(node(), _x, _y))
   3977            return true;
   3978     }
   3979 
   3980     // If we have clipping, then we can't have any spillout.
   3981     bool useOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer();
   3982     bool useClip = (hasControlClip() || useOverflowClip);
   3983     IntRect hitTestArea(result.rectForPoint(_x, _y));
   3984     bool checkChildren = !useClip || (hasControlClip() ? controlClipRect(tx, ty).intersects(hitTestArea) : overflowClipRect(tx, ty, IncludeOverlayScrollbarSize).intersects(hitTestArea));
   3985     if (checkChildren) {
   3986         // Hit test descendants first.
   3987         int scrolledX = tx;
   3988         int scrolledY = ty;
   3989         if (hasOverflowClip()) {
   3990             IntSize offset = layer()->scrolledContentOffset();
   3991             scrolledX -= offset.width();
   3992             scrolledY -= offset.height();
   3993         }
   3994 
   3995         // Hit test contents if we don't have columns.
   3996         if (!hasColumns()) {
   3997             if (hitTestContents(request, result, _x, _y, scrolledX, scrolledY, hitTestAction)) {
   3998                 updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
   3999                 return true;
   4000             }
   4001             if (hitTestAction == HitTestFloat && hitTestFloats(request, result, _x, _y, scrolledX, scrolledY))
   4002                 return true;
   4003         } else if (hitTestColumns(request, result, _x, _y, scrolledX, scrolledY, hitTestAction)) {
   4004             updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
   4005             return true;
   4006         }
   4007     }
   4008 
   4009     // Now hit test our background
   4010     if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) {
   4011         IntRect boundsRect(tx, ty, width(), height());
   4012         if (visibleToHitTesting() && boundsRect.intersects(result.rectForPoint(_x, _y))) {
   4013             updateHitTestResult(result, flipForWritingMode(IntPoint(_x - tx, _y - ty)));
   4014             if (!result.addNodeToRectBasedTestResult(node(), _x, _y, boundsRect))
   4015                 return true;
   4016         }
   4017     }
   4018 
   4019     return false;
   4020 }
   4021 
   4022 bool RenderBlock::hitTestFloats(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty)
   4023 {
   4024     if (!m_floatingObjects)
   4025         return false;
   4026 
   4027     if (isRenderView()) {
   4028         tx += toRenderView(this)->frameView()->scrollX();
   4029         ty += toRenderView(this)->frameView()->scrollY();
   4030     }
   4031 
   4032     FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   4033     FloatingObjectSetIterator begin = floatingObjectSet.begin();
   4034     for (FloatingObjectSetIterator it = floatingObjectSet.end(); it != begin;) {
   4035         --it;
   4036         FloatingObject* floatingObject = *it;
   4037         if (floatingObject->m_shouldPaint && !floatingObject->m_renderer->hasSelfPaintingLayer()) {
   4038             int xOffset = xPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->x();
   4039             int yOffset = yPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->y();
   4040             IntPoint childPoint = flipFloatForWritingMode(floatingObject, IntPoint(tx + xOffset, ty + yOffset));
   4041             if (floatingObject->m_renderer->hitTest(request, result, IntPoint(x, y), childPoint.x(), childPoint.y())) {
   4042                 updateHitTestResult(result, IntPoint(x - childPoint.x(), y - childPoint.y()));
   4043                 return true;
   4044             }
   4045         }
   4046     }
   4047 
   4048     return false;
   4049 }
   4050 
   4051 bool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
   4052 {
   4053     // We need to do multiple passes, breaking up our hit testing into strips.
   4054     ColumnInfo* colInfo = columnInfo();
   4055     int colCount = columnCount(colInfo);
   4056     if (!colCount)
   4057         return false;
   4058     int logicalLeft = logicalLeftOffsetForContent();
   4059     int currLogicalTopOffset = 0;
   4060     int i;
   4061     bool isHorizontal = isHorizontalWritingMode();
   4062     for (i = 0; i < colCount; i++) {
   4063         IntRect colRect = columnRectAt(colInfo, i);
   4064         int blockDelta =  (isHorizontal ? colRect.height() : colRect.width());
   4065         if (style()->isFlippedBlocksWritingMode())
   4066             currLogicalTopOffset += blockDelta;
   4067         else
   4068             currLogicalTopOffset -= blockDelta;
   4069     }
   4070     for (i = colCount - 1; i >= 0; i--) {
   4071         IntRect colRect = columnRectAt(colInfo, i);
   4072         flipForWritingMode(colRect);
   4073         int currLogicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - logicalLeft;
   4074         int blockDelta =  (isHorizontal ? colRect.height() : colRect.width());
   4075         if (style()->isFlippedBlocksWritingMode())
   4076             currLogicalTopOffset -= blockDelta;
   4077         else
   4078             currLogicalTopOffset += blockDelta;
   4079         colRect.move(tx, ty);
   4080 
   4081         if (colRect.intersects(result.rectForPoint(x, y))) {
   4082             // The point is inside this column.
   4083             // Adjust tx and ty to change where we hit test.
   4084 
   4085             IntSize offset = isHorizontal ? IntSize(currLogicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, currLogicalLeftOffset);
   4086             int finalX = tx + offset.width();
   4087             int finalY = ty + offset.height();
   4088             if (result.isRectBasedTest() && !colRect.contains(result.rectForPoint(x, y)))
   4089                 hitTestContents(request, result, x, y, finalX, finalY, hitTestAction);
   4090             else
   4091                 return hitTestContents(request, result, x, y, finalX, finalY, hitTestAction) || (hitTestAction == HitTestFloat && hitTestFloats(request, result, x, y, finalX, finalY));
   4092         }
   4093     }
   4094 
   4095     return false;
   4096 }
   4097 
   4098 bool RenderBlock::hitTestContents(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
   4099 {
   4100     if (childrenInline() && !isTable()) {
   4101         // We have to hit-test our line boxes.
   4102         if (m_lineBoxes.hitTest(this, request, result, x, y, tx, ty, hitTestAction))
   4103             return true;
   4104     } else {
   4105         // Hit test our children.
   4106         HitTestAction childHitTest = hitTestAction;
   4107         if (hitTestAction == HitTestChildBlockBackgrounds)
   4108             childHitTest = HitTestChildBlockBackground;
   4109         for (RenderBox* child = lastChildBox(); child; child = child->previousSiblingBox()) {
   4110             IntPoint childPoint = flipForWritingMode(child, IntPoint(tx, ty), ParentToChildFlippingAdjustment);
   4111             if (!child->hasSelfPaintingLayer() && !child->isFloating() && child->nodeAtPoint(request, result, x, y, childPoint.x(), childPoint.y(), childHitTest))
   4112                 return true;
   4113         }
   4114     }
   4115 
   4116     return false;
   4117 }
   4118 
   4119 Position RenderBlock::positionForBox(InlineBox *box, bool start) const
   4120 {
   4121     if (!box)
   4122         return Position();
   4123 
   4124     if (!box->renderer()->node())
   4125         return Position(node(), start ? caretMinOffset() : caretMaxOffset());
   4126 
   4127     if (!box->isInlineTextBox())
   4128         return Position(box->renderer()->node(), start ? box->renderer()->caretMinOffset() : box->renderer()->caretMaxOffset());
   4129 
   4130     InlineTextBox *textBox = static_cast<InlineTextBox *>(box);
   4131     return Position(box->renderer()->node(), start ? textBox->start() : textBox->start() + textBox->len());
   4132 }
   4133 
   4134 // FIXME: This function should go on RenderObject as an instance method. Then
   4135 // all cases in which positionForPoint recurs could call this instead to
   4136 // prevent crossing editable boundaries. This would require many tests.
   4137 static VisiblePosition positionForPointRespectingEditingBoundaries(RenderBlock* parent, RenderBox* child, const IntPoint& pointInParentCoordinates)
   4138 {
   4139     // FIXME: This is wrong if the child's writing-mode is different from the parent's.
   4140     IntPoint pointInChildCoordinates(pointInParentCoordinates - child->location());
   4141 
   4142     // If this is an anonymous renderer, we just recur normally
   4143     Node* childNode = child->node();
   4144     if (!childNode)
   4145         return child->positionForPoint(pointInChildCoordinates);
   4146 
   4147     // Otherwise, first make sure that the editability of the parent and child agree.
   4148     // If they don't agree, then we return a visible position just before or after the child
   4149     RenderObject* ancestor = parent;
   4150     while (ancestor && !ancestor->node())
   4151         ancestor = ancestor->parent();
   4152 
   4153     // If we can't find an ancestor to check editability on, or editability is unchanged, we recur like normal
   4154     if (!ancestor || ancestor->node()->rendererIsEditable() == childNode->rendererIsEditable())
   4155         return child->positionForPoint(pointInChildCoordinates);
   4156 
   4157     // Otherwise return before or after the child, depending on if the click was to the logical left or logical right of the child
   4158     int childMiddle = parent->logicalWidthForChild(child) / 2;
   4159     int logicalLeft = parent->isHorizontalWritingMode() ? pointInChildCoordinates.x() : pointInChildCoordinates.y();
   4160     if (logicalLeft < childMiddle)
   4161         return ancestor->createVisiblePosition(childNode->nodeIndex(), DOWNSTREAM);
   4162     return ancestor->createVisiblePosition(childNode->nodeIndex() + 1, UPSTREAM);
   4163 }
   4164 
   4165 VisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint& pointInLogicalContents)
   4166 {
   4167     ASSERT(childrenInline());
   4168 
   4169     if (!firstRootBox())
   4170         return createVisiblePosition(0, DOWNSTREAM);
   4171 
   4172     // look for the closest line box in the root box which is at the passed-in y coordinate
   4173     InlineBox* closestBox = 0;
   4174     RootInlineBox* firstRootBoxWithChildren = 0;
   4175     RootInlineBox* lastRootBoxWithChildren = 0;
   4176     for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
   4177         if (!root->firstLeafChild())
   4178             continue;
   4179         if (!firstRootBoxWithChildren)
   4180             firstRootBoxWithChildren = root;
   4181         lastRootBoxWithChildren = root;
   4182 
   4183         // check if this root line box is located at this y coordinate
   4184         if (pointInLogicalContents.y() < root->selectionBottom()) {
   4185             closestBox = root->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
   4186             if (closestBox)
   4187                 break;
   4188         }
   4189     }
   4190 
   4191     bool moveCaretToBoundary = document()->frame()->editor()->behavior().shouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom();
   4192 
   4193     if (!moveCaretToBoundary && !closestBox && lastRootBoxWithChildren) {
   4194         // y coordinate is below last root line box, pretend we hit it
   4195         closestBox = lastRootBoxWithChildren->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
   4196     }
   4197 
   4198     if (closestBox) {
   4199         if (moveCaretToBoundary && pointInLogicalContents.y() < firstRootBoxWithChildren->selectionTop()) {
   4200             // y coordinate is above first root line box, so return the start of the first
   4201             return VisiblePosition(positionForBox(firstRootBoxWithChildren->firstLeafChild(), true), DOWNSTREAM);
   4202         }
   4203 
   4204         // pass the box a top position that is inside it
   4205         IntPoint point(pointInLogicalContents.x(), closestBox->logicalTop());
   4206         if (!isHorizontalWritingMode())
   4207             point = point.transposedPoint();
   4208         if (closestBox->renderer()->isReplaced())
   4209             return positionForPointRespectingEditingBoundaries(this, toRenderBox(closestBox->renderer()), point);
   4210         return closestBox->renderer()->positionForPoint(point);
   4211     }
   4212 
   4213     if (lastRootBoxWithChildren) {
   4214         // We hit this case for Mac behavior when the Y coordinate is below the last box.
   4215         ASSERT(moveCaretToBoundary);
   4216         InlineBox* logicallyLastBox;
   4217         if (lastRootBoxWithChildren->getLogicalEndBoxWithNode(logicallyLastBox))
   4218             return VisiblePosition(positionForBox(logicallyLastBox, false), DOWNSTREAM);
   4219     }
   4220 
   4221     // Can't reach this. We have a root line box, but it has no kids.
   4222     // FIXME: This should ASSERT_NOT_REACHED(), but clicking on placeholder text
   4223     // seems to hit this code path.
   4224     return createVisiblePosition(0, DOWNSTREAM);
   4225 }
   4226 
   4227 static inline bool isChildHitTestCandidate(RenderBox* box)
   4228 {
   4229     return box->height() && box->style()->visibility() == VISIBLE && !box->isFloatingOrPositioned();
   4230 }
   4231 
   4232 VisiblePosition RenderBlock::positionForPoint(const IntPoint& point)
   4233 {
   4234     if (isTable())
   4235         return RenderBox::positionForPoint(point);
   4236 
   4237     if (isReplaced()) {
   4238         // FIXME: This seems wrong when the object's writing-mode doesn't match the line's writing-mode.
   4239         int pointLogicalLeft = isHorizontalWritingMode() ? point.x() : point.y();
   4240         int pointLogicalTop = isHorizontalWritingMode() ? point.y() : point.x();
   4241 
   4242         if (pointLogicalTop < 0 || (pointLogicalTop < logicalHeight() && pointLogicalLeft < 0))
   4243             return createVisiblePosition(caretMinOffset(), DOWNSTREAM);
   4244         if (pointLogicalTop >= logicalHeight() || (pointLogicalTop >= 0 && pointLogicalLeft >= logicalWidth()))
   4245             return createVisiblePosition(caretMaxOffset(), DOWNSTREAM);
   4246     }
   4247 
   4248     int contentsX = point.x();
   4249     int contentsY = point.y();
   4250     offsetForContents(contentsX, contentsY);
   4251     IntPoint pointInContents(contentsX, contentsY);
   4252     IntPoint pointInLogicalContents(pointInContents);
   4253     if (!isHorizontalWritingMode())
   4254         pointInLogicalContents = pointInLogicalContents.transposedPoint();
   4255 
   4256     if (childrenInline())
   4257         return positionForPointWithInlineChildren(pointInLogicalContents);
   4258 
   4259     if (lastChildBox() && pointInContents.y() > lastChildBox()->logicalTop()) {
   4260         for (RenderBox* childBox = lastChildBox(); childBox; childBox = childBox->previousSiblingBox()) {
   4261             if (isChildHitTestCandidate(childBox))
   4262                 return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents);
   4263         }
   4264     } else {
   4265         for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
   4266             // We hit child if our click is above the bottom of its padding box (like IE6/7 and FF3).
   4267             if (isChildHitTestCandidate(childBox) && pointInContents.y() < childBox->logicalBottom())
   4268                 return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents);
   4269         }
   4270     }
   4271 
   4272     // We only get here if there are no hit test candidate children below the click.
   4273     return RenderBox::positionForPoint(point);
   4274 }
   4275 
   4276 void RenderBlock::offsetForContents(int& tx, int& ty) const
   4277 {
   4278     IntPoint contentsPoint(tx, ty);
   4279 
   4280     if (hasOverflowClip())
   4281         contentsPoint += layer()->scrolledContentOffset();
   4282 
   4283     if (hasColumns())
   4284         adjustPointToColumnContents(contentsPoint);
   4285 
   4286     tx = contentsPoint.x();
   4287     ty = contentsPoint.y();
   4288 }
   4289 
   4290 int RenderBlock::availableLogicalWidth() const
   4291 {
   4292     // If we have multiple columns, then the available logical width is reduced to our column width.
   4293     if (hasColumns())
   4294         return desiredColumnWidth();
   4295     return RenderBox::availableLogicalWidth();
   4296 }
   4297 
   4298 int RenderBlock::columnGap() const
   4299 {
   4300     if (style()->hasNormalColumnGap())
   4301         return style()->fontDescription().computedPixelSize(); // "1em" is recommended as the normal gap setting. Matches <p> margins.
   4302     return static_cast<int>(style()->columnGap());
   4303 }
   4304 
   4305 void RenderBlock::calcColumnWidth()
   4306 {
   4307     // Calculate our column width and column count.
   4308     unsigned desiredColumnCount = 1;
   4309     int desiredColumnWidth = contentLogicalWidth();
   4310 
   4311     // For now, we don't support multi-column layouts when printing, since we have to do a lot of work for proper pagination.
   4312     if (document()->paginated() || (style()->hasAutoColumnCount() && style()->hasAutoColumnWidth())) {
   4313         setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
   4314         return;
   4315     }
   4316 
   4317     int availWidth = desiredColumnWidth;
   4318     int colGap = columnGap();
   4319     int colWidth = max(1, static_cast<int>(style()->columnWidth()));
   4320     int colCount = max(1, static_cast<int>(style()->columnCount()));
   4321 
   4322     if (style()->hasAutoColumnWidth() && !style()->hasAutoColumnCount()) {
   4323         desiredColumnCount = colCount;
   4324         desiredColumnWidth = max<int>(0, (availWidth - ((desiredColumnCount - 1) * colGap)) / desiredColumnCount);
   4325     } else if (!style()->hasAutoColumnWidth() && style()->hasAutoColumnCount()) {
   4326         desiredColumnCount = max<int>(1, (float)(availWidth + colGap) / (colWidth + colGap));
   4327         desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colGap;
   4328     } else {
   4329         desiredColumnCount = max(min<int>(colCount, (float)(availWidth + colGap) / (colWidth + colGap)), 1);
   4330         desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colGap;
   4331     }
   4332     setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
   4333 }
   4334 
   4335 void RenderBlock::setDesiredColumnCountAndWidth(int count, int width)
   4336 {
   4337     bool destroyColumns = !firstChild()
   4338                           || (count == 1 && style()->hasAutoColumnWidth())
   4339                           || firstChild()->isAnonymousColumnsBlock()
   4340                           || firstChild()->isAnonymousColumnSpanBlock();
   4341     if (destroyColumns) {
   4342         if (hasColumns()) {
   4343             delete gColumnInfoMap->take(this);
   4344             setHasColumns(false);
   4345         }
   4346     } else {
   4347         ColumnInfo* info;
   4348         if (hasColumns())
   4349             info = gColumnInfoMap->get(this);
   4350         else {
   4351             if (!gColumnInfoMap)
   4352                 gColumnInfoMap = new ColumnInfoMap;
   4353             info = new ColumnInfo;
   4354             gColumnInfoMap->add(this, info);
   4355             setHasColumns(true);
   4356         }
   4357         info->setDesiredColumnCount(count);
   4358         info->setDesiredColumnWidth(width);
   4359     }
   4360 }
   4361 
   4362 int RenderBlock::desiredColumnWidth() const
   4363 {
   4364     if (!hasColumns())
   4365         return contentLogicalWidth();
   4366     return gColumnInfoMap->get(this)->desiredColumnWidth();
   4367 }
   4368 
   4369 unsigned RenderBlock::desiredColumnCount() const
   4370 {
   4371     if (!hasColumns())
   4372         return 1;
   4373     return gColumnInfoMap->get(this)->desiredColumnCount();
   4374 }
   4375 
   4376 ColumnInfo* RenderBlock::columnInfo() const
   4377 {
   4378     if (!hasColumns())
   4379         return 0;
   4380     return gColumnInfoMap->get(this);
   4381 }
   4382 
   4383 unsigned RenderBlock::columnCount(ColumnInfo* colInfo) const
   4384 {
   4385     ASSERT(hasColumns() && gColumnInfoMap->get(this) == colInfo);
   4386     return colInfo->columnCount();
   4387 }
   4388 
   4389 IntRect RenderBlock::columnRectAt(ColumnInfo* colInfo, unsigned index) const
   4390 {
   4391     ASSERT(hasColumns() && gColumnInfoMap->get(this) == colInfo);
   4392 
   4393     // Compute the appropriate rect based off our information.
   4394     int colLogicalWidth = colInfo->desiredColumnWidth();
   4395     int colLogicalHeight = colInfo->columnHeight();
   4396     int colLogicalTop = borderBefore() + paddingBefore();
   4397     int colGap = columnGap();
   4398     int colLogicalLeft = style()->isLeftToRightDirection() ?
   4399                           logicalLeftOffsetForContent() + (index * (colLogicalWidth + colGap))
   4400                         : logicalLeftOffsetForContent() + contentLogicalWidth() - colLogicalWidth - (index * (colLogicalWidth + colGap));
   4401     IntRect rect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
   4402     if (isHorizontalWritingMode())
   4403         return IntRect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
   4404     return IntRect(colLogicalTop, colLogicalLeft, colLogicalHeight, colLogicalWidth);
   4405 }
   4406 
   4407 bool RenderBlock::layoutColumns(bool hasSpecifiedPageLogicalHeight, int pageLogicalHeight, LayoutStateMaintainer& statePusher)
   4408 {
   4409     if (!hasColumns())
   4410         return false;
   4411 
   4412     // FIXME: We don't balance properly at all in the presence of forced page breaks.  We need to understand what
   4413     // the distance between forced page breaks is so that we can avoid making the minimum column height too tall.
   4414     ColumnInfo* colInfo = columnInfo();
   4415     int desiredColumnCount = colInfo->desiredColumnCount();
   4416     if (!hasSpecifiedPageLogicalHeight) {
   4417         int columnHeight = pageLogicalHeight;
   4418         int minColumnCount = colInfo->forcedBreaks() + 1;
   4419         if (minColumnCount >= desiredColumnCount) {
   4420             // The forced page breaks are in control of the balancing.  Just set the column height to the
   4421             // maximum page break distance.
   4422             if (!pageLogicalHeight) {
   4423                 int distanceBetweenBreaks = max(colInfo->maximumDistanceBetweenForcedBreaks(),
   4424                                                 view()->layoutState()->pageLogicalOffset(borderBefore() + paddingBefore() + contentLogicalHeight()) - colInfo->forcedBreakOffset());
   4425                 columnHeight = max(colInfo->minimumColumnHeight(), distanceBetweenBreaks);
   4426             }
   4427         } else if (contentLogicalHeight() > pageLogicalHeight * desiredColumnCount) {
   4428             // Now that we know the intrinsic height of the columns, we have to rebalance them.
   4429             columnHeight = max(colInfo->minimumColumnHeight(), (int)ceilf((float)contentLogicalHeight() / desiredColumnCount));
   4430         }
   4431 
   4432         if (columnHeight && columnHeight != pageLogicalHeight) {
   4433             statePusher.pop();
   4434             m_everHadLayout = true;
   4435             layoutBlock(false, columnHeight);
   4436             return true;
   4437         }
   4438     }
   4439 
   4440     if (pageLogicalHeight)
   4441         colInfo->setColumnCountAndHeight(ceilf((float)contentLogicalHeight() / pageLogicalHeight), pageLogicalHeight);
   4442 
   4443     if (columnCount(colInfo)) {
   4444         setLogicalHeight(borderBefore() + paddingBefore() + colInfo->columnHeight() + borderAfter() + paddingAfter() + scrollbarLogicalHeight());
   4445         m_overflow.clear();
   4446     }
   4447 
   4448     return false;
   4449 }
   4450 
   4451 void RenderBlock::adjustPointToColumnContents(IntPoint& point) const
   4452 {
   4453     // Just bail if we have no columns.
   4454     if (!hasColumns())
   4455         return;
   4456 
   4457     ColumnInfo* colInfo = columnInfo();
   4458     if (!columnCount(colInfo))
   4459         return;
   4460 
   4461     // Determine which columns we intersect.
   4462     int colGap = columnGap();
   4463     int halfColGap = colGap / 2;
   4464     IntPoint columnPoint(columnRectAt(colInfo, 0).location());
   4465     int logicalOffset = 0;
   4466     for (unsigned i = 0; i < colInfo->columnCount(); i++) {
   4467         // Add in half the column gap to the left and right of the rect.
   4468         IntRect colRect = columnRectAt(colInfo, i);
   4469         if (isHorizontalWritingMode()) {
   4470             IntRect gapAndColumnRect(colRect.x() - halfColGap, colRect.y(), colRect.width() + colGap, colRect.height());
   4471             if (point.x() >= gapAndColumnRect.x() && point.x() < gapAndColumnRect.maxX()) {
   4472                 // FIXME: The clamping that follows is not completely right for right-to-left
   4473                 // content.
   4474                 // Clamp everything above the column to its top left.
   4475                 if (point.y() < gapAndColumnRect.y())
   4476                     point = gapAndColumnRect.location();
   4477                 // Clamp everything below the column to the next column's top left. If there is
   4478                 // no next column, this still maps to just after this column.
   4479                 else if (point.y() >= gapAndColumnRect.maxY()) {
   4480                     point = gapAndColumnRect.location();
   4481                     point.move(0, gapAndColumnRect.height());
   4482                 }
   4483 
   4484                 // We're inside the column.  Translate the x and y into our column coordinate space.
   4485                 point.move(columnPoint.x() - colRect.x(), logicalOffset);
   4486                 return;
   4487             }
   4488 
   4489             // Move to the next position.
   4490             logicalOffset += colRect.height();
   4491         } else {
   4492             IntRect gapAndColumnRect(colRect.x(), colRect.y() - halfColGap, colRect.width(), colRect.height() + colGap);
   4493             if (point.y() >= gapAndColumnRect.y() && point.y() < gapAndColumnRect.maxY()) {
   4494                 // FIXME: The clamping that follows is not completely right for right-to-left
   4495                 // content.
   4496                 // Clamp everything above the column to its top left.
   4497                 if (point.x() < gapAndColumnRect.x())
   4498                     point = gapAndColumnRect.location();
   4499                 // Clamp everything below the column to the next column's top left. If there is
   4500                 // no next column, this still maps to just after this column.
   4501                 else if (point.x() >= gapAndColumnRect.maxX()) {
   4502                     point = gapAndColumnRect.location();
   4503                     point.move(gapAndColumnRect.width(), 0);
   4504                 }
   4505 
   4506                 // We're inside the column.  Translate the x and y into our column coordinate space.
   4507                 point.move(logicalOffset, columnPoint.y() - colRect.y());
   4508                 return;
   4509             }
   4510 
   4511             // Move to the next position.
   4512             logicalOffset += colRect.width();
   4513         }
   4514     }
   4515 }
   4516 
   4517 void RenderBlock::adjustRectForColumns(IntRect& r) const
   4518 {
   4519     // Just bail if we have no columns.
   4520     if (!hasColumns())
   4521         return;
   4522 
   4523     ColumnInfo* colInfo = columnInfo();
   4524 
   4525     // Begin with a result rect that is empty.
   4526     IntRect result;
   4527 
   4528     // Determine which columns we intersect.
   4529     unsigned colCount = columnCount(colInfo);
   4530     if (!colCount)
   4531         return;
   4532 
   4533     int logicalLeft = logicalLeftOffsetForContent();
   4534     int currLogicalOffset = 0;
   4535 
   4536     for (unsigned i = 0; i < colCount; i++) {
   4537         IntRect colRect = columnRectAt(colInfo, i);
   4538         IntRect repaintRect = r;
   4539         if (isHorizontalWritingMode()) {
   4540             int currXOffset = colRect.x() - logicalLeft;
   4541             repaintRect.move(currXOffset, currLogicalOffset);
   4542             currLogicalOffset -= colRect.height();
   4543         } else {
   4544             int currYOffset = colRect.y() - logicalLeft;
   4545             repaintRect.move(currLogicalOffset, currYOffset);
   4546             currLogicalOffset -= colRect.width();
   4547         }
   4548         repaintRect.intersect(colRect);
   4549         result.unite(repaintRect);
   4550     }
   4551 
   4552     r = result;
   4553 }
   4554 
   4555 IntPoint RenderBlock::flipForWritingModeIncludingColumns(const IntPoint& point) const
   4556 {
   4557     ASSERT(hasColumns());
   4558     if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
   4559         return point;
   4560     ColumnInfo* colInfo = columnInfo();
   4561     int columnLogicalHeight = colInfo->columnHeight();
   4562     int expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
   4563     if (isHorizontalWritingMode())
   4564         return IntPoint(point.x(), expandedLogicalHeight - point.y());
   4565     return IntPoint(expandedLogicalHeight - point.x(), point.y());
   4566 }
   4567 
   4568 void RenderBlock::flipForWritingModeIncludingColumns(IntRect& rect) const
   4569 {
   4570     ASSERT(hasColumns());
   4571     if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
   4572         return;
   4573 
   4574     ColumnInfo* colInfo = columnInfo();
   4575     int columnLogicalHeight = colInfo->columnHeight();
   4576     int expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
   4577     if (isHorizontalWritingMode())
   4578         rect.setY(expandedLogicalHeight - rect.maxY());
   4579     else
   4580         rect.setX(expandedLogicalHeight - rect.maxX());
   4581 }
   4582 
   4583 void RenderBlock::adjustForColumns(IntSize& offset, const IntPoint& point) const
   4584 {
   4585     if (!hasColumns())
   4586         return;
   4587 
   4588     ColumnInfo* colInfo = columnInfo();
   4589 
   4590     int logicalLeft = logicalLeftOffsetForContent();
   4591     size_t colCount = columnCount(colInfo);
   4592     int colLogicalWidth = colInfo->desiredColumnWidth();
   4593     int colLogicalHeight = colInfo->columnHeight();
   4594 
   4595     for (size_t i = 0; i < colCount; ++i) {
   4596         // Compute the edges for a given column in the block progression direction.
   4597         IntRect sliceRect = IntRect(logicalLeft, borderBefore() + paddingBefore() + i * colLogicalHeight, colLogicalWidth, colLogicalHeight);
   4598         if (!isHorizontalWritingMode())
   4599             sliceRect = sliceRect.transposedRect();
   4600 
   4601         // If we have a flipped blocks writing mode, then convert the column so that it's coming from the after edge (either top or left edge).
   4602         flipForWritingModeIncludingColumns(sliceRect);
   4603 
   4604         int logicalOffset = style()->isFlippedBlocksWritingMode() ? (colCount - 1 - i) * colLogicalHeight : i * colLogicalHeight;
   4605 
   4606         // Now we're in the same coordinate space as the point.  See if it is inside the rectangle.
   4607         if (isHorizontalWritingMode()) {
   4608             if (point.y() >= sliceRect.y() && point.y() < sliceRect.maxY()) {
   4609                 offset.expand(columnRectAt(colInfo, i).x() - logicalLeft, -logicalOffset);
   4610                 return;
   4611             }
   4612         } else {
   4613             if (point.x() >= sliceRect.x() && point.x() < sliceRect.maxX()) {
   4614                 offset.expand(-logicalOffset, columnRectAt(colInfo, i).y() - logicalLeft);
   4615                 return;
   4616             }
   4617         }
   4618     }
   4619 }
   4620 
   4621 void RenderBlock::computePreferredLogicalWidths()
   4622 {
   4623     ASSERT(preferredLogicalWidthsDirty());
   4624 
   4625     updateFirstLetter();
   4626 
   4627     if (!isTableCell() && style()->logicalWidth().isFixed() && style()->logicalWidth().value() > 0)
   4628         m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeContentBoxLogicalWidth(style()->logicalWidth().value());
   4629     else {
   4630         m_minPreferredLogicalWidth = 0;
   4631         m_maxPreferredLogicalWidth = 0;
   4632 
   4633         if (childrenInline())
   4634             computeInlinePreferredLogicalWidths();
   4635         else
   4636             computeBlockPreferredLogicalWidths();
   4637 
   4638         m_maxPreferredLogicalWidth = max(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
   4639 
   4640         if (!style()->autoWrap() && childrenInline()) {
   4641             m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth;
   4642 
   4643             // A horizontal marquee with inline children has no minimum width.
   4644             if (layer() && layer()->marquee() && layer()->marquee()->isHorizontal())
   4645                 m_minPreferredLogicalWidth = 0;
   4646         }
   4647 
   4648         int scrollbarWidth = 0;
   4649         if (hasOverflowClip() && style()->overflowY() == OSCROLL) {
   4650             layer()->setHasVerticalScrollbar(true);
   4651             scrollbarWidth = verticalScrollbarWidth();
   4652             m_maxPreferredLogicalWidth += scrollbarWidth;
   4653         }
   4654 
   4655         if (isTableCell()) {
   4656             Length w = toRenderTableCell(this)->styleOrColLogicalWidth();
   4657             if (w.isFixed() && w.value() > 0) {
   4658                 m_maxPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(w.value()));
   4659                 scrollbarWidth = 0;
   4660             }
   4661         }
   4662 
   4663         m_minPreferredLogicalWidth += scrollbarWidth;
   4664     }
   4665 
   4666     if (style()->logicalMinWidth().isFixed() && style()->logicalMinWidth().value() > 0) {
   4667         m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMinWidth().value()));
   4668         m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMinWidth().value()));
   4669     }
   4670 
   4671     if (style()->logicalMaxWidth().isFixed() && style()->logicalMaxWidth().value() != undefinedLength) {
   4672         m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMaxWidth().value()));
   4673         m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMaxWidth().value()));
   4674     }
   4675 
   4676     int borderAndPadding = borderAndPaddingLogicalWidth();
   4677     m_minPreferredLogicalWidth += borderAndPadding;
   4678     m_maxPreferredLogicalWidth += borderAndPadding;
   4679 
   4680     setPreferredLogicalWidthsDirty(false);
   4681 }
   4682 
   4683 struct InlineMinMaxIterator {
   4684 /* InlineMinMaxIterator is a class that will iterate over all render objects that contribute to
   4685    inline min/max width calculations.  Note the following about the way it walks:
   4686    (1) Positioned content is skipped (since it does not contribute to min/max width of a block)
   4687    (2) We do not drill into the children of floats or replaced elements, since you can't break
   4688        in the middle of such an element.
   4689    (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side can have
   4690        distinct borders/margin/padding that contribute to the min/max width.
   4691 */
   4692     RenderObject* parent;
   4693     RenderObject* current;
   4694     bool endOfInline;
   4695 
   4696     InlineMinMaxIterator(RenderObject* p, bool end = false)
   4697         :parent(p), current(p), endOfInline(end) {}
   4698 
   4699     RenderObject* next();
   4700 };
   4701 
   4702 RenderObject* InlineMinMaxIterator::next()
   4703 {
   4704     RenderObject* result = 0;
   4705     bool oldEndOfInline = endOfInline;
   4706     endOfInline = false;
   4707     while (current || current == parent) {
   4708         if (!oldEndOfInline &&
   4709             (current == parent ||
   4710              (!current->isFloating() && !current->isReplaced() && !current->isPositioned())))
   4711             result = current->firstChild();
   4712         if (!result) {
   4713             // We hit the end of our inline. (It was empty, e.g., <span></span>.)
   4714             if (!oldEndOfInline && current->isRenderInline()) {
   4715                 result = current;
   4716                 endOfInline = true;
   4717                 break;
   4718             }
   4719 
   4720             while (current && current != parent) {
   4721                 result = current->nextSibling();
   4722                 if (result) break;
   4723                 current = current->parent();
   4724                 if (current && current != parent && current->isRenderInline()) {
   4725                     result = current;
   4726                     endOfInline = true;
   4727                     break;
   4728                 }
   4729             }
   4730         }
   4731 
   4732         if (!result)
   4733             break;
   4734 
   4735         if (!result->isPositioned() && (result->isText() || result->isFloating() || result->isReplaced() || result->isRenderInline()))
   4736              break;
   4737 
   4738         current = result;
   4739         result = 0;
   4740     }
   4741 
   4742     // Update our position.
   4743     current = result;
   4744     return current;
   4745 }
   4746 
   4747 static int getBPMWidth(int childValue, Length cssUnit)
   4748 {
   4749     if (cssUnit.type() != Auto)
   4750         return (cssUnit.isFixed() ? cssUnit.value() : childValue);
   4751     return 0;
   4752 }
   4753 
   4754 static int getBorderPaddingMargin(const RenderBoxModelObject* child, bool endOfInline)
   4755 {
   4756     RenderStyle* cstyle = child->style();
   4757     if (endOfInline)
   4758         return getBPMWidth(child->marginEnd(), cstyle->marginEnd()) +
   4759                getBPMWidth(child->paddingEnd(), cstyle->paddingEnd()) +
   4760                child->borderEnd();
   4761     return getBPMWidth(child->marginStart(), cstyle->marginStart()) +
   4762                getBPMWidth(child->paddingStart(), cstyle->paddingStart()) +
   4763                child->borderStart();
   4764 }
   4765 
   4766 static inline void stripTrailingSpace(float& inlineMax, float& inlineMin,
   4767                                       RenderObject* trailingSpaceChild)
   4768 {
   4769     if (trailingSpaceChild && trailingSpaceChild->isText()) {
   4770         // Collapse away the trailing space at the end of a block.
   4771         RenderText* t = toRenderText(trailingSpaceChild);
   4772         const UChar space = ' ';
   4773         const Font& font = t->style()->font(); // FIXME: This ignores first-line.
   4774         float spaceWidth = font.width(TextRun(&space, 1));
   4775         inlineMax -= spaceWidth + font.wordSpacing();
   4776         if (inlineMin > inlineMax)
   4777             inlineMin = inlineMax;
   4778     }
   4779 }
   4780 
   4781 static inline void updatePreferredWidth(int& preferredWidth, float& result)
   4782 {
   4783     int snappedResult = ceilf(result);
   4784     preferredWidth = max(snappedResult, preferredWidth);
   4785 }
   4786 
   4787 void RenderBlock::computeInlinePreferredLogicalWidths()
   4788 {
   4789     float inlineMax = 0;
   4790     float inlineMin = 0;
   4791 
   4792     int cw = containingBlock()->contentLogicalWidth();
   4793 
   4794     // If we are at the start of a line, we want to ignore all white-space.
   4795     // Also strip spaces if we previously had text that ended in a trailing space.
   4796     bool stripFrontSpaces = true;
   4797     RenderObject* trailingSpaceChild = 0;
   4798 
   4799     // Firefox and Opera will allow a table cell to grow to fit an image inside it under
   4800     // very specific cirucumstances (in order to match common WinIE renderings).
   4801     // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
   4802     bool allowImagesToBreak = !document()->inQuirksMode() || !isTableCell() || !style()->logicalWidth().isIntrinsicOrAuto();
   4803 
   4804     bool autoWrap, oldAutoWrap;
   4805     autoWrap = oldAutoWrap = style()->autoWrap();
   4806 
   4807     InlineMinMaxIterator childIterator(this);
   4808     bool addedTextIndent = false; // Only gets added in once.
   4809     RenderObject* prevFloat = 0;
   4810     while (RenderObject* child = childIterator.next()) {
   4811         autoWrap = child->isReplaced() ? child->parent()->style()->autoWrap() :
   4812             child->style()->autoWrap();
   4813 
   4814         if (!child->isBR()) {
   4815             // Step One: determine whether or not we need to go ahead and
   4816             // terminate our current line.  Each discrete chunk can become
   4817             // the new min-width, if it is the widest chunk seen so far, and
   4818             // it can also become the max-width.
   4819 
   4820             // Children fall into three categories:
   4821             // (1) An inline flow object.  These objects always have a min/max of 0,
   4822             // and are included in the iteration solely so that their margins can
   4823             // be added in.
   4824             //
   4825             // (2) An inline non-text non-flow object, e.g., an inline replaced element.
   4826             // These objects can always be on a line by themselves, so in this situation
   4827             // we need to go ahead and break the current line, and then add in our own
   4828             // margins and min/max width on its own line, and then terminate the line.
   4829             //
   4830             // (3) A text object.  Text runs can have breakable characters at the start,
   4831             // the middle or the end.  They may also lose whitespace off the front if
   4832             // we're already ignoring whitespace.  In order to compute accurate min-width
   4833             // information, we need three pieces of information.
   4834             // (a) the min-width of the first non-breakable run.  Should be 0 if the text string
   4835             // starts with whitespace.
   4836             // (b) the min-width of the last non-breakable run. Should be 0 if the text string
   4837             // ends with whitespace.
   4838             // (c) the min/max width of the string (trimmed for whitespace).
   4839             //
   4840             // If the text string starts with whitespace, then we need to go ahead and
   4841             // terminate our current line (unless we're already in a whitespace stripping
   4842             // mode.
   4843             //
   4844             // If the text string has a breakable character in the middle, but didn't start
   4845             // with whitespace, then we add the width of the first non-breakable run and
   4846             // then end the current line.  We then need to use the intermediate min/max width
   4847             // values (if any of them are larger than our current min/max).  We then look at
   4848             // the width of the last non-breakable run and use that to start a new line
   4849             // (unless we end in whitespace).
   4850             RenderStyle* cstyle = child->style();
   4851             float childMin = 0;
   4852             float childMax = 0;
   4853 
   4854             if (!child->isText()) {
   4855                 // Case (1) and (2).  Inline replaced and inline flow elements.
   4856                 if (child->isRenderInline()) {
   4857                     // Add in padding/border/margin from the appropriate side of
   4858                     // the element.
   4859                     float bpm = getBorderPaddingMargin(toRenderInline(child), childIterator.endOfInline);
   4860                     childMin += bpm;
   4861                     childMax += bpm;
   4862 
   4863                     inlineMin += childMin;
   4864                     inlineMax += childMax;
   4865 
   4866                     child->setPreferredLogicalWidthsDirty(false);
   4867                 } else {
   4868                     // Inline replaced elts add in their margins to their min/max values.
   4869                     float margins = 0;
   4870                     Length startMargin = cstyle->marginStart();
   4871                     Length endMargin = cstyle->marginEnd();
   4872                     if (startMargin.isFixed())
   4873                         margins += startMargin.value();
   4874                     if (endMargin.isFixed())
   4875                         margins += endMargin.value();
   4876                     childMin += margins;
   4877                     childMax += margins;
   4878                 }
   4879             }
   4880 
   4881             if (!child->isRenderInline() && !child->isText()) {
   4882                 // Case (2). Inline replaced elements and floats.
   4883                 // Go ahead and terminate the current line as far as
   4884                 // minwidth is concerned.
   4885                 childMin += child->minPreferredLogicalWidth();
   4886                 childMax += child->maxPreferredLogicalWidth();
   4887 
   4888                 bool clearPreviousFloat;
   4889                 if (child->isFloating()) {
   4890                     clearPreviousFloat = (prevFloat
   4891                         && ((prevFloat->style()->floating() == FLEFT && (child->style()->clear() & CLEFT))
   4892                             || (prevFloat->style()->floating() == FRIGHT && (child->style()->clear() & CRIGHT))));
   4893                     prevFloat = child;
   4894                 } else
   4895                     clearPreviousFloat = false;
   4896 
   4897                 bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak;
   4898                 if ((canBreakReplacedElement && (autoWrap || oldAutoWrap)) || clearPreviousFloat) {
   4899                     updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
   4900                     inlineMin = 0;
   4901                 }
   4902 
   4903                 // If we're supposed to clear the previous float, then terminate maxwidth as well.
   4904                 if (clearPreviousFloat) {
   4905                     updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
   4906                     inlineMax = 0;
   4907                 }
   4908 
   4909                 // Add in text-indent.  This is added in only once.
   4910                 int ti = 0;
   4911                 if (!addedTextIndent) {
   4912                     addedTextIndent = true;
   4913                     ti = style()->textIndent().calcMinValue(cw);
   4914                     childMin += ti;
   4915                     childMax += ti;
   4916                 }
   4917 
   4918                 // Add our width to the max.
   4919                 inlineMax += childMax;
   4920 
   4921                 if (!autoWrap || !canBreakReplacedElement) {
   4922                     if (child->isFloating())
   4923                         updatePreferredWidth(m_minPreferredLogicalWidth, childMin);
   4924                     else
   4925                         inlineMin += childMin;
   4926                 } else {
   4927                     // Now check our line.
   4928                     updatePreferredWidth(m_minPreferredLogicalWidth, childMin);
   4929 
   4930                     // Now start a new line.
   4931                     inlineMin = 0;
   4932                 }
   4933 
   4934                 // We are no longer stripping whitespace at the start of
   4935                 // a line.
   4936                 if (!child->isFloating()) {
   4937                     stripFrontSpaces = false;
   4938                     trailingSpaceChild = 0;
   4939                 }
   4940             } else if (child->isText()) {
   4941                 // Case (3). Text.
   4942                 RenderText* t = toRenderText(child);
   4943 
   4944                 if (t->isWordBreak()) {
   4945                     updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
   4946                     inlineMin = 0;
   4947                     continue;
   4948                 }
   4949 
   4950                 if (t->style()->hasTextCombine() && t->isCombineText())
   4951                     toRenderCombineText(t)->combineText();
   4952 
   4953                 // Determine if we have a breakable character.  Pass in
   4954                 // whether or not we should ignore any spaces at the front
   4955                 // of the string.  If those are going to be stripped out,
   4956                 // then they shouldn't be considered in the breakable char
   4957                 // check.
   4958                 bool hasBreakableChar, hasBreak;
   4959                 float beginMin, endMin;
   4960                 bool beginWS, endWS;
   4961                 float beginMax, endMax;
   4962                 t->trimmedPrefWidths(inlineMax, beginMin, beginWS, endMin, endWS,
   4963                                      hasBreakableChar, hasBreak, beginMax, endMax,
   4964                                      childMin, childMax, stripFrontSpaces);
   4965 
   4966                 // This text object will not be rendered, but it may still provide a breaking opportunity.
   4967                 if (!hasBreak && childMax == 0) {
   4968                     if (autoWrap && (beginWS || endWS)) {
   4969                         updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
   4970                         inlineMin = 0;
   4971                     }
   4972                     continue;
   4973                 }
   4974 
   4975                 if (stripFrontSpaces)
   4976                     trailingSpaceChild = child;
   4977                 else
   4978                     trailingSpaceChild = 0;
   4979 
   4980                 // Add in text-indent.  This is added in only once.
   4981                 int ti = 0;
   4982                 if (!addedTextIndent) {
   4983                     addedTextIndent = true;
   4984                     ti = style()->textIndent().calcMinValue(cw);
   4985                     childMin+=ti; beginMin += ti;
   4986                     childMax+=ti; beginMax += ti;
   4987                 }
   4988 
   4989                 // If we have no breakable characters at all,
   4990                 // then this is the easy case. We add ourselves to the current
   4991                 // min and max and continue.
   4992                 if (!hasBreakableChar) {
   4993                     inlineMin += childMin;
   4994                 } else {
   4995                     // We have a breakable character.  Now we need to know if
   4996                     // we start and end with whitespace.
   4997                     if (beginWS)
   4998                         // Go ahead and end the current line.
   4999                         updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
   5000                     else {
   5001                         inlineMin += beginMin;
   5002                         updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
   5003                         childMin -= ti;
   5004                     }
   5005 
   5006                     inlineMin = childMin;
   5007 
   5008                     if (endWS) {
   5009                         // We end in whitespace, which means we can go ahead
   5010                         // and end our current line.
   5011                         updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
   5012                         inlineMin = 0;
   5013                     } else {
   5014                         updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
   5015                         inlineMin = endMin;
   5016                     }
   5017                 }
   5018 
   5019                 if (hasBreak) {
   5020                     inlineMax += beginMax;
   5021                     updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
   5022                     updatePreferredWidth(m_maxPreferredLogicalWidth, childMax);
   5023                     inlineMax = endMax;
   5024                 } else
   5025                     inlineMax += childMax;
   5026             }
   5027 
   5028             // Ignore spaces after a list marker.
   5029             if (child->isListMarker())
   5030                 stripFrontSpaces = true;
   5031         } else {
   5032             updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
   5033             updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
   5034             inlineMin = inlineMax = 0;
   5035             stripFrontSpaces = true;
   5036             trailingSpaceChild = 0;
   5037         }
   5038 
   5039         oldAutoWrap = autoWrap;
   5040     }
   5041 
   5042     if (style()->collapseWhiteSpace())
   5043         stripTrailingSpace(inlineMax, inlineMin, trailingSpaceChild);
   5044 
   5045     updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
   5046     updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
   5047 }
   5048 
   5049 // Use a very large value (in effect infinite).
   5050 #define BLOCK_MAX_WIDTH 15000
   5051 
   5052 void RenderBlock::computeBlockPreferredLogicalWidths()
   5053 {
   5054     bool nowrap = style()->whiteSpace() == NOWRAP;
   5055 
   5056     RenderObject *child = firstChild();
   5057     int floatLeftWidth = 0, floatRightWidth = 0;
   5058     while (child) {
   5059         // Positioned children don't affect the min/max width
   5060         if (child->isPositioned()) {
   5061             child = child->nextSibling();
   5062             continue;
   5063         }
   5064 
   5065         if (child->isFloating() || (child->isBox() && toRenderBox(child)->avoidsFloats())) {
   5066             int floatTotalWidth = floatLeftWidth + floatRightWidth;
   5067             if (child->style()->clear() & CLEFT) {
   5068                 m_maxPreferredLogicalWidth = max(floatTotalWidth, m_maxPreferredLogicalWidth);
   5069                 floatLeftWidth = 0;
   5070             }
   5071             if (child->style()->clear() & CRIGHT) {
   5072                 m_maxPreferredLogicalWidth = max(floatTotalWidth, m_maxPreferredLogicalWidth);
   5073                 floatRightWidth = 0;
   5074             }
   5075         }
   5076 
   5077         // A margin basically has three types: fixed, percentage, and auto (variable).
   5078         // Auto and percentage margins simply become 0 when computing min/max width.
   5079         // Fixed margins can be added in as is.
   5080         Length startMarginLength = child->style()->marginStart();
   5081         Length endMarginLength = child->style()->marginEnd();
   5082         int margin = 0;
   5083         int marginStart = 0;
   5084         int marginEnd = 0;
   5085         if (startMarginLength.isFixed())
   5086             marginStart += startMarginLength.value();
   5087         if (endMarginLength.isFixed())
   5088             marginEnd += endMarginLength.value();
   5089         margin = marginStart + marginEnd;
   5090 
   5091         int w = child->minPreferredLogicalWidth() + margin;
   5092         m_minPreferredLogicalWidth = max(w, m_minPreferredLogicalWidth);
   5093 
   5094         // IE ignores tables for calculation of nowrap. Makes some sense.
   5095         if (nowrap && !child->isTable())
   5096             m_maxPreferredLogicalWidth = max(w, m_maxPreferredLogicalWidth);
   5097 
   5098         w = child->maxPreferredLogicalWidth() + margin;
   5099 
   5100         if (!child->isFloating()) {
   5101             if (child->isBox() && toRenderBox(child)->avoidsFloats()) {
   5102                 // Determine a left and right max value based off whether or not the floats can fit in the
   5103                 // margins of the object.  For negative margins, we will attempt to overlap the float if the negative margin
   5104                 // is smaller than the float width.
   5105                 bool ltr = containingBlock()->style()->isLeftToRightDirection();
   5106                 int marginLogicalLeft = ltr ? marginStart : marginEnd;
   5107                 int marginLogicalRight = ltr ? marginEnd : marginStart;
   5108                 int maxLeft = marginLogicalLeft > 0 ? max(floatLeftWidth, marginLogicalLeft) : floatLeftWidth + marginLogicalLeft;
   5109                 int maxRight = marginLogicalRight > 0 ? max(floatRightWidth, marginLogicalRight) : floatRightWidth + marginLogicalRight;
   5110                 w = child->maxPreferredLogicalWidth() + maxLeft + maxRight;
   5111                 w = max(w, floatLeftWidth + floatRightWidth);
   5112             }
   5113             else
   5114                 m_maxPreferredLogicalWidth = max(floatLeftWidth + floatRightWidth, m_maxPreferredLogicalWidth);
   5115             floatLeftWidth = floatRightWidth = 0;
   5116         }
   5117 
   5118         if (child->isFloating()) {
   5119             if (style()->floating() == FLEFT)
   5120                 floatLeftWidth += w;
   5121             else
   5122                 floatRightWidth += w;
   5123         } else
   5124             m_maxPreferredLogicalWidth = max(w, m_maxPreferredLogicalWidth);
   5125 
   5126         // A very specific WinIE quirk.
   5127         // Example:
   5128         /*
   5129            <div style="position:absolute; width:100px; top:50px;">
   5130               <div style="position:absolute;left:0px;top:50px;height:50px;background-color:green">
   5131                 <table style="width:100%"><tr><td></table>
   5132               </div>
   5133            </div>
   5134         */
   5135         // In the above example, the inner absolute positioned block should have a computed width
   5136         // of 100px because of the table.
   5137         // We can achieve this effect by making the maxwidth of blocks that contain tables
   5138         // with percentage widths be infinite (as long as they are not inside a table cell).
   5139         if (document()->inQuirksMode() && child->style()->logicalWidth().isPercent() &&
   5140             !isTableCell() && child->isTable() && m_maxPreferredLogicalWidth < BLOCK_MAX_WIDTH) {
   5141             RenderBlock* cb = containingBlock();
   5142             while (!cb->isRenderView() && !cb->isTableCell())
   5143                 cb = cb->containingBlock();
   5144             if (!cb->isTableCell())
   5145                 m_maxPreferredLogicalWidth = BLOCK_MAX_WIDTH;
   5146         }
   5147 
   5148         child = child->nextSibling();
   5149     }
   5150 
   5151     // Always make sure these values are non-negative.
   5152     m_minPreferredLogicalWidth = max(0, m_minPreferredLogicalWidth);
   5153     m_maxPreferredLogicalWidth = max(0, m_maxPreferredLogicalWidth);
   5154 
   5155     m_maxPreferredLogicalWidth = max(floatLeftWidth + floatRightWidth, m_maxPreferredLogicalWidth);
   5156 }
   5157 
   5158 bool RenderBlock::hasLineIfEmpty() const
   5159 {
   5160     if (!node())
   5161         return false;
   5162 
   5163     if (node()->rendererIsEditable() && node()->rootEditableElement() == node())
   5164         return true;
   5165 
   5166     if (node()->isShadowRoot() && (node()->shadowHost()->hasTagName(inputTag)))
   5167         return true;
   5168 
   5169     return false;
   5170 }
   5171 
   5172 int RenderBlock::lineHeight(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
   5173 {
   5174     // Inline blocks are replaced elements. Otherwise, just pass off to
   5175     // the base class.  If we're being queried as though we're the root line
   5176     // box, then the fact that we're an inline-block is irrelevant, and we behave
   5177     // just like a block.
   5178     if (isReplaced() && linePositionMode == PositionOnContainingLine)
   5179         return RenderBox::lineHeight(firstLine, direction, linePositionMode);
   5180 
   5181     if (firstLine && document()->usesFirstLineRules()) {
   5182         RenderStyle* s = style(firstLine);
   5183         if (s != style())
   5184             return s->computedLineHeight();
   5185     }
   5186 
   5187     if (m_lineHeight == -1)
   5188         m_lineHeight = style()->computedLineHeight();
   5189 
   5190     return m_lineHeight;
   5191 }
   5192 
   5193 int RenderBlock::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
   5194 {
   5195     // Inline blocks are replaced elements. Otherwise, just pass off to
   5196     // the base class.  If we're being queried as though we're the root line
   5197     // box, then the fact that we're an inline-block is irrelevant, and we behave
   5198     // just like a block.
   5199     if (isReplaced() && linePositionMode == PositionOnContainingLine) {
   5200         // For "leaf" theme objects, let the theme decide what the baseline position is.
   5201         // FIXME: Might be better to have a custom CSS property instead, so that if the theme
   5202         // is turned off, checkboxes/radios will still have decent baselines.
   5203         // FIXME: Need to patch form controls to deal with vertical lines.
   5204         if (style()->hasAppearance() && !theme()->isControlContainer(style()->appearance()))
   5205             return theme()->baselinePosition(this);
   5206 
   5207         // CSS2.1 states that the baseline of an inline block is the baseline of the last line box in
   5208         // the normal flow.  We make an exception for marquees, since their baselines are meaningless
   5209         // (the content inside them moves).  This matches WinIE as well, which just bottom-aligns them.
   5210         // We also give up on finding a baseline if we have a vertical scrollbar, or if we are scrolled
   5211         // vertically (e.g., an overflow:hidden block that has had scrollTop moved) or if the baseline is outside
   5212         // of our content box.
   5213         bool ignoreBaseline = (layer() && (layer()->marquee() || (direction == HorizontalLine ? (layer()->verticalScrollbar() || layer()->scrollYOffset() != 0)
   5214             : (layer()->horizontalScrollbar() || layer()->scrollXOffset() != 0)))) || (isWritingModeRoot() && !isRubyRun());
   5215 
   5216         int baselinePos = ignoreBaseline ? -1 : lastLineBoxBaseline();
   5217 
   5218         int bottomOfContent = direction == HorizontalLine ? borderTop() + paddingTop() + contentHeight() : borderRight() + paddingRight() + contentWidth();
   5219         if (baselinePos != -1 && baselinePos <= bottomOfContent)
   5220             return direction == HorizontalLine ? marginTop() + baselinePos : marginRight() + baselinePos;
   5221 
   5222         return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
   5223     }
   5224 
   5225     const FontMetrics& fontMetrics = style(firstLine)->fontMetrics();
   5226     return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2;
   5227 }
   5228 
   5229 int RenderBlock::firstLineBoxBaseline() const
   5230 {
   5231     if (!isBlockFlow() || (isWritingModeRoot() && !isRubyRun()))
   5232         return -1;
   5233 
   5234     if (childrenInline()) {
   5235         if (firstLineBox())
   5236             return firstLineBox()->logicalTop() + style(true)->fontMetrics().ascent(firstRootBox()->baselineType());
   5237         else
   5238             return -1;
   5239     }
   5240     else {
   5241         for (RenderBox* curr = firstChildBox(); curr; curr = curr->nextSiblingBox()) {
   5242             if (!curr->isFloatingOrPositioned()) {
   5243                 int result = curr->firstLineBoxBaseline();
   5244                 if (result != -1)
   5245                     return curr->logicalTop() + result; // Translate to our coordinate space.
   5246             }
   5247         }
   5248     }
   5249 
   5250     return -1;
   5251 }
   5252 
   5253 int RenderBlock::lastLineBoxBaseline() const
   5254 {
   5255     if (!isBlockFlow() || (isWritingModeRoot() && !isRubyRun()))
   5256         return -1;
   5257 
   5258     LineDirectionMode lineDirection = isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
   5259 
   5260     if (childrenInline()) {
   5261         if (!firstLineBox() && hasLineIfEmpty()) {
   5262             const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
   5263             return fontMetrics.ascent()
   5264                  + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
   5265                  + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
   5266         }
   5267         if (lastLineBox())
   5268             return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->fontMetrics().ascent(lastRootBox()->baselineType());
   5269         return -1;
   5270     } else {
   5271         bool haveNormalFlowChild = false;
   5272         for (RenderBox* curr = lastChildBox(); curr; curr = curr->previousSiblingBox()) {
   5273             if (!curr->isFloatingOrPositioned()) {
   5274                 haveNormalFlowChild = true;
   5275                 int result = curr->lastLineBoxBaseline();
   5276                 if (result != -1)
   5277                     return curr->logicalTop() + result; // Translate to our coordinate space.
   5278             }
   5279         }
   5280         if (!haveNormalFlowChild && hasLineIfEmpty()) {
   5281             const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
   5282             return fontMetrics.ascent()
   5283                  + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
   5284                  + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
   5285         }
   5286     }
   5287 
   5288     return -1;
   5289 }
   5290 
   5291 bool RenderBlock::containsNonZeroBidiLevel() const
   5292 {
   5293     for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
   5294         for (InlineBox* box = root->firstLeafChild(); box; box = box->nextLeafChild()) {
   5295             if (box->bidiLevel())
   5296                 return true;
   5297         }
   5298     }
   5299     return false;
   5300 }
   5301 
   5302 RenderBlock* RenderBlock::firstLineBlock() const
   5303 {
   5304     RenderBlock* firstLineBlock = const_cast<RenderBlock*>(this);
   5305     bool hasPseudo = false;
   5306     while (true) {
   5307         hasPseudo = firstLineBlock->style()->hasPseudoStyle(FIRST_LINE);
   5308         if (hasPseudo)
   5309             break;
   5310         RenderObject* parentBlock = firstLineBlock->parent();
   5311         if (firstLineBlock->isReplaced() || firstLineBlock->isFloating() ||
   5312             !parentBlock || parentBlock->firstChild() != firstLineBlock || !parentBlock->isBlockFlow())
   5313             break;
   5314         ASSERT(parentBlock->isRenderBlock());
   5315         firstLineBlock = toRenderBlock(parentBlock);
   5316     }
   5317 
   5318     if (!hasPseudo)
   5319         return 0;
   5320 
   5321     return firstLineBlock;
   5322 }
   5323 
   5324 static RenderStyle* styleForFirstLetter(RenderObject* firstLetterBlock, RenderObject* firstLetterContainer)
   5325 {
   5326     RenderStyle* pseudoStyle = firstLetterBlock->getCachedPseudoStyle(FIRST_LETTER, firstLetterContainer->firstLineStyle());
   5327     // Force inline display (except for floating first-letters).
   5328     pseudoStyle->setDisplay(pseudoStyle->isFloating() ? BLOCK : INLINE);
   5329     // CSS2 says first-letter can't be positioned.
   5330     pseudoStyle->setPosition(StaticPosition);
   5331     return pseudoStyle;
   5332 }
   5333 
   5334 // CSS 2.1 http://www.w3.org/TR/CSS21/selector.html#first-letter
   5335 // "Punctuation (i.e, characters defined in Unicode [UNICODE] in the "open" (Ps), "close" (Pe),
   5336 // "initial" (Pi). "final" (Pf) and "other" (Po) punctuation classes), that precedes or follows the first letter should be included"
   5337 static inline bool isPunctuationForFirstLetter(UChar c)
   5338 {
   5339     CharCategory charCategory = category(c);
   5340     return charCategory == Punctuation_Open
   5341         || charCategory == Punctuation_Close
   5342         || charCategory == Punctuation_InitialQuote
   5343         || charCategory == Punctuation_FinalQuote
   5344         || charCategory == Punctuation_Other;
   5345 }
   5346 
   5347 static inline bool shouldSkipForFirstLetter(UChar c)
   5348 {
   5349     return isSpaceOrNewline(c) || c == noBreakSpace || isPunctuationForFirstLetter(c);
   5350 }
   5351 
   5352 void RenderBlock::updateFirstLetter()
   5353 {
   5354     if (!document()->usesFirstLetterRules())
   5355         return;
   5356     // Don't recur
   5357     if (style()->styleType() == FIRST_LETTER)
   5358         return;
   5359 
   5360     // FIXME: We need to destroy the first-letter object if it is no longer the first child.  Need to find
   5361     // an efficient way to check for that situation though before implementing anything.
   5362     RenderObject* firstLetterBlock = this;
   5363     bool hasPseudoStyle = false;
   5364     while (true) {
   5365         // We only honor first-letter if the firstLetterBlock can have children in the DOM. This correctly
   5366         // prevents form controls from honoring first-letter.
   5367         hasPseudoStyle = firstLetterBlock->style()->hasPseudoStyle(FIRST_LETTER)
   5368             && firstLetterBlock->canHaveChildren();
   5369         if (hasPseudoStyle)
   5370             break;
   5371         RenderObject* parentBlock = firstLetterBlock->parent();
   5372         if (firstLetterBlock->isReplaced() || !parentBlock || parentBlock->firstChild() != firstLetterBlock ||
   5373             !parentBlock->isBlockFlow())
   5374             break;
   5375         firstLetterBlock = parentBlock;
   5376     }
   5377 
   5378     if (!hasPseudoStyle)
   5379         return;
   5380 
   5381     // Drill into inlines looking for our first text child.
   5382     RenderObject* currChild = firstLetterBlock->firstChild();
   5383     while (currChild) {
   5384         if (currChild->isText())
   5385             break;
   5386         if (currChild->isListMarker())
   5387             currChild = currChild->nextSibling();
   5388         else if (currChild->isFloatingOrPositioned()) {
   5389             if (currChild->style()->styleType() == FIRST_LETTER) {
   5390                 currChild = currChild->firstChild();
   5391                 break;
   5392             }
   5393             currChild = currChild->nextSibling();
   5394         } else if (currChild->isReplaced() || currChild->isRenderButton() || currChild->isMenuList())
   5395             break;
   5396         else if (currChild->style()->hasPseudoStyle(FIRST_LETTER) && currChild->canHaveChildren())  {
   5397             // We found a lower-level node with first-letter, which supersedes the higher-level style
   5398             firstLetterBlock = currChild;
   5399             currChild = currChild->firstChild();
   5400         }
   5401         else
   5402             currChild = currChild->firstChild();
   5403     }
   5404 
   5405     if (!currChild)
   5406         return;
   5407 
   5408     // If the child already has style, then it has already been created, so we just want
   5409     // to update it.
   5410     if (currChild->parent()->style()->styleType() == FIRST_LETTER) {
   5411         RenderObject* firstLetter = currChild->parent();
   5412         RenderObject* firstLetterContainer = firstLetter->parent();
   5413         RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
   5414 
   5415         if (Node::diff(firstLetter->style(), pseudoStyle) == Node::Detach) {
   5416             // The first-letter renderer needs to be replaced. Create a new renderer of the right type.
   5417             RenderObject* newFirstLetter;
   5418             if (pseudoStyle->display() == INLINE)
   5419                 newFirstLetter = new (renderArena()) RenderInline(document());
   5420             else
   5421                 newFirstLetter = new (renderArena()) RenderBlock(document());
   5422             newFirstLetter->setStyle(pseudoStyle);
   5423 
   5424             // Move the first letter into the new renderer.
   5425             view()->disableLayoutState();
   5426             while (RenderObject* child = firstLetter->firstChild()) {
   5427                 if (child->isText())
   5428                     toRenderText(child)->removeAndDestroyTextBoxes();
   5429                 firstLetter->removeChild(child);
   5430                 newFirstLetter->addChild(child, 0);
   5431             }
   5432 
   5433             RenderTextFragment* remainingText = 0;
   5434             RenderObject* nextSibling = firstLetter->nextSibling();
   5435             RenderObject* next = nextSibling;
   5436             while (next) {
   5437                 if (next->isText() && toRenderText(next)->isTextFragment()) {
   5438                     remainingText = toRenderTextFragment(next);
   5439                     break;
   5440                 }
   5441                 next = next->nextSibling();
   5442             }
   5443             if (remainingText) {
   5444                 ASSERT(remainingText->node()->renderer() == remainingText);
   5445                 // Replace the old renderer with the new one.
   5446                 remainingText->setFirstLetter(newFirstLetter);
   5447             }
   5448             firstLetter->destroy();
   5449             firstLetter = newFirstLetter;
   5450             firstLetterContainer->addChild(firstLetter, nextSibling);
   5451             view()->enableLayoutState();
   5452         } else
   5453             firstLetter->setStyle(pseudoStyle);
   5454 
   5455         for (RenderObject* genChild = firstLetter->firstChild(); genChild; genChild = genChild->nextSibling()) {
   5456             if (genChild->isText())
   5457                 genChild->setStyle(pseudoStyle);
   5458         }
   5459 
   5460         return;
   5461     }
   5462 
   5463     if (!currChild->isText() || currChild->isBR())
   5464         return;
   5465 
   5466     // If the child does not already have style, we create it here.
   5467     RenderObject* firstLetterContainer = currChild->parent();
   5468 
   5469     // Our layout state is not valid for the repaints we are going to trigger by
   5470     // adding and removing children of firstLetterContainer.
   5471     view()->disableLayoutState();
   5472 
   5473     RenderText* textObj = toRenderText(currChild);
   5474 
   5475     // Create our pseudo style now that we have our firstLetterContainer determined.
   5476     RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
   5477 
   5478     RenderObject* firstLetter = 0;
   5479     if (pseudoStyle->display() == INLINE)
   5480         firstLetter = new (renderArena()) RenderInline(document());
   5481     else
   5482         firstLetter = new (renderArena()) RenderBlock(document());
   5483     firstLetter->setStyle(pseudoStyle);
   5484     firstLetterContainer->addChild(firstLetter, currChild);
   5485 
   5486     // The original string is going to be either a generated content string or a DOM node's
   5487     // string.  We want the original string before it got transformed in case first-letter has
   5488     // no text-transform or a different text-transform applied to it.
   5489     RefPtr<StringImpl> oldText = textObj->originalText();
   5490     ASSERT(oldText);
   5491 
   5492     if (oldText && oldText->length() > 0) {
   5493         unsigned length = 0;
   5494 
   5495         // Account for leading spaces and punctuation.
   5496         while (length < oldText->length() && shouldSkipForFirstLetter((*oldText)[length]))
   5497             length++;
   5498 
   5499         // Account for first letter.
   5500         length++;
   5501 
   5502         // Keep looking for whitespace and allowed punctuation, but avoid
   5503         // accumulating just whitespace into the :first-letter.
   5504         for (unsigned scanLength = length; scanLength < oldText->length(); ++scanLength) {
   5505             UChar c = (*oldText)[scanLength];
   5506 
   5507             if (!shouldSkipForFirstLetter(c))
   5508                 break;
   5509 
   5510             if (isPunctuationForFirstLetter(c))
   5511                 length = scanLength + 1;
   5512          }
   5513 
   5514         // Construct a text fragment for the text after the first letter.
   5515         // This text fragment might be empty.
   5516         RenderTextFragment* remainingText =
   5517             new (renderArena()) RenderTextFragment(textObj->node() ? textObj->node() : textObj->document(), oldText.get(), length, oldText->length() - length);
   5518         remainingText->setStyle(textObj->style());
   5519         if (remainingText->node())
   5520             remainingText->node()->setRenderer(remainingText);
   5521 
   5522         firstLetterContainer->addChild(remainingText, textObj);
   5523         firstLetterContainer->removeChild(textObj);
   5524         remainingText->setFirstLetter(firstLetter);
   5525 
   5526         // construct text fragment for the first letter
   5527         RenderTextFragment* letter =
   5528             new (renderArena()) RenderTextFragment(remainingText->node() ? remainingText->node() : remainingText->document(), oldText.get(), 0, length);
   5529         letter->setStyle(pseudoStyle);
   5530         firstLetter->addChild(letter);
   5531 
   5532         textObj->destroy();
   5533     }
   5534     view()->enableLayoutState();
   5535 }
   5536 
   5537 // Helper methods for obtaining the last line, computing line counts and heights for line counts
   5538 // (crawling into blocks).
   5539 static bool shouldCheckLines(RenderObject* obj)
   5540 {
   5541     return !obj->isFloatingOrPositioned() && !obj->isRunIn() &&
   5542             obj->isBlockFlow() && obj->style()->height().isAuto() &&
   5543             (!obj->isFlexibleBox() || obj->style()->boxOrient() == VERTICAL);
   5544 }
   5545 
   5546 static RootInlineBox* getLineAtIndex(RenderBlock* block, int i, int& count)
   5547 {
   5548     if (block->style()->visibility() == VISIBLE) {
   5549         if (block->childrenInline()) {
   5550             for (RootInlineBox* box = block->firstRootBox(); box; box = box->nextRootBox()) {
   5551                 if (count++ == i)
   5552                     return box;
   5553             }
   5554         }
   5555         else {
   5556             for (RenderObject* obj = block->firstChild(); obj; obj = obj->nextSibling()) {
   5557                 if (shouldCheckLines(obj)) {
   5558                     RootInlineBox *box = getLineAtIndex(toRenderBlock(obj), i, count);
   5559                     if (box)
   5560                         return box;
   5561                 }
   5562             }
   5563         }
   5564     }
   5565     return 0;
   5566 }
   5567 
   5568 static int getHeightForLineCount(RenderBlock* block, int l, bool includeBottom, int& count)
   5569 {
   5570     if (block->style()->visibility() == VISIBLE) {
   5571         if (block->childrenInline()) {
   5572             for (RootInlineBox* box = block->firstRootBox(); box; box = box->nextRootBox()) {
   5573                 if (++count == l)
   5574                     return box->lineBottom() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : 0);
   5575             }
   5576         }
   5577         else {
   5578             RenderBox* normalFlowChildWithoutLines = 0;
   5579             for (RenderBox* obj = block->firstChildBox(); obj; obj = obj->nextSiblingBox()) {
   5580                 if (shouldCheckLines(obj)) {
   5581                     int result = getHeightForLineCount(toRenderBlock(obj), l, false, count);
   5582                     if (result != -1)
   5583                         return result + obj->y() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : 0);
   5584                 }
   5585                 else if (!obj->isFloatingOrPositioned() && !obj->isRunIn())
   5586                     normalFlowChildWithoutLines = obj;
   5587             }
   5588             if (normalFlowChildWithoutLines && l == 0)
   5589                 return normalFlowChildWithoutLines->y() + normalFlowChildWithoutLines->height();
   5590         }
   5591     }
   5592 
   5593     return -1;
   5594 }
   5595 
   5596 RootInlineBox* RenderBlock::lineAtIndex(int i)
   5597 {
   5598     int count = 0;
   5599     return getLineAtIndex(this, i, count);
   5600 }
   5601 
   5602 int RenderBlock::lineCount()
   5603 {
   5604     int count = 0;
   5605     if (style()->visibility() == VISIBLE) {
   5606         if (childrenInline())
   5607             for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
   5608                 count++;
   5609         else
   5610             for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling())
   5611                 if (shouldCheckLines(obj))
   5612                     count += toRenderBlock(obj)->lineCount();
   5613     }
   5614     return count;
   5615 }
   5616 
   5617 int RenderBlock::heightForLineCount(int l)
   5618 {
   5619     int count = 0;
   5620     return getHeightForLineCount(this, l, true, count);
   5621 }
   5622 
   5623 void RenderBlock::adjustForBorderFit(int x, int& left, int& right) const
   5624 {
   5625     // We don't deal with relative positioning.  Our assumption is that you shrink to fit the lines without accounting
   5626     // for either overflow or translations via relative positioning.
   5627     if (style()->visibility() == VISIBLE) {
   5628         if (childrenInline()) {
   5629             for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) {
   5630                 if (box->firstChild())
   5631                     left = min(left, x + static_cast<int>(box->firstChild()->x()));
   5632                 if (box->lastChild())
   5633                     right = max(right, x + static_cast<int>(ceilf(box->lastChild()->logicalRight())));
   5634             }
   5635         }
   5636         else {
   5637             for (RenderBox* obj = firstChildBox(); obj; obj = obj->nextSiblingBox()) {
   5638                 if (!obj->isFloatingOrPositioned()) {
   5639                     if (obj->isBlockFlow() && !obj->hasOverflowClip())
   5640                         toRenderBlock(obj)->adjustForBorderFit(x + obj->x(), left, right);
   5641                     else if (obj->style()->visibility() == VISIBLE) {
   5642                         // We are a replaced element or some kind of non-block-flow object.
   5643                         left = min(left, x + obj->x());
   5644                         right = max(right, x + obj->x() + obj->width());
   5645                     }
   5646                 }
   5647             }
   5648         }
   5649 
   5650         if (m_floatingObjects) {
   5651             FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   5652             FloatingObjectSetIterator end = floatingObjectSet.end();
   5653             for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   5654                 FloatingObject* r = *it;
   5655                 // Only examine the object if our m_shouldPaint flag is set.
   5656                 if (r->m_shouldPaint) {
   5657                     int floatLeft = xPositionForFloatIncludingMargin(r) - r->m_renderer->x();
   5658                     int floatRight = floatLeft + r->m_renderer->width();
   5659                     left = min(left, floatLeft);
   5660                     right = max(right, floatRight);
   5661                 }
   5662             }
   5663         }
   5664     }
   5665 }
   5666 
   5667 void RenderBlock::borderFitAdjust(int& x, int& w) const
   5668 {
   5669     if (style()->borderFit() == BorderFitBorder)
   5670         return;
   5671 
   5672     // Walk any normal flow lines to snugly fit.
   5673     int left = INT_MAX;
   5674     int right = INT_MIN;
   5675     int oldWidth = w;
   5676     adjustForBorderFit(0, left, right);
   5677     if (left != INT_MAX) {
   5678         left -= (borderLeft() + paddingLeft());
   5679         if (left > 0) {
   5680             x += left;
   5681             w -= left;
   5682         }
   5683     }
   5684     if (right != INT_MIN) {
   5685         right += (borderRight() + paddingRight());
   5686         if (right < oldWidth)
   5687             w -= (oldWidth - right);
   5688     }
   5689 }
   5690 
   5691 void RenderBlock::clearTruncation()
   5692 {
   5693     if (style()->visibility() == VISIBLE) {
   5694         if (childrenInline() && hasMarkupTruncation()) {
   5695             setHasMarkupTruncation(false);
   5696             for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
   5697                 box->clearTruncation();
   5698         }
   5699         else
   5700             for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling())
   5701                 if (shouldCheckLines(obj))
   5702                     toRenderBlock(obj)->clearTruncation();
   5703     }
   5704 }
   5705 
   5706 void RenderBlock::setMaxMarginBeforeValues(int pos, int neg)
   5707 {
   5708     if (!m_rareData) {
   5709         if (pos == RenderBlockRareData::positiveMarginBeforeDefault(this) && neg == RenderBlockRareData::negativeMarginBeforeDefault(this))
   5710             return;
   5711         m_rareData = new RenderBlockRareData(this);
   5712     }
   5713     m_rareData->m_margins.setPositiveMarginBefore(pos);
   5714     m_rareData->m_margins.setNegativeMarginBefore(neg);
   5715 }
   5716 
   5717 void RenderBlock::setMaxMarginAfterValues(int pos, int neg)
   5718 {
   5719     if (!m_rareData) {
   5720         if (pos == RenderBlockRareData::positiveMarginAfterDefault(this) && neg == RenderBlockRareData::negativeMarginAfterDefault(this))
   5721             return;
   5722         m_rareData = new RenderBlockRareData(this);
   5723     }
   5724     m_rareData->m_margins.setPositiveMarginAfter(pos);
   5725     m_rareData->m_margins.setNegativeMarginAfter(neg);
   5726 }
   5727 
   5728 void RenderBlock::setPaginationStrut(int strut)
   5729 {
   5730     if (!m_rareData) {
   5731         if (!strut)
   5732             return;
   5733         m_rareData = new RenderBlockRareData(this);
   5734     }
   5735     m_rareData->m_paginationStrut = strut;
   5736 }
   5737 
   5738 void RenderBlock::setPageLogicalOffset(int logicalOffset)
   5739 {
   5740     if (!m_rareData) {
   5741         if (!logicalOffset)
   5742             return;
   5743         m_rareData = new RenderBlockRareData(this);
   5744     }
   5745     m_rareData->m_pageLogicalOffset = logicalOffset;
   5746 }
   5747 
   5748 void RenderBlock::absoluteRects(Vector<IntRect>& rects, int tx, int ty)
   5749 {
   5750     // For blocks inside inlines, we go ahead and include margins so that we run right up to the
   5751     // inline boxes above and below us (thus getting merged with them to form a single irregular
   5752     // shape).
   5753     if (isAnonymousBlockContinuation()) {
   5754         // FIXME: This is wrong for block-flows that are horizontal.
   5755         // https://bugs.webkit.org/show_bug.cgi?id=46781
   5756         rects.append(IntRect(tx, ty - collapsedMarginBefore(),
   5757                              width(), height() + collapsedMarginBefore() + collapsedMarginAfter()));
   5758         continuation()->absoluteRects(rects,
   5759                                       tx - x() + inlineElementContinuation()->containingBlock()->x(),
   5760                                       ty - y() + inlineElementContinuation()->containingBlock()->y());
   5761     } else
   5762         rects.append(IntRect(tx, ty, width(), height()));
   5763 }
   5764 
   5765 void RenderBlock::absoluteQuads(Vector<FloatQuad>& quads)
   5766 {
   5767     // For blocks inside inlines, we go ahead and include margins so that we run right up to the
   5768     // inline boxes above and below us (thus getting merged with them to form a single irregular
   5769     // shape).
   5770     if (isAnonymousBlockContinuation()) {
   5771         // FIXME: This is wrong for block-flows that are horizontal.
   5772         // https://bugs.webkit.org/show_bug.cgi?id=46781
   5773         FloatRect localRect(0, -collapsedMarginBefore(),
   5774                             width(), height() + collapsedMarginBefore() + collapsedMarginAfter());
   5775         quads.append(localToAbsoluteQuad(localRect));
   5776         continuation()->absoluteQuads(quads);
   5777     } else
   5778         quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width(), height())));
   5779 }
   5780 
   5781 IntRect RenderBlock::rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth)
   5782 {
   5783     IntRect r(RenderBox::rectWithOutlineForRepaint(repaintContainer, outlineWidth));
   5784     if (isAnonymousBlockContinuation())
   5785         r.inflateY(collapsedMarginBefore()); // FIXME: This is wrong for block-flows that are horizontal.
   5786     return r;
   5787 }
   5788 
   5789 RenderObject* RenderBlock::hoverAncestor() const
   5790 {
   5791     return isAnonymousBlockContinuation() ? continuation() : RenderBox::hoverAncestor();
   5792 }
   5793 
   5794 void RenderBlock::updateDragState(bool dragOn)
   5795 {
   5796     RenderBox::updateDragState(dragOn);
   5797     if (continuation())
   5798         continuation()->updateDragState(dragOn);
   5799 }
   5800 
   5801 RenderStyle* RenderBlock::outlineStyleForRepaint() const
   5802 {
   5803     return isAnonymousBlockContinuation() ? continuation()->style() : style();
   5804 }
   5805 
   5806 void RenderBlock::childBecameNonInline(RenderObject*)
   5807 {
   5808     makeChildrenNonInline();
   5809     if (isAnonymousBlock() && parent() && parent()->isRenderBlock())
   5810         toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
   5811     // |this| may be dead here
   5812 }
   5813 
   5814 void RenderBlock::updateHitTestResult(HitTestResult& result, const IntPoint& point)
   5815 {
   5816     if (result.innerNode())
   5817         return;
   5818 
   5819     Node* n = node();
   5820     if (isAnonymousBlockContinuation())
   5821         // We are in the margins of block elements that are part of a continuation.  In
   5822         // this case we're actually still inside the enclosing element that was
   5823         // split.  Go ahead and set our inner node accordingly.
   5824         n = continuation()->node();
   5825 
   5826     if (n) {
   5827         result.setInnerNode(n);
   5828         if (!result.innerNonSharedNode())
   5829             result.setInnerNonSharedNode(n);
   5830         result.setLocalPoint(point);
   5831     }
   5832 }
   5833 
   5834 IntRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, int* extraWidthToEndOfLine)
   5835 {
   5836     // Do the normal calculation in most cases.
   5837     if (firstChild())
   5838         return RenderBox::localCaretRect(inlineBox, caretOffset, extraWidthToEndOfLine);
   5839 
   5840     // This is a special case:
   5841     // The element is not an inline element, and it's empty. So we have to
   5842     // calculate a fake position to indicate where objects are to be inserted.
   5843 
   5844     // FIXME: This does not take into account either :first-line or :first-letter
   5845     // However, as soon as some content is entered, the line boxes will be
   5846     // constructed and this kludge is not called any more. So only the caret size
   5847     // of an empty :first-line'd block is wrong. I think we can live with that.
   5848     RenderStyle* currentStyle = firstLineStyle();
   5849     int height = lineHeight(true, currentStyle->isHorizontalWritingMode() ? HorizontalLine : VerticalLine);
   5850 
   5851     enum CaretAlignment { alignLeft, alignRight, alignCenter };
   5852 
   5853     CaretAlignment alignment = alignLeft;
   5854 
   5855     switch (currentStyle->textAlign()) {
   5856         case TAAUTO:
   5857         case JUSTIFY:
   5858             if (!currentStyle->isLeftToRightDirection())
   5859                 alignment = alignRight;
   5860             break;
   5861         case LEFT:
   5862         case WEBKIT_LEFT:
   5863             break;
   5864         case CENTER:
   5865         case WEBKIT_CENTER:
   5866             alignment = alignCenter;
   5867             break;
   5868         case RIGHT:
   5869         case WEBKIT_RIGHT:
   5870             alignment = alignRight;
   5871             break;
   5872         case TASTART:
   5873             if (!currentStyle->isLeftToRightDirection())
   5874                 alignment = alignRight;
   5875             break;
   5876         case TAEND:
   5877             if (currentStyle->isLeftToRightDirection())
   5878                 alignment = alignRight;
   5879             break;
   5880     }
   5881 
   5882     int x = borderLeft() + paddingLeft();
   5883     int w = width();
   5884 
   5885     switch (alignment) {
   5886         case alignLeft:
   5887             break;
   5888         case alignCenter:
   5889             x = (x + w - (borderRight() + paddingRight())) / 2;
   5890             break;
   5891         case alignRight:
   5892             x = w - (borderRight() + paddingRight()) - caretWidth;
   5893             break;
   5894     }
   5895 
   5896     if (extraWidthToEndOfLine) {
   5897         if (isRenderBlock()) {
   5898             *extraWidthToEndOfLine = w - (x + caretWidth);
   5899         } else {
   5900             // FIXME: This code looks wrong.
   5901             // myRight and containerRight are set up, but then clobbered.
   5902             // So *extraWidthToEndOfLine will always be 0 here.
   5903 
   5904             int myRight = x + caretWidth;
   5905             // FIXME: why call localToAbsoluteForContent() twice here, too?
   5906             FloatPoint absRightPoint = localToAbsolute(FloatPoint(myRight, 0));
   5907 
   5908             int containerRight = containingBlock()->x() + containingBlockLogicalWidthForContent();
   5909             FloatPoint absContainerPoint = localToAbsolute(FloatPoint(containerRight, 0));
   5910 
   5911             *extraWidthToEndOfLine = absContainerPoint.x() - absRightPoint.x();
   5912         }
   5913     }
   5914 
   5915     int y = paddingTop() + borderTop();
   5916 
   5917     return IntRect(x, y, caretWidth, height);
   5918 }
   5919 
   5920 void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
   5921 {
   5922     // For blocks inside inlines, we go ahead and include margins so that we run right up to the
   5923     // inline boxes above and below us (thus getting merged with them to form a single irregular
   5924     // shape).
   5925     if (inlineElementContinuation()) {
   5926         // FIXME: This check really isn't accurate.
   5927         bool nextInlineHasLineBox = inlineElementContinuation()->firstLineBox();
   5928         // FIXME: This is wrong. The principal renderer may not be the continuation preceding this block.
   5929         // FIXME: This is wrong for block-flows that are horizontal.
   5930         // https://bugs.webkit.org/show_bug.cgi?id=46781
   5931         bool prevInlineHasLineBox = toRenderInline(inlineElementContinuation()->node()->renderer())->firstLineBox();
   5932         int topMargin = prevInlineHasLineBox ? collapsedMarginBefore() : 0;
   5933         int bottomMargin = nextInlineHasLineBox ? collapsedMarginAfter() : 0;
   5934         IntRect rect(tx, ty - topMargin, width(), height() + topMargin + bottomMargin);
   5935         if (!rect.isEmpty())
   5936             rects.append(rect);
   5937     } else if (width() && height())
   5938         rects.append(IntRect(tx, ty, width(), height()));
   5939 
   5940     if (!hasOverflowClip() && !hasControlClip()) {
   5941         for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
   5942             int top = max(curr->lineTop(), curr->logicalTop());
   5943             int bottom = min(curr->lineBottom(), curr->logicalTop() + curr->logicalHeight());
   5944             IntRect rect(tx + curr->x(), ty + top, curr->logicalWidth(), bottom - top);
   5945             if (!rect.isEmpty())
   5946                 rects.append(rect);
   5947         }
   5948 
   5949         for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
   5950             if (!curr->isText() && !curr->isListMarker() && curr->isBox()) {
   5951                 RenderBox* box = toRenderBox(curr);
   5952                 FloatPoint pos;
   5953                 // FIXME: This doesn't work correctly with transforms.
   5954                 if (box->layer())
   5955                     pos = curr->localToAbsolute();
   5956                 else
   5957                     pos = FloatPoint(tx + box->x(), ty + box->y());
   5958                 box->addFocusRingRects(rects, pos.x(), pos.y());
   5959             }
   5960         }
   5961     }
   5962 
   5963     if (inlineElementContinuation())
   5964         inlineElementContinuation()->addFocusRingRects(rects,
   5965                                                        tx - x() + inlineElementContinuation()->containingBlock()->x(),
   5966                                                        ty - y() + inlineElementContinuation()->containingBlock()->y());
   5967 }
   5968 
   5969 RenderBlock* RenderBlock::createAnonymousBlock(bool isFlexibleBox) const
   5970 {
   5971     RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
   5972 
   5973     RenderBlock* newBox = 0;
   5974     if (isFlexibleBox) {
   5975         newStyle->setDisplay(BOX);
   5976         newBox = new (renderArena()) RenderFlexibleBox(document() /* anonymous box */);
   5977     } else {
   5978         newStyle->setDisplay(BLOCK);
   5979         newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
   5980     }
   5981 
   5982     newBox->setStyle(newStyle.release());
   5983     return newBox;
   5984 }
   5985 
   5986 RenderBlock* RenderBlock::createAnonymousBlockWithSameTypeAs(RenderBlock* otherAnonymousBlock) const
   5987 {
   5988     if (otherAnonymousBlock->isAnonymousColumnsBlock())
   5989         return createAnonymousColumnsBlock();
   5990     if (otherAnonymousBlock->isAnonymousColumnSpanBlock())
   5991         return createAnonymousColumnSpanBlock();
   5992     return createAnonymousBlock(otherAnonymousBlock->style()->display() == BOX);
   5993 }
   5994 
   5995 RenderBlock* RenderBlock::createAnonymousColumnsBlock() const
   5996 {
   5997     RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
   5998     newStyle->inheritColumnPropertiesFrom(style());
   5999     newStyle->setDisplay(BLOCK);
   6000 
   6001     RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
   6002     newBox->setStyle(newStyle.release());
   6003     return newBox;
   6004 }
   6005 
   6006 RenderBlock* RenderBlock::createAnonymousColumnSpanBlock() const
   6007 {
   6008     RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
   6009     newStyle->setColumnSpan(true);
   6010     newStyle->setDisplay(BLOCK);
   6011 
   6012     RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
   6013     newBox->setStyle(newStyle.release());
   6014     return newBox;
   6015 }
   6016 
   6017 int RenderBlock::nextPageLogicalTop(int logicalOffset) const
   6018 {
   6019     LayoutState* layoutState = view()->layoutState();
   6020     if (!layoutState->m_pageLogicalHeight)
   6021         return logicalOffset;
   6022 
   6023     // The logicalOffset is in our coordinate space.  We can add in our pushed offset.
   6024     int pageLogicalHeight = layoutState->m_pageLogicalHeight;
   6025     IntSize delta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
   6026     int offset = isHorizontalWritingMode() ? delta.height() : delta.width();
   6027     int remainingLogicalHeight = (pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight) % pageLogicalHeight;
   6028     return logicalOffset + remainingLogicalHeight;
   6029 }
   6030 
   6031 static bool inNormalFlow(RenderBox* child)
   6032 {
   6033     RenderBlock* curr = child->containingBlock();
   6034     RenderBlock* initialBlock = child->view();
   6035     while (curr && curr != initialBlock) {
   6036         if (curr->hasColumns())
   6037             return true;
   6038         if (curr->isFloatingOrPositioned())
   6039             return false;
   6040         curr = curr->containingBlock();
   6041     }
   6042     return true;
   6043 }
   6044 
   6045 int RenderBlock::applyBeforeBreak(RenderBox* child, int logicalOffset)
   6046 {
   6047     // FIXME: Add page break checking here when we support printing.
   6048     bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
   6049     bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight; // FIXME: Once columns can print we have to check this.
   6050     bool checkBeforeAlways = (checkColumnBreaks && child->style()->columnBreakBefore() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakBefore() == PBALWAYS);
   6051     if (checkBeforeAlways && inNormalFlow(child)) {
   6052         if (checkColumnBreaks)
   6053             view()->layoutState()->addForcedColumnBreak(logicalOffset);
   6054         return nextPageLogicalTop(logicalOffset);
   6055     }
   6056     return logicalOffset;
   6057 }
   6058 
   6059 int RenderBlock::applyAfterBreak(RenderBox* child, int logicalOffset, MarginInfo& marginInfo)
   6060 {
   6061     // FIXME: Add page break checking here when we support printing.
   6062     bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
   6063     bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight; // FIXME: Once columns can print we have to check this.
   6064     bool checkAfterAlways = (checkColumnBreaks && child->style()->columnBreakAfter() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakAfter() == PBALWAYS);
   6065     if (checkAfterAlways && inNormalFlow(child)) {
   6066         marginInfo.setMarginAfterQuirk(true); // Cause margins to be discarded for any following content.
   6067         if (checkColumnBreaks)
   6068             view()->layoutState()->addForcedColumnBreak(logicalOffset);
   6069         return nextPageLogicalTop(logicalOffset);
   6070     }
   6071     return logicalOffset;
   6072 }
   6073 
   6074 int RenderBlock::adjustForUnsplittableChild(RenderBox* child, int logicalOffset, bool includeMargins)
   6075 {
   6076     bool isUnsplittable = child->isReplaced() || child->scrollsOverflow();
   6077     if (!isUnsplittable)
   6078         return logicalOffset;
   6079     int childLogicalHeight = logicalHeightForChild(child) + (includeMargins ? marginBeforeForChild(child) + marginAfterForChild(child) : 0);
   6080     LayoutState* layoutState = view()->layoutState();
   6081     if (layoutState->m_columnInfo)
   6082         layoutState->m_columnInfo->updateMinimumColumnHeight(childLogicalHeight);
   6083     int pageLogicalHeight = layoutState->m_pageLogicalHeight;
   6084     if (!pageLogicalHeight || childLogicalHeight > pageLogicalHeight)
   6085         return logicalOffset;
   6086     IntSize delta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
   6087     int offset = isHorizontalWritingMode() ? delta.height() : delta.width();
   6088     int remainingLogicalHeight = (pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight) % pageLogicalHeight;
   6089     if (remainingLogicalHeight < childLogicalHeight)
   6090         return logicalOffset + remainingLogicalHeight;
   6091     return logicalOffset;
   6092 }
   6093 
   6094 void RenderBlock::adjustLinePositionForPagination(RootInlineBox* lineBox, int& delta)
   6095 {
   6096     // FIXME: For now we paginate using line overflow.  This ensures that lines don't overlap at all when we
   6097     // put a strut between them for pagination purposes.  However, this really isn't the desired rendering, since
   6098     // the line on the top of the next page will appear too far down relative to the same kind of line at the top
   6099     // of the first column.
   6100     //
   6101     // The rendering we would like to see is one where the lineTop is at the top of the column, and any line overflow
   6102     // simply spills out above the top of the column.  This effect would match what happens at the top of the first column.
   6103     // We can't achieve this rendering, however, until we stop columns from clipping to the column bounds (thus allowing
   6104     // for overflow to occur), and then cache visible overflow for each column rect.
   6105     //
   6106     // Furthermore, the paint we have to do when a column has overflow has to be special.  We need to exclude
   6107     // content that paints in a previous column (and content that paints in the following column).
   6108     //
   6109     // FIXME: Another problem with simply moving lines is that the available line width may change (because of floats).
   6110     // Technically if the location we move the line to has a different line width than our old position, then we need to dirty the
   6111     // line and all following lines.
   6112     LayoutState* layoutState = view()->layoutState();
   6113     int pageLogicalHeight = layoutState->m_pageLogicalHeight;
   6114     IntRect logicalVisualOverflow = lineBox->logicalVisualOverflowRect(lineBox->lineTop(), lineBox->lineBottom());
   6115     int logicalOffset = logicalVisualOverflow.y();
   6116     int lineHeight = logicalVisualOverflow.maxY() - logicalOffset;
   6117     if (layoutState->m_columnInfo)
   6118         layoutState->m_columnInfo->updateMinimumColumnHeight(lineHeight);
   6119     logicalOffset += delta;
   6120     lineBox->setPaginationStrut(0);
   6121     if (!pageLogicalHeight || lineHeight > pageLogicalHeight)
   6122         return;
   6123     IntSize offsetDelta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
   6124     int offset = isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.width();
   6125     int remainingLogicalHeight = pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight;
   6126     if (remainingLogicalHeight < lineHeight) {
   6127         int totalLogicalHeight = lineHeight + max(0, logicalOffset);
   6128         if (lineBox == firstRootBox() && totalLogicalHeight < pageLogicalHeight && !isPositioned() && !isTableCell())
   6129             setPaginationStrut(remainingLogicalHeight + max(0, logicalOffset));
   6130         else {
   6131             delta += remainingLogicalHeight;
   6132             lineBox->setPaginationStrut(remainingLogicalHeight);
   6133         }
   6134     }
   6135 }
   6136 
   6137 int RenderBlock::collapsedMarginBeforeForChild(RenderBox* child) const
   6138 {
   6139     // If the child has the same directionality as we do, then we can just return its
   6140     // collapsed margin.
   6141     if (!child->isWritingModeRoot())
   6142         return child->collapsedMarginBefore();
   6143 
   6144     // The child has a different directionality.  If the child is parallel, then it's just
   6145     // flipped relative to us.  We can use the collapsed margin for the opposite edge.
   6146     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
   6147         return child->collapsedMarginAfter();
   6148 
   6149     // The child is perpendicular to us, which means its margins don't collapse but are on the
   6150     // "logical left/right" sides of the child box.  We can just return the raw margin in this case.
   6151     return marginBeforeForChild(child);
   6152 }
   6153 
   6154 int RenderBlock::collapsedMarginAfterForChild(RenderBox* child) const
   6155 {
   6156     // If the child has the same directionality as we do, then we can just return its
   6157     // collapsed margin.
   6158     if (!child->isWritingModeRoot())
   6159         return child->collapsedMarginAfter();
   6160 
   6161     // The child has a different directionality.  If the child is parallel, then it's just
   6162     // flipped relative to us.  We can use the collapsed margin for the opposite edge.
   6163     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
   6164         return child->collapsedMarginBefore();
   6165 
   6166     // The child is perpendicular to us, which means its margins don't collapse but are on the
   6167     // "logical left/right" side of the child box.  We can just return the raw margin in this case.
   6168     return marginAfterForChild(child);
   6169 }
   6170 
   6171 int RenderBlock::marginBeforeForChild(RenderBoxModelObject* child) const
   6172 {
   6173     switch (style()->writingMode()) {
   6174     case TopToBottomWritingMode:
   6175         return child->marginTop();
   6176     case BottomToTopWritingMode:
   6177         return child->marginBottom();
   6178     case LeftToRightWritingMode:
   6179         return child->marginLeft();
   6180     case RightToLeftWritingMode:
   6181         return child->marginRight();
   6182     }
   6183     ASSERT_NOT_REACHED();
   6184     return child->marginTop();
   6185 }
   6186 
   6187 int RenderBlock::marginAfterForChild(RenderBoxModelObject* child) const
   6188 {
   6189     switch (style()->writingMode()) {
   6190     case TopToBottomWritingMode:
   6191         return child->marginBottom();
   6192     case BottomToTopWritingMode:
   6193         return child->marginTop();
   6194     case LeftToRightWritingMode:
   6195         return child->marginRight();
   6196     case RightToLeftWritingMode:
   6197         return child->marginLeft();
   6198     }
   6199     ASSERT_NOT_REACHED();
   6200     return child->marginBottom();
   6201 }
   6202 
   6203 int RenderBlock::marginStartForChild(RenderBoxModelObject* child) const
   6204 {
   6205     if (isHorizontalWritingMode())
   6206         return style()->isLeftToRightDirection() ? child->marginLeft() : child->marginRight();
   6207     return style()->isLeftToRightDirection() ? child->marginTop() : child->marginBottom();
   6208 }
   6209 
   6210 int RenderBlock::marginEndForChild(RenderBoxModelObject* child) const
   6211 {
   6212     if (isHorizontalWritingMode())
   6213         return style()->isLeftToRightDirection() ? child->marginRight() : child->marginLeft();
   6214     return style()->isLeftToRightDirection() ? child->marginBottom() : child->marginTop();
   6215 }
   6216 
   6217 void RenderBlock::setMarginStartForChild(RenderBox* child, int margin)
   6218 {
   6219     if (isHorizontalWritingMode()) {
   6220         if (style()->isLeftToRightDirection())
   6221             child->setMarginLeft(margin);
   6222         else
   6223             child->setMarginRight(margin);
   6224     } else {
   6225         if (style()->isLeftToRightDirection())
   6226             child->setMarginTop(margin);
   6227         else
   6228             child->setMarginBottom(margin);
   6229     }
   6230 }
   6231 
   6232 void RenderBlock::setMarginEndForChild(RenderBox* child, int margin)
   6233 {
   6234     if (isHorizontalWritingMode()) {
   6235         if (style()->isLeftToRightDirection())
   6236             child->setMarginRight(margin);
   6237         else
   6238             child->setMarginLeft(margin);
   6239     } else {
   6240         if (style()->isLeftToRightDirection())
   6241             child->setMarginBottom(margin);
   6242         else
   6243             child->setMarginTop(margin);
   6244     }
   6245 }
   6246 
   6247 void RenderBlock::setMarginBeforeForChild(RenderBox* child, int margin)
   6248 {
   6249     switch (style()->writingMode()) {
   6250     case TopToBottomWritingMode:
   6251         child->setMarginTop(margin);
   6252         break;
   6253     case BottomToTopWritingMode:
   6254         child->setMarginBottom(margin);
   6255         break;
   6256     case LeftToRightWritingMode:
   6257         child->setMarginLeft(margin);
   6258         break;
   6259     case RightToLeftWritingMode:
   6260         child->setMarginRight(margin);
   6261         break;
   6262     }
   6263 }
   6264 
   6265 void RenderBlock::setMarginAfterForChild(RenderBox* child, int margin)
   6266 {
   6267     switch (style()->writingMode()) {
   6268     case TopToBottomWritingMode:
   6269         child->setMarginBottom(margin);
   6270         break;
   6271     case BottomToTopWritingMode:
   6272         child->setMarginTop(margin);
   6273         break;
   6274     case LeftToRightWritingMode:
   6275         child->setMarginRight(margin);
   6276         break;
   6277     case RightToLeftWritingMode:
   6278         child->setMarginLeft(margin);
   6279         break;
   6280     }
   6281 }
   6282 
   6283 RenderBlock::MarginValues RenderBlock::marginValuesForChild(RenderBox* child)
   6284 {
   6285     int childBeforePositive = 0;
   6286     int childBeforeNegative = 0;
   6287     int childAfterPositive = 0;
   6288     int childAfterNegative = 0;
   6289 
   6290     int beforeMargin = 0;
   6291     int afterMargin = 0;
   6292 
   6293     RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0;
   6294 
   6295     // If the child has the same directionality as we do, then we can just return its
   6296     // margins in the same direction.
   6297     if (!child->isWritingModeRoot()) {
   6298         if (childRenderBlock) {
   6299             childBeforePositive = childRenderBlock->maxPositiveMarginBefore();
   6300             childBeforeNegative = childRenderBlock->maxNegativeMarginBefore();
   6301             childAfterPositive = childRenderBlock->maxPositiveMarginAfter();
   6302             childAfterNegative = childRenderBlock->maxNegativeMarginAfter();
   6303         } else {
   6304             beforeMargin = child->marginBefore();
   6305             afterMargin = child->marginAfter();
   6306         }
   6307     } else if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) {
   6308         // The child has a different directionality.  If the child is parallel, then it's just
   6309         // flipped relative to us.  We can use the margins for the opposite edges.
   6310         if (childRenderBlock) {
   6311             childBeforePositive = childRenderBlock->maxPositiveMarginAfter();
   6312             childBeforeNegative = childRenderBlock->maxNegativeMarginAfter();
   6313             childAfterPositive = childRenderBlock->maxPositiveMarginBefore();
   6314             childAfterNegative = childRenderBlock->maxNegativeMarginBefore();
   6315         } else {
   6316             beforeMargin = child->marginAfter();
   6317             afterMargin = child->marginBefore();
   6318         }
   6319     } else {
   6320         // The child is perpendicular to us, which means its margins don't collapse but are on the
   6321         // "logical left/right" sides of the child box.  We can just return the raw margin in this case.
   6322         beforeMargin = marginBeforeForChild(child);
   6323         afterMargin = marginAfterForChild(child);
   6324     }
   6325 
   6326     // Resolve uncollapsing margins into their positive/negative buckets.
   6327     if (beforeMargin) {
   6328         if (beforeMargin > 0)
   6329             childBeforePositive = beforeMargin;
   6330         else
   6331             childBeforeNegative = -beforeMargin;
   6332     }
   6333     if (afterMargin) {
   6334         if (afterMargin > 0)
   6335             childAfterPositive = afterMargin;
   6336         else
   6337             childAfterNegative = -afterMargin;
   6338     }
   6339 
   6340     return MarginValues(childBeforePositive, childBeforeNegative, childAfterPositive, childAfterNegative);
   6341 }
   6342 
   6343 const char* RenderBlock::renderName() const
   6344 {
   6345     if (isBody())
   6346         return "RenderBody"; // FIXME: Temporary hack until we know that the regression tests pass.
   6347 
   6348     if (isFloating())
   6349         return "RenderBlock (floating)";
   6350     if (isPositioned())
   6351         return "RenderBlock (positioned)";
   6352     if (isAnonymousColumnsBlock())
   6353         return "RenderBlock (anonymous multi-column)";
   6354     if (isAnonymousColumnSpanBlock())
   6355         return "RenderBlock (anonymous multi-column span)";
   6356     if (isAnonymousBlock())
   6357         return "RenderBlock (anonymous)";
   6358     else if (isAnonymous())
   6359         return "RenderBlock (generated)";
   6360     if (isRelPositioned())
   6361         return "RenderBlock (relative positioned)";
   6362     if (isRunIn())
   6363         return "RenderBlock (run-in)";
   6364     return "RenderBlock";
   6365 }
   6366 
   6367 inline void RenderBlock::FloatingObjects::clear()
   6368 {
   6369     m_set.clear();
   6370     m_leftObjectsCount = 0;
   6371     m_rightObjectsCount = 0;
   6372 }
   6373 
   6374 inline void RenderBlock::FloatingObjects::increaseObjectsCount(FloatingObject::Type type)
   6375 {
   6376     if (type == FloatingObject::FloatLeft)
   6377         m_leftObjectsCount++;
   6378     else
   6379         m_rightObjectsCount++;
   6380 }
   6381 
   6382 inline void RenderBlock::FloatingObjects::decreaseObjectsCount(FloatingObject::Type type)
   6383 {
   6384     if (type == FloatingObject::FloatLeft)
   6385         m_leftObjectsCount--;
   6386     else
   6387         m_rightObjectsCount--;
   6388 }
   6389 
   6390 } // namespace WebCore
   6391