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