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 (isInline() && 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     for (RenderObject* curr = this; curr; curr = curr->parent()) {
    424         if (!curr->isRenderBlock() || curr->isFloatingOrPositioned() || curr->isTableCell() || curr->isRoot() || curr->isRenderView() || curr->hasOverflowClip()
    425             || curr->isInlineBlockOrInlineTable())
    426             return 0;
    427 
    428         RenderBlock* currBlock = toRenderBlock(curr);
    429         if (currBlock->style()->specifiesColumns() && (allowAnonymousColumnBlock || !currBlock->isAnonymousColumnsBlock()))
    430             return currBlock;
    431 
    432         if (currBlock->isAnonymousColumnSpanBlock())
    433             return 0;
    434     }
    435     return 0;
    436 }
    437 
    438 RenderBlock* RenderBlock::clone() const
    439 {
    440     RenderBlock* cloneBlock;
    441     if (isAnonymousBlock())
    442         cloneBlock = createAnonymousBlock();
    443     else {
    444         cloneBlock = new (renderArena()) RenderBlock(node());
    445         cloneBlock->setStyle(style());
    446     }
    447     cloneBlock->setChildrenInline(childrenInline());
    448     return cloneBlock;
    449 }
    450 
    451 void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
    452                               RenderBlock* middleBlock,
    453                               RenderObject* beforeChild, RenderBoxModelObject* oldCont)
    454 {
    455     // Create a clone of this inline.
    456     RenderBlock* cloneBlock = clone();
    457     if (!isAnonymousBlock())
    458         cloneBlock->setContinuation(oldCont);
    459 
    460     // Now take all of the children from beforeChild to the end and remove
    461     // them from |this| and place them in the clone.
    462     if (!beforeChild && isAfterContent(lastChild()))
    463         beforeChild = lastChild();
    464     moveChildrenTo(cloneBlock, beforeChild, 0);
    465 
    466     // Hook |clone| up as the continuation of the middle block.
    467     if (!cloneBlock->isAnonymousBlock())
    468         middleBlock->setContinuation(cloneBlock);
    469 
    470     // We have been reparented and are now under the fromBlock.  We need
    471     // to walk up our block parent chain until we hit the containing anonymous columns block.
    472     // Once we hit the anonymous columns block we're done.
    473     RenderBoxModelObject* curr = toRenderBoxModelObject(parent());
    474     RenderBoxModelObject* currChild = this;
    475 
    476     while (curr && curr != fromBlock) {
    477         ASSERT(curr->isRenderBlock());
    478 
    479         RenderBlock* blockCurr = toRenderBlock(curr);
    480 
    481         // Create a new clone.
    482         RenderBlock* cloneChild = cloneBlock;
    483         cloneBlock = blockCurr->clone();
    484 
    485         // Insert our child clone as the first child.
    486         cloneBlock->children()->appendChildNode(cloneBlock, cloneChild);
    487 
    488         // Hook the clone up as a continuation of |curr|.  Note we do encounter
    489         // anonymous blocks possibly as we walk up the block chain.  When we split an
    490         // anonymous block, there's no need to do any continuation hookup, since we haven't
    491         // actually split a real element.
    492         if (!blockCurr->isAnonymousBlock()) {
    493             oldCont = blockCurr->continuation();
    494             blockCurr->setContinuation(cloneBlock);
    495             cloneBlock->setContinuation(oldCont);
    496         }
    497 
    498         // Someone may have indirectly caused a <q> to split.  When this happens, the :after content
    499         // has to move into the inline continuation.  Call updateBeforeAfterContent to ensure that the inline's :after
    500         // content gets properly destroyed.
    501         if (document()->usesBeforeAfterRules())
    502             blockCurr->children()->updateBeforeAfterContent(blockCurr, AFTER);
    503 
    504         // Now we need to take all of the children starting from the first child
    505         // *after* currChild and append them all to the clone.
    506         RenderObject* afterContent = isAfterContent(cloneBlock->lastChild()) ? cloneBlock->lastChild() : 0;
    507         blockCurr->moveChildrenTo(cloneBlock, currChild->nextSibling(), 0, afterContent);
    508 
    509         // Keep walking up the chain.
    510         currChild = curr;
    511         curr = toRenderBoxModelObject(curr->parent());
    512     }
    513 
    514     // Now we are at the columns block level. We need to put the clone into the toBlock.
    515     toBlock->children()->appendChildNode(toBlock, cloneBlock);
    516 
    517     // Now take all the children after currChild and remove them from the fromBlock
    518     // and put them in the toBlock.
    519     fromBlock->moveChildrenTo(toBlock, currChild->nextSibling(), 0);
    520 }
    521 
    522 void RenderBlock::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
    523                             RenderObject* newChild, RenderBoxModelObject* oldCont)
    524 {
    525     RenderBlock* pre = 0;
    526     RenderBlock* block = containingColumnsBlock();
    527 
    528     // Delete our line boxes before we do the inline split into continuations.
    529     block->deleteLineBoxTree();
    530 
    531     bool madeNewBeforeBlock = false;
    532     if (block->isAnonymousColumnsBlock()) {
    533         // We can reuse this block and make it the preBlock of the next continuation.
    534         pre = block;
    535         pre->removePositionedObjects(0);
    536         block = toRenderBlock(block->parent());
    537     } else {
    538         // No anonymous block available for use.  Make one.
    539         pre = block->createAnonymousColumnsBlock();
    540         pre->setChildrenInline(false);
    541         madeNewBeforeBlock = true;
    542     }
    543 
    544     RenderBlock* post = block->createAnonymousColumnsBlock();
    545     post->setChildrenInline(false);
    546 
    547     RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
    548     if (madeNewBeforeBlock)
    549         block->children()->insertChildNode(block, pre, boxFirst);
    550     block->children()->insertChildNode(block, newBlockBox, boxFirst);
    551     block->children()->insertChildNode(block, post, boxFirst);
    552     block->setChildrenInline(false);
    553 
    554     if (madeNewBeforeBlock)
    555         block->moveChildrenTo(pre, boxFirst, 0);
    556 
    557     splitBlocks(pre, post, newBlockBox, beforeChild, oldCont);
    558 
    559     // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
    560     // time in makeChildrenNonInline by just setting this explicitly up front.
    561     newBlockBox->setChildrenInline(false);
    562 
    563     // We delayed adding the newChild until now so that the |newBlockBox| would be fully
    564     // connected, thus allowing newChild access to a renderArena should it need
    565     // to wrap itself in additional boxes (e.g., table construction).
    566     newBlockBox->addChild(newChild);
    567 
    568     // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
    569     // get deleted properly.  Because objects moves from the pre block into the post block, we want to
    570     // make new line boxes instead of leaving the old line boxes around.
    571     pre->setNeedsLayoutAndPrefWidthsRecalc();
    572     block->setNeedsLayoutAndPrefWidthsRecalc();
    573     post->setNeedsLayoutAndPrefWidthsRecalc();
    574 }
    575 
    576 RenderObject* RenderBlock::splitAnonymousBlocksAroundChild(RenderObject* beforeChild)
    577 {
    578     while (beforeChild->parent() != this) {
    579         RenderBlock* blockToSplit = toRenderBlock(beforeChild->parent());
    580         if (blockToSplit->firstChild() != beforeChild) {
    581             // We have to split the parentBlock into two blocks.
    582             RenderBlock* post = createAnonymousBlockWithSameTypeAs(blockToSplit);
    583             post->setChildrenInline(blockToSplit->childrenInline());
    584             RenderBlock* parentBlock = toRenderBlock(blockToSplit->parent());
    585             parentBlock->children()->insertChildNode(parentBlock, post, blockToSplit->nextSibling());
    586             blockToSplit->moveChildrenTo(post, beforeChild, 0, blockToSplit->hasLayer());
    587             post->setNeedsLayoutAndPrefWidthsRecalc();
    588             blockToSplit->setNeedsLayoutAndPrefWidthsRecalc();
    589             beforeChild = post;
    590         } else
    591             beforeChild = blockToSplit;
    592     }
    593     return beforeChild;
    594 }
    595 
    596 void RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlock* newBlockBox, RenderObject* newChild)
    597 {
    598     RenderBlock* pre = 0;
    599     RenderBlock* post = 0;
    600     RenderBlock* block = this; // Eventually block will not just be |this|, but will also be a block nested inside |this|.  Assign to a variable
    601                                // so that we don't have to patch all of the rest of the code later on.
    602 
    603     // Delete the block's line boxes before we do the split.
    604     block->deleteLineBoxTree();
    605 
    606     if (beforeChild && beforeChild->parent() != this)
    607         beforeChild = splitAnonymousBlocksAroundChild(beforeChild);
    608 
    609     if (beforeChild != firstChild()) {
    610         pre = block->createAnonymousColumnsBlock();
    611         pre->setChildrenInline(block->childrenInline());
    612     }
    613 
    614     if (beforeChild) {
    615         post = block->createAnonymousColumnsBlock();
    616         post->setChildrenInline(block->childrenInline());
    617     }
    618 
    619     RenderObject* boxFirst = block->firstChild();
    620     if (pre)
    621         block->children()->insertChildNode(block, pre, boxFirst);
    622     block->children()->insertChildNode(block, newBlockBox, boxFirst);
    623     if (post)
    624         block->children()->insertChildNode(block, post, boxFirst);
    625     block->setChildrenInline(false);
    626 
    627     // 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).
    628     block->moveChildrenTo(pre, boxFirst, beforeChild, true);
    629     block->moveChildrenTo(post, beforeChild, 0, true);
    630 
    631     // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
    632     // time in makeChildrenNonInline by just setting this explicitly up front.
    633     newBlockBox->setChildrenInline(false);
    634 
    635     // We delayed adding the newChild until now so that the |newBlockBox| would be fully
    636     // connected, thus allowing newChild access to a renderArena should it need
    637     // to wrap itself in additional boxes (e.g., table construction).
    638     newBlockBox->addChild(newChild);
    639 
    640     // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
    641     // get deleted properly.  Because objects moved from the pre block into the post block, we want to
    642     // make new line boxes instead of leaving the old line boxes around.
    643     if (pre)
    644         pre->setNeedsLayoutAndPrefWidthsRecalc();
    645     block->setNeedsLayoutAndPrefWidthsRecalc();
    646     if (post)
    647         post->setNeedsLayoutAndPrefWidthsRecalc();
    648 }
    649 
    650 RenderBlock* RenderBlock::columnsBlockForSpanningElement(RenderObject* newChild)
    651 {
    652     // FIXME: This function is the gateway for the addition of column-span support.  It will
    653     // be added to in three stages:
    654     // (1) Immediate children of a multi-column block can span.
    655     // (2) Nested block-level children with only block-level ancestors between them and the multi-column block can span.
    656     // (3) Nested children with block or inline ancestors between them and the multi-column block can span (this is when we
    657     // cross the streams and have to cope with both types of continuations mixed together).
    658     // This function currently supports (1) and (2).
    659     RenderBlock* columnsBlockAncestor = 0;
    660     if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isFloatingOrPositioned()
    661         && !newChild->isInline() && !isAnonymousColumnSpanBlock()) {
    662         if (style()->specifiesColumns())
    663             columnsBlockAncestor = this;
    664         else if (parent() && parent()->isRenderBlock())
    665             columnsBlockAncestor = toRenderBlock(parent())->containingColumnsBlock(false);
    666     }
    667     return columnsBlockAncestor;
    668 }
    669 
    670 void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
    671 {
    672     // Make sure we don't append things after :after-generated content if we have it.
    673     if (!beforeChild) {
    674         RenderObject* lastRenderer = lastChild();
    675         if (isAfterContent(lastRenderer))
    676             beforeChild = lastRenderer;
    677         else if (lastRenderer && lastRenderer->isAnonymousBlock() && isAfterContent(lastRenderer->lastChild()))
    678             beforeChild = lastRenderer->lastChild();
    679     }
    680 
    681     // If the requested beforeChild is not one of our children, then this is because
    682     // there is an anonymous container within this object that contains the beforeChild.
    683     if (beforeChild && beforeChild->parent() != this) {
    684         RenderObject* anonymousChild = beforeChild->parent();
    685         ASSERT(anonymousChild);
    686 
    687         while (anonymousChild->parent() != this)
    688             anonymousChild = anonymousChild->parent();
    689 
    690         ASSERT(anonymousChild->isAnonymous());
    691 
    692         if (anonymousChild->isAnonymousBlock()) {
    693             // Insert the child into the anonymous block box instead of here.
    694             if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)
    695                 beforeChild->parent()->addChild(newChild, beforeChild);
    696             else
    697                 addChild(newChild, beforeChild->parent());
    698             return;
    699         }
    700 
    701         ASSERT(anonymousChild->isTable());
    702         if ((newChild->isTableCol() && newChild->style()->display() == TABLE_COLUMN_GROUP)
    703                 || (newChild->isRenderBlock() && newChild->style()->display() == TABLE_CAPTION)
    704                 || newChild->isTableSection()
    705                 || newChild->isTableRow()
    706                 || newChild->isTableCell()) {
    707             // Insert into the anonymous table.
    708             anonymousChild->addChild(newChild, beforeChild);
    709             return;
    710         }
    711 
    712         // Go on to insert before the anonymous table.
    713         beforeChild = anonymousChild;
    714     }
    715 
    716     // Check for a spanning element in columns.
    717     RenderBlock* columnsBlockAncestor = columnsBlockForSpanningElement(newChild);
    718     if (columnsBlockAncestor) {
    719         // We are placing a column-span element inside a block.
    720         RenderBlock* newBox = createAnonymousColumnSpanBlock();
    721 
    722         if (columnsBlockAncestor != this) {
    723             // We are nested inside a multi-column element and are being split by the span.  We have to break up
    724             // our block into continuations.
    725             RenderBoxModelObject* oldContinuation = continuation();
    726             setContinuation(newBox);
    727 
    728             // Someone may have put a <p> inside a <q>, causing a split.  When this happens, the :after content
    729             // has to move into the inline continuation.  Call updateBeforeAfterContent to ensure that our :after
    730             // content gets properly destroyed.
    731             bool isLastChild = (beforeChild == lastChild());
    732             if (document()->usesBeforeAfterRules())
    733                 children()->updateBeforeAfterContent(this, AFTER);
    734             if (isLastChild && beforeChild != lastChild())
    735                 beforeChild = 0; // We destroyed the last child, so now we need to update our insertion
    736                                  // point to be 0.  It's just a straight append now.
    737 
    738             splitFlow(beforeChild, newBox, newChild, oldContinuation);
    739             return;
    740         }
    741 
    742         // We have to perform a split of this block's children.  This involves creating an anonymous block box to hold
    743         // the column-spanning |newChild|.  We take all of the children from before |newChild| and put them into
    744         // one anonymous columns block, and all of the children after |newChild| go into another anonymous block.
    745         makeChildrenAnonymousColumnBlocks(beforeChild, newBox, newChild);
    746         return;
    747     }
    748 
    749     bool madeBoxesNonInline = false;
    750 
    751     // A block has to either have all of its children inline, or all of its children as blocks.
    752     // So, if our children are currently inline and a block child has to be inserted, we move all our
    753     // inline children into anonymous block boxes.
    754     if (childrenInline() && !newChild->isInline() && !newChild->isFloatingOrPositioned()) {
    755         // This is a block with inline content. Wrap the inline content in anonymous blocks.
    756         makeChildrenNonInline(beforeChild);
    757         madeBoxesNonInline = true;
    758 
    759         if (beforeChild && beforeChild->parent() != this) {
    760             beforeChild = beforeChild->parent();
    761             ASSERT(beforeChild->isAnonymousBlock());
    762             ASSERT(beforeChild->parent() == this);
    763         }
    764     } else if (!childrenInline() && (newChild->isFloatingOrPositioned() || newChild->isInline())) {
    765         // If we're inserting an inline child but all of our children are blocks, then we have to make sure
    766         // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise
    767         // a new one is created and inserted into our list of children in the appropriate position.
    768         RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();
    769 
    770         if (afterChild && afterChild->isAnonymousBlock()) {
    771             afterChild->addChild(newChild);
    772             return;
    773         }
    774 
    775         if (newChild->isInline()) {
    776             // No suitable existing anonymous box - create a new one.
    777             RenderBlock* newBox = createAnonymousBlock();
    778             RenderBox::addChild(newBox, beforeChild);
    779             newBox->addChild(newChild);
    780             return;
    781         }
    782     }
    783 
    784     RenderBox::addChild(newChild, beforeChild);
    785 
    786     if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRenderBlock())
    787         toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
    788     // this object may be dead here
    789 }
    790 
    791 void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
    792 {
    793     if (continuation() && !isAnonymousBlock())
    794         return addChildToContinuation(newChild, beforeChild);
    795     return addChildIgnoringContinuation(newChild, beforeChild);
    796 }
    797 
    798 void RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild)
    799 {
    800     if (!isAnonymousBlock() && firstChild() && (firstChild()->isAnonymousColumnsBlock() || firstChild()->isAnonymousColumnSpanBlock()))
    801         return addChildToAnonymousColumnBlocks(newChild, beforeChild);
    802     return addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
    803 }
    804 
    805 static void getInlineRun(RenderObject* start, RenderObject* boundary,
    806                          RenderObject*& inlineRunStart,
    807                          RenderObject*& inlineRunEnd)
    808 {
    809     // Beginning at |start| we find the largest contiguous run of inlines that
    810     // we can.  We denote the run with start and end points, |inlineRunStart|
    811     // and |inlineRunEnd|.  Note that these two values may be the same if
    812     // we encounter only one inline.
    813     //
    814     // We skip any non-inlines we encounter as long as we haven't found any
    815     // inlines yet.
    816     //
    817     // |boundary| indicates a non-inclusive boundary point.  Regardless of whether |boundary|
    818     // is inline or not, we will not include it in a run with inlines before it.  It's as though we encountered
    819     // a non-inline.
    820 
    821     // Start by skipping as many non-inlines as we can.
    822     RenderObject * curr = start;
    823     bool sawInline;
    824     do {
    825         while (curr && !(curr->isInline() || curr->isFloatingOrPositioned()))
    826             curr = curr->nextSibling();
    827 
    828         inlineRunStart = inlineRunEnd = curr;
    829 
    830         if (!curr)
    831             return; // No more inline children to be found.
    832 
    833         sawInline = curr->isInline();
    834 
    835         curr = curr->nextSibling();
    836         while (curr && (curr->isInline() || curr->isFloatingOrPositioned()) && (curr != boundary)) {
    837             inlineRunEnd = curr;
    838             if (curr->isInline())
    839                 sawInline = true;
    840             curr = curr->nextSibling();
    841         }
    842     } while (!sawInline);
    843 }
    844 
    845 void RenderBlock::deleteLineBoxTree()
    846 {
    847     m_lineBoxes.deleteLineBoxTree(renderArena());
    848 }
    849 
    850 RootInlineBox* RenderBlock::createRootInlineBox()
    851 {
    852     return new (renderArena()) RootInlineBox(this);
    853 }
    854 
    855 RootInlineBox* RenderBlock::createAndAppendRootInlineBox()
    856 {
    857     RootInlineBox* rootBox = createRootInlineBox();
    858     m_lineBoxes.appendLineBox(rootBox);
    859     return rootBox;
    860 }
    861 
    862 void RenderBlock::moveChildTo(RenderBlock* to, RenderObject* child, RenderObject* beforeChild, bool fullRemoveInsert)
    863 {
    864     ASSERT(this == child->parent());
    865     ASSERT(!beforeChild || to == beforeChild->parent());
    866     to->children()->insertChildNode(to, children()->removeChildNode(this, child, fullRemoveInsert), beforeChild, fullRemoveInsert);
    867 }
    868 
    869 void RenderBlock::moveChildrenTo(RenderBlock* to, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert)
    870 {
    871     ASSERT(!beforeChild || to == beforeChild->parent());
    872     RenderObject* nextChild = startChild;
    873     while (nextChild && nextChild != endChild) {
    874         RenderObject* child = nextChild;
    875         nextChild = child->nextSibling();
    876         to->children()->insertChildNode(to, children()->removeChildNode(this, child, fullRemoveInsert), beforeChild, fullRemoveInsert);
    877         if (child == endChild)
    878             return;
    879     }
    880 }
    881 
    882 void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
    883 {
    884     // makeChildrenNonInline takes a block whose children are *all* inline and it
    885     // makes sure that inline children are coalesced under anonymous
    886     // blocks.  If |insertionPoint| is defined, then it represents the insertion point for
    887     // the new block child that is causing us to have to wrap all the inlines.  This
    888     // means that we cannot coalesce inlines before |insertionPoint| with inlines following
    889     // |insertionPoint|, because the new child is going to be inserted in between the inlines,
    890     // splitting them.
    891     ASSERT(isInlineBlockOrInlineTable() || !isInline());
    892     ASSERT(!insertionPoint || insertionPoint->parent() == this);
    893 
    894     setChildrenInline(false);
    895 
    896     RenderObject *child = firstChild();
    897     if (!child)
    898         return;
    899 
    900     deleteLineBoxTree();
    901 
    902     while (child) {
    903         RenderObject *inlineRunStart, *inlineRunEnd;
    904         getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);
    905 
    906         if (!inlineRunStart)
    907             break;
    908 
    909         child = inlineRunEnd->nextSibling();
    910 
    911         RenderBlock* block = createAnonymousBlock();
    912         children()->insertChildNode(this, block, inlineRunStart);
    913         moveChildrenTo(block, inlineRunStart, child);
    914     }
    915 
    916 #ifndef NDEBUG
    917     for (RenderObject *c = firstChild(); c; c = c->nextSibling())
    918         ASSERT(!c->isInline());
    919 #endif
    920 
    921     repaint();
    922 }
    923 
    924 void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
    925 {
    926     ASSERT(child->isAnonymousBlock());
    927     ASSERT(!child->childrenInline());
    928 
    929     if (child->continuation() || (child->firstChild() && (child->isAnonymousColumnSpanBlock() || child->isAnonymousColumnsBlock())))
    930         return;
    931 
    932     RenderObject* firstAnChild = child->m_children.firstChild();
    933     RenderObject* lastAnChild = child->m_children.lastChild();
    934     if (firstAnChild) {
    935         RenderObject* o = firstAnChild;
    936         while (o) {
    937             o->setParent(this);
    938             o = o->nextSibling();
    939         }
    940         firstAnChild->setPreviousSibling(child->previousSibling());
    941         lastAnChild->setNextSibling(child->nextSibling());
    942         if (child->previousSibling())
    943             child->previousSibling()->setNextSibling(firstAnChild);
    944         if (child->nextSibling())
    945             child->nextSibling()->setPreviousSibling(lastAnChild);
    946 
    947         if (child == m_children.firstChild())
    948             m_children.setFirstChild(firstAnChild);
    949         if (child == m_children.lastChild())
    950             m_children.setLastChild(lastAnChild);
    951     } else {
    952         if (child == m_children.firstChild())
    953             m_children.setFirstChild(child->nextSibling());
    954         if (child == m_children.lastChild())
    955             m_children.setLastChild(child->previousSibling());
    956 
    957         if (child->previousSibling())
    958             child->previousSibling()->setNextSibling(child->nextSibling());
    959         if (child->nextSibling())
    960             child->nextSibling()->setPreviousSibling(child->previousSibling());
    961     }
    962     child->setParent(0);
    963     child->setPreviousSibling(0);
    964     child->setNextSibling(0);
    965 
    966     child->children()->setFirstChild(0);
    967     child->m_next = 0;
    968 
    969     child->destroy();
    970 }
    971 
    972 static bool canMergeContiguousAnonymousBlocks(RenderObject* oldChild, RenderObject* prev, RenderObject* next)
    973 {
    974     if (oldChild->documentBeingDestroyed() || oldChild->isInline() || oldChild->virtualContinuation())
    975         return false;
    976 
    977     if (oldChild->parent() && oldChild->parent()->isDetails())
    978         return false;
    979 
    980     if ((prev && (!prev->isAnonymousBlock() || toRenderBlock(prev)->continuation() || toRenderBlock(prev)->beingDestroyed()))
    981         || (next && (!next->isAnonymousBlock() || toRenderBlock(next)->continuation() || toRenderBlock(next)->beingDestroyed())))
    982         return false;
    983 
    984     // FIXME: This check isn't required when inline run-ins can't be split into continuations.
    985     if (prev && prev->firstChild() && prev->firstChild()->isInline() && prev->firstChild()->isRunIn())
    986         return false;
    987 
    988     if ((prev && (prev->isRubyRun() || prev->isRubyBase()))
    989         || (next && (next->isRubyRun() || next->isRubyBase())))
    990         return false;
    991 
    992     if (!prev || !next)
    993         return true;
    994 
    995     // Make sure the types of the anonymous blocks match up.
    996     return prev->isAnonymousColumnsBlock() == next->isAnonymousColumnsBlock()
    997            && prev->isAnonymousColumnSpanBlock() == next->isAnonymousColumnSpanBlock();
    998 }
    999 
   1000 void RenderBlock::removeChild(RenderObject* oldChild)
   1001 {
   1002     // If this child is a block, and if our previous and next siblings are
   1003     // both anonymous blocks with inline content, then we can go ahead and
   1004     // fold the inline content back together.
   1005     RenderObject* prev = oldChild->previousSibling();
   1006     RenderObject* next = oldChild->nextSibling();
   1007     bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, prev, next);
   1008     if (canMergeAnonymousBlocks && prev && next) {
   1009         prev->setNeedsLayoutAndPrefWidthsRecalc();
   1010         RenderBlock* nextBlock = toRenderBlock(next);
   1011         RenderBlock* prevBlock = toRenderBlock(prev);
   1012 
   1013         if (prev->childrenInline() != next->childrenInline()) {
   1014             RenderBlock* inlineChildrenBlock = prev->childrenInline() ? prevBlock : nextBlock;
   1015             RenderBlock* blockChildrenBlock = prev->childrenInline() ? nextBlock : prevBlock;
   1016 
   1017             // Place the inline children block inside of the block children block instead of deleting it.
   1018             // In order to reuse it, we have to reset it to just be a generic anonymous block.  Make sure
   1019             // to clear out inherited column properties by just making a new style, and to also clear the
   1020             // column span flag if it is set.
   1021             ASSERT(!inlineChildrenBlock->continuation());
   1022             RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
   1023             children()->removeChildNode(this, inlineChildrenBlock, inlineChildrenBlock->hasLayer());
   1024             inlineChildrenBlock->setStyle(newStyle);
   1025 
   1026             // Now just put the inlineChildrenBlock inside the blockChildrenBlock.
   1027             blockChildrenBlock->children()->insertChildNode(blockChildrenBlock, inlineChildrenBlock, prev == inlineChildrenBlock ? blockChildrenBlock->firstChild() : 0,
   1028                                                             inlineChildrenBlock->hasLayer() || blockChildrenBlock->hasLayer());
   1029             next->setNeedsLayoutAndPrefWidthsRecalc();
   1030 
   1031             // inlineChildrenBlock got reparented to blockChildrenBlock, so it is no longer a child
   1032             // of "this". we null out prev or next so that is not used later in the function.
   1033             if (inlineChildrenBlock == prevBlock)
   1034                 prev = 0;
   1035             else
   1036                 next = 0;
   1037         } else {
   1038             // Take all the children out of the |next| block and put them in
   1039             // the |prev| block.
   1040             nextBlock->moveAllChildrenTo(prevBlock, nextBlock->hasLayer() || prevBlock->hasLayer());
   1041 
   1042             // Delete the now-empty block's lines and nuke it.
   1043             nextBlock->deleteLineBoxTree();
   1044             nextBlock->destroy();
   1045             next = 0;
   1046         }
   1047     }
   1048 
   1049     RenderBox::removeChild(oldChild);
   1050 
   1051     RenderObject* child = prev ? prev : next;
   1052     if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && !isFlexibleBox()) {
   1053         // The removal has knocked us down to containing only a single anonymous
   1054         // box.  We can go ahead and pull the content right back up into our
   1055         // box.
   1056         setNeedsLayoutAndPrefWidthsRecalc();
   1057         setChildrenInline(child->childrenInline());
   1058         RenderBlock* anonBlock = toRenderBlock(children()->removeChildNode(this, child, child->hasLayer()));
   1059         anonBlock->moveAllChildrenTo(this, child->hasLayer());
   1060         // Delete the now-empty block's lines and nuke it.
   1061         anonBlock->deleteLineBoxTree();
   1062         anonBlock->destroy();
   1063     }
   1064 
   1065     if (!firstChild() && !documentBeingDestroyed()) {
   1066         // If this was our last child be sure to clear out our line boxes.
   1067         if (childrenInline())
   1068             lineBoxes()->deleteLineBoxes(renderArena());
   1069     }
   1070 }
   1071 
   1072 bool RenderBlock::isSelfCollapsingBlock() const
   1073 {
   1074     // We are not self-collapsing if we
   1075     // (a) have a non-zero height according to layout (an optimization to avoid wasting time)
   1076     // (b) are a table,
   1077     // (c) have border/padding,
   1078     // (d) have a min-height
   1079     // (e) have specified that one of our margins can't collapse using a CSS extension
   1080     if (logicalHeight() > 0
   1081         || isTable() || borderAndPaddingLogicalHeight()
   1082         || style()->logicalMinHeight().isPositive()
   1083         || style()->marginBeforeCollapse() == MSEPARATE || style()->marginAfterCollapse() == MSEPARATE)
   1084         return false;
   1085 
   1086     Length logicalHeightLength = style()->logicalHeight();
   1087     bool hasAutoHeight = logicalHeightLength.isAuto();
   1088     if (logicalHeightLength.isPercent() && !document()->inQuirksMode()) {
   1089         hasAutoHeight = true;
   1090         for (RenderBlock* cb = containingBlock(); !cb->isRenderView(); cb = cb->containingBlock()) {
   1091             if (cb->style()->logicalHeight().isFixed() || cb->isTableCell())
   1092                 hasAutoHeight = false;
   1093         }
   1094     }
   1095 
   1096     // If the height is 0 or auto, then whether or not we are a self-collapsing block depends
   1097     // on whether we have content that is all self-collapsing or not.
   1098     if (hasAutoHeight || ((logicalHeightLength.isFixed() || logicalHeightLength.isPercent()) && logicalHeightLength.isZero())) {
   1099         // If the block has inline children, see if we generated any line boxes.  If we have any
   1100         // line boxes, then we can't be self-collapsing, since we have content.
   1101         if (childrenInline())
   1102             return !firstLineBox();
   1103 
   1104         // Whether or not we collapse is dependent on whether all our normal flow children
   1105         // are also self-collapsing.
   1106         for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
   1107             if (child->isFloatingOrPositioned())
   1108                 continue;
   1109             if (!child->isSelfCollapsingBlock())
   1110                 return false;
   1111         }
   1112         return true;
   1113     }
   1114     return false;
   1115 }
   1116 
   1117 void RenderBlock::startDelayUpdateScrollInfo()
   1118 {
   1119     if (gDelayUpdateScrollInfo == 0) {
   1120         ASSERT(!gDelayedUpdateScrollInfoSet);
   1121         gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet;
   1122     }
   1123     ASSERT(gDelayedUpdateScrollInfoSet);
   1124     ++gDelayUpdateScrollInfo;
   1125 }
   1126 
   1127 void RenderBlock::finishDelayUpdateScrollInfo()
   1128 {
   1129     --gDelayUpdateScrollInfo;
   1130     ASSERT(gDelayUpdateScrollInfo >= 0);
   1131     if (gDelayUpdateScrollInfo == 0) {
   1132         ASSERT(gDelayedUpdateScrollInfoSet);
   1133 
   1134         OwnPtr<DelayedUpdateScrollInfoSet> infoSet(gDelayedUpdateScrollInfoSet);
   1135         gDelayedUpdateScrollInfoSet = 0;
   1136 
   1137         for (DelayedUpdateScrollInfoSet::iterator it = infoSet->begin(); it != infoSet->end(); ++it) {
   1138             RenderBlock* block = *it;
   1139             if (block->hasOverflowClip()) {
   1140                 block->layer()->updateScrollInfoAfterLayout();
   1141             }
   1142         }
   1143     }
   1144 }
   1145 
   1146 void RenderBlock::updateScrollInfoAfterLayout()
   1147 {
   1148     if (hasOverflowClip()) {
   1149         if (gDelayUpdateScrollInfo)
   1150             gDelayedUpdateScrollInfoSet->add(this);
   1151         else
   1152             layer()->updateScrollInfoAfterLayout();
   1153     }
   1154 }
   1155 
   1156 void RenderBlock::layout()
   1157 {
   1158     // Update our first letter info now.
   1159     updateFirstLetter();
   1160 
   1161     // Table cells call layoutBlock directly, so don't add any logic here.  Put code into
   1162     // layoutBlock().
   1163     layoutBlock(false);
   1164 
   1165     // It's safe to check for control clip here, since controls can never be table cells.
   1166     // If we have a lightweight clip, there can never be any overflow from children.
   1167     if (hasControlClip() && m_overflow)
   1168         clearLayoutOverflow();
   1169 }
   1170 
   1171 void RenderBlock::layoutBlock(bool relayoutChildren, int pageLogicalHeight)
   1172 {
   1173     ASSERT(needsLayout());
   1174 
   1175     if (isInline() && !isInlineBlockOrInlineTable()) // Inline <form>s inside various table elements can
   1176         return;                                      // cause us to come in here.  Just bail.
   1177 
   1178     if (!relayoutChildren && simplifiedLayout())
   1179         return;
   1180 
   1181     LayoutRepainter repainter(*this, m_everHadLayout && checkForRepaintDuringLayout());
   1182 
   1183     int oldWidth = logicalWidth();
   1184     int oldColumnWidth = desiredColumnWidth();
   1185 
   1186     computeLogicalWidth();
   1187     calcColumnWidth();
   1188 
   1189     m_overflow.clear();
   1190 
   1191     if (oldWidth != logicalWidth() || oldColumnWidth != desiredColumnWidth())
   1192         relayoutChildren = true;
   1193 
   1194 #ifdef ANDROID_LAYOUT
   1195     checkAndSetRelayoutChildren(&relayoutChildren);
   1196 #endif
   1197 
   1198     clearFloats();
   1199 
   1200     int previousHeight = logicalHeight();
   1201     setLogicalHeight(0);
   1202     bool hasSpecifiedPageLogicalHeight = false;
   1203     bool pageLogicalHeightChanged = false;
   1204     ColumnInfo* colInfo = columnInfo();
   1205     if (hasColumns()) {
   1206         if (!pageLogicalHeight) {
   1207             // We need to go ahead and set our explicit page height if one exists, so that we can
   1208             // avoid doing two layout passes.
   1209             computeLogicalHeight();
   1210             int columnHeight = contentLogicalHeight();
   1211             if (columnHeight > 0) {
   1212                 pageLogicalHeight = columnHeight;
   1213                 hasSpecifiedPageLogicalHeight = true;
   1214             }
   1215             setLogicalHeight(0);
   1216         }
   1217         if (colInfo->columnHeight() != pageLogicalHeight && m_everHadLayout) {
   1218             colInfo->setColumnHeight(pageLogicalHeight);
   1219             pageLogicalHeightChanged = true;
   1220         }
   1221 
   1222         if (!hasSpecifiedPageLogicalHeight && !pageLogicalHeight)
   1223             colInfo->clearForcedBreaks();
   1224     }
   1225 
   1226     LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode(), pageLogicalHeight, pageLogicalHeightChanged, colInfo);
   1227 
   1228     // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track
   1229     // our current maximal positive and negative margins.  These values are used when we
   1230     // are collapsed with adjacent blocks, so for example, if you have block A and B
   1231     // collapsing together, then you'd take the maximal positive margin from both A and B
   1232     // and subtract it from the maximal negative margin from both A and B to get the
   1233     // true collapsed margin.  This algorithm is recursive, so when we finish layout()
   1234     // our block knows its current maximal positive/negative values.
   1235     //
   1236     // Start out by setting our margin values to our current margins.  Table cells have
   1237     // no margins, so we don't fill in the values for table cells.
   1238     bool isCell = isTableCell();
   1239     if (!isCell) {
   1240         initMaxMarginValues();
   1241 
   1242         setMarginBeforeQuirk(style()->marginBefore().quirk());
   1243         setMarginAfterQuirk(style()->marginAfter().quirk());
   1244 
   1245         Node* n = node();
   1246         if (n && n->hasTagName(formTag) && static_cast<HTMLFormElement*>(n)->isMalformed()) {
   1247             // See if this form is malformed (i.e., unclosed). If so, don't give the form
   1248             // a bottom margin.
   1249             setMaxMarginAfterValues(0, 0);
   1250         }
   1251 
   1252         setPaginationStrut(0);
   1253     }
   1254 
   1255     // For overflow:scroll blocks, ensure we have both scrollbars in place always.
   1256     if (scrollsOverflow()) {
   1257         if (style()->overflowX() == OSCROLL)
   1258             layer()->setHasHorizontalScrollbar(true);
   1259         if (style()->overflowY() == OSCROLL)
   1260             layer()->setHasVerticalScrollbar(true);
   1261     }
   1262 
   1263     int repaintLogicalTop = 0;
   1264     int repaintLogicalBottom = 0;
   1265     int maxFloatLogicalBottom = 0;
   1266     if (!firstChild() && !isAnonymousBlock())
   1267         setChildrenInline(true);
   1268     if (childrenInline())
   1269         layoutInlineChildren(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
   1270     else
   1271         layoutBlockChildren(relayoutChildren, maxFloatLogicalBottom);
   1272 
   1273     // Expand our intrinsic height to encompass floats.
   1274     int toAdd = borderAfter() + paddingAfter() + scrollbarLogicalHeight();
   1275     if (lowestFloatLogicalBottom() > (logicalHeight() - toAdd) && expandsToEncloseOverhangingFloats())
   1276         setLogicalHeight(lowestFloatLogicalBottom() + toAdd);
   1277 
   1278     if (layoutColumns(hasSpecifiedPageLogicalHeight, pageLogicalHeight, statePusher))
   1279         return;
   1280 
   1281     // Calculate our new height.
   1282     int oldHeight = logicalHeight();
   1283     int oldClientAfterEdge = clientLogicalBottom();
   1284     computeLogicalHeight();
   1285     int newHeight = logicalHeight();
   1286     if (oldHeight != newHeight) {
   1287         if (oldHeight > newHeight && maxFloatLogicalBottom > newHeight && !childrenInline()) {
   1288             // One of our children's floats may have become an overhanging float for us. We need to look for it.
   1289             for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
   1290                 if (child->isBlockFlow() && !child->isFloatingOrPositioned()) {
   1291                     RenderBlock* block = toRenderBlock(child);
   1292                     if (block->lowestFloatLogicalBottom() + block->logicalTop() > newHeight)
   1293                         addOverhangingFloats(block, -block->logicalLeft(), -block->logicalTop(), false);
   1294                 }
   1295             }
   1296         }
   1297     }
   1298 
   1299     if (previousHeight != newHeight)
   1300         relayoutChildren = true;
   1301 
   1302     layoutPositionedObjects(relayoutChildren || isRoot());
   1303 
   1304     // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway).
   1305     computeOverflow(oldClientAfterEdge);
   1306 
   1307     statePusher.pop();
   1308 
   1309     if (view()->layoutState()->m_pageLogicalHeight)
   1310         setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(logicalTop()));
   1311 
   1312     updateLayerTransform();
   1313 
   1314     // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
   1315     // we overflow or not.
   1316     updateScrollInfoAfterLayout();
   1317 
   1318     // Repaint with our new bounds if they are different from our old bounds.
   1319     bool didFullRepaint = repainter.repaintAfterLayout();
   1320     if (!didFullRepaint && repaintLogicalTop != repaintLogicalBottom && (style()->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) {
   1321         // FIXME: We could tighten up the left and right invalidation points if we let layoutInlineChildren fill them in based off the particular lines
   1322         // it had to lay out.  We wouldn't need the hasOverflowClip() hack in that case either.
   1323         int repaintLogicalLeft = logicalLeftVisualOverflow();
   1324         int repaintLogicalRight = logicalRightVisualOverflow();
   1325         if (hasOverflowClip()) {
   1326             // 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.
   1327             // 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.
   1328             // layoutInlineChildren should be patched to compute the entire repaint rect.
   1329             repaintLogicalLeft = min(repaintLogicalLeft, logicalLeftLayoutOverflow());
   1330             repaintLogicalRight = max(repaintLogicalRight, logicalRightLayoutOverflow());
   1331         }
   1332 
   1333         IntRect repaintRect;
   1334         if (isHorizontalWritingMode())
   1335             repaintRect = IntRect(repaintLogicalLeft, repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop);
   1336         else
   1337             repaintRect = IntRect(repaintLogicalTop, repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft);
   1338 
   1339         // The repaint rect may be split across columns, in which case adjustRectForColumns() will return the union.
   1340         adjustRectForColumns(repaintRect);
   1341 
   1342         repaintRect.inflate(maximalOutlineSize(PaintPhaseOutline));
   1343 
   1344         if (hasOverflowClip()) {
   1345             // Adjust repaint rect for scroll offset
   1346             repaintRect.move(-layer()->scrolledContentOffset());
   1347 
   1348             // Don't allow this rect to spill out of our overflow box.
   1349             repaintRect.intersect(IntRect(0, 0, width(), height()));
   1350         }
   1351 
   1352         // Make sure the rect is still non-empty after intersecting for overflow above
   1353         if (!repaintRect.isEmpty()) {
   1354             repaintRectangle(repaintRect); // We need to do a partial repaint of our content.
   1355             if (hasReflection())
   1356                 repaintRectangle(reflectedRect(repaintRect));
   1357         }
   1358     }
   1359     setNeedsLayout(false);
   1360 }
   1361 
   1362 void RenderBlock::addOverflowFromChildren()
   1363 {
   1364     if (!hasColumns()) {
   1365         if (childrenInline())
   1366             addOverflowFromInlineChildren();
   1367         else
   1368             addOverflowFromBlockChildren();
   1369     } else {
   1370         ColumnInfo* colInfo = columnInfo();
   1371         if (columnCount(colInfo)) {
   1372             IntRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
   1373             if (isHorizontalWritingMode()) {
   1374                 int overflowLeft = !style()->isLeftToRightDirection() ? min(0, lastRect.x()) : 0;
   1375                 int overflowRight = style()->isLeftToRightDirection() ? max(width(), lastRect.maxX()) : 0;
   1376                 int overflowHeight = borderBefore() + paddingBefore() + colInfo->columnHeight();
   1377                 addLayoutOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight));
   1378                 if (!hasOverflowClip())
   1379                     addVisualOverflow(IntRect(overflowLeft, 0, overflowRight - overflowLeft, overflowHeight));
   1380             } else {
   1381                 IntRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
   1382                 int overflowTop = !style()->isLeftToRightDirection() ? min(0, lastRect.y()) : 0;
   1383                 int overflowBottom = style()->isLeftToRightDirection() ? max(height(), lastRect.maxY()) : 0;
   1384                 int overflowWidth = borderBefore() + paddingBefore() + colInfo->columnHeight();
   1385                 addLayoutOverflow(IntRect(0, overflowTop, overflowWidth, overflowBottom - overflowTop));
   1386                 if (!hasOverflowClip())
   1387                     addVisualOverflow(IntRect(0, overflowTop, overflowWidth, overflowBottom - overflowTop));
   1388             }
   1389         }
   1390     }
   1391 }
   1392 
   1393 void RenderBlock::computeOverflow(int oldClientAfterEdge, bool recomputeFloats)
   1394 {
   1395     // Add overflow from children.
   1396     addOverflowFromChildren();
   1397 
   1398     if (!hasColumns() && (recomputeFloats || isRoot() || expandsToEncloseOverhangingFloats() || hasSelfPaintingLayer()))
   1399         addOverflowFromFloats();
   1400 
   1401     // Add in the overflow from positioned objects.
   1402     addOverflowFromPositionedObjects();
   1403 
   1404     if (hasOverflowClip()) {
   1405         // When we have overflow clip, propagate the original spillout since it will include collapsed bottom margins
   1406         // and bottom padding.  Set the axis we don't care about to be 1, since we want this overflow to always
   1407         // be considered reachable.
   1408         IntRect clientRect(clientBoxRect());
   1409         IntRect rectToApply;
   1410         if (isHorizontalWritingMode())
   1411             rectToApply = IntRect(clientRect.x(), clientRect.y(), 1, max(0, oldClientAfterEdge - clientRect.y()));
   1412         else
   1413             rectToApply = IntRect(clientRect.x(), clientRect.y(), max(0, oldClientAfterEdge - clientRect.x()), 1);
   1414         addLayoutOverflow(rectToApply);
   1415     }
   1416 
   1417     // Add visual overflow from box-shadow and reflections.
   1418     addShadowOverflow();
   1419 }
   1420 
   1421 void RenderBlock::addOverflowFromBlockChildren()
   1422 {
   1423     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
   1424         if (!child->isFloatingOrPositioned())
   1425             addOverflowFromChild(child);
   1426     }
   1427 }
   1428 
   1429 void RenderBlock::addOverflowFromFloats()
   1430 {
   1431     if (!m_floatingObjects)
   1432         return;
   1433 
   1434     FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   1435     FloatingObjectSetIterator end = floatingObjectSet.end();
   1436     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   1437         FloatingObject* r = *it;
   1438         if (r->m_isDescendant)
   1439             addOverflowFromChild(r->m_renderer, IntSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r)));
   1440     }
   1441     return;
   1442 }
   1443 
   1444 void RenderBlock::addOverflowFromPositionedObjects()
   1445 {
   1446     if (!m_positionedObjects)
   1447         return;
   1448 
   1449     RenderBox* positionedObject;
   1450     Iterator end = m_positionedObjects->end();
   1451     for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
   1452         positionedObject = *it;
   1453 
   1454         // Fixed positioned elements don't contribute to layout overflow, since they don't scroll with the content.
   1455         if (positionedObject->style()->position() != FixedPosition)
   1456             addOverflowFromChild(positionedObject);
   1457     }
   1458 }
   1459 
   1460 bool RenderBlock::expandsToEncloseOverhangingFloats() const
   1461 {
   1462     return isInlineBlockOrInlineTable() || isFloatingOrPositioned() || hasOverflowClip() || (parent() && parent()->isFlexibleBox())
   1463            || hasColumns() || isTableCell() || isFieldset() || isWritingModeRoot();
   1464 }
   1465 
   1466 void RenderBlock::adjustPositionedBlock(RenderBox* child, const MarginInfo& marginInfo)
   1467 {
   1468     bool isHorizontal = isHorizontalWritingMode();
   1469     bool hasStaticBlockPosition = child->style()->hasStaticBlockPosition(isHorizontal);
   1470     RenderLayer* childLayer = child->layer();
   1471 
   1472     childLayer->setStaticInlinePosition(borderAndPaddingStart());
   1473 
   1474     int logicalTop = logicalHeight();
   1475     if (!marginInfo.canCollapseWithMarginBefore()) {
   1476         child->computeBlockDirectionMargins(this);
   1477         int marginBefore = marginBeforeForChild(child);
   1478         int collapsedBeforePos = marginInfo.positiveMargin();
   1479         int collapsedBeforeNeg = marginInfo.negativeMargin();
   1480         if (marginBefore > 0) {
   1481             if (marginBefore > collapsedBeforePos)
   1482                 collapsedBeforePos = marginBefore;
   1483         } else {
   1484             if (-marginBefore > collapsedBeforeNeg)
   1485                 collapsedBeforeNeg = -marginBefore;
   1486         }
   1487         logicalTop += (collapsedBeforePos - collapsedBeforeNeg) - marginBefore;
   1488     }
   1489     if (childLayer->staticBlockPosition() != logicalTop) {
   1490         childLayer->setStaticBlockPosition(logicalTop);
   1491         if (hasStaticBlockPosition)
   1492             child->setChildNeedsLayout(true, false);
   1493     }
   1494 }
   1495 
   1496 void RenderBlock::adjustFloatingBlock(const MarginInfo& marginInfo)
   1497 {
   1498     // The float should be positioned taking into account the bottom margin
   1499     // of the previous flow.  We add that margin into the height, get the
   1500     // float positioned properly, and then subtract the margin out of the
   1501     // height again.  In the case of self-collapsing blocks, we always just
   1502     // use the top margins, since the self-collapsing block collapsed its
   1503     // own bottom margin into its top margin.
   1504     //
   1505     // Note also that the previous flow may collapse its margin into the top of
   1506     // our block.  If this is the case, then we do not add the margin in to our
   1507     // height when computing the position of the float.   This condition can be tested
   1508     // for by simply calling canCollapseWithMarginBefore.  See
   1509     // http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html for
   1510     // an example of this scenario.
   1511     int marginOffset = marginInfo.canCollapseWithMarginBefore() ? 0 : marginInfo.margin();
   1512     setLogicalHeight(logicalHeight() + marginOffset);
   1513     positionNewFloats();
   1514     setLogicalHeight(logicalHeight() - marginOffset);
   1515 }
   1516 
   1517 bool RenderBlock::handleSpecialChild(RenderBox* child, const MarginInfo& marginInfo)
   1518 {
   1519     // Handle in the given order
   1520     return handlePositionedChild(child, marginInfo)
   1521         || handleFloatingChild(child, marginInfo)
   1522         || handleRunInChild(child);
   1523 }
   1524 
   1525 
   1526 bool RenderBlock::handlePositionedChild(RenderBox* child, const MarginInfo& marginInfo)
   1527 {
   1528     if (child->isPositioned()) {
   1529         child->containingBlock()->insertPositionedObject(child);
   1530         adjustPositionedBlock(child, marginInfo);
   1531         return true;
   1532     }
   1533     return false;
   1534 }
   1535 
   1536 bool RenderBlock::handleFloatingChild(RenderBox* child, const MarginInfo& marginInfo)
   1537 {
   1538     if (child->isFloating()) {
   1539         insertFloatingObject(child);
   1540         adjustFloatingBlock(marginInfo);
   1541         return true;
   1542     }
   1543     return false;
   1544 }
   1545 
   1546 bool RenderBlock::handleRunInChild(RenderBox* child)
   1547 {
   1548     // See if we have a run-in element with inline children.  If the
   1549     // children aren't inline, then just treat the run-in as a normal
   1550     // block.
   1551     if (!child->isRunIn() || !child->childrenInline())
   1552         return false;
   1553     // FIXME: We don't handle non-block elements with run-in for now.
   1554     if (!child->isRenderBlock())
   1555         return false;
   1556 
   1557     RenderBlock* blockRunIn = toRenderBlock(child);
   1558     RenderObject* curr = blockRunIn->nextSibling();
   1559     if (!curr || !curr->isRenderBlock() || !curr->childrenInline() || curr->isRunIn() || curr->isAnonymous() || curr->isFloatingOrPositioned())
   1560         return false;
   1561 
   1562     RenderBlock* currBlock = toRenderBlock(curr);
   1563 
   1564     // Remove the old child.
   1565     children()->removeChildNode(this, blockRunIn);
   1566 
   1567     // Create an inline.
   1568     Node* runInNode = blockRunIn->node();
   1569     RenderInline* inlineRunIn = new (renderArena()) RenderInline(runInNode ? runInNode : document());
   1570     inlineRunIn->setStyle(blockRunIn->style());
   1571 
   1572     bool runInIsGenerated = child->style()->styleType() == BEFORE || child->style()->styleType() == AFTER;
   1573 
   1574     // Move the nodes from the old child to the new child, but skip any :before/:after content.  It has already
   1575     // been regenerated by the new inline.
   1576     for (RenderObject* runInChild = blockRunIn->firstChild(); runInChild;) {
   1577         RenderObject* nextSibling = runInChild->nextSibling();
   1578         if (runInIsGenerated || (runInChild->style()->styleType() != BEFORE && runInChild->style()->styleType() != AFTER)) {
   1579             blockRunIn->children()->removeChildNode(blockRunIn, runInChild, false);
   1580             inlineRunIn->addChild(runInChild); // Use addChild instead of appendChildNode since it handles correct placement of the children relative to :after-generated content.
   1581         }
   1582         runInChild = nextSibling;
   1583     }
   1584 
   1585     // 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
   1586     // anything before the first child. e.g. details tag. See https://bugs.webkit.org/show_bug.cgi?id=58228.
   1587     currBlock->addChild(inlineRunIn, currBlock->firstChild());
   1588 
   1589     // If the run-in had an element, we need to set the new renderer.
   1590     if (runInNode)
   1591         runInNode->setRenderer(inlineRunIn);
   1592 
   1593     // Destroy the block run-in, which includes deleting its line box tree.
   1594     blockRunIn->deleteLineBoxTree();
   1595     blockRunIn->destroy();
   1596 
   1597     // The block acts like an inline, so just null out its
   1598     // position.
   1599 
   1600     return true;
   1601 }
   1602 
   1603 int RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo)
   1604 {
   1605     // Get the four margin values for the child and cache them.
   1606     const MarginValues childMargins = marginValuesForChild(child);
   1607 
   1608     // Get our max pos and neg top margins.
   1609     int posTop = childMargins.positiveMarginBefore();
   1610     int negTop = childMargins.negativeMarginBefore();
   1611 
   1612     // For self-collapsing blocks, collapse our bottom margins into our
   1613     // top to get new posTop and negTop values.
   1614     if (child->isSelfCollapsingBlock()) {
   1615         posTop = max(posTop, childMargins.positiveMarginAfter());
   1616         negTop = max(negTop, childMargins.negativeMarginAfter());
   1617     }
   1618 
   1619     // See if the top margin is quirky. We only care if this child has
   1620     // margins that will collapse with us.
   1621     bool topQuirk = child->isMarginBeforeQuirk() || style()->marginBeforeCollapse() == MDISCARD;
   1622 
   1623     if (marginInfo.canCollapseWithMarginBefore()) {
   1624         // This child is collapsing with the top of the
   1625         // block.  If it has larger margin values, then we need to update
   1626         // our own maximal values.
   1627         if (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !topQuirk)
   1628             setMaxMarginBeforeValues(max(posTop, maxPositiveMarginBefore()), max(negTop, maxNegativeMarginBefore()));
   1629 
   1630         // The minute any of the margins involved isn't a quirk, don't
   1631         // collapse it away, even if the margin is smaller (www.webreference.com
   1632         // has an example of this, a <dt> with 0.8em author-specified inside
   1633         // a <dl> inside a <td>.
   1634         if (!marginInfo.determinedMarginBeforeQuirk() && !topQuirk && (posTop - negTop)) {
   1635             setMarginBeforeQuirk(false);
   1636             marginInfo.setDeterminedMarginBeforeQuirk(true);
   1637         }
   1638 
   1639         if (!marginInfo.determinedMarginBeforeQuirk() && topQuirk && !marginBefore())
   1640             // We have no top margin and our top child has a quirky margin.
   1641             // We will pick up this quirky margin and pass it through.
   1642             // This deals with the <td><div><p> case.
   1643             // Don't do this for a block that split two inlines though.  You do
   1644             // still apply margins in this case.
   1645             setMarginBeforeQuirk(true);
   1646     }
   1647 
   1648     if (marginInfo.quirkContainer() && marginInfo.atBeforeSideOfBlock() && (posTop - negTop))
   1649         marginInfo.setMarginBeforeQuirk(topQuirk);
   1650 
   1651     int beforeCollapseLogicalTop = logicalHeight();
   1652     int logicalTop = beforeCollapseLogicalTop;
   1653     if (child->isSelfCollapsingBlock()) {
   1654         // This child has no height.  We need to compute our
   1655         // position before we collapse the child's margins together,
   1656         // so that we can get an accurate position for the zero-height block.
   1657         int collapsedBeforePos = max(marginInfo.positiveMargin(), childMargins.positiveMarginBefore());
   1658         int collapsedBeforeNeg = max(marginInfo.negativeMargin(), childMargins.negativeMarginBefore());
   1659         marginInfo.setMargin(collapsedBeforePos, collapsedBeforeNeg);
   1660 
   1661         // Now collapse the child's margins together, which means examining our
   1662         // bottom margin values as well.
   1663         marginInfo.setPositiveMarginIfLarger(childMargins.positiveMarginAfter());
   1664         marginInfo.setNegativeMarginIfLarger(childMargins.negativeMarginAfter());
   1665 
   1666         if (!marginInfo.canCollapseWithMarginBefore())
   1667             // We need to make sure that the position of the self-collapsing block
   1668             // is correct, since it could have overflowing content
   1669             // that needs to be positioned correctly (e.g., a block that
   1670             // had a specified height of 0 but that actually had subcontent).
   1671             logicalTop = logicalHeight() + collapsedBeforePos - collapsedBeforeNeg;
   1672     }
   1673     else {
   1674         if (child->style()->marginBeforeCollapse() == MSEPARATE) {
   1675             setLogicalHeight(logicalHeight() + marginInfo.margin() + marginBeforeForChild(child));
   1676             logicalTop = logicalHeight();
   1677         }
   1678         else if (!marginInfo.atBeforeSideOfBlock() ||
   1679             (!marginInfo.canCollapseMarginBeforeWithChildren()
   1680              && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.marginBeforeQuirk()))) {
   1681             // We're collapsing with a previous sibling's margins and not
   1682             // with the top of the block.
   1683             setLogicalHeight(logicalHeight() + max(marginInfo.positiveMargin(), posTop) - max(marginInfo.negativeMargin(), negTop));
   1684             logicalTop = logicalHeight();
   1685         }
   1686 
   1687         marginInfo.setPositiveMargin(childMargins.positiveMarginAfter());
   1688         marginInfo.setNegativeMargin(childMargins.negativeMarginAfter());
   1689 
   1690         if (marginInfo.margin())
   1691             marginInfo.setMarginAfterQuirk(child->isMarginAfterQuirk() || style()->marginAfterCollapse() == MDISCARD);
   1692     }
   1693 
   1694     // If margins would pull us past the top of the next page, then we need to pull back and pretend like the margins
   1695     // collapsed into the page edge.
   1696     bool paginated = view()->layoutState()->isPaginated();
   1697     if (paginated && logicalTop > beforeCollapseLogicalTop) {
   1698         int oldLogicalTop = logicalTop;
   1699         logicalTop = min(logicalTop, nextPageLogicalTop(beforeCollapseLogicalTop));
   1700         setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop));
   1701     }
   1702     return logicalTop;
   1703 }
   1704 
   1705 int RenderBlock::clearFloatsIfNeeded(RenderBox* child, MarginInfo& marginInfo, int oldTopPosMargin, int oldTopNegMargin, int yPos)
   1706 {
   1707     int heightIncrease = getClearDelta(child, yPos);
   1708     if (!heightIncrease)
   1709         return yPos;
   1710 
   1711     if (child->isSelfCollapsingBlock()) {
   1712         // For self-collapsing blocks that clear, they can still collapse their
   1713         // margins with following siblings.  Reset the current margins to represent
   1714         // the self-collapsing block's margins only.
   1715         // CSS2.1 states:
   1716         // "An element that has had clearance applied to it never collapses its top margin with its parent block's bottom margin.
   1717         // Therefore if we are at the bottom of the block, let's go ahead and reset margins to only include the
   1718         // self-collapsing block's bottom margin.
   1719         bool atBottomOfBlock = true;
   1720         for (RenderBox* curr = child->nextSiblingBox(); curr && atBottomOfBlock; curr = curr->nextSiblingBox()) {
   1721             if (!curr->isFloatingOrPositioned())
   1722                 atBottomOfBlock = false;
   1723         }
   1724 
   1725         MarginValues childMargins = marginValuesForChild(child);
   1726         if (atBottomOfBlock) {
   1727             marginInfo.setPositiveMargin(childMargins.positiveMarginAfter());
   1728             marginInfo.setNegativeMargin(childMargins.negativeMarginAfter());
   1729         } else {
   1730             marginInfo.setPositiveMargin(max(childMargins.positiveMarginBefore(), childMargins.positiveMarginAfter()));
   1731             marginInfo.setNegativeMargin(max(childMargins.negativeMarginBefore(), childMargins.negativeMarginAfter()));
   1732         }
   1733 
   1734         // Adjust our height such that we are ready to be collapsed with subsequent siblings (or the bottom
   1735         // of the parent block).
   1736         setLogicalHeight(child->y() - max(0, marginInfo.margin()));
   1737     } else
   1738         // Increase our height by the amount we had to clear.
   1739         setLogicalHeight(height() + heightIncrease);
   1740 
   1741     if (marginInfo.canCollapseWithMarginBefore()) {
   1742         // We can no longer collapse with the top of the block since a clear
   1743         // occurred.  The empty blocks collapse into the cleared block.
   1744         // FIXME: This isn't quite correct.  Need clarification for what to do
   1745         // if the height the cleared block is offset by is smaller than the
   1746         // margins involved.
   1747         setMaxMarginBeforeValues(oldTopPosMargin, oldTopNegMargin);
   1748         marginInfo.setAtBeforeSideOfBlock(false);
   1749     }
   1750 
   1751     return yPos + heightIncrease;
   1752 }
   1753 
   1754 int RenderBlock::estimateLogicalTopPosition(RenderBox* child, const MarginInfo& marginInfo)
   1755 {
   1756     // FIXME: We need to eliminate the estimation of vertical position, because when it's wrong we sometimes trigger a pathological
   1757     // relayout if there are intruding floats.
   1758     int logicalTopEstimate = logicalHeight();
   1759     if (!marginInfo.canCollapseWithMarginBefore()) {
   1760         int childMarginBefore = child->selfNeedsLayout() ? marginBeforeForChild(child) : collapsedMarginBeforeForChild(child);
   1761         logicalTopEstimate += max(marginInfo.margin(), childMarginBefore);
   1762     }
   1763 
   1764     bool paginated = view()->layoutState()->isPaginated();
   1765 
   1766     // Adjust logicalTopEstimate down to the next page if the margins are so large that we don't fit on the current
   1767     // page.
   1768     if (paginated && logicalTopEstimate > logicalHeight())
   1769         logicalTopEstimate = min(logicalTopEstimate, nextPageLogicalTop(logicalHeight()));
   1770 
   1771     logicalTopEstimate += getClearDelta(child, logicalTopEstimate);
   1772 
   1773     if (paginated) {
   1774         // If the object has a page or column break value of "before", then we should shift to the top of the next page.
   1775         logicalTopEstimate = applyBeforeBreak(child, logicalTopEstimate);
   1776 
   1777         // For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one.
   1778         logicalTopEstimate = adjustForUnsplittableChild(child, logicalTopEstimate);
   1779 
   1780         if (!child->selfNeedsLayout() && child->isRenderBlock())
   1781             logicalTopEstimate += toRenderBlock(child)->paginationStrut();
   1782     }
   1783 
   1784     return logicalTopEstimate;
   1785 }
   1786 
   1787 void RenderBlock::determineLogicalLeftPositionForChild(RenderBox* child)
   1788 {
   1789     int startPosition = borderStart() + paddingStart();
   1790     int totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + availableLogicalWidth();
   1791 
   1792     // Add in our start margin.
   1793     int childMarginStart = marginStartForChild(child);
   1794     int newPosition = startPosition + childMarginStart;
   1795 
   1796     // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats.  They need
   1797     // to shift over as necessary to dodge any floats that might get in the way.
   1798     if (child->avoidsFloats()) {
   1799         int startOff = style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(logicalHeight(), false) : totalAvailableLogicalWidth - logicalRightOffsetForLine(logicalHeight(), false);
   1800         if (style()->textAlign() != WEBKIT_CENTER && !child->style()->marginStartUsing(style()).isAuto()) {
   1801             if (childMarginStart < 0)
   1802                 startOff += childMarginStart;
   1803             newPosition = max(newPosition, startOff); // Let the float sit in the child's margin if it can fit.
   1804         } else if (startOff != startPosition) {
   1805             // The object is shifting to the "end" side of the block. The object might be centered, so we need to
   1806             // recalculate our inline direction margins. Note that the containing block content
   1807             // width computation will take into account the delta between |startOff| and |startPosition|
   1808             // so that we can just pass the content width in directly to the |computeMarginsInContainingBlockInlineDirection|
   1809             // function.
   1810             child->computeInlineDirectionMargins(this, availableLogicalWidthForLine(logicalTopForChild(child), false), logicalWidthForChild(child));
   1811             newPosition = startOff + marginStartForChild(child);
   1812         }
   1813     }
   1814 
   1815     setLogicalLeftForChild(child, style()->isLeftToRightDirection() ? newPosition : totalAvailableLogicalWidth - newPosition - logicalWidthForChild(child), ApplyLayoutDelta);
   1816 }
   1817 
   1818 void RenderBlock::setCollapsedBottomMargin(const MarginInfo& marginInfo)
   1819 {
   1820     if (marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()) {
   1821         // Update our max pos/neg bottom margins, since we collapsed our bottom margins
   1822         // with our children.
   1823         setMaxMarginAfterValues(max(maxPositiveMarginAfter(), marginInfo.positiveMargin()), max(maxNegativeMarginAfter(), marginInfo.negativeMargin()));
   1824 
   1825         if (!marginInfo.marginAfterQuirk())
   1826             setMarginAfterQuirk(false);
   1827 
   1828         if (marginInfo.marginAfterQuirk() && marginAfter() == 0)
   1829             // We have no bottom margin and our last child has a quirky margin.
   1830             // We will pick up this quirky margin and pass it through.
   1831             // This deals with the <td><div><p> case.
   1832             setMarginAfterQuirk(true);
   1833     }
   1834 }
   1835 
   1836 void RenderBlock::handleAfterSideOfBlock(int beforeSide, int afterSide, MarginInfo& marginInfo)
   1837 {
   1838     marginInfo.setAtAfterSideOfBlock(true);
   1839 
   1840     // If we can't collapse with children then go ahead and add in the bottom margin.
   1841     if (!marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()
   1842         && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.marginAfterQuirk()))
   1843         setLogicalHeight(logicalHeight() + marginInfo.margin());
   1844 
   1845     // Now add in our bottom border/padding.
   1846     setLogicalHeight(logicalHeight() + afterSide);
   1847 
   1848     // Negative margins can cause our height to shrink below our minimal height (border/padding).
   1849     // If this happens, ensure that the computed height is increased to the minimal height.
   1850     setLogicalHeight(max(logicalHeight(), beforeSide + afterSide));
   1851 
   1852     // Update our bottom collapsed margin info.
   1853     setCollapsedBottomMargin(marginInfo);
   1854 }
   1855 
   1856 void RenderBlock::setLogicalLeftForChild(RenderBox* child, int logicalLeft, ApplyLayoutDeltaMode applyDelta)
   1857 {
   1858     if (isHorizontalWritingMode()) {
   1859         if (applyDelta == ApplyLayoutDelta)
   1860             view()->addLayoutDelta(IntSize(child->x() - logicalLeft, 0));
   1861         child->setX(logicalLeft);
   1862     } else {
   1863         if (applyDelta == ApplyLayoutDelta)
   1864             view()->addLayoutDelta(IntSize(0, child->y() - logicalLeft));
   1865         child->setY(logicalLeft);
   1866     }
   1867 }
   1868 
   1869 void RenderBlock::setLogicalTopForChild(RenderBox* child, int logicalTop, ApplyLayoutDeltaMode applyDelta)
   1870 {
   1871     if (isHorizontalWritingMode()) {
   1872         if (applyDelta == ApplyLayoutDelta)
   1873             view()->addLayoutDelta(IntSize(0, child->y() - logicalTop));
   1874         child->setY(logicalTop);
   1875     } else {
   1876         if (applyDelta == ApplyLayoutDelta)
   1877             view()->addLayoutDelta(IntSize(child->x() - logicalTop, 0));
   1878         child->setX(logicalTop);
   1879     }
   1880 }
   1881 
   1882 void RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatLogicalBottom)
   1883 {
   1884     if (gPercentHeightDescendantsMap) {
   1885         if (HashSet<RenderBox*>* descendants = gPercentHeightDescendantsMap->get(this)) {
   1886             HashSet<RenderBox*>::iterator end = descendants->end();
   1887             for (HashSet<RenderBox*>::iterator it = descendants->begin(); it != end; ++it) {
   1888                 RenderBox* box = *it;
   1889                 while (box != this) {
   1890                     if (box->normalChildNeedsLayout())
   1891                         break;
   1892                     box->setChildNeedsLayout(true, false);
   1893                     box = box->containingBlock();
   1894                     ASSERT(box);
   1895                     if (!box)
   1896                         break;
   1897                 }
   1898             }
   1899         }
   1900     }
   1901 
   1902     int beforeEdge = borderBefore() + paddingBefore();
   1903     int afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeight();
   1904 
   1905     setLogicalHeight(beforeEdge);
   1906 
   1907     // The margin struct caches all our current margin collapsing state.  The compact struct caches state when we encounter compacts,
   1908     MarginInfo marginInfo(this, beforeEdge, afterEdge);
   1909 
   1910     // Fieldsets need to find their legend and position it inside the border of the object.
   1911     // The legend then gets skipped during normal layout.  The same is true for ruby text.
   1912     // It doesn't get included in the normal layout process but is instead skipped.
   1913     RenderObject* childToExclude = layoutSpecialExcludedChild(relayoutChildren);
   1914 
   1915     int previousFloatLogicalBottom = 0;
   1916     maxFloatLogicalBottom = 0;
   1917 
   1918     RenderBox* next = firstChildBox();
   1919 
   1920     while (next) {
   1921         RenderBox* child = next;
   1922         next = child->nextSiblingBox();
   1923 
   1924         if (childToExclude == child)
   1925             continue; // Skip this child, since it will be positioned by the specialized subclass (fieldsets and ruby runs).
   1926 
   1927         // Make sure we layout children if they need it.
   1928         // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into
   1929         // an auto value.  Add a method to determine this, so that we can avoid the relayout.
   1930         if (relayoutChildren || ((child->style()->logicalHeight().isPercent() || child->style()->logicalMinHeight().isPercent() || child->style()->logicalMaxHeight().isPercent()) && !isRenderView()))
   1931             child->setChildNeedsLayout(true, false);
   1932 
   1933         // If relayoutChildren is set and the child has percentage padding, we also need to invalidate the child's pref widths.
   1934         if (relayoutChildren && (child->style()->paddingStart().isPercent() || child->style()->paddingEnd().isPercent()))
   1935             child->setPreferredLogicalWidthsDirty(true, false);
   1936 
   1937         // Handle the four types of special elements first.  These include positioned content, floating content, compacts and
   1938         // run-ins.  When we encounter these four types of objects, we don't actually lay them out as normal flow blocks.
   1939         if (handleSpecialChild(child, marginInfo))
   1940             continue;
   1941 
   1942         // Lay out the child.
   1943         layoutBlockChild(child, marginInfo, previousFloatLogicalBottom, maxFloatLogicalBottom);
   1944     }
   1945 
   1946     // Now do the handling of the bottom of the block, adding in our bottom border/padding and
   1947     // determining the correct collapsed bottom margin information.
   1948     handleAfterSideOfBlock(beforeEdge, afterEdge, marginInfo);
   1949 }
   1950 
   1951 void RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, int& previousFloatLogicalBottom, int& maxFloatLogicalBottom)
   1952 {
   1953     int oldPosMarginBefore = maxPositiveMarginBefore();
   1954     int oldNegMarginBefore = maxNegativeMarginBefore();
   1955 
   1956     // The child is a normal flow object.  Compute the margins we will use for collapsing now.
   1957     child->computeBlockDirectionMargins(this);
   1958 
   1959     // Do not allow a collapse if the margin-before-collapse style is set to SEPARATE.
   1960     if (child->style()->marginBeforeCollapse() == MSEPARATE) {
   1961         marginInfo.setAtBeforeSideOfBlock(false);
   1962         marginInfo.clearMargin();
   1963     }
   1964 
   1965     // Try to guess our correct logical top position.  In most cases this guess will
   1966     // be correct.  Only if we're wrong (when we compute the real logical top position)
   1967     // will we have to potentially relayout.
   1968     int logicalTopEstimate = estimateLogicalTopPosition(child, marginInfo);
   1969 
   1970     // Cache our old rect so that we can dirty the proper repaint rects if the child moves.
   1971     IntRect oldRect(child->x(), child->y() , child->width(), child->height());
   1972     int oldLogicalTop = logicalTopForChild(child);
   1973 
   1974 #ifndef NDEBUG
   1975     IntSize oldLayoutDelta = view()->layoutDelta();
   1976 #endif
   1977     // Go ahead and position the child as though it didn't collapse with the top.
   1978     setLogicalTopForChild(child, logicalTopEstimate, ApplyLayoutDelta);
   1979 
   1980     RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0;
   1981     bool markDescendantsWithFloats = false;
   1982     if (logicalTopEstimate != oldLogicalTop && !child->avoidsFloats() && childRenderBlock && childRenderBlock->containsFloats())
   1983         markDescendantsWithFloats = true;
   1984     else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) {
   1985         // If an element might be affected by the presence of floats, then always mark it for
   1986         // layout.
   1987         int fb = max(previousFloatLogicalBottom, lowestFloatLogicalBottom());
   1988         if (fb > logicalTopEstimate)
   1989             markDescendantsWithFloats = true;
   1990     }
   1991 
   1992     if (childRenderBlock) {
   1993         if (markDescendantsWithFloats)
   1994             childRenderBlock->markAllDescendantsWithFloatsForLayout();
   1995         if (!child->isWritingModeRoot())
   1996             previousFloatLogicalBottom = max(previousFloatLogicalBottom, oldLogicalTop + childRenderBlock->lowestFloatLogicalBottom());
   1997     }
   1998 
   1999     if (!child->needsLayout())
   2000         child->markForPaginationRelayoutIfNeeded();
   2001 
   2002     bool childHadLayout = child->m_everHadLayout;
   2003     bool childNeededLayout = child->needsLayout();
   2004     if (childNeededLayout)
   2005         child->layout();
   2006 
   2007     // Cache if we are at the top of the block right now.
   2008     bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock();
   2009 
   2010     // Now determine the correct ypos based off examination of collapsing margin
   2011     // values.
   2012     int logicalTopBeforeClear = collapseMargins(child, marginInfo);
   2013 
   2014     // Now check for clear.
   2015     int logicalTopAfterClear = clearFloatsIfNeeded(child, marginInfo, oldPosMarginBefore, oldNegMarginBefore, logicalTopBeforeClear);
   2016 
   2017     bool paginated = view()->layoutState()->isPaginated();
   2018     if (paginated) {
   2019         int oldTop = logicalTopAfterClear;
   2020 
   2021         // If the object has a page or column break value of "before", then we should shift to the top of the next page.
   2022         logicalTopAfterClear = applyBeforeBreak(child, logicalTopAfterClear);
   2023 
   2024         // For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one.
   2025         int logicalTopBeforeUnsplittableAdjustment = logicalTopAfterClear;
   2026         int logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChild(child, logicalTopAfterClear);
   2027 
   2028         int paginationStrut = 0;
   2029         int unsplittableAdjustmentDelta = logicalTopAfterUnsplittableAdjustment - logicalTopBeforeUnsplittableAdjustment;
   2030         if (unsplittableAdjustmentDelta)
   2031             paginationStrut = unsplittableAdjustmentDelta;
   2032         else if (childRenderBlock && childRenderBlock->paginationStrut())
   2033             paginationStrut = childRenderBlock->paginationStrut();
   2034 
   2035         if (paginationStrut) {
   2036             // We are willing to propagate out to our parent block as long as we were at the top of the block prior
   2037             // to collapsing our margins, and as long as we didn't clear or move as a result of other pagination.
   2038             if (atBeforeSideOfBlock && oldTop == logicalTopBeforeClear && !isPositioned() && !isTableCell()) {
   2039                 // FIXME: Should really check if we're exceeding the page height before propagating the strut, but we don't
   2040                 // have all the information to do so (the strut only has the remaining amount to push).  Gecko gets this wrong too
   2041                 // and pushes to the next page anyway, so not too concerned about it.
   2042                 setPaginationStrut(logicalTopAfterClear + paginationStrut);
   2043                 if (childRenderBlock)
   2044                     childRenderBlock->setPaginationStrut(0);
   2045             } else
   2046                 logicalTopAfterClear += paginationStrut;
   2047         }
   2048 
   2049         // Similar to how we apply clearance.  Go ahead and boost height() to be the place where we're going to position the child.
   2050         setLogicalHeight(logicalHeight() + (logicalTopAfterClear - oldTop));
   2051     }
   2052 
   2053     setLogicalTopForChild(child, logicalTopAfterClear, ApplyLayoutDelta);
   2054 
   2055     // Now we have a final top position.  See if it really does end up being different from our estimate.
   2056     if (logicalTopAfterClear != logicalTopEstimate) {
   2057         if (child->shrinkToAvoidFloats()) {
   2058             // The child's width depends on the line width.
   2059             // When the child shifts to clear an item, its width can
   2060             // change (because it has more available line width).
   2061             // So go ahead and mark the item as dirty.
   2062             child->setChildNeedsLayout(true, false);
   2063         }
   2064         if (childRenderBlock) {
   2065             if (!child->avoidsFloats() && childRenderBlock->containsFloats())
   2066                 childRenderBlock->markAllDescendantsWithFloatsForLayout();
   2067             if (!child->needsLayout())
   2068                 child->markForPaginationRelayoutIfNeeded();
   2069         }
   2070 
   2071         // Our guess was wrong. Make the child lay itself out again.
   2072         child->layoutIfNeeded();
   2073     }
   2074 
   2075     // We are no longer at the top of the block if we encounter a non-empty child.
   2076     // This has to be done after checking for clear, so that margins can be reset if a clear occurred.
   2077     if (marginInfo.atBeforeSideOfBlock() && !child->isSelfCollapsingBlock())
   2078         marginInfo.setAtBeforeSideOfBlock(false);
   2079 
   2080     // Now place the child in the correct left position
   2081     determineLogicalLeftPositionForChild(child);
   2082 
   2083     // Update our height now that the child has been placed in the correct position.
   2084     setLogicalHeight(logicalHeight() + logicalHeightForChild(child));
   2085     if (child->style()->marginAfterCollapse() == MSEPARATE) {
   2086         setLogicalHeight(logicalHeight() + marginAfterForChild(child));
   2087         marginInfo.clearMargin();
   2088     }
   2089     // If the child has overhanging floats that intrude into following siblings (or possibly out
   2090     // of this block), then the parent gets notified of the floats now.
   2091     if (childRenderBlock && childRenderBlock->containsFloats())
   2092         maxFloatLogicalBottom = max(maxFloatLogicalBottom, addOverhangingFloats(toRenderBlock(child), -child->logicalLeft(), -child->logicalTop(), !childNeededLayout));
   2093 
   2094     IntSize childOffset(child->x() - oldRect.x(), child->y() - oldRect.y());
   2095     if (childOffset.width() || childOffset.height()) {
   2096         view()->addLayoutDelta(childOffset);
   2097 
   2098         // If the child moved, we have to repaint it as well as any floating/positioned
   2099         // descendants.  An exception is if we need a layout.  In this case, we know we're going to
   2100         // repaint ourselves (and the child) anyway.
   2101         if (childHadLayout && !selfNeedsLayout() && child->checkForRepaintDuringLayout())
   2102             child->repaintDuringLayoutIfMoved(oldRect);
   2103     }
   2104 
   2105     if (!childHadLayout && child->checkForRepaintDuringLayout()) {
   2106         child->repaint();
   2107         child->repaintOverhangingFloats(true);
   2108     }
   2109 
   2110     if (paginated) {
   2111         // Check for an after page/column break.
   2112         int newHeight = applyAfterBreak(child, logicalHeight(), marginInfo);
   2113         if (newHeight != height())
   2114             setLogicalHeight(newHeight);
   2115     }
   2116 
   2117     ASSERT(oldLayoutDelta == view()->layoutDelta());
   2118 }
   2119 
   2120 void RenderBlock::simplifiedNormalFlowLayout()
   2121 {
   2122     if (childrenInline()) {
   2123         ListHashSet<RootInlineBox*> lineBoxes;
   2124         bool endOfInline = false;
   2125         RenderObject* o = bidiFirst(this, 0, false);
   2126         while (o) {
   2127             if (!o->isPositioned() && (o->isReplaced() || o->isFloating())) {
   2128                 o->layoutIfNeeded();
   2129                 if (toRenderBox(o)->inlineBoxWrapper()) {
   2130                     RootInlineBox* box = toRenderBox(o)->inlineBoxWrapper()->root();
   2131                     lineBoxes.add(box);
   2132                 }
   2133             } else if (o->isText() || (o->isRenderInline() && !endOfInline))
   2134                 o->setNeedsLayout(false);
   2135             o = bidiNext(this, o, 0, false, &endOfInline);
   2136         }
   2137 
   2138         // FIXME: Glyph overflow will get lost in this case, but not really a big deal.
   2139         GlyphOverflowAndFallbackFontsMap textBoxDataMap;
   2140         for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it != lineBoxes.end(); ++it) {
   2141             RootInlineBox* box = *it;
   2142             box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap);
   2143         }
   2144     } else {
   2145         for (RenderBox* box = firstChildBox(); box; box = box->nextSiblingBox()) {
   2146             if (!box->isPositioned())
   2147                 box->layoutIfNeeded();
   2148         }
   2149     }
   2150 }
   2151 
   2152 bool RenderBlock::simplifiedLayout()
   2153 {
   2154     if ((!posChildNeedsLayout() && !needsSimplifiedNormalFlowLayout()) || normalChildNeedsLayout() || selfNeedsLayout())
   2155         return false;
   2156 
   2157     LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
   2158 
   2159     if (needsPositionedMovementLayout() && !tryLayoutDoingPositionedMovementOnly())
   2160         return false;
   2161 
   2162     // Lay out positioned descendants or objects that just need to recompute overflow.
   2163     if (needsSimplifiedNormalFlowLayout())
   2164         simplifiedNormalFlowLayout();
   2165 
   2166     // Lay out our positioned objects if our positioned child bit is set.
   2167     if (posChildNeedsLayout())
   2168         layoutPositionedObjects(false);
   2169 
   2170     // Recompute our overflow information.
   2171     // FIXME: We could do better here by computing a temporary overflow object from layoutPositionedObjects and only
   2172     // updating our overflow if we either used to have overflow or if the new temporary object has overflow.
   2173     // For now just always recompute overflow.  This is no worse performance-wise than the old code that called rightmostPosition and
   2174     // lowestPosition on every relayout so it's not a regression.
   2175     m_overflow.clear();
   2176     computeOverflow(clientLogicalBottom(), true);
   2177 
   2178     statePusher.pop();
   2179 
   2180     updateLayerTransform();
   2181 
   2182     updateScrollInfoAfterLayout();
   2183 
   2184     setNeedsLayout(false);
   2185     return true;
   2186 }
   2187 
   2188 void RenderBlock::layoutPositionedObjects(bool relayoutChildren)
   2189 {
   2190     if (!m_positionedObjects)
   2191         return;
   2192 
   2193     if (hasColumns())
   2194         view()->layoutState()->clearPaginationInformation(); // Positioned objects are not part of the column flow, so they don't paginate with the columns.
   2195 
   2196     RenderBox* r;
   2197     Iterator end = m_positionedObjects->end();
   2198     for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
   2199         r = *it;
   2200         // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the
   2201         // non-positioned block.  Rather than trying to detect all of these movement cases, we just always lay out positioned
   2202         // objects that are positioned implicitly like this.  Such objects are rare, and so in typical DHTML menu usage (where everything is
   2203         // positioned explicitly) this should not incur a performance penalty.
   2204         if (relayoutChildren || (r->style()->hasStaticBlockPosition(isHorizontalWritingMode()) && r->parent() != this && r->parent()->isBlockFlow()))
   2205             r->setChildNeedsLayout(true, false);
   2206 
   2207         // If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths.
   2208         if (relayoutChildren && (r->style()->paddingStart().isPercent() || r->style()->paddingEnd().isPercent()))
   2209             r->setPreferredLogicalWidthsDirty(true, false);
   2210 
   2211         if (!r->needsLayout())
   2212             r->markForPaginationRelayoutIfNeeded();
   2213 
   2214         // 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
   2215         // and we hit the available width constraint, the layoutIfNeeded() will catch it and do a full layout.
   2216         if (r->needsPositionedMovementLayoutOnly() && r->tryLayoutDoingPositionedMovementOnly())
   2217             r->setNeedsLayout(false);
   2218         r->layoutIfNeeded();
   2219     }
   2220 
   2221     if (hasColumns())
   2222         view()->layoutState()->m_columnInfo = columnInfo(); // FIXME: Kind of gross. We just put this back into the layout state so that pop() will work.
   2223 }
   2224 
   2225 void RenderBlock::markPositionedObjectsForLayout()
   2226 {
   2227     if (m_positionedObjects) {
   2228         RenderBox* r;
   2229         Iterator end = m_positionedObjects->end();
   2230         for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
   2231             r = *it;
   2232             r->setChildNeedsLayout(true);
   2233         }
   2234     }
   2235 }
   2236 
   2237 void RenderBlock::markForPaginationRelayoutIfNeeded()
   2238 {
   2239     ASSERT(!needsLayout());
   2240     if (needsLayout())
   2241         return;
   2242 
   2243     if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(logicalTop()) != pageLogicalOffset()))
   2244         setChildNeedsLayout(true, false);
   2245 }
   2246 
   2247 void RenderBlock::repaintOverhangingFloats(bool paintAllDescendants)
   2248 {
   2249     // Repaint any overhanging floats (if we know we're the one to paint them).
   2250     // Otherwise, bail out.
   2251     if (!hasOverhangingFloats())
   2252         return;
   2253 
   2254     // FIXME: Avoid disabling LayoutState. At the very least, don't disable it for floats originating
   2255     // in this block. Better yet would be to push extra state for the containers of other floats.
   2256     view()->disableLayoutState();
   2257     FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   2258     FloatingObjectSetIterator end = floatingObjectSet.end();
   2259     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   2260         FloatingObject* r = *it;
   2261         // Only repaint the object if it is overhanging, is not in its own layer, and
   2262         // is our responsibility to paint (m_shouldPaint is set). When paintAllDescendants is true, the latter
   2263         // condition is replaced with being a descendant of us.
   2264         if (logicalBottomForFloat(r) > logicalHeight() && ((paintAllDescendants && r->m_renderer->isDescendantOf(this)) || r->m_shouldPaint) && !r->m_renderer->hasSelfPaintingLayer()) {
   2265             r->m_renderer->repaint();
   2266             r->m_renderer->repaintOverhangingFloats();
   2267         }
   2268     }
   2269     view()->enableLayoutState();
   2270 }
   2271 
   2272 void RenderBlock::paint(PaintInfo& paintInfo, int tx, int ty)
   2273 {
   2274     tx += x();
   2275     ty += y();
   2276 
   2277     PaintPhase phase = paintInfo.phase;
   2278 
   2279     // Check if we need to do anything at all.
   2280     // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
   2281     // paints the root's background.
   2282     if (!isRoot()) {
   2283         IntRect overflowBox = visualOverflowRect();
   2284         flipForWritingMode(overflowBox);
   2285         overflowBox.inflate(maximalOutlineSize(paintInfo.phase));
   2286         overflowBox.move(tx, ty);
   2287         if (!overflowBox.intersects(paintInfo.rect))
   2288             return;
   2289     }
   2290 
   2291     bool pushedClip = pushContentsClip(paintInfo, tx, ty);
   2292     paintObject(paintInfo, tx, ty);
   2293     if (pushedClip)
   2294         popContentsClip(paintInfo, phase, tx, ty);
   2295 
   2296     // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
   2297     // z-index.  We paint after we painted the background/border, so that the scrollbars will
   2298     // sit above the background/border.
   2299     if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && paintInfo.shouldPaintWithinRoot(this))
   2300         layer()->paintOverflowControls(paintInfo.context, tx, ty, paintInfo.rect);
   2301 }
   2302 
   2303 void RenderBlock::paintColumnRules(PaintInfo& paintInfo, int tx, int ty)
   2304 {
   2305     const Color& ruleColor = style()->visitedDependentColor(CSSPropertyWebkitColumnRuleColor);
   2306     bool ruleTransparent = style()->columnRuleIsTransparent();
   2307     EBorderStyle ruleStyle = style()->columnRuleStyle();
   2308     int ruleWidth = style()->columnRuleWidth();
   2309     int colGap = columnGap();
   2310     bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent && ruleWidth <= colGap;
   2311     if (!renderRule)
   2312         return;
   2313 
   2314     // We need to do multiple passes, breaking up our child painting into strips.
   2315     ColumnInfo* colInfo = columnInfo();
   2316     unsigned colCount = columnCount(colInfo);
   2317     int currLogicalLeftOffset = style()->isLeftToRightDirection() ? 0 : contentLogicalWidth();
   2318     int ruleAdd = logicalLeftOffsetForContent();
   2319     int ruleLogicalLeft = style()->isLeftToRightDirection() ? 0 : contentLogicalWidth();
   2320     for (unsigned i = 0; i < colCount; i++) {
   2321         IntRect colRect = columnRectAt(colInfo, i);
   2322 
   2323         int inlineDirectionSize = isHorizontalWritingMode() ? colRect.width() : colRect.height();
   2324 
   2325         // Move to the next position.
   2326         if (style()->isLeftToRightDirection()) {
   2327             ruleLogicalLeft += inlineDirectionSize + colGap / 2;
   2328             currLogicalLeftOffset += inlineDirectionSize + colGap;
   2329         } else {
   2330             ruleLogicalLeft -= (inlineDirectionSize + colGap / 2);
   2331             currLogicalLeftOffset -= (inlineDirectionSize + colGap);
   2332         }
   2333 
   2334         // Now paint the column rule.
   2335         if (i < colCount - 1) {
   2336             int ruleLeft = isHorizontalWritingMode() ? tx + ruleLogicalLeft - ruleWidth / 2 + ruleAdd : tx + borderBefore() + paddingBefore();
   2337             int ruleRight = isHorizontalWritingMode() ? ruleLeft + ruleWidth : ruleLeft + contentWidth();
   2338             int ruleTop = isHorizontalWritingMode() ? ty + borderTop() + paddingTop() : ty + ruleLogicalLeft - ruleWidth / 2 + ruleAdd;
   2339             int ruleBottom = isHorizontalWritingMode() ? ruleTop + contentHeight() : ruleTop + ruleWidth;
   2340             drawLineForBoxSide(paintInfo.context, ruleLeft, ruleTop, ruleRight, ruleBottom,
   2341                                style()->isLeftToRightDirection() ? BSLeft : BSRight, ruleColor, ruleStyle, 0, 0);
   2342         }
   2343 
   2344         ruleLogicalLeft = currLogicalLeftOffset;
   2345     }
   2346 }
   2347 
   2348 void RenderBlock::paintColumnContents(PaintInfo& paintInfo, int tx, int ty, bool paintingFloats)
   2349 {
   2350     // We need to do multiple passes, breaking up our child painting into strips.
   2351     GraphicsContext* context = paintInfo.context;
   2352     ColumnInfo* colInfo = columnInfo();
   2353     unsigned colCount = columnCount(colInfo);
   2354     if (!colCount)
   2355         return;
   2356     int currLogicalTopOffset = 0;
   2357     for (unsigned i = 0; i < colCount; i++) {
   2358         // For each rect, we clip to the rect, and then we adjust our coords.
   2359         IntRect colRect = columnRectAt(colInfo, i);
   2360         flipForWritingMode(colRect);
   2361         int logicalLeftOffset = (isHorizontalWritingMode() ? colRect.x() : colRect.y()) - logicalLeftOffsetForContent();
   2362         IntSize offset = isHorizontalWritingMode() ? IntSize(logicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, logicalLeftOffset);
   2363         colRect.move(tx, ty);
   2364         PaintInfo info(paintInfo);
   2365         info.rect.intersect(colRect);
   2366 
   2367         if (!info.rect.isEmpty()) {
   2368             context->save();
   2369 
   2370             // Each strip pushes a clip, since column boxes are specified as being
   2371             // like overflow:hidden.
   2372             context->clip(colRect);
   2373 
   2374             // Adjust our x and y when painting.
   2375             int finalX = tx + offset.width();
   2376             int finalY = ty + offset.height();
   2377             if (paintingFloats)
   2378                 paintFloats(info, finalX, finalY, paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip);
   2379             else
   2380                 paintContents(info, finalX, finalY);
   2381 
   2382             context->restore();
   2383         }
   2384 
   2385         int blockDelta = (isHorizontalWritingMode() ? colRect.height() : colRect.width());
   2386         if (style()->isFlippedBlocksWritingMode())
   2387             currLogicalTopOffset += blockDelta;
   2388         else
   2389             currLogicalTopOffset -= blockDelta;
   2390     }
   2391 }
   2392 
   2393 void RenderBlock::paintContents(PaintInfo& paintInfo, int tx, int ty)
   2394 {
   2395     // Avoid painting descendants of the root element when stylesheets haven't loaded.  This eliminates FOUC.
   2396     // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
   2397     // will do a full repaint().
   2398     if (document()->didLayoutWithPendingStylesheets() && !isRenderView())
   2399         return;
   2400 
   2401     if (childrenInline())
   2402         m_lineBoxes.paint(this, paintInfo, tx, ty);
   2403     else
   2404         paintChildren(paintInfo, tx, ty);
   2405 }
   2406 
   2407 void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
   2408 {
   2409     PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase;
   2410     newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase;
   2411 
   2412     // We don't paint our own background, but we do let the kids paint their backgrounds.
   2413     PaintInfo info(paintInfo);
   2414     info.phase = newPhase;
   2415     info.updatePaintingRootForChildren(this);
   2416 
   2417     // FIXME: Paint-time pagination is obsolete and is now only used by embedded WebViews inside AppKit
   2418     // NSViews.  Do not add any more code for this.
   2419     RenderView* renderView = view();
   2420     bool usePrintRect = !renderView->printRect().isEmpty();
   2421 
   2422     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
   2423         // Check for page-break-before: always, and if it's set, break and bail.
   2424         bool checkBeforeAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakBefore() == PBALWAYS);
   2425         if (checkBeforeAlways
   2426             && (ty + child->y()) > paintInfo.rect.y()
   2427             && (ty + child->y()) < paintInfo.rect.maxY()) {
   2428             view()->setBestTruncatedAt(ty + child->y(), this, true);
   2429             return;
   2430         }
   2431 
   2432         if (!child->isFloating() && child->isReplaced() && usePrintRect && child->height() <= renderView->printRect().height()) {
   2433             // Paginate block-level replaced elements.
   2434             if (ty + child->y() + child->height() > renderView->printRect().maxY()) {
   2435                 if (ty + child->y() < renderView->truncatedAt())
   2436                     renderView->setBestTruncatedAt(ty + child->y(), child);
   2437                 // If we were able to truncate, don't paint.
   2438                 if (ty + child->y() >= renderView->truncatedAt())
   2439                     break;
   2440             }
   2441         }
   2442 
   2443         IntPoint childPoint = flipForWritingMode(child, IntPoint(tx, ty), ParentToChildFlippingAdjustment);
   2444         if (!child->hasSelfPaintingLayer() && !child->isFloating())
   2445             child->paint(info, childPoint.x(), childPoint.y());
   2446 
   2447         // Check for page-break-after: always, and if it's set, break and bail.
   2448         bool checkAfterAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakAfter() == PBALWAYS);
   2449         if (checkAfterAlways
   2450             && (ty + child->y() + child->height()) > paintInfo.rect.y()
   2451             && (ty + child->y() + child->height()) < paintInfo.rect.maxY()) {
   2452             view()->setBestTruncatedAt(ty + child->y() + child->height() + max(0, child->collapsedMarginAfter()), this, true);
   2453             return;
   2454         }
   2455     }
   2456 }
   2457 
   2458 void RenderBlock::paintCaret(PaintInfo& paintInfo, int tx, int ty, CaretType type)
   2459 {
   2460     SelectionController* selection = type == CursorCaret ? frame()->selection() : frame()->page()->dragCaretController();
   2461 
   2462     // Paint the caret if the SelectionController says so or if caret browsing is enabled
   2463     bool caretBrowsing = frame()->settings() && frame()->settings()->caretBrowsingEnabled();
   2464     RenderObject* caretPainter = selection->caretRenderer();
   2465     if (caretPainter == this && (selection->isContentEditable() || caretBrowsing)) {
   2466         // Convert the painting offset into the local coordinate system of this renderer,
   2467         // to match the localCaretRect computed by the SelectionController
   2468         offsetForContents(tx, ty);
   2469 
   2470         if (type == CursorCaret)
   2471             frame()->selection()->paintCaret(paintInfo.context, tx, ty, paintInfo.rect);
   2472         else
   2473             frame()->selection()->paintDragCaret(paintInfo.context, tx, ty, paintInfo.rect);
   2474     }
   2475 }
   2476 
   2477 void RenderBlock::paintObject(PaintInfo& paintInfo, int tx, int ty)
   2478 {
   2479     PaintPhase paintPhase = paintInfo.phase;
   2480 
   2481     // 1. paint background, borders etc
   2482     if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && style()->visibility() == VISIBLE) {
   2483         if (hasBoxDecorations())
   2484             paintBoxDecorations(paintInfo, tx, ty);
   2485         if (hasColumns())
   2486             paintColumnRules(paintInfo, tx, ty);
   2487     }
   2488 
   2489     if (paintPhase == PaintPhaseMask && style()->visibility() == VISIBLE) {
   2490         paintMask(paintInfo, tx, ty);
   2491         return;
   2492     }
   2493 
   2494     // We're done.  We don't bother painting any children.
   2495     if (paintPhase == PaintPhaseBlockBackground)
   2496         return;
   2497 
   2498     // Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div).
   2499     int scrolledX = tx;
   2500     int scrolledY = ty;
   2501     if (hasOverflowClip()) {
   2502         IntSize offset = layer()->scrolledContentOffset();
   2503         scrolledX -= offset.width();
   2504         scrolledY -= offset.height();
   2505     }
   2506 
   2507     // 2. paint contents
   2508     if (paintPhase != PaintPhaseSelfOutline) {
   2509         if (hasColumns())
   2510             paintColumnContents(paintInfo, scrolledX, scrolledY);
   2511         else
   2512             paintContents(paintInfo, scrolledX, scrolledY);
   2513     }
   2514 
   2515     // 3. paint selection
   2516     // FIXME: Make this work with multi column layouts.  For now don't fill gaps.
   2517     bool isPrinting = document()->printing();
   2518     if (!isPrinting && !hasColumns())
   2519         paintSelection(paintInfo, scrolledX, scrolledY); // Fill in gaps in selection on lines and between blocks.
   2520 
   2521     // 4. paint floats.
   2522     if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip) {
   2523         if (hasColumns())
   2524             paintColumnContents(paintInfo, scrolledX, scrolledY, true);
   2525         else
   2526             paintFloats(paintInfo, scrolledX, scrolledY, paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip);
   2527     }
   2528 
   2529     // 5. paint outline.
   2530     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
   2531         paintOutline(paintInfo.context, tx, ty, width(), height());
   2532 
   2533     // 6. paint continuation outlines.
   2534     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) {
   2535         RenderInline* inlineCont = inlineElementContinuation();
   2536         if (inlineCont && inlineCont->hasOutline() && inlineCont->style()->visibility() == VISIBLE) {
   2537             RenderInline* inlineRenderer = toRenderInline(inlineCont->node()->renderer());
   2538             RenderBlock* cb = containingBlock();
   2539 
   2540             bool inlineEnclosedInSelfPaintingLayer = false;
   2541             for (RenderBoxModelObject* box = inlineRenderer; box != cb; box = box->parent()->enclosingBoxModelObject()) {
   2542                 if (box->hasSelfPaintingLayer()) {
   2543                     inlineEnclosedInSelfPaintingLayer = true;
   2544                     break;
   2545                 }
   2546             }
   2547 
   2548             if (!inlineEnclosedInSelfPaintingLayer)
   2549                 cb->addContinuationWithOutline(inlineRenderer);
   2550             else if (!inlineRenderer->firstLineBox())
   2551                 inlineRenderer->paintOutline(paintInfo.context, tx - x() + inlineRenderer->containingBlock()->x(),
   2552                                              ty - y() + inlineRenderer->containingBlock()->y());
   2553         }
   2554         paintContinuationOutlines(paintInfo, tx, ty);
   2555     }
   2556 
   2557     // 7. paint caret.
   2558     // If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground,
   2559     // then paint the caret.
   2560     if (paintPhase == PaintPhaseForeground) {
   2561         paintCaret(paintInfo, scrolledX, scrolledY, CursorCaret);
   2562         paintCaret(paintInfo, scrolledX, scrolledY, DragCaret);
   2563     }
   2564 }
   2565 
   2566 IntPoint RenderBlock::flipFloatForWritingMode(const FloatingObject* child, const IntPoint& point) const
   2567 {
   2568     if (!style()->isFlippedBlocksWritingMode())
   2569         return point;
   2570 
   2571     // This is similar to the ParentToChildFlippingAdjustment in RenderBox::flipForWritingMode.  We have to subtract out our left/top offsets twice, since
   2572     // it's going to get added back in.  We hide this complication here so that the calling code looks normal for the unflipped
   2573     // case.
   2574     if (isHorizontalWritingMode())
   2575         return IntPoint(point.x(), point.y() + height() - child->renderer()->height() - 2 * yPositionForFloatIncludingMargin(child));
   2576     return IntPoint(point.x() + width() - child->width() - 2 * xPositionForFloatIncludingMargin(child), point.y());
   2577 }
   2578 
   2579 void RenderBlock::paintFloats(PaintInfo& paintInfo, int tx, int ty, bool preservePhase)
   2580 {
   2581     if (!m_floatingObjects)
   2582         return;
   2583 
   2584     FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   2585     FloatingObjectSetIterator end = floatingObjectSet.end();
   2586     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   2587         FloatingObject* r = *it;
   2588         // Only paint the object if our m_shouldPaint flag is set.
   2589         if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
   2590             PaintInfo currentPaintInfo(paintInfo);
   2591             currentPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
   2592             IntPoint childPoint = flipFloatForWritingMode(r, IntPoint(tx + xPositionForFloatIncludingMargin(r) - r->m_renderer->x(), ty + yPositionForFloatIncludingMargin(r) - r->m_renderer->y()));
   2593             r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
   2594             if (!preservePhase) {
   2595                 currentPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
   2596                 r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
   2597                 currentPaintInfo.phase = PaintPhaseFloat;
   2598                 r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
   2599                 currentPaintInfo.phase = PaintPhaseForeground;
   2600                 r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
   2601                 currentPaintInfo.phase = PaintPhaseOutline;
   2602                 r->m_renderer->paint(currentPaintInfo, childPoint.x(), childPoint.y());
   2603             }
   2604         }
   2605     }
   2606 }
   2607 
   2608 void RenderBlock::paintEllipsisBoxes(PaintInfo& paintInfo, int tx, int ty)
   2609 {
   2610     if (!paintInfo.shouldPaintWithinRoot(this) || !firstLineBox())
   2611         return;
   2612 
   2613     if (style()->visibility() == VISIBLE && paintInfo.phase == PaintPhaseForeground) {
   2614         // We can check the first box and last box and avoid painting if we don't
   2615         // intersect.
   2616         int yPos = ty + firstLineBox()->y();
   2617         int h = lastLineBox()->y() + lastLineBox()->logicalHeight() - firstLineBox()->y();
   2618         if (yPos >= paintInfo.rect.maxY() || yPos + h <= paintInfo.rect.y())
   2619             return;
   2620 
   2621         // See if our boxes intersect with the dirty rect.  If so, then we paint
   2622         // them.  Note that boxes can easily overlap, so we can't make any assumptions
   2623         // based off positions of our first line box or our last line box.
   2624         for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
   2625             yPos = ty + curr->y();
   2626             h = curr->logicalHeight();
   2627             if (curr->ellipsisBox() && yPos < paintInfo.rect.maxY() && yPos + h > paintInfo.rect.y())
   2628                 curr->paintEllipsisBox(paintInfo, tx, ty, curr->lineTop(), curr->lineBottom());
   2629         }
   2630     }
   2631 }
   2632 
   2633 RenderInline* RenderBlock::inlineElementContinuation() const
   2634 {
   2635     RenderBoxModelObject* continuation = this->continuation();
   2636     return continuation && continuation->isInline() ? toRenderInline(continuation) : 0;
   2637 }
   2638 
   2639 RenderBlock* RenderBlock::blockElementContinuation() const
   2640 {
   2641     RenderBoxModelObject* currentContinuation = continuation();
   2642     if (!currentContinuation || currentContinuation->isInline())
   2643         return 0;
   2644     RenderBlock* nextContinuation = toRenderBlock(currentContinuation);
   2645     if (nextContinuation->isAnonymousBlock())
   2646         return nextContinuation->blockElementContinuation();
   2647     return nextContinuation;
   2648 }
   2649 
   2650 static ContinuationOutlineTableMap* continuationOutlineTable()
   2651 {
   2652     DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ());
   2653     return &table;
   2654 }
   2655 
   2656 void RenderBlock::addContinuationWithOutline(RenderInline* flow)
   2657 {
   2658     // We can't make this work if the inline is in a layer.  We'll just rely on the broken
   2659     // way of painting.
   2660     ASSERT(!flow->layer() && !flow->isInlineElementContinuation());
   2661 
   2662     ContinuationOutlineTableMap* table = continuationOutlineTable();
   2663     ListHashSet<RenderInline*>* continuations = table->get(this);
   2664     if (!continuations) {
   2665         continuations = new ListHashSet<RenderInline*>;
   2666         table->set(this, continuations);
   2667     }
   2668 
   2669     continuations->add(flow);
   2670 }
   2671 
   2672 bool RenderBlock::paintsContinuationOutline(RenderInline* flow)
   2673 {
   2674     ContinuationOutlineTableMap* table = continuationOutlineTable();
   2675     if (table->isEmpty())
   2676         return false;
   2677 
   2678     ListHashSet<RenderInline*>* continuations = table->get(this);
   2679     if (!continuations)
   2680         return false;
   2681 
   2682     return continuations->contains(flow);
   2683 }
   2684 
   2685 void RenderBlock::paintContinuationOutlines(PaintInfo& info, int tx, int ty)
   2686 {
   2687     ContinuationOutlineTableMap* table = continuationOutlineTable();
   2688     if (table->isEmpty())
   2689         return;
   2690 
   2691     ListHashSet<RenderInline*>* continuations = table->get(this);
   2692     if (!continuations)
   2693         return;
   2694 
   2695     // Paint each continuation outline.
   2696     ListHashSet<RenderInline*>::iterator end = continuations->end();
   2697     for (ListHashSet<RenderInline*>::iterator it = continuations->begin(); it != end; ++it) {
   2698         // Need to add in the coordinates of the intervening blocks.
   2699         RenderInline* flow = *it;
   2700         RenderBlock* block = flow->containingBlock();
   2701         for ( ; block && block != this; block = block->containingBlock()) {
   2702             tx += block->x();
   2703             ty += block->y();
   2704         }
   2705         ASSERT(block);
   2706         flow->paintOutline(info.context, tx, ty);
   2707     }
   2708 
   2709     // Delete
   2710     delete continuations;
   2711     table->remove(this);
   2712 }
   2713 
   2714 bool RenderBlock::shouldPaintSelectionGaps() const
   2715 {
   2716     return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot();
   2717 }
   2718 
   2719 bool RenderBlock::isSelectionRoot() const
   2720 {
   2721     if (!node())
   2722         return false;
   2723 
   2724     // FIXME: Eventually tables should have to learn how to fill gaps between cells, at least in simple non-spanning cases.
   2725     if (isTable())
   2726         return false;
   2727 
   2728     if (isBody() || isRoot() || hasOverflowClip() || isRelPositioned() ||
   2729         isFloatingOrPositioned() || isTableCell() || isInlineBlockOrInlineTable() || hasTransform() ||
   2730         hasReflection() || hasMask() || isWritingModeRoot())
   2731         return true;
   2732 
   2733     if (view() && view()->selectionStart()) {
   2734         Node* startElement = view()->selectionStart()->node();
   2735         if (startElement && startElement->rootEditableElement() == node())
   2736             return true;
   2737     }
   2738 
   2739     return false;
   2740 }
   2741 
   2742 GapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer)
   2743 {
   2744     ASSERT(!needsLayout());
   2745 
   2746     if (!shouldPaintSelectionGaps())
   2747         return GapRects();
   2748 
   2749     // FIXME: this is broken with transforms
   2750     TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
   2751     mapLocalToContainer(repaintContainer, false, false, transformState);
   2752     IntPoint offsetFromRepaintContainer = roundedIntPoint(transformState.mappedPoint());
   2753 
   2754     if (hasOverflowClip())
   2755         offsetFromRepaintContainer -= layer()->scrolledContentOffset();
   2756 
   2757     int lastTop = 0;
   2758     int lastLeft = logicalLeftSelectionOffset(this, lastTop);
   2759     int lastRight = logicalRightSelectionOffset(this, lastTop);
   2760 
   2761     return selectionGaps(this, offsetFromRepaintContainer, IntSize(), lastTop, lastLeft, lastRight);
   2762 }
   2763 
   2764 void RenderBlock::paintSelection(PaintInfo& paintInfo, int tx, int ty)
   2765 {
   2766     if (shouldPaintSelectionGaps() && paintInfo.phase == PaintPhaseForeground) {
   2767         int lastTop = 0;
   2768         int lastLeft = logicalLeftSelectionOffset(this, lastTop);
   2769         int lastRight = logicalRightSelectionOffset(this, lastTop);
   2770         paintInfo.context->save();
   2771         IntRect gapRectsBounds = selectionGaps(this, IntPoint(tx, ty), IntSize(), lastTop, lastLeft, lastRight, &paintInfo);
   2772         if (!gapRectsBounds.isEmpty()) {
   2773             if (RenderLayer* layer = enclosingLayer()) {
   2774                 gapRectsBounds.move(IntSize(-tx, -ty));
   2775                 if (!hasLayer()) {
   2776                     IntRect localBounds(gapRectsBounds);
   2777                     flipForWritingMode(localBounds);
   2778                     gapRectsBounds = localToContainerQuad(FloatRect(localBounds), layer->renderer()).enclosingBoundingBox();
   2779                     gapRectsBounds.move(layer->scrolledContentOffset());
   2780                 }
   2781                 layer->addBlockSelectionGapsBounds(gapRectsBounds);
   2782             }
   2783         }
   2784         paintInfo.context->restore();
   2785     }
   2786 }
   2787 
   2788 static void clipOutPositionedObjects(const PaintInfo* paintInfo, const IntPoint& offset, RenderBlock::PositionedObjectsListHashSet* positionedObjects)
   2789 {
   2790     if (!positionedObjects)
   2791         return;
   2792 
   2793     RenderBlock::PositionedObjectsListHashSet::const_iterator end = positionedObjects->end();
   2794     for (RenderBlock::PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
   2795         RenderBox* r = *it;
   2796         paintInfo->context->clipOut(IntRect(offset.x() + r->x(), offset.y() + r->y(), r->width(), r->height()));
   2797     }
   2798 }
   2799 
   2800 static int blockDirectionOffset(RenderBlock* rootBlock, const IntSize& offsetFromRootBlock)
   2801 {
   2802     return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.height() : offsetFromRootBlock.width();
   2803 }
   2804 
   2805 static int inlineDirectionOffset(RenderBlock* rootBlock, const IntSize& offsetFromRootBlock)
   2806 {
   2807     return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.width() : offsetFromRootBlock.height();
   2808 }
   2809 
   2810 IntRect RenderBlock::logicalRectToPhysicalRect(const IntPoint& rootBlockPhysicalPosition, const IntRect& logicalRect)
   2811 {
   2812     IntRect result;
   2813     if (isHorizontalWritingMode())
   2814         result = logicalRect;
   2815     else
   2816         result = IntRect(logicalRect.y(), logicalRect.x(), logicalRect.height(), logicalRect.width());
   2817     flipForWritingMode(result);
   2818     result.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
   2819     return result;
   2820 }
   2821 
   2822 GapRects RenderBlock::selectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
   2823                                     int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo)
   2824 {
   2825     // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore.
   2826     // Clip out floating and positioned objects when painting selection gaps.
   2827     if (paintInfo) {
   2828         // Note that we don't clip out overflow for positioned objects.  We just stick to the border box.
   2829         IntRect flippedBlockRect = IntRect(offsetFromRootBlock.width(), offsetFromRootBlock.height(), width(), height());
   2830         rootBlock->flipForWritingMode(flippedBlockRect);
   2831         flippedBlockRect.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
   2832         clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), m_positionedObjects.get());
   2833         if (isBody() || isRoot()) // The <body> must make sure to examine its containingBlock's positioned objects.
   2834             for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock())
   2835                 clipOutPositionedObjects(paintInfo, IntPoint(cb->x(), cb->y()), cb->m_positionedObjects.get()); // FIXME: Not right for flipped writing modes.
   2836         if (m_floatingObjects) {
   2837             FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   2838             FloatingObjectSetIterator end = floatingObjectSet.end();
   2839             for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   2840                 FloatingObject* r = *it;
   2841                 IntRect floatBox = IntRect(offsetFromRootBlock.width() + xPositionForFloatIncludingMargin(r),
   2842                                            offsetFromRootBlock.height() + yPositionForFloatIncludingMargin(r),
   2843                                            r->m_renderer->width(), r->m_renderer->height());
   2844                 rootBlock->flipForWritingMode(floatBox);
   2845                 floatBox.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
   2846                 paintInfo->context->clipOut(floatBox);
   2847             }
   2848         }
   2849     }
   2850 
   2851     // 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
   2852     // fixed).
   2853     GapRects result;
   2854     if (!isBlockFlow()) // FIXME: Make multi-column selection gap filling work someday.
   2855         return result;
   2856 
   2857     if (hasColumns() || hasTransform() || style()->columnSpan()) {
   2858         // FIXME: We should learn how to gap fill multiple columns and transforms eventually.
   2859         lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
   2860         lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight());
   2861         lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight());
   2862         return result;
   2863     }
   2864 
   2865     if (childrenInline())
   2866         result = inlineSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
   2867     else
   2868         result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
   2869 
   2870     // Go ahead and fill the vertical gap all the way to the bottom of our block if the selection extends past our block.
   2871     if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd))
   2872         result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
   2873                                              logicalHeight(), paintInfo));
   2874     return result;
   2875 }
   2876 
   2877 GapRects RenderBlock::inlineSelectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
   2878                                           int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo)
   2879 {
   2880     GapRects result;
   2881 
   2882     bool containsStart = selectionState() == SelectionStart || selectionState() == SelectionBoth;
   2883 
   2884     if (!firstLineBox()) {
   2885         if (containsStart) {
   2886             // Go ahead and update our lastLogicalTop to be the bottom of the block.  <hr>s or empty blocks with height can trip this
   2887             // case.
   2888             lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
   2889             lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight());
   2890             lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight());
   2891         }
   2892         return result;
   2893     }
   2894 
   2895     RootInlineBox* lastSelectedLine = 0;
   2896     RootInlineBox* curr;
   2897     for (curr = firstRootBox(); curr && !curr->hasSelectedChildren(); curr = curr->nextRootBox()) { }
   2898 
   2899     // Now paint the gaps for the lines.
   2900     for (; curr && curr->hasSelectedChildren(); curr = curr->nextRootBox()) {
   2901         int selTop =  curr->selectionTop();
   2902         int selHeight = curr->selectionHeight();
   2903 
   2904         if (!containsStart && !lastSelectedLine &&
   2905             selectionState() != SelectionStart && selectionState() != SelectionBoth)
   2906             result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
   2907                                                  selTop, paintInfo));
   2908 
   2909         IntRect logicalRect(curr->logicalLeft(), selTop, curr->logicalWidth(), selTop + selHeight);
   2910         logicalRect.move(isHorizontalWritingMode() ? offsetFromRootBlock : IntSize(offsetFromRootBlock.height(), offsetFromRootBlock.width()));
   2911         IntRect physicalRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect);
   2912         if (!paintInfo || (isHorizontalWritingMode() && physicalRect.y() < paintInfo->rect.maxY() && physicalRect.maxY() > paintInfo->rect.y())
   2913             || (!isHorizontalWritingMode() && physicalRect.x() < paintInfo->rect.maxX() && physicalRect.maxX() > paintInfo->rect.x()))
   2914             result.unite(curr->lineSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, selTop, selHeight, paintInfo));
   2915 
   2916         lastSelectedLine = curr;
   2917     }
   2918 
   2919     if (containsStart && !lastSelectedLine)
   2920         // VisibleSelection must start just after our last line.
   2921         lastSelectedLine = lastRootBox();
   2922 
   2923     if (lastSelectedLine && selectionState() != SelectionEnd && selectionState() != SelectionBoth) {
   2924         // Go ahead and update our lastY to be the bottom of the last selected line.
   2925         lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + lastSelectedLine->selectionBottom();
   2926         lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
   2927         lastLogicalRight = logicalRightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
   2928     }
   2929     return result;
   2930 }
   2931 
   2932 GapRects RenderBlock::blockSelectionGaps(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
   2933                                          int& lastLogicalTop, int& lastLogicalLeft, int& lastLogicalRight, const PaintInfo* paintInfo)
   2934 {
   2935     GapRects result;
   2936 
   2937     // Go ahead and jump right to the first block child that contains some selected objects.
   2938     RenderBox* curr;
   2939     for (curr = firstChildBox(); curr && curr->selectionState() == SelectionNone; curr = curr->nextSiblingBox()) { }
   2940 
   2941     for (bool sawSelectionEnd = false; curr && !sawSelectionEnd; curr = curr->nextSiblingBox()) {
   2942         SelectionState childState = curr->selectionState();
   2943         if (childState == SelectionBoth || childState == SelectionEnd)
   2944             sawSelectionEnd = true;
   2945 
   2946         if (curr->isFloatingOrPositioned())
   2947             continue; // We must be a normal flow object in order to even be considered.
   2948 
   2949         if (curr->isRelPositioned() && curr->hasLayer()) {
   2950             // If the relposition offset is anything other than 0, then treat this just like an absolute positioned element.
   2951             // Just disregard it completely.
   2952             IntSize relOffset = curr->layer()->relativePositionOffset();
   2953             if (relOffset.width() || relOffset.height())
   2954                 continue;
   2955         }
   2956 
   2957         bool paintsOwnSelection = curr->shouldPaintSelectionGaps() || curr->isTable(); // FIXME: Eventually we won't special-case table like this.
   2958         bool fillBlockGaps = paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone);
   2959         if (fillBlockGaps) {
   2960             // We need to fill the vertical gap above this object.
   2961             if (childState == SelectionEnd || childState == SelectionInside)
   2962                 // Fill the gap above the object.
   2963                 result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
   2964                                                      curr->logicalTop(), paintInfo));
   2965 
   2966             // 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*
   2967             // our object.  We know this if the selection did not end inside our object.
   2968             if (paintsOwnSelection && (childState == SelectionStart || sawSelectionEnd))
   2969                 childState = SelectionNone;
   2970 
   2971             // Fill side gaps on this object based off its state.
   2972             bool leftGap, rightGap;
   2973             getSelectionGapInfo(childState, leftGap, rightGap);
   2974 
   2975             if (leftGap)
   2976                 result.uniteLeft(logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalLeft(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
   2977             if (rightGap)
   2978                 result.uniteRight(logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalRight(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
   2979 
   2980             // Update lastLogicalTop to be just underneath the object.  lastLogicalLeft and lastLogicalRight extend as far as
   2981             // they can without bumping into floating or positioned objects.  Ideally they will go right up
   2982             // to the border of the root selection block.
   2983             lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + curr->logicalBottom();
   2984             lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, curr->logicalBottom());
   2985             lastLogicalRight = logicalRightSelectionOffset(rootBlock, curr->logicalBottom());
   2986         } else if (childState != SelectionNone)
   2987             // We must be a block that has some selected object inside it.  Go ahead and recur.
   2988             result.unite(toRenderBlock(curr)->selectionGaps(rootBlock, rootBlockPhysicalPosition, IntSize(offsetFromRootBlock.width() + curr->x(), offsetFromRootBlock.height() + curr->y()),
   2989                                                             lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo));
   2990     }
   2991     return result;
   2992 }
   2993 
   2994 IntRect RenderBlock::blockSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
   2995                                        int lastLogicalTop, int lastLogicalLeft, int lastLogicalRight, int logicalBottom, const PaintInfo* paintInfo)
   2996 {
   2997     int logicalTop = lastLogicalTop;
   2998     int logicalHeight = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalBottom - logicalTop;
   2999     if (logicalHeight <= 0)
   3000         return IntRect();
   3001 
   3002     // Get the selection offsets for the bottom of the gap
   3003     int logicalLeft = max(lastLogicalLeft, logicalLeftSelectionOffset(rootBlock, logicalBottom));
   3004     int logicalRight = min(lastLogicalRight, logicalRightSelectionOffset(rootBlock, logicalBottom));
   3005     int logicalWidth = logicalRight - logicalLeft;
   3006     if (logicalWidth <= 0)
   3007         return IntRect();
   3008 
   3009     IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(logicalLeft, logicalTop, logicalWidth, logicalHeight));
   3010     if (paintInfo)
   3011         paintInfo->context->fillRect(gapRect, selectionBackgroundColor(), style()->colorSpace());
   3012     return gapRect;
   3013 }
   3014 
   3015 IntRect RenderBlock::logicalLeftSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
   3016                                              RenderObject* selObj, int logicalLeft, int logicalTop, int logicalHeight, const PaintInfo* paintInfo)
   3017 {
   3018     int rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
   3019     int rootBlockLogicalLeft = max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight));
   3020     int rootBlockLogicalRight = min(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalLeft, min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight)));
   3021     int rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
   3022     if (rootBlockLogicalWidth <= 0)
   3023         return IntRect();
   3024 
   3025     IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
   3026     if (paintInfo)
   3027         paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
   3028     return gapRect;
   3029 }
   3030 
   3031 IntRect RenderBlock::logicalRightSelectionGap(RenderBlock* rootBlock, const IntPoint& rootBlockPhysicalPosition, const IntSize& offsetFromRootBlock,
   3032                                               RenderObject* selObj, int logicalRight, int logicalTop, int logicalHeight, const PaintInfo* paintInfo)
   3033 {
   3034     int rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
   3035     int rootBlockLogicalLeft = max(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + logicalRight, max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight)));
   3036     int rootBlockLogicalRight = min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight));
   3037     int rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
   3038     if (rootBlockLogicalWidth <= 0)
   3039         return IntRect();
   3040 
   3041     IntRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, IntRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
   3042     if (paintInfo)
   3043         paintInfo->context->fillRect(gapRect, selObj->selectionBackgroundColor(), selObj->style()->colorSpace());
   3044     return gapRect;
   3045 }
   3046 
   3047 void RenderBlock::getSelectionGapInfo(SelectionState state, bool& leftGap, bool& rightGap)
   3048 {
   3049     bool ltr = style()->isLeftToRightDirection();
   3050     leftGap = (state == RenderObject::SelectionInside) ||
   3051               (state == RenderObject::SelectionEnd && ltr) ||
   3052               (state == RenderObject::SelectionStart && !ltr);
   3053     rightGap = (state == RenderObject::SelectionInside) ||
   3054                (state == RenderObject::SelectionStart && ltr) ||
   3055                (state == RenderObject::SelectionEnd && !ltr);
   3056 }
   3057 
   3058 int RenderBlock::logicalLeftSelectionOffset(RenderBlock* rootBlock, int position)
   3059 {
   3060     int logicalLeft = logicalLeftOffsetForLine(position, false);
   3061     if (logicalLeft == logicalLeftOffsetForContent()) {
   3062         if (rootBlock != this)
   3063             // The border can potentially be further extended by our containingBlock().
   3064             return containingBlock()->logicalLeftSelectionOffset(rootBlock, position + logicalTop());
   3065         return logicalLeft;
   3066     } else {
   3067         RenderBlock* cb = this;
   3068         while (cb != rootBlock) {
   3069             logicalLeft += cb->logicalLeft();
   3070             cb = cb->containingBlock();
   3071         }
   3072     }
   3073     return logicalLeft;
   3074 }
   3075 
   3076 int RenderBlock::logicalRightSelectionOffset(RenderBlock* rootBlock, int position)
   3077 {
   3078     int logicalRight = logicalRightOffsetForLine(position, false);
   3079     if (logicalRight == logicalRightOffsetForContent()) {
   3080         if (rootBlock != this)
   3081             // The border can potentially be further extended by our containingBlock().
   3082             return containingBlock()->logicalRightSelectionOffset(rootBlock, position + logicalTop());
   3083         return logicalRight;
   3084     } else {
   3085         RenderBlock* cb = this;
   3086         while (cb != rootBlock) {
   3087             logicalRight += cb->logicalLeft();
   3088             cb = cb->containingBlock();
   3089         }
   3090     }
   3091     return logicalRight;
   3092 }
   3093 
   3094 void RenderBlock::insertPositionedObject(RenderBox* o)
   3095 {
   3096     // Create the list of special objects if we don't aleady have one
   3097     if (!m_positionedObjects)
   3098         m_positionedObjects = adoptPtr(new PositionedObjectsListHashSet);
   3099 
   3100     m_positionedObjects->add(o);
   3101 }
   3102 
   3103 void RenderBlock::removePositionedObject(RenderBox* o)
   3104 {
   3105     if (m_positionedObjects)
   3106         m_positionedObjects->remove(o);
   3107 }
   3108 
   3109 void RenderBlock::removePositionedObjects(RenderBlock* o)
   3110 {
   3111     if (!m_positionedObjects)
   3112         return;
   3113 
   3114     RenderBox* r;
   3115 
   3116     Iterator end = m_positionedObjects->end();
   3117 
   3118     Vector<RenderBox*, 16> deadObjects;
   3119 
   3120     for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
   3121         r = *it;
   3122         if (!o || r->isDescendantOf(o)) {
   3123             if (o)
   3124                 r->setChildNeedsLayout(true, false);
   3125 
   3126             // It is parent blocks job to add positioned child to positioned objects list of its containing block
   3127             // Parent layout needs to be invalidated to ensure this happens.
   3128             RenderObject* p = r->parent();
   3129             while (p && !p->isRenderBlock())
   3130                 p = p->parent();
   3131             if (p)
   3132                 p->setChildNeedsLayout(true);
   3133 
   3134             deadObjects.append(r);
   3135         }
   3136     }
   3137 
   3138     for (unsigned i = 0; i < deadObjects.size(); i++)
   3139         m_positionedObjects->remove(deadObjects.at(i));
   3140 }
   3141 
   3142 RenderBlock::FloatingObject* RenderBlock::insertFloatingObject(RenderBox* o)
   3143 {
   3144     ASSERT(o->isFloating());
   3145 
   3146     // Create the list of special objects if we don't aleady have one
   3147     if (!m_floatingObjects)
   3148         m_floatingObjects = adoptPtr(new FloatingObjects);
   3149     else {
   3150         // Don't insert the object again if it's already in the list
   3151         FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3152         FloatingObjectSetIterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(o);
   3153         if (it != floatingObjectSet.end())
   3154             return *it;
   3155     }
   3156 
   3157     // Create the special object entry & append it to the list
   3158 
   3159     FloatingObject* newObj = new FloatingObject(o->style()->floating() == FLEFT ? FloatingObject::FloatLeft : FloatingObject::FloatRight);
   3160 
   3161     // Our location is irrelevant if we're unsplittable or no pagination is in effect.
   3162     // Just go ahead and lay out the float.
   3163     bool isChildRenderBlock = o->isRenderBlock();
   3164     if (isChildRenderBlock && !o->needsLayout() && view()->layoutState()->pageLogicalHeightChanged())
   3165         o->setChildNeedsLayout(true, false);
   3166 
   3167     bool affectedByPagination = isChildRenderBlock && view()->layoutState()->m_pageLogicalHeight;
   3168     if (!affectedByPagination || isWritingModeRoot()) // We are unsplittable if we're a block flow root.
   3169         o->layoutIfNeeded();
   3170     else {
   3171         o->computeLogicalWidth();
   3172         o->computeBlockDirectionMargins(this);
   3173     }
   3174     setLogicalWidthForFloat(newObj, logicalWidthForChild(o) + marginStartForChild(o) + marginEndForChild(o));
   3175 
   3176     newObj->m_shouldPaint = !o->hasSelfPaintingLayer(); // If a layer exists, the float will paint itself.  Otherwise someone else will.
   3177     newObj->m_isDescendant = true;
   3178     newObj->m_renderer = o;
   3179 
   3180     m_floatingObjects->increaseObjectsCount(newObj->type());
   3181     m_floatingObjects->set().add(newObj);
   3182 
   3183     return newObj;
   3184 }
   3185 
   3186 void RenderBlock::removeFloatingObject(RenderBox* o)
   3187 {
   3188     if (m_floatingObjects) {
   3189         FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3190         FloatingObjectSet::iterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(o);
   3191         if (it != floatingObjectSet.end()) {
   3192             FloatingObject* r = *it;
   3193             if (childrenInline()) {
   3194                 int logicalTop = logicalTopForFloat(r);
   3195                 int logicalBottom = logicalBottomForFloat(r);
   3196 
   3197                 // Fix for https://bugs.webkit.org/show_bug.cgi?id=54995.
   3198                 if (logicalBottom < 0 || logicalBottom < logicalTop || logicalTop == numeric_limits<int>::max())
   3199                     logicalBottom = numeric_limits<int>::max();
   3200                 else {
   3201                     // Special-case zero- and less-than-zero-height floats: those don't touch
   3202                     // the line that they're on, but it still needs to be dirtied. This is
   3203                     // accomplished by pretending they have a height of 1.
   3204                     logicalBottom = max(logicalBottom, logicalTop + 1);
   3205                 }
   3206                 if (r->m_originatingLine) {
   3207                     ASSERT(r->m_originatingLine->renderer() == this);
   3208                     r->m_originatingLine->markDirty();
   3209 #if !ASSERT_DISABLED
   3210                     r->m_originatingLine = 0;
   3211 #endif
   3212                 }
   3213                 markLinesDirtyInBlockRange(0, logicalBottom);
   3214             }
   3215             m_floatingObjects->decreaseObjectsCount(r->type());
   3216             floatingObjectSet.remove(it);
   3217             ASSERT(!r->m_originatingLine);
   3218             delete r;
   3219         }
   3220     }
   3221 }
   3222 
   3223 void RenderBlock::removeFloatingObjectsBelow(FloatingObject* lastFloat, int logicalOffset)
   3224 {
   3225     if (!m_floatingObjects)
   3226         return;
   3227 
   3228     FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3229     FloatingObject* curr = floatingObjectSet.last();
   3230     while (curr != lastFloat && (!curr->isPlaced() || logicalTopForFloat(curr) >= logicalOffset)) {
   3231         m_floatingObjects->decreaseObjectsCount(curr->type());
   3232         floatingObjectSet.removeLast();
   3233         ASSERT(!curr->m_originatingLine);
   3234         delete curr;
   3235         curr = floatingObjectSet.last();
   3236     }
   3237 }
   3238 
   3239 bool RenderBlock::positionNewFloats()
   3240 {
   3241     if (!m_floatingObjects)
   3242         return false;
   3243 
   3244     FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3245     if (floatingObjectSet.isEmpty())
   3246         return false;
   3247 
   3248     // If all floats have already been positioned, then we have no work to do.
   3249     if (floatingObjectSet.last()->isPlaced())
   3250         return false;
   3251 
   3252     // Move backwards through our floating object list until we find a float that has
   3253     // already been positioned.  Then we'll be able to move forward, positioning all of
   3254     // the new floats that need it.
   3255     FloatingObjectSetIterator it = floatingObjectSet.end();
   3256     --it; // Go to last item.
   3257     FloatingObjectSetIterator begin = floatingObjectSet.begin();
   3258     FloatingObject* lastPlacedFloatingObject = 0;
   3259     while (it != begin) {
   3260         --it;
   3261         if ((*it)->isPlaced()) {
   3262             lastPlacedFloatingObject = *it;
   3263             ++it;
   3264             break;
   3265         }
   3266     }
   3267 
   3268     int logicalTop = logicalHeight();
   3269 
   3270     // The float cannot start above the top position of the last positioned float.
   3271     if (lastPlacedFloatingObject)
   3272         logicalTop = max(logicalTopForFloat(lastPlacedFloatingObject), logicalTop);
   3273 
   3274     FloatingObjectSetIterator end = floatingObjectSet.end();
   3275     // Now walk through the set of unpositioned floats and place them.
   3276     for (; it != end; ++it) {
   3277          FloatingObject* floatingObject = *it;
   3278         // The containing block is responsible for positioning floats, so if we have floats in our
   3279         // list that come from somewhere else, do not attempt to position them.
   3280         if (floatingObject->renderer()->containingBlock() != this)
   3281             continue;
   3282 
   3283         RenderBox* childBox = floatingObject->renderer();
   3284         int childLogicalLeftMargin = style()->isLeftToRightDirection() ? marginStartForChild(childBox) : marginEndForChild(childBox);
   3285 
   3286         int rightOffset = logicalRightOffsetForContent(); // Constant part of right offset.
   3287         int leftOffset = logicalLeftOffsetForContent(); // Constant part of left offset.
   3288         int floatLogicalWidth = logicalWidthForFloat(floatingObject); // The width we look for.
   3289         if (rightOffset - leftOffset < floatLogicalWidth)
   3290             floatLogicalWidth = rightOffset - leftOffset; // Never look for more than what will be available.
   3291 
   3292         IntRect oldRect(childBox->x(), childBox->y() , childBox->width(), childBox->height());
   3293 
   3294         if (childBox->style()->clear() & CLEFT)
   3295             logicalTop = max(lowestFloatLogicalBottom(FloatingObject::FloatLeft), logicalTop);
   3296         if (childBox->style()->clear() & CRIGHT)
   3297             logicalTop = max(lowestFloatLogicalBottom(FloatingObject::FloatRight), logicalTop);
   3298 
   3299         int floatLogicalLeft;
   3300         if (childBox->style()->floating() == FLEFT) {
   3301             int heightRemainingLeft = 1;
   3302             int heightRemainingRight = 1;
   3303             floatLogicalLeft = logicalLeftOffsetForLine(logicalTop, leftOffset, false, &heightRemainingLeft);
   3304             while (logicalRightOffsetForLine(logicalTop, rightOffset, false, &heightRemainingRight) - floatLogicalLeft < floatLogicalWidth) {
   3305                 logicalTop += min(heightRemainingLeft, heightRemainingRight);
   3306                 floatLogicalLeft = logicalLeftOffsetForLine(logicalTop, leftOffset, false, &heightRemainingLeft);
   3307             }
   3308             floatLogicalLeft = max(0, floatLogicalLeft);
   3309         } else {
   3310             int heightRemainingLeft = 1;
   3311             int heightRemainingRight = 1;
   3312             floatLogicalLeft = logicalRightOffsetForLine(logicalTop, rightOffset, false, &heightRemainingRight);
   3313             while (floatLogicalLeft - logicalLeftOffsetForLine(logicalTop, leftOffset, false, &heightRemainingLeft) < floatLogicalWidth) {
   3314                 logicalTop += min(heightRemainingLeft, heightRemainingRight);
   3315                 floatLogicalLeft = logicalRightOffsetForLine(logicalTop, rightOffset, false, &heightRemainingRight);
   3316             }
   3317             floatLogicalLeft -= logicalWidthForFloat(floatingObject); // Use the original width of the float here, since the local variable
   3318                                                                       // |floatLogicalWidth| was capped to the available line width.
   3319                                                                       // See fast/block/float/clamped-right-float.html.
   3320         }
   3321 
   3322         setLogicalLeftForFloat(floatingObject, floatLogicalLeft);
   3323         setLogicalLeftForChild(childBox, floatLogicalLeft + childLogicalLeftMargin);
   3324         setLogicalTopForChild(childBox, logicalTop + marginBeforeForChild(childBox));
   3325 
   3326         if (view()->layoutState()->isPaginated()) {
   3327             RenderBlock* childBlock = childBox->isRenderBlock() ? toRenderBlock(childBox) : 0;
   3328 
   3329             if (!childBox->needsLayout())
   3330                 childBox->markForPaginationRelayoutIfNeeded();;
   3331             childBox->layoutIfNeeded();
   3332 
   3333             // If we are unsplittable and don't fit, then we need to move down.
   3334             // We include our margins as part of the unsplittable area.
   3335             int newLogicalTop = adjustForUnsplittableChild(childBox, logicalTop, true);
   3336 
   3337             // See if we have a pagination strut that is making us move down further.
   3338             // Note that an unsplittable child can't also have a pagination strut, so this is
   3339             // exclusive with the case above.
   3340             if (childBlock && childBlock->paginationStrut()) {
   3341                 newLogicalTop += childBlock->paginationStrut();
   3342                 childBlock->setPaginationStrut(0);
   3343             }
   3344 
   3345             if (newLogicalTop != logicalTop) {
   3346                 floatingObject->m_paginationStrut = newLogicalTop - logicalTop;
   3347                 logicalTop = newLogicalTop;
   3348                 setLogicalTopForChild(childBox, logicalTop + marginBeforeForChild(childBox));
   3349                 if (childBlock)
   3350                     childBlock->setChildNeedsLayout(true, false);
   3351                 childBox->layoutIfNeeded();
   3352             }
   3353         }
   3354 
   3355         setLogicalTopForFloat(floatingObject, logicalTop);
   3356         setLogicalHeightForFloat(floatingObject, logicalHeightForChild(childBox) + marginBeforeForChild(childBox) + marginAfterForChild(childBox));
   3357 
   3358         floatingObject->setIsPlaced();
   3359 
   3360         // If the child moved, we have to repaint it.
   3361         if (childBox->checkForRepaintDuringLayout())
   3362             childBox->repaintDuringLayoutIfMoved(oldRect);
   3363     }
   3364     return true;
   3365 }
   3366 
   3367 void RenderBlock::newLine(EClear clear)
   3368 {
   3369     positionNewFloats();
   3370     // set y position
   3371     int newY = 0;
   3372     switch (clear)
   3373     {
   3374         case CLEFT:
   3375             newY = lowestFloatLogicalBottom(FloatingObject::FloatLeft);
   3376             break;
   3377         case CRIGHT:
   3378             newY = lowestFloatLogicalBottom(FloatingObject::FloatRight);
   3379             break;
   3380         case CBOTH:
   3381             newY = lowestFloatLogicalBottom();
   3382         default:
   3383             break;
   3384     }
   3385     if (height() < newY)
   3386         setLogicalHeight(newY);
   3387 }
   3388 
   3389 void RenderBlock::addPercentHeightDescendant(RenderBox* descendant)
   3390 {
   3391     if (!gPercentHeightDescendantsMap) {
   3392         gPercentHeightDescendantsMap = new PercentHeightDescendantsMap;
   3393         gPercentHeightContainerMap = new PercentHeightContainerMap;
   3394     }
   3395 
   3396     HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(this);
   3397     if (!descendantSet) {
   3398         descendantSet = new HashSet<RenderBox*>;
   3399         gPercentHeightDescendantsMap->set(this, descendantSet);
   3400     }
   3401     bool added = descendantSet->add(descendant).second;
   3402     if (!added) {
   3403         ASSERT(gPercentHeightContainerMap->get(descendant));
   3404         ASSERT(gPercentHeightContainerMap->get(descendant)->contains(this));
   3405         return;
   3406     }
   3407 
   3408     HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->get(descendant);
   3409     if (!containerSet) {
   3410         containerSet = new HashSet<RenderBlock*>;
   3411         gPercentHeightContainerMap->set(descendant, containerSet);
   3412     }
   3413     ASSERT(!containerSet->contains(this));
   3414     containerSet->add(this);
   3415 }
   3416 
   3417 void RenderBlock::removePercentHeightDescendant(RenderBox* descendant)
   3418 {
   3419     if (!gPercentHeightContainerMap)
   3420         return;
   3421 
   3422     HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->take(descendant);
   3423     if (!containerSet)
   3424         return;
   3425 
   3426     HashSet<RenderBlock*>::iterator end = containerSet->end();
   3427     for (HashSet<RenderBlock*>::iterator it = containerSet->begin(); it != end; ++it) {
   3428         RenderBlock* container = *it;
   3429         HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(container);
   3430         ASSERT(descendantSet);
   3431         if (!descendantSet)
   3432             continue;
   3433         ASSERT(descendantSet->contains(descendant));
   3434         descendantSet->remove(descendant);
   3435         if (descendantSet->isEmpty()) {
   3436             gPercentHeightDescendantsMap->remove(container);
   3437             delete descendantSet;
   3438         }
   3439     }
   3440 
   3441     delete containerSet;
   3442 }
   3443 
   3444 HashSet<RenderBox*>* RenderBlock::percentHeightDescendants() const
   3445 {
   3446     return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0;
   3447 }
   3448 
   3449 // FIXME: The logicalLeftOffsetForLine/logicalRightOffsetForLine functions are very slow if there are many floats
   3450 // present. We need to add a structure to floating objects to represent "lines" of floats.  Then instead of checking
   3451 // each float individually, we'd just walk backwards through the "lines" and stop when we hit a line that is fully above
   3452 // the vertical offset that we'd like to check.  Computing the "lines" would be rather complicated, but could replace the left
   3453 // objects and right objects count hack that is currently used here.
   3454 int RenderBlock::logicalLeftOffsetForLine(int logicalTop, int fixedOffset, bool applyTextIndent, int* heightRemaining) const
   3455 {
   3456     int left = fixedOffset;
   3457     if (m_floatingObjects && m_floatingObjects->hasLeftObjects()) {
   3458         if (heightRemaining)
   3459             *heightRemaining = 1;
   3460 
   3461         // We know the list is non-empty, since we have "left" objects to search for.
   3462         // Therefore we can assume that begin != end, and that we can do at least one
   3463         // decrement.
   3464         FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3465         FloatingObjectSetIterator begin = floatingObjectSet.begin();
   3466         FloatingObjectSetIterator it = floatingObjectSet.end();
   3467         do {
   3468             --it;
   3469             FloatingObject* r = *it;
   3470             if (r->isPlaced() && logicalTopForFloat(r) <= logicalTop && logicalBottomForFloat(r) > logicalTop
   3471                 && r->type() == FloatingObject::FloatLeft
   3472                 && logicalRightForFloat(r) > left) {
   3473                 left = max(left, logicalRightForFloat(r));
   3474                 if (heightRemaining)
   3475                     *heightRemaining = logicalBottomForFloat(r) - logicalTop;
   3476             }
   3477         } while (it != begin);
   3478     }
   3479 
   3480     if (applyTextIndent && style()->isLeftToRightDirection()) {
   3481         int cw = 0;
   3482         if (style()->textIndent().isPercent())
   3483             cw = containingBlock()->availableLogicalWidth();
   3484         left += style()->textIndent().calcMinValue(cw);
   3485     }
   3486 
   3487     return left;
   3488 }
   3489 
   3490 int RenderBlock::logicalRightOffsetForLine(int logicalTop, int fixedOffset, bool applyTextIndent, int* heightRemaining) const
   3491 {
   3492     int right = fixedOffset;
   3493 
   3494     if (m_floatingObjects && m_floatingObjects->hasRightObjects()) {
   3495         if (heightRemaining)
   3496             *heightRemaining = 1;
   3497 
   3498         // We know the list is non-empty, since we have "right" objects to search for.
   3499         // Therefore we can assume that begin != end, and that we can do at least one
   3500         // decrement.
   3501         FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3502         FloatingObjectSetIterator begin = floatingObjectSet.begin();
   3503         FloatingObjectSetIterator it = floatingObjectSet.end();
   3504         do {
   3505             --it;
   3506             FloatingObject* r = *it;
   3507             if (r->isPlaced() && logicalTopForFloat(r) <= logicalTop && logicalBottomForFloat(r) > logicalTop
   3508                 && r->type() == FloatingObject::FloatRight
   3509                 && logicalLeftForFloat(r) < right) {
   3510                 right = min(right, logicalLeftForFloat(r));
   3511                 if (heightRemaining)
   3512                     *heightRemaining = logicalBottomForFloat(r) - logicalTop;
   3513             }
   3514         } while (it != begin);
   3515     }
   3516 
   3517     if (applyTextIndent && !style()->isLeftToRightDirection()) {
   3518         int cw = 0;
   3519         if (style()->textIndent().isPercent())
   3520             cw = containingBlock()->availableLogicalWidth();
   3521         right -= style()->textIndent().calcMinValue(cw);
   3522     }
   3523 
   3524     return right;
   3525 }
   3526 
   3527 int RenderBlock::availableLogicalWidthForLine(int position, bool firstLine) const
   3528 {
   3529     int result = logicalRightOffsetForLine(position, firstLine) - logicalLeftOffsetForLine(position, firstLine);
   3530     return (result < 0) ? 0 : result;
   3531 }
   3532 
   3533 int RenderBlock::nextFloatLogicalBottomBelow(int logicalHeight) const
   3534 {
   3535     if (!m_floatingObjects)
   3536         return 0;
   3537 
   3538     int bottom = INT_MAX;
   3539     FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3540     FloatingObjectSetIterator end = floatingObjectSet.end();
   3541     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   3542         FloatingObject* r = *it;
   3543         int floatBottom = logicalBottomForFloat(r);
   3544         if (floatBottom > logicalHeight)
   3545             bottom = min(floatBottom, bottom);
   3546     }
   3547 
   3548     return bottom == INT_MAX ? 0 : bottom;
   3549 }
   3550 
   3551 int RenderBlock::lowestFloatLogicalBottom(FloatingObject::Type floatType) const
   3552 {
   3553     if (!m_floatingObjects)
   3554         return 0;
   3555     int lowestFloatBottom = 0;
   3556     FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3557     FloatingObjectSetIterator end = floatingObjectSet.end();
   3558     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   3559         FloatingObject* r = *it;
   3560         if (r->isPlaced() && r->type() & floatType)
   3561             lowestFloatBottom = max(lowestFloatBottom, logicalBottomForFloat(r));
   3562     }
   3563     return lowestFloatBottom;
   3564 }
   3565 
   3566 void RenderBlock::markLinesDirtyInBlockRange(int logicalTop, int logicalBottom, RootInlineBox* highest)
   3567 {
   3568     if (logicalTop >= logicalBottom)
   3569         return;
   3570 
   3571     RootInlineBox* lowestDirtyLine = lastRootBox();
   3572     RootInlineBox* afterLowest = lowestDirtyLine;
   3573     while (lowestDirtyLine && lowestDirtyLine->blockLogicalHeight() >= logicalBottom && logicalBottom < numeric_limits<int>::max()) {
   3574         afterLowest = lowestDirtyLine;
   3575         lowestDirtyLine = lowestDirtyLine->prevRootBox();
   3576     }
   3577 
   3578     while (afterLowest && afterLowest != highest && (afterLowest->blockLogicalHeight() >= logicalTop || afterLowest->blockLogicalHeight() < 0)) {
   3579         afterLowest->markDirty();
   3580         afterLowest = afterLowest->prevRootBox();
   3581     }
   3582 }
   3583 
   3584 void RenderBlock::clearFloats()
   3585 {
   3586     // Inline blocks are covered by the isReplaced() check in the avoidFloats method.
   3587     if (avoidsFloats() || isRoot() || isRenderView() || isFloatingOrPositioned() || isTableCell()) {
   3588         if (m_floatingObjects) {
   3589             deleteAllValues(m_floatingObjects->set());
   3590             m_floatingObjects->clear();
   3591         }
   3592         return;
   3593     }
   3594 
   3595     typedef HashMap<RenderObject*, FloatingObject*> RendererToFloatInfoMap;
   3596     RendererToFloatInfoMap floatMap;
   3597 
   3598     if (m_floatingObjects) {
   3599         FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3600         if (childrenInline()) {
   3601             FloatingObjectSet::iterator end = floatingObjectSet.end();
   3602             for (FloatingObjectSet::iterator it = floatingObjectSet.begin(); it != end; ++it) {
   3603                 FloatingObject* f = *it;
   3604                 floatMap.add(f->m_renderer, f);
   3605             }
   3606         } else
   3607             deleteAllValues(floatingObjectSet);
   3608         m_floatingObjects->clear();
   3609     }
   3610 
   3611     // We should not process floats if the parent node is not a RenderBlock. Otherwise, we will add
   3612     // floats in an invalid context. This will cause a crash arising from a bad cast on the parent.
   3613     // See <rdar://problem/8049753>, where float property is applied on a text node in a SVG.
   3614     if (!parent() || !parent()->isRenderBlock())
   3615         return;
   3616 
   3617     // Attempt to locate a previous sibling with overhanging floats.  We skip any elements that are
   3618     // out of flow (like floating/positioned elements), and we also skip over any objects that may have shifted
   3619     // to avoid floats.
   3620     bool parentHasFloats = false;
   3621     RenderBlock* parentBlock = toRenderBlock(parent());
   3622     RenderObject* prev = previousSibling();
   3623     while (prev && (prev->isFloatingOrPositioned() || !prev->isBox() || !prev->isRenderBlock() || toRenderBlock(prev)->avoidsFloats())) {
   3624         if (prev->isFloating())
   3625             parentHasFloats = true;
   3626          prev = prev->previousSibling();
   3627     }
   3628 
   3629     // First add in floats from the parent.
   3630     int logicalTopOffset = logicalTop();
   3631     if (parentHasFloats)
   3632         addIntrudingFloats(parentBlock, parentBlock->logicalLeftOffsetForContent(), logicalTopOffset);
   3633 
   3634     int logicalLeftOffset = 0;
   3635     if (prev)
   3636         logicalTopOffset -= toRenderBox(prev)->logicalTop();
   3637     else {
   3638         prev = parentBlock;
   3639         logicalLeftOffset += parentBlock->logicalLeftOffsetForContent();
   3640     }
   3641 
   3642     // Add overhanging floats from the previous RenderBlock, but only if it has a float that intrudes into our space.
   3643     if (!prev || !prev->isRenderBlock())
   3644         return;
   3645 
   3646     RenderBlock* block = toRenderBlock(prev);
   3647     if (block->m_floatingObjects && block->lowestFloatLogicalBottom() > logicalTopOffset)
   3648         addIntrudingFloats(block, logicalLeftOffset, logicalTopOffset);
   3649 
   3650     if (childrenInline()) {
   3651         int changeLogicalTop = numeric_limits<int>::max();
   3652         int changeLogicalBottom = numeric_limits<int>::min();
   3653         if (m_floatingObjects) {
   3654             FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3655             FloatingObjectSetIterator end = floatingObjectSet.end();
   3656             for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   3657                 FloatingObject* f = *it;
   3658                 FloatingObject* oldFloatingObject = floatMap.get(f->m_renderer);
   3659                 int logicalBottom = logicalBottomForFloat(f);
   3660                 if (oldFloatingObject) {
   3661                     int oldLogicalBottom = logicalBottomForFloat(oldFloatingObject);
   3662                     if (logicalWidthForFloat(f) != logicalWidthForFloat(oldFloatingObject) || logicalLeftForFloat(f) != logicalLeftForFloat(oldFloatingObject)) {
   3663                         changeLogicalTop = 0;
   3664                         changeLogicalBottom = max(changeLogicalBottom, max(logicalBottom, oldLogicalBottom));
   3665                     } else if (logicalBottom != oldLogicalBottom) {
   3666                         changeLogicalTop = min(changeLogicalTop, min(logicalBottom, oldLogicalBottom));
   3667                         changeLogicalBottom = max(changeLogicalBottom, max(logicalBottom, oldLogicalBottom));
   3668                     }
   3669 
   3670                     floatMap.remove(f->m_renderer);
   3671                     if (oldFloatingObject->m_originatingLine) {
   3672                         ASSERT(oldFloatingObject->m_originatingLine->renderer() == this);
   3673                         oldFloatingObject->m_originatingLine->markDirty();
   3674                     }
   3675                     delete oldFloatingObject;
   3676                 } else {
   3677                     changeLogicalTop = 0;
   3678                     changeLogicalBottom = max(changeLogicalBottom, logicalBottom);
   3679                 }
   3680             }
   3681         }
   3682 
   3683         RendererToFloatInfoMap::iterator end = floatMap.end();
   3684         for (RendererToFloatInfoMap::iterator it = floatMap.begin(); it != end; ++it) {
   3685             FloatingObject* floatingObject = (*it).second;
   3686             if (!floatingObject->m_isDescendant) {
   3687                 changeLogicalTop = 0;
   3688                 changeLogicalBottom = max(changeLogicalBottom, logicalBottomForFloat(floatingObject));
   3689             }
   3690         }
   3691         deleteAllValues(floatMap);
   3692 
   3693         markLinesDirtyInBlockRange(changeLogicalTop, changeLogicalBottom);
   3694     }
   3695 }
   3696 
   3697 int RenderBlock::addOverhangingFloats(RenderBlock* child, int logicalLeftOffset, int logicalTopOffset, bool makeChildPaintOtherFloats)
   3698 {
   3699     // Prevent floats from being added to the canvas by the root element, e.g., <html>.
   3700     if (child->hasOverflowClip() || !child->containsFloats() || child->isRoot() || child->hasColumns() || child->isWritingModeRoot())
   3701         return 0;
   3702 
   3703     int childLogicalTop = child->logicalTop();
   3704     int lowestFloatLogicalBottom = 0;
   3705 
   3706     // Floats that will remain the child's responsibility to paint should factor into its
   3707     // overflow.
   3708     FloatingObjectSetIterator childEnd = child->m_floatingObjects->set().end();
   3709     for (FloatingObjectSetIterator childIt = child->m_floatingObjects->set().begin(); childIt != childEnd; ++childIt) {
   3710         FloatingObject* r = *childIt;
   3711         int logicalBottomForFloat = min(this->logicalBottomForFloat(r), numeric_limits<int>::max() - childLogicalTop);
   3712         int logicalBottom = childLogicalTop + logicalBottomForFloat;
   3713         lowestFloatLogicalBottom = max(lowestFloatLogicalBottom, logicalBottom);
   3714 
   3715         if (logicalBottom > logicalHeight()) {
   3716             // If the object is not in the list, we add it now.
   3717             if (!containsFloat(r->m_renderer)) {
   3718                 int leftOffset = isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset;
   3719                 int topOffset = isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset;
   3720                 FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->x() - leftOffset, r->y() - topOffset, r->width(), r->height()));
   3721                 floatingObj->m_renderer = r->m_renderer;
   3722 
   3723                 // The nearest enclosing layer always paints the float (so that zindex and stacking
   3724                 // behaves properly).  We always want to propagate the desire to paint the float as
   3725                 // far out as we can, to the outermost block that overlaps the float, stopping only
   3726                 // if we hit a self-painting layer boundary.
   3727                 if (r->m_renderer->enclosingFloatPaintingLayer() == enclosingFloatPaintingLayer())
   3728                     r->m_shouldPaint = false;
   3729                 else
   3730                     floatingObj->m_shouldPaint = false;
   3731 
   3732                 floatingObj->m_isDescendant = true;
   3733 
   3734                 // We create the floating object list lazily.
   3735                 if (!m_floatingObjects)
   3736                     m_floatingObjects = adoptPtr(new FloatingObjects);
   3737 
   3738                 m_floatingObjects->increaseObjectsCount(floatingObj->type());
   3739                 m_floatingObjects->set().add(floatingObj);
   3740             }
   3741         } else {
   3742             if (makeChildPaintOtherFloats && !r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer() &&
   3743                 r->m_renderer->isDescendantOf(child) && r->m_renderer->enclosingFloatPaintingLayer() == child->enclosingFloatPaintingLayer()) {
   3744                 // The float is not overhanging from this block, so if it is a descendant of the child, the child should
   3745                 // paint it (the other case is that it is intruding into the child), unless it has its own layer or enclosing
   3746                 // layer.
   3747                 // If makeChildPaintOtherFloats is false, it means that the child must already know about all the floats
   3748                 // it should paint.
   3749                 r->m_shouldPaint = true;
   3750             }
   3751 
   3752             // 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
   3753             // child now.
   3754             if (r->m_isDescendant)
   3755                 child->addOverflowFromChild(r->m_renderer, IntSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r)));
   3756         }
   3757     }
   3758     return lowestFloatLogicalBottom;
   3759 }
   3760 
   3761 bool RenderBlock::hasOverhangingFloat(RenderBox* renderer)
   3762 {
   3763     if (!m_floatingObjects || hasColumns() || !parent())
   3764         return false;
   3765 
   3766     FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3767     FloatingObjectSetIterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(renderer);
   3768     if (it == floatingObjectSet.end())
   3769         return false;
   3770 
   3771     return logicalBottomForFloat(*it) > logicalHeight();
   3772 }
   3773 
   3774 void RenderBlock::addIntrudingFloats(RenderBlock* prev, int logicalLeftOffset, int logicalTopOffset)
   3775 {
   3776     // If the parent or previous sibling doesn't have any floats to add, don't bother.
   3777     if (!prev->m_floatingObjects)
   3778         return;
   3779 
   3780     logicalLeftOffset += (isHorizontalWritingMode() ? marginLeft() : marginTop());
   3781 
   3782     FloatingObjectSet& prevSet = prev->m_floatingObjects->set();
   3783     FloatingObjectSetIterator prevEnd = prevSet.end();
   3784     for (FloatingObjectSetIterator prevIt = prevSet.begin(); prevIt != prevEnd; ++prevIt) {
   3785         FloatingObject* r = *prevIt;
   3786         if (logicalBottomForFloat(r) > logicalTopOffset) {
   3787             if (!m_floatingObjects || !m_floatingObjects->set().contains(r)) {
   3788                 int leftOffset = isHorizontalWritingMode() ? logicalLeftOffset : logicalTopOffset;
   3789                 int topOffset = isHorizontalWritingMode() ? logicalTopOffset : logicalLeftOffset;
   3790 
   3791                 FloatingObject* floatingObj = new FloatingObject(r->type(), IntRect(r->x() - leftOffset, r->y() - topOffset, r->width(), r->height()));
   3792 
   3793                 // Applying the child's margin makes no sense in the case where the child was passed in.
   3794                 // since this margin was added already through the modification of the |logicalLeftOffset| variable
   3795                 // above.  |logicalLeftOffset| will equal the margin in this case, so it's already been taken
   3796                 // into account.  Only apply this code if prev is the parent, since otherwise the left margin
   3797                 // will get applied twice.
   3798                 if (prev != parent()) {
   3799                     if (isHorizontalWritingMode())
   3800                         floatingObj->setX(floatingObj->x() + prev->marginLeft());
   3801                     else
   3802                         floatingObj->setY(floatingObj->y() + prev->marginTop());
   3803                 }
   3804 
   3805                 floatingObj->m_shouldPaint = false;  // We are not in the direct inheritance chain for this float. We will never paint it.
   3806                 floatingObj->m_renderer = r->m_renderer;
   3807 
   3808                 // We create the floating object list lazily.
   3809                 if (!m_floatingObjects)
   3810                     m_floatingObjects = adoptPtr(new FloatingObjects);
   3811                 m_floatingObjects->increaseObjectsCount(floatingObj->type());
   3812                 m_floatingObjects->set().add(floatingObj);
   3813             }
   3814         }
   3815     }
   3816 }
   3817 
   3818 bool RenderBlock::avoidsFloats() const
   3819 {
   3820     // Floats can't intrude into our box if we have a non-auto column count or width.
   3821     return RenderBox::avoidsFloats() || !style()->hasAutoColumnCount() || !style()->hasAutoColumnWidth();
   3822 }
   3823 
   3824 bool RenderBlock::containsFloat(RenderBox* renderer)
   3825 {
   3826     return m_floatingObjects && m_floatingObjects->set().contains<RenderBox*, FloatingObjectHashTranslator>(renderer);
   3827 }
   3828 
   3829 void RenderBlock::markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove, bool inLayout)
   3830 {
   3831     if (!m_everHadLayout)
   3832         return;
   3833 
   3834     setChildNeedsLayout(true, !inLayout);
   3835 
   3836     if (floatToRemove)
   3837         removeFloatingObject(floatToRemove);
   3838 
   3839     // Iterate over our children and mark them as needed.
   3840     if (!childrenInline()) {
   3841         for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
   3842             if ((!floatToRemove && child->isFloatingOrPositioned()) || !child->isRenderBlock())
   3843                 continue;
   3844             RenderBlock* childBlock = toRenderBlock(child);
   3845             if ((floatToRemove ? childBlock->containsFloat(floatToRemove) : childBlock->containsFloats()) || childBlock->shrinkToAvoidFloats())
   3846                 childBlock->markAllDescendantsWithFloatsForLayout(floatToRemove, inLayout);
   3847         }
   3848     }
   3849 }
   3850 
   3851 void RenderBlock::markSiblingsWithFloatsForLayout()
   3852 {
   3853     FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3854     FloatingObjectSetIterator end = floatingObjectSet.end();
   3855     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   3856         if (logicalBottomForFloat(*it) > logicalHeight()) {
   3857             RenderBox* floatingBox = (*it)->renderer();
   3858 
   3859             RenderObject* next = nextSibling();
   3860             while (next) {
   3861                 if (next->isRenderBlock() && !next->isFloatingOrPositioned() && !toRenderBlock(next)->avoidsFloats()) {
   3862                     RenderBlock* nextBlock = toRenderBlock(next);
   3863                     if (nextBlock->containsFloat(floatingBox))
   3864                         nextBlock->markAllDescendantsWithFloatsForLayout(floatingBox);
   3865                     else
   3866                         break;
   3867                 }
   3868 
   3869                 next = next->nextSibling();
   3870             }
   3871         }
   3872     }
   3873 }
   3874 
   3875 int RenderBlock::getClearDelta(RenderBox* child, int yPos)
   3876 {
   3877     // There is no need to compute clearance if we have no floats.
   3878     if (!containsFloats())
   3879         return 0;
   3880 
   3881     // At least one float is present.  We need to perform the clearance computation.
   3882     bool clearSet = child->style()->clear() != CNONE;
   3883     int bottom = 0;
   3884     switch (child->style()->clear()) {
   3885         case CNONE:
   3886             break;
   3887         case CLEFT:
   3888             bottom = lowestFloatLogicalBottom(FloatingObject::FloatLeft);
   3889             break;
   3890         case CRIGHT:
   3891             bottom = lowestFloatLogicalBottom(FloatingObject::FloatRight);
   3892             break;
   3893         case CBOTH:
   3894             bottom = lowestFloatLogicalBottom();
   3895             break;
   3896     }
   3897 
   3898     // 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).
   3899     int result = clearSet ? max(0, bottom - yPos) : 0;
   3900     if (!result && child->avoidsFloats()) {
   3901         int y = yPos;
   3902         while (true) {
   3903             int widthAtY = availableLogicalWidthForLine(y, false);
   3904             if (widthAtY == availableLogicalWidth())
   3905                 return y - yPos;
   3906 
   3907             int oldChildY = child->y();
   3908             int oldChildWidth = child->width();
   3909             child->setY(y);
   3910             child->computeLogicalWidth();
   3911             int childWidthAtY = child->width();
   3912             child->setY(oldChildY);
   3913             child->setWidth(oldChildWidth);
   3914 
   3915             if (childWidthAtY <= widthAtY)
   3916                 return y - yPos;
   3917 
   3918             y = nextFloatLogicalBottomBelow(y);
   3919             ASSERT(y >= yPos);
   3920             if (y < yPos)
   3921                 break;
   3922         }
   3923         ASSERT_NOT_REACHED();
   3924     }
   3925     return result;
   3926 }
   3927 
   3928 bool RenderBlock::isPointInOverflowControl(HitTestResult& result, int _x, int _y, int _tx, int _ty)
   3929 {
   3930     if (!scrollsOverflow())
   3931         return false;
   3932 
   3933     return layer()->hitTestOverflowControls(result, IntPoint(_x - _tx, _y - _ty));
   3934 }
   3935 
   3936 bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction)
   3937 {
   3938     int tx = _tx + x();
   3939     int ty = _ty + y();
   3940 
   3941     if (!isRenderView()) {
   3942         // Check if we need to do anything at all.
   3943         IntRect overflowBox = visualOverflowRect();
   3944         overflowBox.move(tx, ty);
   3945         if (!overflowBox.intersects(result.rectForPoint(_x, _y)))
   3946             return false;
   3947     }
   3948 
   3949     if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) && isPointInOverflowControl(result, _x, _y, tx, ty)) {
   3950         updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
   3951         // FIXME: isPointInOverflowControl() doesn't handle rect-based tests yet.
   3952         if (!result.addNodeToRectBasedTestResult(node(), _x, _y))
   3953            return true;
   3954     }
   3955 
   3956     // If we have clipping, then we can't have any spillout.
   3957     bool useOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer();
   3958     bool useClip = (hasControlClip() || useOverflowClip);
   3959     IntRect hitTestArea(result.rectForPoint(_x, _y));
   3960     bool checkChildren = !useClip || (hasControlClip() ? controlClipRect(tx, ty).intersects(hitTestArea) : overflowClipRect(tx, ty, IncludeOverlayScrollbarSize).intersects(hitTestArea));
   3961     if (checkChildren) {
   3962         // Hit test descendants first.
   3963         int scrolledX = tx;
   3964         int scrolledY = ty;
   3965         if (hasOverflowClip()) {
   3966             IntSize offset = layer()->scrolledContentOffset();
   3967             scrolledX -= offset.width();
   3968             scrolledY -= offset.height();
   3969         }
   3970 
   3971         // Hit test contents if we don't have columns.
   3972         if (!hasColumns()) {
   3973             if (hitTestContents(request, result, _x, _y, scrolledX, scrolledY, hitTestAction)) {
   3974                 updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
   3975                 return true;
   3976             }
   3977             if (hitTestAction == HitTestFloat && hitTestFloats(request, result, _x, _y, scrolledX, scrolledY))
   3978                 return true;
   3979         } else if (hitTestColumns(request, result, _x, _y, scrolledX, scrolledY, hitTestAction)) {
   3980             updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
   3981             return true;
   3982         }
   3983     }
   3984 
   3985     // Now hit test our background
   3986     if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) {
   3987         IntRect boundsRect(tx, ty, width(), height());
   3988         if (visibleToHitTesting() && boundsRect.intersects(result.rectForPoint(_x, _y))) {
   3989             updateHitTestResult(result, flipForWritingMode(IntPoint(_x - tx, _y - ty)));
   3990             if (!result.addNodeToRectBasedTestResult(node(), _x, _y, boundsRect))
   3991                 return true;
   3992         }
   3993     }
   3994 
   3995     return false;
   3996 }
   3997 
   3998 bool RenderBlock::hitTestFloats(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty)
   3999 {
   4000     if (!m_floatingObjects)
   4001         return false;
   4002 
   4003     if (isRenderView()) {
   4004         tx += toRenderView(this)->frameView()->scrollX();
   4005         ty += toRenderView(this)->frameView()->scrollY();
   4006     }
   4007 
   4008     FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   4009     FloatingObjectSetIterator begin = floatingObjectSet.begin();
   4010     for (FloatingObjectSetIterator it = floatingObjectSet.end(); it != begin;) {
   4011         --it;
   4012         FloatingObject* floatingObject = *it;
   4013         if (floatingObject->m_shouldPaint && !floatingObject->m_renderer->hasSelfPaintingLayer()) {
   4014             int xOffset = xPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->x();
   4015             int yOffset = yPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->y();
   4016             IntPoint childPoint = flipFloatForWritingMode(floatingObject, IntPoint(tx + xOffset, ty + yOffset));
   4017             if (floatingObject->m_renderer->hitTest(request, result, IntPoint(x, y), childPoint.x(), childPoint.y())) {
   4018                 updateHitTestResult(result, IntPoint(x - childPoint.x(), y - childPoint.y()));
   4019                 return true;
   4020             }
   4021         }
   4022     }
   4023 
   4024     return false;
   4025 }
   4026 
   4027 bool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
   4028 {
   4029     // We need to do multiple passes, breaking up our hit testing into strips.
   4030     ColumnInfo* colInfo = columnInfo();
   4031     int colCount = columnCount(colInfo);
   4032     if (!colCount)
   4033         return false;
   4034     int logicalLeft = logicalLeftOffsetForContent();
   4035     int currLogicalTopOffset = 0;
   4036     int i;
   4037     bool isHorizontal = isHorizontalWritingMode();
   4038     for (i = 0; i < colCount; i++) {
   4039         IntRect colRect = columnRectAt(colInfo, i);
   4040         int blockDelta =  (isHorizontal ? colRect.height() : colRect.width());
   4041         if (style()->isFlippedBlocksWritingMode())
   4042             currLogicalTopOffset += blockDelta;
   4043         else
   4044             currLogicalTopOffset -= blockDelta;
   4045     }
   4046     for (i = colCount - 1; i >= 0; i--) {
   4047         IntRect colRect = columnRectAt(colInfo, i);
   4048         flipForWritingMode(colRect);
   4049         int currLogicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - logicalLeft;
   4050         int blockDelta =  (isHorizontal ? colRect.height() : colRect.width());
   4051         if (style()->isFlippedBlocksWritingMode())
   4052             currLogicalTopOffset -= blockDelta;
   4053         else
   4054             currLogicalTopOffset += blockDelta;
   4055         colRect.move(tx, ty);
   4056 
   4057         if (colRect.intersects(result.rectForPoint(x, y))) {
   4058             // The point is inside this column.
   4059             // Adjust tx and ty to change where we hit test.
   4060 
   4061             IntSize offset = isHorizontal ? IntSize(currLogicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, currLogicalLeftOffset);
   4062             int finalX = tx + offset.width();
   4063             int finalY = ty + offset.height();
   4064             if (result.isRectBasedTest() && !colRect.contains(result.rectForPoint(x, y)))
   4065                 hitTestContents(request, result, x, y, finalX, finalY, hitTestAction);
   4066             else
   4067                 return hitTestContents(request, result, x, y, finalX, finalY, hitTestAction) || (hitTestAction == HitTestFloat && hitTestFloats(request, result, x, y, finalX, finalY));
   4068         }
   4069     }
   4070 
   4071     return false;
   4072 }
   4073 
   4074 bool RenderBlock::hitTestContents(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
   4075 {
   4076     if (childrenInline() && !isTable()) {
   4077         // We have to hit-test our line boxes.
   4078         if (m_lineBoxes.hitTest(this, request, result, x, y, tx, ty, hitTestAction))
   4079             return true;
   4080     } else {
   4081         // Hit test our children.
   4082         HitTestAction childHitTest = hitTestAction;
   4083         if (hitTestAction == HitTestChildBlockBackgrounds)
   4084             childHitTest = HitTestChildBlockBackground;
   4085         for (RenderBox* child = lastChildBox(); child; child = child->previousSiblingBox()) {
   4086             IntPoint childPoint = flipForWritingMode(child, IntPoint(tx, ty), ParentToChildFlippingAdjustment);
   4087             if (!child->hasSelfPaintingLayer() && !child->isFloating() && child->nodeAtPoint(request, result, x, y, childPoint.x(), childPoint.y(), childHitTest))
   4088                 return true;
   4089         }
   4090     }
   4091 
   4092     return false;
   4093 }
   4094 
   4095 Position RenderBlock::positionForBox(InlineBox *box, bool start) const
   4096 {
   4097     if (!box)
   4098         return Position();
   4099 
   4100     if (!box->renderer()->node())
   4101         return Position(node(), start ? caretMinOffset() : caretMaxOffset());
   4102 
   4103     if (!box->isInlineTextBox())
   4104         return Position(box->renderer()->node(), start ? box->renderer()->caretMinOffset() : box->renderer()->caretMaxOffset());
   4105 
   4106     InlineTextBox *textBox = static_cast<InlineTextBox *>(box);
   4107     return Position(box->renderer()->node(), start ? textBox->start() : textBox->start() + textBox->len());
   4108 }
   4109 
   4110 // FIXME: This function should go on RenderObject as an instance method. Then
   4111 // all cases in which positionForPoint recurs could call this instead to
   4112 // prevent crossing editable boundaries. This would require many tests.
   4113 static VisiblePosition positionForPointRespectingEditingBoundaries(RenderBlock* parent, RenderBox* child, const IntPoint& pointInParentCoordinates)
   4114 {
   4115     // FIXME: This is wrong if the child's writing-mode is different from the parent's.
   4116     IntPoint pointInChildCoordinates(pointInParentCoordinates - child->location());
   4117 
   4118     // If this is an anonymous renderer, we just recur normally
   4119     Node* childNode = child->node();
   4120     if (!childNode)
   4121         return child->positionForPoint(pointInChildCoordinates);
   4122 
   4123     // Otherwise, first make sure that the editability of the parent and child agree.
   4124     // If they don't agree, then we return a visible position just before or after the child
   4125     RenderObject* ancestor = parent;
   4126     while (ancestor && !ancestor->node())
   4127         ancestor = ancestor->parent();
   4128 
   4129     // If we can't find an ancestor to check editability on, or editability is unchanged, we recur like normal
   4130     if (!ancestor || ancestor->node()->rendererIsEditable() == childNode->rendererIsEditable())
   4131         return child->positionForPoint(pointInChildCoordinates);
   4132 
   4133     // Otherwise return before or after the child, depending on if the click was to the logical left or logical right of the child
   4134     int childMiddle = parent->logicalWidthForChild(child) / 2;
   4135     int logicalLeft = parent->isHorizontalWritingMode() ? pointInChildCoordinates.x() : pointInChildCoordinates.y();
   4136     if (logicalLeft < childMiddle)
   4137         return ancestor->createVisiblePosition(childNode->nodeIndex(), DOWNSTREAM);
   4138     return ancestor->createVisiblePosition(childNode->nodeIndex() + 1, UPSTREAM);
   4139 }
   4140 
   4141 VisiblePosition RenderBlock::positionForPointWithInlineChildren(const IntPoint& pointInLogicalContents)
   4142 {
   4143     ASSERT(childrenInline());
   4144 
   4145     if (!firstRootBox())
   4146         return createVisiblePosition(0, DOWNSTREAM);
   4147 
   4148     // look for the closest line box in the root box which is at the passed-in y coordinate
   4149     InlineBox* closestBox = 0;
   4150     RootInlineBox* firstRootBoxWithChildren = 0;
   4151     RootInlineBox* lastRootBoxWithChildren = 0;
   4152     for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
   4153         if (!root->firstLeafChild())
   4154             continue;
   4155         if (!firstRootBoxWithChildren)
   4156             firstRootBoxWithChildren = root;
   4157         lastRootBoxWithChildren = root;
   4158 
   4159         // check if this root line box is located at this y coordinate
   4160         if (pointInLogicalContents.y() < root->selectionBottom()) {
   4161             closestBox = root->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
   4162             if (closestBox)
   4163                 break;
   4164         }
   4165     }
   4166 
   4167     bool moveCaretToBoundary = document()->frame()->editor()->behavior().shouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom();
   4168 
   4169     if (!moveCaretToBoundary && !closestBox && lastRootBoxWithChildren) {
   4170         // y coordinate is below last root line box, pretend we hit it
   4171         closestBox = lastRootBoxWithChildren->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
   4172     }
   4173 
   4174     if (closestBox) {
   4175         if (moveCaretToBoundary && pointInLogicalContents.y() < firstRootBoxWithChildren->selectionTop()) {
   4176             // y coordinate is above first root line box, so return the start of the first
   4177             return VisiblePosition(positionForBox(firstRootBoxWithChildren->firstLeafChild(), true), DOWNSTREAM);
   4178         }
   4179 
   4180         // pass the box a top position that is inside it
   4181         IntPoint point(pointInLogicalContents.x(), closestBox->logicalTop());
   4182         if (!isHorizontalWritingMode())
   4183             point = point.transposedPoint();
   4184         if (closestBox->renderer()->isReplaced())
   4185             return positionForPointRespectingEditingBoundaries(this, toRenderBox(closestBox->renderer()), point);
   4186         return closestBox->renderer()->positionForPoint(point);
   4187     }
   4188 
   4189     if (lastRootBoxWithChildren) {
   4190         // We hit this case for Mac behavior when the Y coordinate is below the last box.
   4191         ASSERT(moveCaretToBoundary);
   4192         InlineBox* logicallyLastBox;
   4193         if (lastRootBoxWithChildren->getLogicalEndBoxWithNode(logicallyLastBox))
   4194             return VisiblePosition(positionForBox(logicallyLastBox, false), DOWNSTREAM);
   4195     }
   4196 
   4197     // Can't reach this. We have a root line box, but it has no kids.
   4198     // FIXME: This should ASSERT_NOT_REACHED(), but clicking on placeholder text
   4199     // seems to hit this code path.
   4200     return createVisiblePosition(0, DOWNSTREAM);
   4201 }
   4202 
   4203 static inline bool isChildHitTestCandidate(RenderBox* box)
   4204 {
   4205     return box->height() && box->style()->visibility() == VISIBLE && !box->isFloatingOrPositioned();
   4206 }
   4207 
   4208 VisiblePosition RenderBlock::positionForPoint(const IntPoint& point)
   4209 {
   4210     if (isTable())
   4211         return RenderBox::positionForPoint(point);
   4212 
   4213     if (isReplaced()) {
   4214         // FIXME: This seems wrong when the object's writing-mode doesn't match the line's writing-mode.
   4215         int pointLogicalLeft = isHorizontalWritingMode() ? point.x() : point.y();
   4216         int pointLogicalTop = isHorizontalWritingMode() ? point.y() : point.x();
   4217 
   4218         if (pointLogicalTop < 0 || (pointLogicalTop < logicalHeight() && pointLogicalLeft < 0))
   4219             return createVisiblePosition(caretMinOffset(), DOWNSTREAM);
   4220         if (pointLogicalTop >= logicalHeight() || (pointLogicalTop >= 0 && pointLogicalLeft >= logicalWidth()))
   4221             return createVisiblePosition(caretMaxOffset(), DOWNSTREAM);
   4222     }
   4223 
   4224     int contentsX = point.x();
   4225     int contentsY = point.y();
   4226     offsetForContents(contentsX, contentsY);
   4227     IntPoint pointInContents(contentsX, contentsY);
   4228     IntPoint pointInLogicalContents(pointInContents);
   4229     if (!isHorizontalWritingMode())
   4230         pointInLogicalContents = pointInLogicalContents.transposedPoint();
   4231 
   4232     if (childrenInline())
   4233         return positionForPointWithInlineChildren(pointInLogicalContents);
   4234 
   4235     if (lastChildBox() && pointInContents.y() > lastChildBox()->logicalTop()) {
   4236         for (RenderBox* childBox = lastChildBox(); childBox; childBox = childBox->previousSiblingBox()) {
   4237             if (isChildHitTestCandidate(childBox))
   4238                 return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents);
   4239         }
   4240     } else {
   4241         for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
   4242             // We hit child if our click is above the bottom of its padding box (like IE6/7 and FF3).
   4243             if (isChildHitTestCandidate(childBox) && pointInContents.y() < childBox->logicalBottom())
   4244                 return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents);
   4245         }
   4246     }
   4247 
   4248     // We only get here if there are no hit test candidate children below the click.
   4249     return RenderBox::positionForPoint(point);
   4250 }
   4251 
   4252 void RenderBlock::offsetForContents(int& tx, int& ty) const
   4253 {
   4254     IntPoint contentsPoint(tx, ty);
   4255 
   4256     if (hasOverflowClip())
   4257         contentsPoint += layer()->scrolledContentOffset();
   4258 
   4259     if (hasColumns())
   4260         adjustPointToColumnContents(contentsPoint);
   4261 
   4262     tx = contentsPoint.x();
   4263     ty = contentsPoint.y();
   4264 }
   4265 
   4266 int RenderBlock::availableLogicalWidth() const
   4267 {
   4268     // If we have multiple columns, then the available logical width is reduced to our column width.
   4269     if (hasColumns())
   4270         return desiredColumnWidth();
   4271     return RenderBox::availableLogicalWidth();
   4272 }
   4273 
   4274 int RenderBlock::columnGap() const
   4275 {
   4276     if (style()->hasNormalColumnGap())
   4277         return style()->fontDescription().computedPixelSize(); // "1em" is recommended as the normal gap setting. Matches <p> margins.
   4278     return static_cast<int>(style()->columnGap());
   4279 }
   4280 
   4281 void RenderBlock::calcColumnWidth()
   4282 {
   4283     // Calculate our column width and column count.
   4284     unsigned desiredColumnCount = 1;
   4285     int desiredColumnWidth = contentLogicalWidth();
   4286 
   4287     // For now, we don't support multi-column layouts when printing, since we have to do a lot of work for proper pagination.
   4288     if (document()->paginated() || (style()->hasAutoColumnCount() && style()->hasAutoColumnWidth())) {
   4289         setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
   4290         return;
   4291     }
   4292 
   4293     int availWidth = desiredColumnWidth;
   4294     int colGap = columnGap();
   4295     int colWidth = max(1, static_cast<int>(style()->columnWidth()));
   4296     int colCount = max(1, static_cast<int>(style()->columnCount()));
   4297 
   4298     if (style()->hasAutoColumnWidth() && !style()->hasAutoColumnCount()) {
   4299         desiredColumnCount = colCount;
   4300         desiredColumnWidth = max<int>(0, (availWidth - ((desiredColumnCount - 1) * colGap)) / desiredColumnCount);
   4301     } else if (!style()->hasAutoColumnWidth() && style()->hasAutoColumnCount()) {
   4302         desiredColumnCount = max<int>(1, (float)(availWidth + colGap) / (colWidth + colGap));
   4303         desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colGap;
   4304     } else {
   4305         desiredColumnCount = max(min<int>(colCount, (float)(availWidth + colGap) / (colWidth + colGap)), 1);
   4306         desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colGap;
   4307     }
   4308     setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
   4309 }
   4310 
   4311 void RenderBlock::setDesiredColumnCountAndWidth(int count, int width)
   4312 {
   4313     bool destroyColumns = !firstChild()
   4314                           || (count == 1 && style()->hasAutoColumnWidth())
   4315                           || firstChild()->isAnonymousColumnsBlock()
   4316                           || firstChild()->isAnonymousColumnSpanBlock();
   4317     if (destroyColumns) {
   4318         if (hasColumns()) {
   4319             delete gColumnInfoMap->take(this);
   4320             setHasColumns(false);
   4321         }
   4322     } else {
   4323         ColumnInfo* info;
   4324         if (hasColumns())
   4325             info = gColumnInfoMap->get(this);
   4326         else {
   4327             if (!gColumnInfoMap)
   4328                 gColumnInfoMap = new ColumnInfoMap;
   4329             info = new ColumnInfo;
   4330             gColumnInfoMap->add(this, info);
   4331             setHasColumns(true);
   4332         }
   4333         info->setDesiredColumnCount(count);
   4334         info->setDesiredColumnWidth(width);
   4335     }
   4336 }
   4337 
   4338 int RenderBlock::desiredColumnWidth() const
   4339 {
   4340     if (!hasColumns())
   4341         return contentLogicalWidth();
   4342     return gColumnInfoMap->get(this)->desiredColumnWidth();
   4343 }
   4344 
   4345 unsigned RenderBlock::desiredColumnCount() const
   4346 {
   4347     if (!hasColumns())
   4348         return 1;
   4349     return gColumnInfoMap->get(this)->desiredColumnCount();
   4350 }
   4351 
   4352 ColumnInfo* RenderBlock::columnInfo() const
   4353 {
   4354     if (!hasColumns())
   4355         return 0;
   4356     return gColumnInfoMap->get(this);
   4357 }
   4358 
   4359 unsigned RenderBlock::columnCount(ColumnInfo* colInfo) const
   4360 {
   4361     ASSERT(hasColumns() && gColumnInfoMap->get(this) == colInfo);
   4362     return colInfo->columnCount();
   4363 }
   4364 
   4365 IntRect RenderBlock::columnRectAt(ColumnInfo* colInfo, unsigned index) const
   4366 {
   4367     ASSERT(hasColumns() && gColumnInfoMap->get(this) == colInfo);
   4368 
   4369     // Compute the appropriate rect based off our information.
   4370     int colLogicalWidth = colInfo->desiredColumnWidth();
   4371     int colLogicalHeight = colInfo->columnHeight();
   4372     int colLogicalTop = borderBefore() + paddingBefore();
   4373     int colGap = columnGap();
   4374     int colLogicalLeft = style()->isLeftToRightDirection() ?
   4375                           logicalLeftOffsetForContent() + (index * (colLogicalWidth + colGap))
   4376                         : logicalLeftOffsetForContent() + contentLogicalWidth() - colLogicalWidth - (index * (colLogicalWidth + colGap));
   4377     IntRect rect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
   4378     if (isHorizontalWritingMode())
   4379         return IntRect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
   4380     return IntRect(colLogicalTop, colLogicalLeft, colLogicalHeight, colLogicalWidth);
   4381 }
   4382 
   4383 bool RenderBlock::layoutColumns(bool hasSpecifiedPageLogicalHeight, int pageLogicalHeight, LayoutStateMaintainer& statePusher)
   4384 {
   4385     if (!hasColumns())
   4386         return false;
   4387 
   4388     // FIXME: We don't balance properly at all in the presence of forced page breaks.  We need to understand what
   4389     // the distance between forced page breaks is so that we can avoid making the minimum column height too tall.
   4390     ColumnInfo* colInfo = columnInfo();
   4391     int desiredColumnCount = colInfo->desiredColumnCount();
   4392     if (!hasSpecifiedPageLogicalHeight) {
   4393         int columnHeight = pageLogicalHeight;
   4394         int minColumnCount = colInfo->forcedBreaks() + 1;
   4395         if (minColumnCount >= desiredColumnCount) {
   4396             // The forced page breaks are in control of the balancing.  Just set the column height to the
   4397             // maximum page break distance.
   4398             if (!pageLogicalHeight) {
   4399                 int distanceBetweenBreaks = max(colInfo->maximumDistanceBetweenForcedBreaks(),
   4400                                                 view()->layoutState()->pageLogicalOffset(borderBefore() + paddingBefore() + contentLogicalHeight()) - colInfo->forcedBreakOffset());
   4401                 columnHeight = max(colInfo->minimumColumnHeight(), distanceBetweenBreaks);
   4402             }
   4403         } else if (contentLogicalHeight() > pageLogicalHeight * desiredColumnCount) {
   4404             // Now that we know the intrinsic height of the columns, we have to rebalance them.
   4405             columnHeight = max(colInfo->minimumColumnHeight(), (int)ceilf((float)contentLogicalHeight() / desiredColumnCount));
   4406         }
   4407 
   4408         if (columnHeight && columnHeight != pageLogicalHeight) {
   4409             statePusher.pop();
   4410             m_everHadLayout = true;
   4411             layoutBlock(false, columnHeight);
   4412             return true;
   4413         }
   4414     }
   4415 
   4416     if (pageLogicalHeight)
   4417         colInfo->setColumnCountAndHeight(ceilf((float)contentLogicalHeight() / pageLogicalHeight), pageLogicalHeight);
   4418 
   4419     if (columnCount(colInfo)) {
   4420         setLogicalHeight(borderBefore() + paddingBefore() + colInfo->columnHeight() + borderAfter() + paddingAfter() + scrollbarLogicalHeight());
   4421         m_overflow.clear();
   4422     }
   4423 
   4424     return false;
   4425 }
   4426 
   4427 void RenderBlock::adjustPointToColumnContents(IntPoint& point) const
   4428 {
   4429     // Just bail if we have no columns.
   4430     if (!hasColumns())
   4431         return;
   4432 
   4433     ColumnInfo* colInfo = columnInfo();
   4434     if (!columnCount(colInfo))
   4435         return;
   4436 
   4437     // Determine which columns we intersect.
   4438     int colGap = columnGap();
   4439     int halfColGap = colGap / 2;
   4440     IntPoint columnPoint(columnRectAt(colInfo, 0).location());
   4441     int logicalOffset = 0;
   4442     for (unsigned i = 0; i < colInfo->columnCount(); i++) {
   4443         // Add in half the column gap to the left and right of the rect.
   4444         IntRect colRect = columnRectAt(colInfo, i);
   4445         if (isHorizontalWritingMode()) {
   4446             IntRect gapAndColumnRect(colRect.x() - halfColGap, colRect.y(), colRect.width() + colGap, colRect.height());
   4447             if (point.x() >= gapAndColumnRect.x() && point.x() < gapAndColumnRect.maxX()) {
   4448                 // FIXME: The clamping that follows is not completely right for right-to-left
   4449                 // content.
   4450                 // Clamp everything above the column to its top left.
   4451                 if (point.y() < gapAndColumnRect.y())
   4452                     point = gapAndColumnRect.location();
   4453                 // Clamp everything below the column to the next column's top left. If there is
   4454                 // no next column, this still maps to just after this column.
   4455                 else if (point.y() >= gapAndColumnRect.maxY()) {
   4456                     point = gapAndColumnRect.location();
   4457                     point.move(0, gapAndColumnRect.height());
   4458                 }
   4459 
   4460                 // We're inside the column.  Translate the x and y into our column coordinate space.
   4461                 point.move(columnPoint.x() - colRect.x(), logicalOffset);
   4462                 return;
   4463             }
   4464 
   4465             // Move to the next position.
   4466             logicalOffset += colRect.height();
   4467         } else {
   4468             IntRect gapAndColumnRect(colRect.x(), colRect.y() - halfColGap, colRect.width(), colRect.height() + colGap);
   4469             if (point.y() >= gapAndColumnRect.y() && point.y() < gapAndColumnRect.maxY()) {
   4470                 // FIXME: The clamping that follows is not completely right for right-to-left
   4471                 // content.
   4472                 // Clamp everything above the column to its top left.
   4473                 if (point.x() < gapAndColumnRect.x())
   4474                     point = gapAndColumnRect.location();
   4475                 // Clamp everything below the column to the next column's top left. If there is
   4476                 // no next column, this still maps to just after this column.
   4477                 else if (point.x() >= gapAndColumnRect.maxX()) {
   4478                     point = gapAndColumnRect.location();
   4479                     point.move(gapAndColumnRect.width(), 0);
   4480                 }
   4481 
   4482                 // We're inside the column.  Translate the x and y into our column coordinate space.
   4483                 point.move(logicalOffset, columnPoint.y() - colRect.y());
   4484                 return;
   4485             }
   4486 
   4487             // Move to the next position.
   4488             logicalOffset += colRect.width();
   4489         }
   4490     }
   4491 }
   4492 
   4493 void RenderBlock::adjustRectForColumns(IntRect& r) const
   4494 {
   4495     // Just bail if we have no columns.
   4496     if (!hasColumns())
   4497         return;
   4498 
   4499     ColumnInfo* colInfo = columnInfo();
   4500 
   4501     // Begin with a result rect that is empty.
   4502     IntRect result;
   4503 
   4504     // Determine which columns we intersect.
   4505     unsigned colCount = columnCount(colInfo);
   4506     if (!colCount)
   4507         return;
   4508 
   4509     int logicalLeft = logicalLeftOffsetForContent();
   4510     int currLogicalOffset = 0;
   4511 
   4512     for (unsigned i = 0; i < colCount; i++) {
   4513         IntRect colRect = columnRectAt(colInfo, i);
   4514         IntRect repaintRect = r;
   4515         if (isHorizontalWritingMode()) {
   4516             int currXOffset = colRect.x() - logicalLeft;
   4517             repaintRect.move(currXOffset, currLogicalOffset);
   4518             currLogicalOffset -= colRect.height();
   4519         } else {
   4520             int currYOffset = colRect.y() - logicalLeft;
   4521             repaintRect.move(currLogicalOffset, currYOffset);
   4522             currLogicalOffset -= colRect.width();
   4523         }
   4524         repaintRect.intersect(colRect);
   4525         result.unite(repaintRect);
   4526     }
   4527 
   4528     r = result;
   4529 }
   4530 
   4531 IntPoint RenderBlock::flipForWritingModeIncludingColumns(const IntPoint& point) const
   4532 {
   4533     ASSERT(hasColumns());
   4534     if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
   4535         return point;
   4536     ColumnInfo* colInfo = columnInfo();
   4537     int columnLogicalHeight = colInfo->columnHeight();
   4538     int expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
   4539     if (isHorizontalWritingMode())
   4540         return IntPoint(point.x(), expandedLogicalHeight - point.y());
   4541     return IntPoint(expandedLogicalHeight - point.x(), point.y());
   4542 }
   4543 
   4544 void RenderBlock::flipForWritingModeIncludingColumns(IntRect& rect) const
   4545 {
   4546     ASSERT(hasColumns());
   4547     if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
   4548         return;
   4549 
   4550     ColumnInfo* colInfo = columnInfo();
   4551     int columnLogicalHeight = colInfo->columnHeight();
   4552     int expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
   4553     if (isHorizontalWritingMode())
   4554         rect.setY(expandedLogicalHeight - rect.maxY());
   4555     else
   4556         rect.setX(expandedLogicalHeight - rect.maxX());
   4557 }
   4558 
   4559 void RenderBlock::adjustForColumns(IntSize& offset, const IntPoint& point) const
   4560 {
   4561     if (!hasColumns())
   4562         return;
   4563 
   4564     ColumnInfo* colInfo = columnInfo();
   4565 
   4566     int logicalLeft = logicalLeftOffsetForContent();
   4567     size_t colCount = columnCount(colInfo);
   4568     int colLogicalWidth = colInfo->desiredColumnWidth();
   4569     int colLogicalHeight = colInfo->columnHeight();
   4570 
   4571     for (size_t i = 0; i < colCount; ++i) {
   4572         // Compute the edges for a given column in the block progression direction.
   4573         IntRect sliceRect = IntRect(logicalLeft, borderBefore() + paddingBefore() + i * colLogicalHeight, colLogicalWidth, colLogicalHeight);
   4574         if (!isHorizontalWritingMode())
   4575             sliceRect = sliceRect.transposedRect();
   4576 
   4577         // 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).
   4578         flipForWritingModeIncludingColumns(sliceRect);
   4579 
   4580         int logicalOffset = style()->isFlippedBlocksWritingMode() ? (colCount - 1 - i) * colLogicalHeight : i * colLogicalHeight;
   4581 
   4582         // Now we're in the same coordinate space as the point.  See if it is inside the rectangle.
   4583         if (isHorizontalWritingMode()) {
   4584             if (point.y() >= sliceRect.y() && point.y() < sliceRect.maxY()) {
   4585                 offset.expand(columnRectAt(colInfo, i).x() - logicalLeft, -logicalOffset);
   4586                 return;
   4587             }
   4588         } else {
   4589             if (point.x() >= sliceRect.x() && point.x() < sliceRect.maxX()) {
   4590                 offset.expand(-logicalOffset, columnRectAt(colInfo, i).y() - logicalLeft);
   4591                 return;
   4592             }
   4593         }
   4594     }
   4595 }
   4596 
   4597 void RenderBlock::computePreferredLogicalWidths()
   4598 {
   4599     ASSERT(preferredLogicalWidthsDirty());
   4600 
   4601     updateFirstLetter();
   4602 
   4603     if (!isTableCell() && style()->logicalWidth().isFixed() && style()->logicalWidth().value() > 0)
   4604         m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeContentBoxLogicalWidth(style()->logicalWidth().value());
   4605     else {
   4606         m_minPreferredLogicalWidth = 0;
   4607         m_maxPreferredLogicalWidth = 0;
   4608 
   4609         if (childrenInline())
   4610             computeInlinePreferredLogicalWidths();
   4611         else
   4612             computeBlockPreferredLogicalWidths();
   4613 
   4614         m_maxPreferredLogicalWidth = max(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
   4615 
   4616         if (!style()->autoWrap() && childrenInline()) {
   4617             m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth;
   4618 
   4619             // A horizontal marquee with inline children has no minimum width.
   4620             if (layer() && layer()->marquee() && layer()->marquee()->isHorizontal())
   4621                 m_minPreferredLogicalWidth = 0;
   4622         }
   4623 
   4624         int scrollbarWidth = 0;
   4625         if (hasOverflowClip() && style()->overflowY() == OSCROLL) {
   4626             layer()->setHasVerticalScrollbar(true);
   4627             scrollbarWidth = verticalScrollbarWidth();
   4628             m_maxPreferredLogicalWidth += scrollbarWidth;
   4629         }
   4630 
   4631         if (isTableCell()) {
   4632             Length w = toRenderTableCell(this)->styleOrColLogicalWidth();
   4633             if (w.isFixed() && w.value() > 0) {
   4634                 m_maxPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(w.value()));
   4635                 scrollbarWidth = 0;
   4636             }
   4637         }
   4638 
   4639         m_minPreferredLogicalWidth += scrollbarWidth;
   4640     }
   4641 
   4642     if (style()->logicalMinWidth().isFixed() && style()->logicalMinWidth().value() > 0) {
   4643         m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMinWidth().value()));
   4644         m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMinWidth().value()));
   4645     }
   4646 
   4647     if (style()->logicalMaxWidth().isFixed() && style()->logicalMaxWidth().value() != undefinedLength) {
   4648         m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMaxWidth().value()));
   4649         m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->logicalMaxWidth().value()));
   4650     }
   4651 
   4652     int borderAndPadding = borderAndPaddingLogicalWidth();
   4653     m_minPreferredLogicalWidth += borderAndPadding;
   4654     m_maxPreferredLogicalWidth += borderAndPadding;
   4655 
   4656     setPreferredLogicalWidthsDirty(false);
   4657 }
   4658 
   4659 struct InlineMinMaxIterator {
   4660 /* InlineMinMaxIterator is a class that will iterate over all render objects that contribute to
   4661    inline min/max width calculations.  Note the following about the way it walks:
   4662    (1) Positioned content is skipped (since it does not contribute to min/max width of a block)
   4663    (2) We do not drill into the children of floats or replaced elements, since you can't break
   4664        in the middle of such an element.
   4665    (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side can have
   4666        distinct borders/margin/padding that contribute to the min/max width.
   4667 */
   4668     RenderObject* parent;
   4669     RenderObject* current;
   4670     bool endOfInline;
   4671 
   4672     InlineMinMaxIterator(RenderObject* p, bool end = false)
   4673         :parent(p), current(p), endOfInline(end) {}
   4674 
   4675     RenderObject* next();
   4676 };
   4677 
   4678 RenderObject* InlineMinMaxIterator::next()
   4679 {
   4680     RenderObject* result = 0;
   4681     bool oldEndOfInline = endOfInline;
   4682     endOfInline = false;
   4683     while (current || current == parent) {
   4684         if (!oldEndOfInline &&
   4685             (current == parent ||
   4686              (!current->isFloating() && !current->isReplaced() && !current->isPositioned())))
   4687             result = current->firstChild();
   4688         if (!result) {
   4689             // We hit the end of our inline. (It was empty, e.g., <span></span>.)
   4690             if (!oldEndOfInline && current->isRenderInline()) {
   4691                 result = current;
   4692                 endOfInline = true;
   4693                 break;
   4694             }
   4695 
   4696             while (current && current != parent) {
   4697                 result = current->nextSibling();
   4698                 if (result) break;
   4699                 current = current->parent();
   4700                 if (current && current != parent && current->isRenderInline()) {
   4701                     result = current;
   4702                     endOfInline = true;
   4703                     break;
   4704                 }
   4705             }
   4706         }
   4707 
   4708         if (!result)
   4709             break;
   4710 
   4711         if (!result->isPositioned() && (result->isText() || result->isFloating() || result->isReplaced() || result->isRenderInline()))
   4712              break;
   4713 
   4714         current = result;
   4715         result = 0;
   4716     }
   4717 
   4718     // Update our position.
   4719     current = result;
   4720     return current;
   4721 }
   4722 
   4723 static int getBPMWidth(int childValue, Length cssUnit)
   4724 {
   4725     if (cssUnit.type() != Auto)
   4726         return (cssUnit.isFixed() ? cssUnit.value() : childValue);
   4727     return 0;
   4728 }
   4729 
   4730 static int getBorderPaddingMargin(const RenderBoxModelObject* child, bool endOfInline)
   4731 {
   4732     RenderStyle* cstyle = child->style();
   4733     if (endOfInline)
   4734         return getBPMWidth(child->marginEnd(), cstyle->marginEnd()) +
   4735                getBPMWidth(child->paddingEnd(), cstyle->paddingEnd()) +
   4736                child->borderEnd();
   4737     return getBPMWidth(child->marginStart(), cstyle->marginStart()) +
   4738                getBPMWidth(child->paddingStart(), cstyle->paddingStart()) +
   4739                child->borderStart();
   4740 }
   4741 
   4742 static inline void stripTrailingSpace(float& inlineMax, float& inlineMin,
   4743                                       RenderObject* trailingSpaceChild)
   4744 {
   4745     if (trailingSpaceChild && trailingSpaceChild->isText()) {
   4746         // Collapse away the trailing space at the end of a block.
   4747         RenderText* t = toRenderText(trailingSpaceChild);
   4748         const UChar space = ' ';
   4749         const Font& font = t->style()->font(); // FIXME: This ignores first-line.
   4750         float spaceWidth = font.width(TextRun(&space, 1));
   4751         inlineMax -= spaceWidth + font.wordSpacing();
   4752         if (inlineMin > inlineMax)
   4753             inlineMin = inlineMax;
   4754     }
   4755 }
   4756 
   4757 static inline void updatePreferredWidth(int& preferredWidth, float& result)
   4758 {
   4759     int snappedResult = ceilf(result);
   4760     preferredWidth = max(snappedResult, preferredWidth);
   4761 }
   4762 
   4763 void RenderBlock::computeInlinePreferredLogicalWidths()
   4764 {
   4765     float inlineMax = 0;
   4766     float inlineMin = 0;
   4767 
   4768     int cw = containingBlock()->contentLogicalWidth();
   4769 
   4770     // If we are at the start of a line, we want to ignore all white-space.
   4771     // Also strip spaces if we previously had text that ended in a trailing space.
   4772     bool stripFrontSpaces = true;
   4773     RenderObject* trailingSpaceChild = 0;
   4774 
   4775     // Firefox and Opera will allow a table cell to grow to fit an image inside it under
   4776     // very specific cirucumstances (in order to match common WinIE renderings).
   4777     // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
   4778     bool allowImagesToBreak = !document()->inQuirksMode() || !isTableCell() || !style()->logicalWidth().isIntrinsicOrAuto();
   4779 
   4780     bool autoWrap, oldAutoWrap;
   4781     autoWrap = oldAutoWrap = style()->autoWrap();
   4782 
   4783     InlineMinMaxIterator childIterator(this);
   4784     bool addedTextIndent = false; // Only gets added in once.
   4785     RenderObject* prevFloat = 0;
   4786     while (RenderObject* child = childIterator.next()) {
   4787         autoWrap = child->isReplaced() ? child->parent()->style()->autoWrap() :
   4788             child->style()->autoWrap();
   4789 
   4790         if (!child->isBR()) {
   4791             // Step One: determine whether or not we need to go ahead and
   4792             // terminate our current line.  Each discrete chunk can become
   4793             // the new min-width, if it is the widest chunk seen so far, and
   4794             // it can also become the max-width.
   4795 
   4796             // Children fall into three categories:
   4797             // (1) An inline flow object.  These objects always have a min/max of 0,
   4798             // and are included in the iteration solely so that their margins can
   4799             // be added in.
   4800             //
   4801             // (2) An inline non-text non-flow object, e.g., an inline replaced element.
   4802             // These objects can always be on a line by themselves, so in this situation
   4803             // we need to go ahead and break the current line, and then add in our own
   4804             // margins and min/max width on its own line, and then terminate the line.
   4805             //
   4806             // (3) A text object.  Text runs can have breakable characters at the start,
   4807             // the middle or the end.  They may also lose whitespace off the front if
   4808             // we're already ignoring whitespace.  In order to compute accurate min-width
   4809             // information, we need three pieces of information.
   4810             // (a) the min-width of the first non-breakable run.  Should be 0 if the text string
   4811             // starts with whitespace.
   4812             // (b) the min-width of the last non-breakable run. Should be 0 if the text string
   4813             // ends with whitespace.
   4814             // (c) the min/max width of the string (trimmed for whitespace).
   4815             //
   4816             // If the text string starts with whitespace, then we need to go ahead and
   4817             // terminate our current line (unless we're already in a whitespace stripping
   4818             // mode.
   4819             //
   4820             // If the text string has a breakable character in the middle, but didn't start
   4821             // with whitespace, then we add the width of the first non-breakable run and
   4822             // then end the current line.  We then need to use the intermediate min/max width
   4823             // values (if any of them are larger than our current min/max).  We then look at
   4824             // the width of the last non-breakable run and use that to start a new line
   4825             // (unless we end in whitespace).
   4826             RenderStyle* cstyle = child->style();
   4827             float childMin = 0;
   4828             float childMax = 0;
   4829 
   4830             if (!child->isText()) {
   4831                 // Case (1) and (2).  Inline replaced and inline flow elements.
   4832                 if (child->isRenderInline()) {
   4833                     // Add in padding/border/margin from the appropriate side of
   4834                     // the element.
   4835                     float bpm = getBorderPaddingMargin(toRenderInline(child), childIterator.endOfInline);
   4836                     childMin += bpm;
   4837                     childMax += bpm;
   4838 
   4839                     inlineMin += childMin;
   4840                     inlineMax += childMax;
   4841 
   4842                     child->setPreferredLogicalWidthsDirty(false);
   4843                 } else {
   4844                     // Inline replaced elts add in their margins to their min/max values.
   4845                     float margins = 0;
   4846                     Length startMargin = cstyle->marginStart();
   4847                     Length endMargin = cstyle->marginEnd();
   4848                     if (startMargin.isFixed())
   4849                         margins += startMargin.value();
   4850                     if (endMargin.isFixed())
   4851                         margins += endMargin.value();
   4852                     childMin += margins;
   4853                     childMax += margins;
   4854                 }
   4855             }
   4856 
   4857             if (!child->isRenderInline() && !child->isText()) {
   4858                 // Case (2). Inline replaced elements and floats.
   4859                 // Go ahead and terminate the current line as far as
   4860                 // minwidth is concerned.
   4861                 childMin += child->minPreferredLogicalWidth();
   4862                 childMax += child->maxPreferredLogicalWidth();
   4863 
   4864                 bool clearPreviousFloat;
   4865                 if (child->isFloating()) {
   4866                     clearPreviousFloat = (prevFloat
   4867                         && ((prevFloat->style()->floating() == FLEFT && (child->style()->clear() & CLEFT))
   4868                             || (prevFloat->style()->floating() == FRIGHT && (child->style()->clear() & CRIGHT))));
   4869                     prevFloat = child;
   4870                 } else
   4871                     clearPreviousFloat = false;
   4872 
   4873                 bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak;
   4874                 if ((canBreakReplacedElement && (autoWrap || oldAutoWrap)) || clearPreviousFloat) {
   4875                     updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
   4876                     inlineMin = 0;
   4877                 }
   4878 
   4879                 // If we're supposed to clear the previous float, then terminate maxwidth as well.
   4880                 if (clearPreviousFloat) {
   4881                     updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
   4882                     inlineMax = 0;
   4883                 }
   4884 
   4885                 // Add in text-indent.  This is added in only once.
   4886                 int ti = 0;
   4887                 if (!addedTextIndent) {
   4888                     addedTextIndent = true;
   4889                     ti = style()->textIndent().calcMinValue(cw);
   4890                     childMin += ti;
   4891                     childMax += ti;
   4892                 }
   4893 
   4894                 // Add our width to the max.
   4895                 inlineMax += childMax;
   4896 
   4897                 if (!autoWrap || !canBreakReplacedElement) {
   4898                     if (child->isFloating())
   4899                         updatePreferredWidth(m_minPreferredLogicalWidth, childMin);
   4900                     else
   4901                         inlineMin += childMin;
   4902                 } else {
   4903                     // Now check our line.
   4904                     updatePreferredWidth(m_minPreferredLogicalWidth, childMin);
   4905 
   4906                     // Now start a new line.
   4907                     inlineMin = 0;
   4908                 }
   4909 
   4910                 // We are no longer stripping whitespace at the start of
   4911                 // a line.
   4912                 if (!child->isFloating()) {
   4913                     stripFrontSpaces = false;
   4914                     trailingSpaceChild = 0;
   4915                 }
   4916             } else if (child->isText()) {
   4917                 // Case (3). Text.
   4918                 RenderText* t = toRenderText(child);
   4919 
   4920                 if (t->isWordBreak()) {
   4921                     updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
   4922                     inlineMin = 0;
   4923                     continue;
   4924                 }
   4925 
   4926                 if (t->style()->hasTextCombine() && t->isCombineText())
   4927                     toRenderCombineText(t)->combineText();
   4928 
   4929                 // Determine if we have a breakable character.  Pass in
   4930                 // whether or not we should ignore any spaces at the front
   4931                 // of the string.  If those are going to be stripped out,
   4932                 // then they shouldn't be considered in the breakable char
   4933                 // check.
   4934                 bool hasBreakableChar, hasBreak;
   4935                 float beginMin, endMin;
   4936                 bool beginWS, endWS;
   4937                 float beginMax, endMax;
   4938                 t->trimmedPrefWidths(inlineMax, beginMin, beginWS, endMin, endWS,
   4939                                      hasBreakableChar, hasBreak, beginMax, endMax,
   4940                                      childMin, childMax, stripFrontSpaces);
   4941 
   4942                 // This text object will not be rendered, but it may still provide a breaking opportunity.
   4943                 if (!hasBreak && childMax == 0) {
   4944                     if (autoWrap && (beginWS || endWS)) {
   4945                         updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
   4946                         inlineMin = 0;
   4947                     }
   4948                     continue;
   4949                 }
   4950 
   4951                 if (stripFrontSpaces)
   4952                     trailingSpaceChild = child;
   4953                 else
   4954                     trailingSpaceChild = 0;
   4955 
   4956                 // Add in text-indent.  This is added in only once.
   4957                 int ti = 0;
   4958                 if (!addedTextIndent) {
   4959                     addedTextIndent = true;
   4960                     ti = style()->textIndent().calcMinValue(cw);
   4961                     childMin+=ti; beginMin += ti;
   4962                     childMax+=ti; beginMax += ti;
   4963                 }
   4964 
   4965                 // If we have no breakable characters at all,
   4966                 // then this is the easy case. We add ourselves to the current
   4967                 // min and max and continue.
   4968                 if (!hasBreakableChar) {
   4969                     inlineMin += childMin;
   4970                 } else {
   4971                     // We have a breakable character.  Now we need to know if
   4972                     // we start and end with whitespace.
   4973                     if (beginWS)
   4974                         // Go ahead and end the current line.
   4975                         updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
   4976                     else {
   4977                         inlineMin += beginMin;
   4978                         updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
   4979                         childMin -= ti;
   4980                     }
   4981 
   4982                     inlineMin = childMin;
   4983 
   4984                     if (endWS) {
   4985                         // We end in whitespace, which means we can go ahead
   4986                         // and end our current line.
   4987                         updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
   4988                         inlineMin = 0;
   4989                     } else {
   4990                         updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
   4991                         inlineMin = endMin;
   4992                     }
   4993                 }
   4994 
   4995                 if (hasBreak) {
   4996                     inlineMax += beginMax;
   4997                     updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
   4998                     updatePreferredWidth(m_maxPreferredLogicalWidth, childMax);
   4999                     inlineMax = endMax;
   5000                 } else
   5001                     inlineMax += childMax;
   5002             }
   5003 
   5004             // Ignore spaces after a list marker.
   5005             if (child->isListMarker())
   5006                 stripFrontSpaces = true;
   5007         } else {
   5008             updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
   5009             updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
   5010             inlineMin = inlineMax = 0;
   5011             stripFrontSpaces = true;
   5012             trailingSpaceChild = 0;
   5013         }
   5014 
   5015         oldAutoWrap = autoWrap;
   5016     }
   5017 
   5018     if (style()->collapseWhiteSpace())
   5019         stripTrailingSpace(inlineMax, inlineMin, trailingSpaceChild);
   5020 
   5021     updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
   5022     updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
   5023 }
   5024 
   5025 // Use a very large value (in effect infinite).
   5026 #define BLOCK_MAX_WIDTH 15000
   5027 
   5028 void RenderBlock::computeBlockPreferredLogicalWidths()
   5029 {
   5030     bool nowrap = style()->whiteSpace() == NOWRAP;
   5031 
   5032     RenderObject *child = firstChild();
   5033     int floatLeftWidth = 0, floatRightWidth = 0;
   5034     while (child) {
   5035         // Positioned children don't affect the min/max width
   5036         if (child->isPositioned()) {
   5037             child = child->nextSibling();
   5038             continue;
   5039         }
   5040 
   5041         if (child->isFloating() || (child->isBox() && toRenderBox(child)->avoidsFloats())) {
   5042             int floatTotalWidth = floatLeftWidth + floatRightWidth;
   5043             if (child->style()->clear() & CLEFT) {
   5044                 m_maxPreferredLogicalWidth = max(floatTotalWidth, m_maxPreferredLogicalWidth);
   5045                 floatLeftWidth = 0;
   5046             }
   5047             if (child->style()->clear() & CRIGHT) {
   5048                 m_maxPreferredLogicalWidth = max(floatTotalWidth, m_maxPreferredLogicalWidth);
   5049                 floatRightWidth = 0;
   5050             }
   5051         }
   5052 
   5053         // A margin basically has three types: fixed, percentage, and auto (variable).
   5054         // Auto and percentage margins simply become 0 when computing min/max width.
   5055         // Fixed margins can be added in as is.
   5056         Length startMarginLength = child->style()->marginStart();
   5057         Length endMarginLength = child->style()->marginEnd();
   5058         int margin = 0;
   5059         int marginStart = 0;
   5060         int marginEnd = 0;
   5061         if (startMarginLength.isFixed())
   5062             marginStart += startMarginLength.value();
   5063         if (endMarginLength.isFixed())
   5064             marginEnd += endMarginLength.value();
   5065         margin = marginStart + marginEnd;
   5066 
   5067         int w = child->minPreferredLogicalWidth() + margin;
   5068         m_minPreferredLogicalWidth = max(w, m_minPreferredLogicalWidth);
   5069 
   5070         // IE ignores tables for calculation of nowrap. Makes some sense.
   5071         if (nowrap && !child->isTable())
   5072             m_maxPreferredLogicalWidth = max(w, m_maxPreferredLogicalWidth);
   5073 
   5074         w = child->maxPreferredLogicalWidth() + margin;
   5075 
   5076         if (!child->isFloating()) {
   5077             if (child->isBox() && toRenderBox(child)->avoidsFloats()) {
   5078                 // Determine a left and right max value based off whether or not the floats can fit in the
   5079                 // margins of the object.  For negative margins, we will attempt to overlap the float if the negative margin
   5080                 // is smaller than the float width.
   5081                 bool ltr = containingBlock()->style()->isLeftToRightDirection();
   5082                 int marginLogicalLeft = ltr ? marginStart : marginEnd;
   5083                 int marginLogicalRight = ltr ? marginEnd : marginStart;
   5084                 int maxLeft = marginLogicalLeft > 0 ? max(floatLeftWidth, marginLogicalLeft) : floatLeftWidth + marginLogicalLeft;
   5085                 int maxRight = marginLogicalRight > 0 ? max(floatRightWidth, marginLogicalRight) : floatRightWidth + marginLogicalRight;
   5086                 w = child->maxPreferredLogicalWidth() + maxLeft + maxRight;
   5087                 w = max(w, floatLeftWidth + floatRightWidth);
   5088             }
   5089             else
   5090                 m_maxPreferredLogicalWidth = max(floatLeftWidth + floatRightWidth, m_maxPreferredLogicalWidth);
   5091             floatLeftWidth = floatRightWidth = 0;
   5092         }
   5093 
   5094         if (child->isFloating()) {
   5095             if (style()->floating() == FLEFT)
   5096                 floatLeftWidth += w;
   5097             else
   5098                 floatRightWidth += w;
   5099         } else
   5100             m_maxPreferredLogicalWidth = max(w, m_maxPreferredLogicalWidth);
   5101 
   5102         // A very specific WinIE quirk.
   5103         // Example:
   5104         /*
   5105            <div style="position:absolute; width:100px; top:50px;">
   5106               <div style="position:absolute;left:0px;top:50px;height:50px;background-color:green">
   5107                 <table style="width:100%"><tr><td></table>
   5108               </div>
   5109            </div>
   5110         */
   5111         // In the above example, the inner absolute positioned block should have a computed width
   5112         // of 100px because of the table.
   5113         // We can achieve this effect by making the maxwidth of blocks that contain tables
   5114         // with percentage widths be infinite (as long as they are not inside a table cell).
   5115         if (document()->inQuirksMode() && child->style()->logicalWidth().isPercent() &&
   5116             !isTableCell() && child->isTable() && m_maxPreferredLogicalWidth < BLOCK_MAX_WIDTH) {
   5117             RenderBlock* cb = containingBlock();
   5118             while (!cb->isRenderView() && !cb->isTableCell())
   5119                 cb = cb->containingBlock();
   5120             if (!cb->isTableCell())
   5121                 m_maxPreferredLogicalWidth = BLOCK_MAX_WIDTH;
   5122         }
   5123 
   5124         child = child->nextSibling();
   5125     }
   5126 
   5127     // Always make sure these values are non-negative.
   5128     m_minPreferredLogicalWidth = max(0, m_minPreferredLogicalWidth);
   5129     m_maxPreferredLogicalWidth = max(0, m_maxPreferredLogicalWidth);
   5130 
   5131     m_maxPreferredLogicalWidth = max(floatLeftWidth + floatRightWidth, m_maxPreferredLogicalWidth);
   5132 }
   5133 
   5134 bool RenderBlock::hasLineIfEmpty() const
   5135 {
   5136     if (!node())
   5137         return false;
   5138 
   5139     if (node()->rendererIsEditable() && node()->rootEditableElement() == node())
   5140         return true;
   5141 
   5142     if (node()->isShadowRoot() && (node()->shadowHost()->hasTagName(inputTag)))
   5143         return true;
   5144 
   5145     return false;
   5146 }
   5147 
   5148 int RenderBlock::lineHeight(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
   5149 {
   5150     // Inline blocks are replaced elements. Otherwise, just pass off to
   5151     // the base class.  If we're being queried as though we're the root line
   5152     // box, then the fact that we're an inline-block is irrelevant, and we behave
   5153     // just like a block.
   5154     if (isReplaced() && linePositionMode == PositionOnContainingLine)
   5155         return RenderBox::lineHeight(firstLine, direction, linePositionMode);
   5156 
   5157     if (firstLine && document()->usesFirstLineRules()) {
   5158         RenderStyle* s = style(firstLine);
   5159         if (s != style())
   5160             return s->computedLineHeight();
   5161     }
   5162 
   5163     if (m_lineHeight == -1)
   5164         m_lineHeight = style()->computedLineHeight();
   5165 
   5166     return m_lineHeight;
   5167 }
   5168 
   5169 int RenderBlock::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
   5170 {
   5171     // Inline blocks are replaced elements. Otherwise, just pass off to
   5172     // the base class.  If we're being queried as though we're the root line
   5173     // box, then the fact that we're an inline-block is irrelevant, and we behave
   5174     // just like a block.
   5175     if (isReplaced() && linePositionMode == PositionOnContainingLine) {
   5176         // For "leaf" theme objects, let the theme decide what the baseline position is.
   5177         // FIXME: Might be better to have a custom CSS property instead, so that if the theme
   5178         // is turned off, checkboxes/radios will still have decent baselines.
   5179         // FIXME: Need to patch form controls to deal with vertical lines.
   5180         if (style()->hasAppearance() && !theme()->isControlContainer(style()->appearance()))
   5181             return theme()->baselinePosition(this);
   5182 
   5183         // CSS2.1 states that the baseline of an inline block is the baseline of the last line box in
   5184         // the normal flow.  We make an exception for marquees, since their baselines are meaningless
   5185         // (the content inside them moves).  This matches WinIE as well, which just bottom-aligns them.
   5186         // We also give up on finding a baseline if we have a vertical scrollbar, or if we are scrolled
   5187         // vertically (e.g., an overflow:hidden block that has had scrollTop moved) or if the baseline is outside
   5188         // of our content box.
   5189         bool ignoreBaseline = (layer() && (layer()->marquee() || (direction == HorizontalLine ? (layer()->verticalScrollbar() || layer()->scrollYOffset() != 0)
   5190             : (layer()->horizontalScrollbar() || layer()->scrollXOffset() != 0)))) || (isWritingModeRoot() && !isRubyRun());
   5191 
   5192         int baselinePos = ignoreBaseline ? -1 : lastLineBoxBaseline();
   5193 
   5194         int bottomOfContent = direction == HorizontalLine ? borderTop() + paddingTop() + contentHeight() : borderRight() + paddingRight() + contentWidth();
   5195         if (baselinePos != -1 && baselinePos <= bottomOfContent)
   5196             return direction == HorizontalLine ? marginTop() + baselinePos : marginRight() + baselinePos;
   5197 
   5198         return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
   5199     }
   5200 
   5201     const FontMetrics& fontMetrics = style(firstLine)->fontMetrics();
   5202     return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2;
   5203 }
   5204 
   5205 int RenderBlock::firstLineBoxBaseline() const
   5206 {
   5207     if (!isBlockFlow() || (isWritingModeRoot() && !isRubyRun()))
   5208         return -1;
   5209 
   5210     if (childrenInline()) {
   5211         if (firstLineBox())
   5212             return firstLineBox()->logicalTop() + style(true)->fontMetrics().ascent(firstRootBox()->baselineType());
   5213         else
   5214             return -1;
   5215     }
   5216     else {
   5217         for (RenderBox* curr = firstChildBox(); curr; curr = curr->nextSiblingBox()) {
   5218             if (!curr->isFloatingOrPositioned()) {
   5219                 int result = curr->firstLineBoxBaseline();
   5220                 if (result != -1)
   5221                     return curr->logicalTop() + result; // Translate to our coordinate space.
   5222             }
   5223         }
   5224     }
   5225 
   5226     return -1;
   5227 }
   5228 
   5229 int RenderBlock::lastLineBoxBaseline() const
   5230 {
   5231     if (!isBlockFlow() || (isWritingModeRoot() && !isRubyRun()))
   5232         return -1;
   5233 
   5234     LineDirectionMode lineDirection = isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
   5235 
   5236     if (childrenInline()) {
   5237         if (!firstLineBox() && hasLineIfEmpty()) {
   5238             const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
   5239             return fontMetrics.ascent()
   5240                  + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
   5241                  + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
   5242         }
   5243         if (lastLineBox())
   5244             return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->fontMetrics().ascent(lastRootBox()->baselineType());
   5245         return -1;
   5246     } else {
   5247         bool haveNormalFlowChild = false;
   5248         for (RenderBox* curr = lastChildBox(); curr; curr = curr->previousSiblingBox()) {
   5249             if (!curr->isFloatingOrPositioned()) {
   5250                 haveNormalFlowChild = true;
   5251                 int result = curr->lastLineBoxBaseline();
   5252                 if (result != -1)
   5253                     return curr->logicalTop() + result; // Translate to our coordinate space.
   5254             }
   5255         }
   5256         if (!haveNormalFlowChild && hasLineIfEmpty()) {
   5257             const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
   5258             return fontMetrics.ascent()
   5259                  + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
   5260                  + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
   5261         }
   5262     }
   5263 
   5264     return -1;
   5265 }
   5266 
   5267 bool RenderBlock::containsNonZeroBidiLevel() const
   5268 {
   5269     for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
   5270         for (InlineBox* box = root->firstLeafChild(); box; box = box->nextLeafChild()) {
   5271             if (box->bidiLevel())
   5272                 return true;
   5273         }
   5274     }
   5275     return false;
   5276 }
   5277 
   5278 RenderBlock* RenderBlock::firstLineBlock() const
   5279 {
   5280     RenderBlock* firstLineBlock = const_cast<RenderBlock*>(this);
   5281     bool hasPseudo = false;
   5282     while (true) {
   5283         hasPseudo = firstLineBlock->style()->hasPseudoStyle(FIRST_LINE);
   5284         if (hasPseudo)
   5285             break;
   5286         RenderObject* parentBlock = firstLineBlock->parent();
   5287         if (firstLineBlock->isReplaced() || firstLineBlock->isFloating() ||
   5288             !parentBlock || parentBlock->firstChild() != firstLineBlock || !parentBlock->isBlockFlow())
   5289             break;
   5290         ASSERT(parentBlock->isRenderBlock());
   5291         firstLineBlock = toRenderBlock(parentBlock);
   5292     }
   5293 
   5294     if (!hasPseudo)
   5295         return 0;
   5296 
   5297     return firstLineBlock;
   5298 }
   5299 
   5300 static RenderStyle* styleForFirstLetter(RenderObject* firstLetterBlock, RenderObject* firstLetterContainer)
   5301 {
   5302     RenderStyle* pseudoStyle = firstLetterBlock->getCachedPseudoStyle(FIRST_LETTER, firstLetterContainer->firstLineStyle());
   5303     // Force inline display (except for floating first-letters).
   5304     pseudoStyle->setDisplay(pseudoStyle->isFloating() ? BLOCK : INLINE);
   5305     // CSS2 says first-letter can't be positioned.
   5306     pseudoStyle->setPosition(StaticPosition);
   5307     return pseudoStyle;
   5308 }
   5309 
   5310 // CSS 2.1 http://www.w3.org/TR/CSS21/selector.html#first-letter
   5311 // "Punctuation (i.e, characters defined in Unicode [UNICODE] in the "open" (Ps), "close" (Pe),
   5312 // "initial" (Pi). "final" (Pf) and "other" (Po) punctuation classes), that precedes or follows the first letter should be included"
   5313 static inline bool isPunctuationForFirstLetter(UChar c)
   5314 {
   5315     CharCategory charCategory = category(c);
   5316     return charCategory == Punctuation_Open
   5317         || charCategory == Punctuation_Close
   5318         || charCategory == Punctuation_InitialQuote
   5319         || charCategory == Punctuation_FinalQuote
   5320         || charCategory == Punctuation_Other;
   5321 }
   5322 
   5323 static inline bool shouldSkipForFirstLetter(UChar c)
   5324 {
   5325     return isSpaceOrNewline(c) || c == noBreakSpace || isPunctuationForFirstLetter(c);
   5326 }
   5327 
   5328 void RenderBlock::updateFirstLetter()
   5329 {
   5330     if (!document()->usesFirstLetterRules())
   5331         return;
   5332     // Don't recur
   5333     if (style()->styleType() == FIRST_LETTER)
   5334         return;
   5335 
   5336     // FIXME: We need to destroy the first-letter object if it is no longer the first child.  Need to find
   5337     // an efficient way to check for that situation though before implementing anything.
   5338     RenderObject* firstLetterBlock = this;
   5339     bool hasPseudoStyle = false;
   5340     while (true) {
   5341         // We only honor first-letter if the firstLetterBlock can have children in the DOM. This correctly
   5342         // prevents form controls from honoring first-letter.
   5343         hasPseudoStyle = firstLetterBlock->style()->hasPseudoStyle(FIRST_LETTER)
   5344             && firstLetterBlock->canHaveChildren();
   5345         if (hasPseudoStyle)
   5346             break;
   5347         RenderObject* parentBlock = firstLetterBlock->parent();
   5348         if (firstLetterBlock->isReplaced() || !parentBlock || parentBlock->firstChild() != firstLetterBlock ||
   5349             !parentBlock->isBlockFlow())
   5350             break;
   5351         firstLetterBlock = parentBlock;
   5352     }
   5353 
   5354     if (!hasPseudoStyle)
   5355         return;
   5356 
   5357     // Drill into inlines looking for our first text child.
   5358     RenderObject* currChild = firstLetterBlock->firstChild();
   5359     while (currChild && ((!currChild->isReplaced() && !currChild->isRenderButton() && !currChild->isMenuList()) || currChild->isFloatingOrPositioned()) && !currChild->isText()) {
   5360         if (currChild->isFloatingOrPositioned()) {
   5361             if (currChild->style()->styleType() == FIRST_LETTER) {
   5362                 currChild = currChild->firstChild();
   5363                 break;
   5364             }
   5365             currChild = currChild->nextSibling();
   5366         } else
   5367             currChild = currChild->firstChild();
   5368     }
   5369 
   5370     // Get list markers out of the way.
   5371     while (currChild && currChild->isListMarker())
   5372         currChild = currChild->nextSibling();
   5373 
   5374     if (!currChild)
   5375         return;
   5376 
   5377     // If the child already has style, then it has already been created, so we just want
   5378     // to update it.
   5379     if (currChild->parent()->style()->styleType() == FIRST_LETTER) {
   5380         RenderObject* firstLetter = currChild->parent();
   5381         RenderObject* firstLetterContainer = firstLetter->parent();
   5382         RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
   5383 
   5384         if (Node::diff(firstLetter->style(), pseudoStyle) == Node::Detach) {
   5385             // The first-letter renderer needs to be replaced. Create a new renderer of the right type.
   5386             RenderObject* newFirstLetter;
   5387             if (pseudoStyle->display() == INLINE)
   5388                 newFirstLetter = new (renderArena()) RenderInline(document());
   5389             else
   5390                 newFirstLetter = new (renderArena()) RenderBlock(document());
   5391             newFirstLetter->setStyle(pseudoStyle);
   5392 
   5393             // Move the first letter into the new renderer.
   5394             view()->disableLayoutState();
   5395             while (RenderObject* child = firstLetter->firstChild()) {
   5396                 if (child->isText())
   5397                     toRenderText(child)->removeAndDestroyTextBoxes();
   5398                 firstLetter->removeChild(child);
   5399                 newFirstLetter->addChild(child, 0);
   5400             }
   5401 
   5402             RenderTextFragment* remainingText = 0;
   5403             RenderObject* nextSibling = firstLetter->nextSibling();
   5404             RenderObject* next = nextSibling;
   5405             while (next) {
   5406                 if (next->isText() && toRenderText(next)->isTextFragment()) {
   5407                     remainingText = toRenderTextFragment(next);
   5408                     break;
   5409                 }
   5410                 next = next->nextSibling();
   5411             }
   5412             if (remainingText) {
   5413                 ASSERT(remainingText->node()->renderer() == remainingText);
   5414                 // Replace the old renderer with the new one.
   5415                 remainingText->setFirstLetter(newFirstLetter);
   5416             }
   5417             firstLetter->destroy();
   5418             firstLetter = newFirstLetter;
   5419             firstLetterContainer->addChild(firstLetter, nextSibling);
   5420             view()->enableLayoutState();
   5421         } else
   5422             firstLetter->setStyle(pseudoStyle);
   5423 
   5424         for (RenderObject* genChild = firstLetter->firstChild(); genChild; genChild = genChild->nextSibling()) {
   5425             if (genChild->isText())
   5426                 genChild->setStyle(pseudoStyle);
   5427         }
   5428 
   5429         return;
   5430     }
   5431 
   5432     if (!currChild->isText() || currChild->isBR())
   5433         return;
   5434 
   5435     // If the child does not already have style, we create it here.
   5436     RenderObject* firstLetterContainer = currChild->parent();
   5437 
   5438     // Our layout state is not valid for the repaints we are going to trigger by
   5439     // adding and removing children of firstLetterContainer.
   5440     view()->disableLayoutState();
   5441 
   5442     RenderText* textObj = toRenderText(currChild);
   5443 
   5444     // Create our pseudo style now that we have our firstLetterContainer determined.
   5445     RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
   5446 
   5447     RenderObject* firstLetter = 0;
   5448     if (pseudoStyle->display() == INLINE)
   5449         firstLetter = new (renderArena()) RenderInline(document());
   5450     else
   5451         firstLetter = new (renderArena()) RenderBlock(document());
   5452     firstLetter->setStyle(pseudoStyle);
   5453     firstLetterContainer->addChild(firstLetter, currChild);
   5454 
   5455     // The original string is going to be either a generated content string or a DOM node's
   5456     // string.  We want the original string before it got transformed in case first-letter has
   5457     // no text-transform or a different text-transform applied to it.
   5458     RefPtr<StringImpl> oldText = textObj->originalText();
   5459     ASSERT(oldText);
   5460 
   5461     if (oldText && oldText->length() > 0) {
   5462         unsigned length = 0;
   5463 
   5464         // Account for leading spaces and punctuation.
   5465         while (length < oldText->length() && shouldSkipForFirstLetter((*oldText)[length]))
   5466             length++;
   5467 
   5468         // Account for first letter.
   5469         length++;
   5470 
   5471         // Keep looking for whitespace and allowed punctuation, but avoid
   5472         // accumulating just whitespace into the :first-letter.
   5473         for (unsigned scanLength = length; scanLength < oldText->length(); ++scanLength) {
   5474             UChar c = (*oldText)[scanLength];
   5475 
   5476             if (!shouldSkipForFirstLetter(c))
   5477                 break;
   5478 
   5479             if (isPunctuationForFirstLetter(c))
   5480                 length = scanLength + 1;
   5481          }
   5482 
   5483         // Construct a text fragment for the text after the first letter.
   5484         // This text fragment might be empty.
   5485         RenderTextFragment* remainingText =
   5486             new (renderArena()) RenderTextFragment(textObj->node() ? textObj->node() : textObj->document(), oldText.get(), length, oldText->length() - length);
   5487         remainingText->setStyle(textObj->style());
   5488         if (remainingText->node())
   5489             remainingText->node()->setRenderer(remainingText);
   5490 
   5491         firstLetterContainer->addChild(remainingText, textObj);
   5492         firstLetterContainer->removeChild(textObj);
   5493         remainingText->setFirstLetter(firstLetter);
   5494 
   5495         // construct text fragment for the first letter
   5496         RenderTextFragment* letter =
   5497             new (renderArena()) RenderTextFragment(remainingText->node() ? remainingText->node() : remainingText->document(), oldText.get(), 0, length);
   5498         letter->setStyle(pseudoStyle);
   5499         firstLetter->addChild(letter);
   5500 
   5501         textObj->destroy();
   5502     }
   5503     view()->enableLayoutState();
   5504 }
   5505 
   5506 // Helper methods for obtaining the last line, computing line counts and heights for line counts
   5507 // (crawling into blocks).
   5508 static bool shouldCheckLines(RenderObject* obj)
   5509 {
   5510     return !obj->isFloatingOrPositioned() && !obj->isRunIn() &&
   5511             obj->isBlockFlow() && obj->style()->height().isAuto() &&
   5512             (!obj->isFlexibleBox() || obj->style()->boxOrient() == VERTICAL);
   5513 }
   5514 
   5515 static RootInlineBox* getLineAtIndex(RenderBlock* block, int i, int& count)
   5516 {
   5517     if (block->style()->visibility() == VISIBLE) {
   5518         if (block->childrenInline()) {
   5519             for (RootInlineBox* box = block->firstRootBox(); box; box = box->nextRootBox()) {
   5520                 if (count++ == i)
   5521                     return box;
   5522             }
   5523         }
   5524         else {
   5525             for (RenderObject* obj = block->firstChild(); obj; obj = obj->nextSibling()) {
   5526                 if (shouldCheckLines(obj)) {
   5527                     RootInlineBox *box = getLineAtIndex(toRenderBlock(obj), i, count);
   5528                     if (box)
   5529                         return box;
   5530                 }
   5531             }
   5532         }
   5533     }
   5534     return 0;
   5535 }
   5536 
   5537 static int getHeightForLineCount(RenderBlock* block, int l, bool includeBottom, int& count)
   5538 {
   5539     if (block->style()->visibility() == VISIBLE) {
   5540         if (block->childrenInline()) {
   5541             for (RootInlineBox* box = block->firstRootBox(); box; box = box->nextRootBox()) {
   5542                 if (++count == l)
   5543                     return box->lineBottom() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : 0);
   5544             }
   5545         }
   5546         else {
   5547             RenderBox* normalFlowChildWithoutLines = 0;
   5548             for (RenderBox* obj = block->firstChildBox(); obj; obj = obj->nextSiblingBox()) {
   5549                 if (shouldCheckLines(obj)) {
   5550                     int result = getHeightForLineCount(toRenderBlock(obj), l, false, count);
   5551                     if (result != -1)
   5552                         return result + obj->y() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : 0);
   5553                 }
   5554                 else if (!obj->isFloatingOrPositioned() && !obj->isRunIn())
   5555                     normalFlowChildWithoutLines = obj;
   5556             }
   5557             if (normalFlowChildWithoutLines && l == 0)
   5558                 return normalFlowChildWithoutLines->y() + normalFlowChildWithoutLines->height();
   5559         }
   5560     }
   5561 
   5562     return -1;
   5563 }
   5564 
   5565 RootInlineBox* RenderBlock::lineAtIndex(int i)
   5566 {
   5567     int count = 0;
   5568     return getLineAtIndex(this, i, count);
   5569 }
   5570 
   5571 int RenderBlock::lineCount()
   5572 {
   5573     int count = 0;
   5574     if (style()->visibility() == VISIBLE) {
   5575         if (childrenInline())
   5576             for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
   5577                 count++;
   5578         else
   5579             for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling())
   5580                 if (shouldCheckLines(obj))
   5581                     count += toRenderBlock(obj)->lineCount();
   5582     }
   5583     return count;
   5584 }
   5585 
   5586 int RenderBlock::heightForLineCount(int l)
   5587 {
   5588     int count = 0;
   5589     return getHeightForLineCount(this, l, true, count);
   5590 }
   5591 
   5592 void RenderBlock::adjustForBorderFit(int x, int& left, int& right) const
   5593 {
   5594     // We don't deal with relative positioning.  Our assumption is that you shrink to fit the lines without accounting
   5595     // for either overflow or translations via relative positioning.
   5596     if (style()->visibility() == VISIBLE) {
   5597         if (childrenInline()) {
   5598             for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) {
   5599                 if (box->firstChild())
   5600                     left = min(left, x + static_cast<int>(box->firstChild()->x()));
   5601                 if (box->lastChild())
   5602                     right = max(right, x + static_cast<int>(ceilf(box->lastChild()->logicalRight())));
   5603             }
   5604         }
   5605         else {
   5606             for (RenderBox* obj = firstChildBox(); obj; obj = obj->nextSiblingBox()) {
   5607                 if (!obj->isFloatingOrPositioned()) {
   5608                     if (obj->isBlockFlow() && !obj->hasOverflowClip())
   5609                         toRenderBlock(obj)->adjustForBorderFit(x + obj->x(), left, right);
   5610                     else if (obj->style()->visibility() == VISIBLE) {
   5611                         // We are a replaced element or some kind of non-block-flow object.
   5612                         left = min(left, x + obj->x());
   5613                         right = max(right, x + obj->x() + obj->width());
   5614                     }
   5615                 }
   5616             }
   5617         }
   5618 
   5619         if (m_floatingObjects) {
   5620             FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   5621             FloatingObjectSetIterator end = floatingObjectSet.end();
   5622             for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   5623                 FloatingObject* r = *it;
   5624                 // Only examine the object if our m_shouldPaint flag is set.
   5625                 if (r->m_shouldPaint) {
   5626                     int floatLeft = xPositionForFloatIncludingMargin(r) - r->m_renderer->x();
   5627                     int floatRight = floatLeft + r->m_renderer->width();
   5628                     left = min(left, floatLeft);
   5629                     right = max(right, floatRight);
   5630                 }
   5631             }
   5632         }
   5633     }
   5634 }
   5635 
   5636 void RenderBlock::borderFitAdjust(int& x, int& w) const
   5637 {
   5638     if (style()->borderFit() == BorderFitBorder)
   5639         return;
   5640 
   5641     // Walk any normal flow lines to snugly fit.
   5642     int left = INT_MAX;
   5643     int right = INT_MIN;
   5644     int oldWidth = w;
   5645     adjustForBorderFit(0, left, right);
   5646     if (left != INT_MAX) {
   5647         left -= (borderLeft() + paddingLeft());
   5648         if (left > 0) {
   5649             x += left;
   5650             w -= left;
   5651         }
   5652     }
   5653     if (right != INT_MIN) {
   5654         right += (borderRight() + paddingRight());
   5655         if (right < oldWidth)
   5656             w -= (oldWidth - right);
   5657     }
   5658 }
   5659 
   5660 void RenderBlock::clearTruncation()
   5661 {
   5662     if (style()->visibility() == VISIBLE) {
   5663         if (childrenInline() && hasMarkupTruncation()) {
   5664             setHasMarkupTruncation(false);
   5665             for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
   5666                 box->clearTruncation();
   5667         }
   5668         else
   5669             for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling())
   5670                 if (shouldCheckLines(obj))
   5671                     toRenderBlock(obj)->clearTruncation();
   5672     }
   5673 }
   5674 
   5675 void RenderBlock::setMaxMarginBeforeValues(int pos, int neg)
   5676 {
   5677     if (!m_rareData) {
   5678         if (pos == RenderBlockRareData::positiveMarginBeforeDefault(this) && neg == RenderBlockRareData::negativeMarginBeforeDefault(this))
   5679             return;
   5680         m_rareData = new RenderBlockRareData(this);
   5681     }
   5682     m_rareData->m_margins.setPositiveMarginBefore(pos);
   5683     m_rareData->m_margins.setNegativeMarginBefore(neg);
   5684 }
   5685 
   5686 void RenderBlock::setMaxMarginAfterValues(int pos, int neg)
   5687 {
   5688     if (!m_rareData) {
   5689         if (pos == RenderBlockRareData::positiveMarginAfterDefault(this) && neg == RenderBlockRareData::negativeMarginAfterDefault(this))
   5690             return;
   5691         m_rareData = new RenderBlockRareData(this);
   5692     }
   5693     m_rareData->m_margins.setPositiveMarginAfter(pos);
   5694     m_rareData->m_margins.setNegativeMarginAfter(neg);
   5695 }
   5696 
   5697 void RenderBlock::setPaginationStrut(int strut)
   5698 {
   5699     if (!m_rareData) {
   5700         if (!strut)
   5701             return;
   5702         m_rareData = new RenderBlockRareData(this);
   5703     }
   5704     m_rareData->m_paginationStrut = strut;
   5705 }
   5706 
   5707 void RenderBlock::setPageLogicalOffset(int logicalOffset)
   5708 {
   5709     if (!m_rareData) {
   5710         if (!logicalOffset)
   5711             return;
   5712         m_rareData = new RenderBlockRareData(this);
   5713     }
   5714     m_rareData->m_pageLogicalOffset = logicalOffset;
   5715 }
   5716 
   5717 void RenderBlock::absoluteRects(Vector<IntRect>& rects, int tx, int ty)
   5718 {
   5719     // For blocks inside inlines, we go ahead and include margins so that we run right up to the
   5720     // inline boxes above and below us (thus getting merged with them to form a single irregular
   5721     // shape).
   5722     if (isAnonymousBlockContinuation()) {
   5723         // FIXME: This is wrong for block-flows that are horizontal.
   5724         // https://bugs.webkit.org/show_bug.cgi?id=46781
   5725         rects.append(IntRect(tx, ty - collapsedMarginBefore(),
   5726                              width(), height() + collapsedMarginBefore() + collapsedMarginAfter()));
   5727         continuation()->absoluteRects(rects,
   5728                                       tx - x() + inlineElementContinuation()->containingBlock()->x(),
   5729                                       ty - y() + inlineElementContinuation()->containingBlock()->y());
   5730     } else
   5731         rects.append(IntRect(tx, ty, width(), height()));
   5732 }
   5733 
   5734 void RenderBlock::absoluteQuads(Vector<FloatQuad>& quads)
   5735 {
   5736     // For blocks inside inlines, we go ahead and include margins so that we run right up to the
   5737     // inline boxes above and below us (thus getting merged with them to form a single irregular
   5738     // shape).
   5739     if (isAnonymousBlockContinuation()) {
   5740         // FIXME: This is wrong for block-flows that are horizontal.
   5741         // https://bugs.webkit.org/show_bug.cgi?id=46781
   5742         FloatRect localRect(0, -collapsedMarginBefore(),
   5743                             width(), height() + collapsedMarginBefore() + collapsedMarginAfter());
   5744         quads.append(localToAbsoluteQuad(localRect));
   5745         continuation()->absoluteQuads(quads);
   5746     } else
   5747         quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width(), height())));
   5748 }
   5749 
   5750 IntRect RenderBlock::rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth)
   5751 {
   5752     IntRect r(RenderBox::rectWithOutlineForRepaint(repaintContainer, outlineWidth));
   5753     if (isAnonymousBlockContinuation())
   5754         r.inflateY(collapsedMarginBefore()); // FIXME: This is wrong for block-flows that are horizontal.
   5755     return r;
   5756 }
   5757 
   5758 RenderObject* RenderBlock::hoverAncestor() const
   5759 {
   5760     return isAnonymousBlockContinuation() ? continuation() : RenderBox::hoverAncestor();
   5761 }
   5762 
   5763 void RenderBlock::updateDragState(bool dragOn)
   5764 {
   5765     RenderBox::updateDragState(dragOn);
   5766     if (continuation())
   5767         continuation()->updateDragState(dragOn);
   5768 }
   5769 
   5770 RenderStyle* RenderBlock::outlineStyleForRepaint() const
   5771 {
   5772     return isAnonymousBlockContinuation() ? continuation()->style() : style();
   5773 }
   5774 
   5775 void RenderBlock::childBecameNonInline(RenderObject*)
   5776 {
   5777     makeChildrenNonInline();
   5778     if (isAnonymousBlock() && parent() && parent()->isRenderBlock())
   5779         toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
   5780     // |this| may be dead here
   5781 }
   5782 
   5783 void RenderBlock::updateHitTestResult(HitTestResult& result, const IntPoint& point)
   5784 {
   5785     if (result.innerNode())
   5786         return;
   5787 
   5788     Node* n = node();
   5789     if (isAnonymousBlockContinuation())
   5790         // We are in the margins of block elements that are part of a continuation.  In
   5791         // this case we're actually still inside the enclosing element that was
   5792         // split.  Go ahead and set our inner node accordingly.
   5793         n = continuation()->node();
   5794 
   5795     if (n) {
   5796         result.setInnerNode(n);
   5797         if (!result.innerNonSharedNode())
   5798             result.setInnerNonSharedNode(n);
   5799         result.setLocalPoint(point);
   5800     }
   5801 }
   5802 
   5803 IntRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, int* extraWidthToEndOfLine)
   5804 {
   5805     // Do the normal calculation in most cases.
   5806     if (firstChild())
   5807         return RenderBox::localCaretRect(inlineBox, caretOffset, extraWidthToEndOfLine);
   5808 
   5809     // This is a special case:
   5810     // The element is not an inline element, and it's empty. So we have to
   5811     // calculate a fake position to indicate where objects are to be inserted.
   5812 
   5813     // FIXME: This does not take into account either :first-line or :first-letter
   5814     // However, as soon as some content is entered, the line boxes will be
   5815     // constructed and this kludge is not called any more. So only the caret size
   5816     // of an empty :first-line'd block is wrong. I think we can live with that.
   5817     RenderStyle* currentStyle = firstLineStyle();
   5818     int height = lineHeight(true, currentStyle->isHorizontalWritingMode() ? HorizontalLine : VerticalLine);
   5819 
   5820     enum CaretAlignment { alignLeft, alignRight, alignCenter };
   5821 
   5822     CaretAlignment alignment = alignLeft;
   5823 
   5824     switch (currentStyle->textAlign()) {
   5825         case TAAUTO:
   5826         case JUSTIFY:
   5827             if (!currentStyle->isLeftToRightDirection())
   5828                 alignment = alignRight;
   5829             break;
   5830         case LEFT:
   5831         case WEBKIT_LEFT:
   5832             break;
   5833         case CENTER:
   5834         case WEBKIT_CENTER:
   5835             alignment = alignCenter;
   5836             break;
   5837         case RIGHT:
   5838         case WEBKIT_RIGHT:
   5839             alignment = alignRight;
   5840             break;
   5841         case TASTART:
   5842             if (!currentStyle->isLeftToRightDirection())
   5843                 alignment = alignRight;
   5844             break;
   5845         case TAEND:
   5846             if (currentStyle->isLeftToRightDirection())
   5847                 alignment = alignRight;
   5848             break;
   5849     }
   5850 
   5851     int x = borderLeft() + paddingLeft();
   5852     int w = width();
   5853 
   5854     switch (alignment) {
   5855         case alignLeft:
   5856             break;
   5857         case alignCenter:
   5858             x = (x + w - (borderRight() + paddingRight())) / 2;
   5859             break;
   5860         case alignRight:
   5861             x = w - (borderRight() + paddingRight()) - caretWidth;
   5862             break;
   5863     }
   5864 
   5865     if (extraWidthToEndOfLine) {
   5866         if (isRenderBlock()) {
   5867             *extraWidthToEndOfLine = w - (x + caretWidth);
   5868         } else {
   5869             // FIXME: This code looks wrong.
   5870             // myRight and containerRight are set up, but then clobbered.
   5871             // So *extraWidthToEndOfLine will always be 0 here.
   5872 
   5873             int myRight = x + caretWidth;
   5874             // FIXME: why call localToAbsoluteForContent() twice here, too?
   5875             FloatPoint absRightPoint = localToAbsolute(FloatPoint(myRight, 0));
   5876 
   5877             int containerRight = containingBlock()->x() + containingBlockLogicalWidthForContent();
   5878             FloatPoint absContainerPoint = localToAbsolute(FloatPoint(containerRight, 0));
   5879 
   5880             *extraWidthToEndOfLine = absContainerPoint.x() - absRightPoint.x();
   5881         }
   5882     }
   5883 
   5884     int y = paddingTop() + borderTop();
   5885 
   5886     return IntRect(x, y, caretWidth, height);
   5887 }
   5888 
   5889 void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
   5890 {
   5891     // For blocks inside inlines, we go ahead and include margins so that we run right up to the
   5892     // inline boxes above and below us (thus getting merged with them to form a single irregular
   5893     // shape).
   5894     if (inlineElementContinuation()) {
   5895         // FIXME: This check really isn't accurate.
   5896         bool nextInlineHasLineBox = inlineElementContinuation()->firstLineBox();
   5897         // FIXME: This is wrong. The principal renderer may not be the continuation preceding this block.
   5898         // FIXME: This is wrong for block-flows that are horizontal.
   5899         // https://bugs.webkit.org/show_bug.cgi?id=46781
   5900         bool prevInlineHasLineBox = toRenderInline(inlineElementContinuation()->node()->renderer())->firstLineBox();
   5901         int topMargin = prevInlineHasLineBox ? collapsedMarginBefore() : 0;
   5902         int bottomMargin = nextInlineHasLineBox ? collapsedMarginAfter() : 0;
   5903         IntRect rect(tx, ty - topMargin, width(), height() + topMargin + bottomMargin);
   5904         if (!rect.isEmpty())
   5905             rects.append(rect);
   5906     } else if (width() && height())
   5907         rects.append(IntRect(tx, ty, width(), height()));
   5908 
   5909     if (!hasOverflowClip() && !hasControlClip()) {
   5910         for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
   5911             int top = max(curr->lineTop(), curr->logicalTop());
   5912             int bottom = min(curr->lineBottom(), curr->logicalTop() + curr->logicalHeight());
   5913             IntRect rect(tx + curr->x(), ty + top, curr->logicalWidth(), bottom - top);
   5914             if (!rect.isEmpty())
   5915                 rects.append(rect);
   5916         }
   5917 
   5918         for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
   5919             if (!curr->isText() && !curr->isListMarker() && curr->isBox()) {
   5920                 RenderBox* box = toRenderBox(curr);
   5921                 FloatPoint pos;
   5922                 // FIXME: This doesn't work correctly with transforms.
   5923                 if (box->layer())
   5924                     pos = curr->localToAbsolute();
   5925                 else
   5926                     pos = FloatPoint(tx + box->x(), ty + box->y());
   5927                 box->addFocusRingRects(rects, pos.x(), pos.y());
   5928             }
   5929         }
   5930     }
   5931 
   5932     if (inlineElementContinuation())
   5933         inlineElementContinuation()->addFocusRingRects(rects,
   5934                                                        tx - x() + inlineElementContinuation()->containingBlock()->x(),
   5935                                                        ty - y() + inlineElementContinuation()->containingBlock()->y());
   5936 }
   5937 
   5938 RenderBlock* RenderBlock::createAnonymousBlock(bool isFlexibleBox) const
   5939 {
   5940     RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
   5941 
   5942     RenderBlock* newBox = 0;
   5943     if (isFlexibleBox) {
   5944         newStyle->setDisplay(BOX);
   5945         newBox = new (renderArena()) RenderFlexibleBox(document() /* anonymous box */);
   5946     } else {
   5947         newStyle->setDisplay(BLOCK);
   5948         newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
   5949     }
   5950 
   5951     newBox->setStyle(newStyle.release());
   5952     return newBox;
   5953 }
   5954 
   5955 RenderBlock* RenderBlock::createAnonymousBlockWithSameTypeAs(RenderBlock* otherAnonymousBlock) const
   5956 {
   5957     if (otherAnonymousBlock->isAnonymousColumnsBlock())
   5958         return createAnonymousColumnsBlock();
   5959     if (otherAnonymousBlock->isAnonymousColumnSpanBlock())
   5960         return createAnonymousColumnSpanBlock();
   5961     return createAnonymousBlock(otherAnonymousBlock->style()->display() == BOX);
   5962 }
   5963 
   5964 RenderBlock* RenderBlock::createAnonymousColumnsBlock() const
   5965 {
   5966     RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
   5967     newStyle->inheritColumnPropertiesFrom(style());
   5968     newStyle->setDisplay(BLOCK);
   5969 
   5970     RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
   5971     newBox->setStyle(newStyle.release());
   5972     return newBox;
   5973 }
   5974 
   5975 RenderBlock* RenderBlock::createAnonymousColumnSpanBlock() const
   5976 {
   5977     RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style());
   5978     newStyle->setColumnSpan(true);
   5979     newStyle->setDisplay(BLOCK);
   5980 
   5981     RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
   5982     newBox->setStyle(newStyle.release());
   5983     return newBox;
   5984 }
   5985 
   5986 int RenderBlock::nextPageLogicalTop(int logicalOffset) const
   5987 {
   5988     LayoutState* layoutState = view()->layoutState();
   5989     if (!layoutState->m_pageLogicalHeight)
   5990         return logicalOffset;
   5991 
   5992     // The logicalOffset is in our coordinate space.  We can add in our pushed offset.
   5993     int pageLogicalHeight = layoutState->m_pageLogicalHeight;
   5994     IntSize delta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
   5995     int offset = isHorizontalWritingMode() ? delta.height() : delta.width();
   5996     int remainingLogicalHeight = (pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight) % pageLogicalHeight;
   5997     return logicalOffset + remainingLogicalHeight;
   5998 }
   5999 
   6000 static bool inNormalFlow(RenderBox* child)
   6001 {
   6002     RenderBlock* curr = child->containingBlock();
   6003     RenderBlock* initialBlock = child->view();
   6004     while (curr && curr != initialBlock) {
   6005         if (curr->hasColumns())
   6006             return true;
   6007         if (curr->isFloatingOrPositioned())
   6008             return false;
   6009         curr = curr->containingBlock();
   6010     }
   6011     return true;
   6012 }
   6013 
   6014 int RenderBlock::applyBeforeBreak(RenderBox* child, int logicalOffset)
   6015 {
   6016     // FIXME: Add page break checking here when we support printing.
   6017     bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
   6018     bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight; // FIXME: Once columns can print we have to check this.
   6019     bool checkBeforeAlways = (checkColumnBreaks && child->style()->columnBreakBefore() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakBefore() == PBALWAYS);
   6020     if (checkBeforeAlways && inNormalFlow(child)) {
   6021         if (checkColumnBreaks)
   6022             view()->layoutState()->addForcedColumnBreak(logicalOffset);
   6023         return nextPageLogicalTop(logicalOffset);
   6024     }
   6025     return logicalOffset;
   6026 }
   6027 
   6028 int RenderBlock::applyAfterBreak(RenderBox* child, int logicalOffset, MarginInfo& marginInfo)
   6029 {
   6030     // FIXME: Add page break checking here when we support printing.
   6031     bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
   6032     bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight; // FIXME: Once columns can print we have to check this.
   6033     bool checkAfterAlways = (checkColumnBreaks && child->style()->columnBreakAfter() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakAfter() == PBALWAYS);
   6034     if (checkAfterAlways && inNormalFlow(child)) {
   6035         marginInfo.setMarginAfterQuirk(true); // Cause margins to be discarded for any following content.
   6036         if (checkColumnBreaks)
   6037             view()->layoutState()->addForcedColumnBreak(logicalOffset);
   6038         return nextPageLogicalTop(logicalOffset);
   6039     }
   6040     return logicalOffset;
   6041 }
   6042 
   6043 int RenderBlock::adjustForUnsplittableChild(RenderBox* child, int logicalOffset, bool includeMargins)
   6044 {
   6045     bool isUnsplittable = child->isReplaced() || child->scrollsOverflow();
   6046     if (!isUnsplittable)
   6047         return logicalOffset;
   6048     int childLogicalHeight = logicalHeightForChild(child) + (includeMargins ? marginBeforeForChild(child) + marginAfterForChild(child) : 0);
   6049     LayoutState* layoutState = view()->layoutState();
   6050     if (layoutState->m_columnInfo)
   6051         layoutState->m_columnInfo->updateMinimumColumnHeight(childLogicalHeight);
   6052     int pageLogicalHeight = layoutState->m_pageLogicalHeight;
   6053     if (!pageLogicalHeight || childLogicalHeight > pageLogicalHeight)
   6054         return logicalOffset;
   6055     IntSize delta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
   6056     int offset = isHorizontalWritingMode() ? delta.height() : delta.width();
   6057     int remainingLogicalHeight = (pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight) % pageLogicalHeight;
   6058     if (remainingLogicalHeight < childLogicalHeight)
   6059         return logicalOffset + remainingLogicalHeight;
   6060     return logicalOffset;
   6061 }
   6062 
   6063 void RenderBlock::adjustLinePositionForPagination(RootInlineBox* lineBox, int& delta)
   6064 {
   6065     // FIXME: For now we paginate using line overflow.  This ensures that lines don't overlap at all when we
   6066     // put a strut between them for pagination purposes.  However, this really isn't the desired rendering, since
   6067     // the line on the top of the next page will appear too far down relative to the same kind of line at the top
   6068     // of the first column.
   6069     //
   6070     // The rendering we would like to see is one where the lineTop is at the top of the column, and any line overflow
   6071     // simply spills out above the top of the column.  This effect would match what happens at the top of the first column.
   6072     // We can't achieve this rendering, however, until we stop columns from clipping to the column bounds (thus allowing
   6073     // for overflow to occur), and then cache visible overflow for each column rect.
   6074     //
   6075     // Furthermore, the paint we have to do when a column has overflow has to be special.  We need to exclude
   6076     // content that paints in a previous column (and content that paints in the following column).
   6077     //
   6078     // FIXME: Another problem with simply moving lines is that the available line width may change (because of floats).
   6079     // Technically if the location we move the line to has a different line width than our old position, then we need to dirty the
   6080     // line and all following lines.
   6081     LayoutState* layoutState = view()->layoutState();
   6082     int pageLogicalHeight = layoutState->m_pageLogicalHeight;
   6083     IntRect logicalVisualOverflow = lineBox->logicalVisualOverflowRect(lineBox->lineTop(), lineBox->lineBottom());
   6084     int logicalOffset = logicalVisualOverflow.y();
   6085     int lineHeight = logicalVisualOverflow.maxY() - logicalOffset;
   6086     if (layoutState->m_columnInfo)
   6087         layoutState->m_columnInfo->updateMinimumColumnHeight(lineHeight);
   6088     logicalOffset += delta;
   6089     lineBox->setPaginationStrut(0);
   6090     if (!pageLogicalHeight || lineHeight > pageLogicalHeight)
   6091         return;
   6092     IntSize offsetDelta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
   6093     int offset = isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.width();
   6094     int remainingLogicalHeight = pageLogicalHeight - (offset + logicalOffset) % pageLogicalHeight;
   6095     if (remainingLogicalHeight < lineHeight) {
   6096         int totalLogicalHeight = lineHeight + max(0, logicalOffset);
   6097         if (lineBox == firstRootBox() && totalLogicalHeight < pageLogicalHeight && !isPositioned() && !isTableCell())
   6098             setPaginationStrut(remainingLogicalHeight + max(0, logicalOffset));
   6099         else {
   6100             delta += remainingLogicalHeight;
   6101             lineBox->setPaginationStrut(remainingLogicalHeight);
   6102         }
   6103     }
   6104 }
   6105 
   6106 int RenderBlock::collapsedMarginBeforeForChild(RenderBox* child) const
   6107 {
   6108     // If the child has the same directionality as we do, then we can just return its
   6109     // collapsed margin.
   6110     if (!child->isWritingModeRoot())
   6111         return child->collapsedMarginBefore();
   6112 
   6113     // The child has a different directionality.  If the child is parallel, then it's just
   6114     // flipped relative to us.  We can use the collapsed margin for the opposite edge.
   6115     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
   6116         return child->collapsedMarginAfter();
   6117 
   6118     // The child is perpendicular to us, which means its margins don't collapse but are on the
   6119     // "logical left/right" sides of the child box.  We can just return the raw margin in this case.
   6120     return marginBeforeForChild(child);
   6121 }
   6122 
   6123 int RenderBlock::collapsedMarginAfterForChild(RenderBox* child) const
   6124 {
   6125     // If the child has the same directionality as we do, then we can just return its
   6126     // collapsed margin.
   6127     if (!child->isWritingModeRoot())
   6128         return child->collapsedMarginAfter();
   6129 
   6130     // The child has a different directionality.  If the child is parallel, then it's just
   6131     // flipped relative to us.  We can use the collapsed margin for the opposite edge.
   6132     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
   6133         return child->collapsedMarginBefore();
   6134 
   6135     // The child is perpendicular to us, which means its margins don't collapse but are on the
   6136     // "logical left/right" side of the child box.  We can just return the raw margin in this case.
   6137     return marginAfterForChild(child);
   6138 }
   6139 
   6140 int RenderBlock::marginBeforeForChild(RenderBoxModelObject* child) const
   6141 {
   6142     switch (style()->writingMode()) {
   6143     case TopToBottomWritingMode:
   6144         return child->marginTop();
   6145     case BottomToTopWritingMode:
   6146         return child->marginBottom();
   6147     case LeftToRightWritingMode:
   6148         return child->marginLeft();
   6149     case RightToLeftWritingMode:
   6150         return child->marginRight();
   6151     }
   6152     ASSERT_NOT_REACHED();
   6153     return child->marginTop();
   6154 }
   6155 
   6156 int RenderBlock::marginAfterForChild(RenderBoxModelObject* child) const
   6157 {
   6158     switch (style()->writingMode()) {
   6159     case TopToBottomWritingMode:
   6160         return child->marginBottom();
   6161     case BottomToTopWritingMode:
   6162         return child->marginTop();
   6163     case LeftToRightWritingMode:
   6164         return child->marginRight();
   6165     case RightToLeftWritingMode:
   6166         return child->marginLeft();
   6167     }
   6168     ASSERT_NOT_REACHED();
   6169     return child->marginBottom();
   6170 }
   6171 
   6172 int RenderBlock::marginStartForChild(RenderBoxModelObject* child) const
   6173 {
   6174     if (isHorizontalWritingMode())
   6175         return style()->isLeftToRightDirection() ? child->marginLeft() : child->marginRight();
   6176     return style()->isLeftToRightDirection() ? child->marginTop() : child->marginBottom();
   6177 }
   6178 
   6179 int RenderBlock::marginEndForChild(RenderBoxModelObject* child) const
   6180 {
   6181     if (isHorizontalWritingMode())
   6182         return style()->isLeftToRightDirection() ? child->marginRight() : child->marginLeft();
   6183     return style()->isLeftToRightDirection() ? child->marginBottom() : child->marginTop();
   6184 }
   6185 
   6186 void RenderBlock::setMarginStartForChild(RenderBox* child, int margin)
   6187 {
   6188     if (isHorizontalWritingMode()) {
   6189         if (style()->isLeftToRightDirection())
   6190             child->setMarginLeft(margin);
   6191         else
   6192             child->setMarginRight(margin);
   6193     } else {
   6194         if (style()->isLeftToRightDirection())
   6195             child->setMarginTop(margin);
   6196         else
   6197             child->setMarginBottom(margin);
   6198     }
   6199 }
   6200 
   6201 void RenderBlock::setMarginEndForChild(RenderBox* child, int margin)
   6202 {
   6203     if (isHorizontalWritingMode()) {
   6204         if (style()->isLeftToRightDirection())
   6205             child->setMarginRight(margin);
   6206         else
   6207             child->setMarginLeft(margin);
   6208     } else {
   6209         if (style()->isLeftToRightDirection())
   6210             child->setMarginBottom(margin);
   6211         else
   6212             child->setMarginTop(margin);
   6213     }
   6214 }
   6215 
   6216 void RenderBlock::setMarginBeforeForChild(RenderBox* child, int margin)
   6217 {
   6218     switch (style()->writingMode()) {
   6219     case TopToBottomWritingMode:
   6220         child->setMarginTop(margin);
   6221         break;
   6222     case BottomToTopWritingMode:
   6223         child->setMarginBottom(margin);
   6224         break;
   6225     case LeftToRightWritingMode:
   6226         child->setMarginLeft(margin);
   6227         break;
   6228     case RightToLeftWritingMode:
   6229         child->setMarginRight(margin);
   6230         break;
   6231     }
   6232 }
   6233 
   6234 void RenderBlock::setMarginAfterForChild(RenderBox* child, int margin)
   6235 {
   6236     switch (style()->writingMode()) {
   6237     case TopToBottomWritingMode:
   6238         child->setMarginBottom(margin);
   6239         break;
   6240     case BottomToTopWritingMode:
   6241         child->setMarginTop(margin);
   6242         break;
   6243     case LeftToRightWritingMode:
   6244         child->setMarginRight(margin);
   6245         break;
   6246     case RightToLeftWritingMode:
   6247         child->setMarginLeft(margin);
   6248         break;
   6249     }
   6250 }
   6251 
   6252 RenderBlock::MarginValues RenderBlock::marginValuesForChild(RenderBox* child)
   6253 {
   6254     int childBeforePositive = 0;
   6255     int childBeforeNegative = 0;
   6256     int childAfterPositive = 0;
   6257     int childAfterNegative = 0;
   6258 
   6259     int beforeMargin = 0;
   6260     int afterMargin = 0;
   6261 
   6262     RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0;
   6263 
   6264     // If the child has the same directionality as we do, then we can just return its
   6265     // margins in the same direction.
   6266     if (!child->isWritingModeRoot()) {
   6267         if (childRenderBlock) {
   6268             childBeforePositive = childRenderBlock->maxPositiveMarginBefore();
   6269             childBeforeNegative = childRenderBlock->maxNegativeMarginBefore();
   6270             childAfterPositive = childRenderBlock->maxPositiveMarginAfter();
   6271             childAfterNegative = childRenderBlock->maxNegativeMarginAfter();
   6272         } else {
   6273             beforeMargin = child->marginBefore();
   6274             afterMargin = child->marginAfter();
   6275         }
   6276     } else if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) {
   6277         // The child has a different directionality.  If the child is parallel, then it's just
   6278         // flipped relative to us.  We can use the margins for the opposite edges.
   6279         if (childRenderBlock) {
   6280             childBeforePositive = childRenderBlock->maxPositiveMarginAfter();
   6281             childBeforeNegative = childRenderBlock->maxNegativeMarginAfter();
   6282             childAfterPositive = childRenderBlock->maxPositiveMarginBefore();
   6283             childAfterNegative = childRenderBlock->maxNegativeMarginBefore();
   6284         } else {
   6285             beforeMargin = child->marginAfter();
   6286             afterMargin = child->marginBefore();
   6287         }
   6288     } else {
   6289         // The child is perpendicular to us, which means its margins don't collapse but are on the
   6290         // "logical left/right" sides of the child box.  We can just return the raw margin in this case.
   6291         beforeMargin = marginBeforeForChild(child);
   6292         afterMargin = marginAfterForChild(child);
   6293     }
   6294 
   6295     // Resolve uncollapsing margins into their positive/negative buckets.
   6296     if (beforeMargin) {
   6297         if (beforeMargin > 0)
   6298             childBeforePositive = beforeMargin;
   6299         else
   6300             childBeforeNegative = -beforeMargin;
   6301     }
   6302     if (afterMargin) {
   6303         if (afterMargin > 0)
   6304             childAfterPositive = afterMargin;
   6305         else
   6306             childAfterNegative = -afterMargin;
   6307     }
   6308 
   6309     return MarginValues(childBeforePositive, childBeforeNegative, childAfterPositive, childAfterNegative);
   6310 }
   6311 
   6312 const char* RenderBlock::renderName() const
   6313 {
   6314     if (isBody())
   6315         return "RenderBody"; // FIXME: Temporary hack until we know that the regression tests pass.
   6316 
   6317     if (isFloating())
   6318         return "RenderBlock (floating)";
   6319     if (isPositioned())
   6320         return "RenderBlock (positioned)";
   6321     if (isAnonymousColumnsBlock())
   6322         return "RenderBlock (anonymous multi-column)";
   6323     if (isAnonymousColumnSpanBlock())
   6324         return "RenderBlock (anonymous multi-column span)";
   6325     if (isAnonymousBlock())
   6326         return "RenderBlock (anonymous)";
   6327     else if (isAnonymous())
   6328         return "RenderBlock (generated)";
   6329     if (isRelPositioned())
   6330         return "RenderBlock (relative positioned)";
   6331     if (isRunIn())
   6332         return "RenderBlock (run-in)";
   6333     return "RenderBlock";
   6334 }
   6335 
   6336 inline void RenderBlock::FloatingObjects::clear()
   6337 {
   6338     m_set.clear();
   6339     m_leftObjectsCount = 0;
   6340     m_rightObjectsCount = 0;
   6341 }
   6342 
   6343 inline void RenderBlock::FloatingObjects::increaseObjectsCount(FloatingObject::Type type)
   6344 {
   6345     if (type == FloatingObject::FloatLeft)
   6346         m_leftObjectsCount++;
   6347     else
   6348         m_rightObjectsCount++;
   6349 }
   6350 
   6351 inline void RenderBlock::FloatingObjects::decreaseObjectsCount(FloatingObject::Type type)
   6352 {
   6353     if (type == FloatingObject::FloatLeft)
   6354         m_leftObjectsCount--;
   6355     else
   6356         m_rightObjectsCount--;
   6357 }
   6358 
   6359 } // namespace WebCore
   6360