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, 2011 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 "core/rendering/RenderBlock.h"
     26 
     27 #include "HTMLNames.h"
     28 #include "core/accessibility/AXObjectCache.h"
     29 #include "core/dom/Document.h"
     30 #include "core/dom/Element.h"
     31 #include "core/dom/OverflowEvent.h"
     32 #include "core/dom/shadow/ShadowRoot.h"
     33 #include "core/editing/Editor.h"
     34 #include "core/editing/FrameSelection.h"
     35 #include "core/page/Frame.h"
     36 #include "core/page/FrameView.h"
     37 #include "core/page/Page.h"
     38 #include "core/page/Settings.h"
     39 #include "core/platform/PODFreeListArena.h"
     40 #include "core/platform/graphics/FloatQuad.h"
     41 #include "core/platform/graphics/GraphicsContextStateSaver.h"
     42 #include "core/platform/graphics/transforms/TransformState.h"
     43 #include "core/rendering/ColumnInfo.h"
     44 #include "core/rendering/HitTestLocation.h"
     45 #include "core/rendering/HitTestResult.h"
     46 #include "core/rendering/InlineIterator.h"
     47 #include "core/rendering/InlineTextBox.h"
     48 #include "core/rendering/LayoutRepainter.h"
     49 #include "core/rendering/PaintInfo.h"
     50 #include "core/rendering/RenderCombineText.h"
     51 #include "core/rendering/RenderDeprecatedFlexibleBox.h"
     52 #include "core/rendering/RenderFlexibleBox.h"
     53 #include "core/rendering/RenderInline.h"
     54 #include "core/rendering/RenderLayer.h"
     55 #include "core/rendering/RenderMarquee.h"
     56 #include "core/rendering/RenderNamedFlowThread.h"
     57 #include "core/rendering/RenderRegion.h"
     58 #include "core/rendering/RenderTableCell.h"
     59 #include "core/rendering/RenderTextFragment.h"
     60 #include "core/rendering/RenderTheme.h"
     61 #include "core/rendering/RenderView.h"
     62 #include "core/rendering/shapes/ShapeInsideInfo.h"
     63 #include "core/rendering/shapes/ShapeOutsideInfo.h"
     64 #include "core/rendering/svg/SVGTextRunRenderingContext.h"
     65 #include "wtf/StdLibExtras.h"
     66 #include "wtf/TemporaryChange.h"
     67 
     68 using namespace std;
     69 using namespace WTF;
     70 using namespace Unicode;
     71 
     72 namespace WebCore {
     73 
     74 using namespace HTMLNames;
     75 
     76 struct SameSizeAsRenderBlock : public RenderBox {
     77     void* pointers[2];
     78     RenderObjectChildList children;
     79     RenderLineBoxList lineBoxes;
     80     uint32_t bitfields;
     81 };
     82 
     83 COMPILE_ASSERT(sizeof(RenderBlock) == sizeof(SameSizeAsRenderBlock), RenderBlock_should_stay_small);
     84 
     85 struct SameSizeAsFloatingObject {
     86     void* pointers[2];
     87     LayoutRect rect;
     88     int paginationStrut;
     89     uint32_t bitfields : 8;
     90 };
     91 
     92 COMPILE_ASSERT(sizeof(RenderBlock::MarginValues) == sizeof(LayoutUnit[4]), MarginValues_should_stay_small);
     93 
     94 struct SameSizeAsMarginInfo {
     95     uint32_t bitfields : 16;
     96     LayoutUnit margins[2];
     97 };
     98 
     99 typedef WTF::HashMap<const RenderBox*, OwnPtr<ColumnInfo> > ColumnInfoMap;
    100 static ColumnInfoMap* gColumnInfoMap = 0;
    101 
    102 static TrackedDescendantsMap* gPositionedDescendantsMap = 0;
    103 static TrackedDescendantsMap* gPercentHeightDescendantsMap = 0;
    104 
    105 static TrackedContainerMap* gPositionedContainerMap = 0;
    106 static TrackedContainerMap* gPercentHeightContainerMap = 0;
    107 
    108 typedef WTF::HashMap<RenderBlock*, OwnPtr<ListHashSet<RenderInline*> > > ContinuationOutlineTableMap;
    109 
    110 typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet;
    111 static int gDelayUpdateScrollInfo = 0;
    112 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0;
    113 
    114 static bool gColumnFlowSplitEnabled = true;
    115 
    116 bool RenderBlock::s_canPropagateFloatIntoSibling = false;
    117 
    118 // This class helps dispatching the 'overflow' event on layout change. overflow can be set on RenderBoxes, yet the existing code
    119 // only works on RenderBlocks. If this change, this class should be shared with other RenderBoxes.
    120 class OverflowEventDispatcher {
    121     WTF_MAKE_NONCOPYABLE(OverflowEventDispatcher);
    122 public:
    123     OverflowEventDispatcher(const RenderBlock* block)
    124         : m_block(block)
    125         , m_hadHorizontalLayoutOverflow(false)
    126         , m_hadVerticalLayoutOverflow(false)
    127     {
    128         m_shouldDispatchEvent = !m_block->isAnonymous() && m_block->hasOverflowClip() && m_block->document()->hasListenerType(Document::OVERFLOWCHANGED_LISTENER);
    129         if (m_shouldDispatchEvent) {
    130             m_hadHorizontalLayoutOverflow = m_block->hasHorizontalLayoutOverflow();
    131             m_hadVerticalLayoutOverflow = m_block->hasVerticalLayoutOverflow();
    132         }
    133     }
    134 
    135     ~OverflowEventDispatcher()
    136     {
    137         if (!m_shouldDispatchEvent)
    138             return;
    139 
    140         bool hasHorizontalLayoutOverflow = m_block->hasHorizontalLayoutOverflow();
    141         bool hasVerticalLayoutOverflow = m_block->hasVerticalLayoutOverflow();
    142 
    143         bool horizontalLayoutOverflowChanged = hasHorizontalLayoutOverflow != m_hadHorizontalLayoutOverflow;
    144         bool verticalLayoutOverflowChanged = hasVerticalLayoutOverflow != m_hadVerticalLayoutOverflow;
    145         if (horizontalLayoutOverflowChanged || verticalLayoutOverflowChanged) {
    146             if (FrameView* frameView = m_block->document()->view())
    147                 frameView->scheduleEvent(OverflowEvent::create(horizontalLayoutOverflowChanged, hasHorizontalLayoutOverflow, verticalLayoutOverflowChanged, hasVerticalLayoutOverflow), m_block->node());
    148         }
    149     }
    150 
    151 private:
    152     const RenderBlock* m_block;
    153     bool m_shouldDispatchEvent;
    154     bool m_hadHorizontalLayoutOverflow;
    155     bool m_hadVerticalLayoutOverflow;
    156 };
    157 
    158 // Our MarginInfo state used when laying out block children.
    159 RenderBlock::MarginInfo::MarginInfo(RenderBlock* block, LayoutUnit beforeBorderPadding, LayoutUnit afterBorderPadding)
    160     : m_atBeforeSideOfBlock(true)
    161     , m_atAfterSideOfBlock(false)
    162     , m_hasMarginBeforeQuirk(false)
    163     , m_hasMarginAfterQuirk(false)
    164     , m_determinedMarginBeforeQuirk(false)
    165     , m_discardMargin(false)
    166 {
    167     RenderStyle* blockStyle = block->style();
    168     ASSERT(block->isRenderView() || block->parent());
    169     m_canCollapseWithChildren = !block->isRenderView() && !block->isRoot() && !block->isOutOfFlowPositioned()
    170         && !block->isFloating() && !block->isTableCell() && !block->hasOverflowClip() && !block->isInlineBlockOrInlineTable()
    171         && !block->isRenderFlowThread() && !block->isWritingModeRoot() && !block->parent()->isFlexibleBox()
    172         && blockStyle->hasAutoColumnCount() && blockStyle->hasAutoColumnWidth() && !blockStyle->columnSpan();
    173 
    174     m_canCollapseMarginBeforeWithChildren = m_canCollapseWithChildren && !beforeBorderPadding && blockStyle->marginBeforeCollapse() != MSEPARATE;
    175 
    176     // If any height other than auto is specified in CSS, then we don't collapse our bottom
    177     // margins with our children's margins.  To do otherwise would be to risk odd visual
    178     // effects when the children overflow out of the parent block and yet still collapse
    179     // with it.  We also don't collapse if we have any bottom border/padding.
    180     m_canCollapseMarginAfterWithChildren = m_canCollapseWithChildren && (afterBorderPadding == 0) &&
    181         (blockStyle->logicalHeight().isAuto() && !blockStyle->logicalHeight().value()) && blockStyle->marginAfterCollapse() != MSEPARATE;
    182 
    183     m_quirkContainer = block->isTableCell() || block->isBody();
    184 
    185     m_discardMargin = m_canCollapseMarginBeforeWithChildren && block->mustDiscardMarginBefore();
    186 
    187     m_positiveMargin = (m_canCollapseMarginBeforeWithChildren && !block->mustDiscardMarginBefore()) ? block->maxPositiveMarginBefore() : LayoutUnit();
    188     m_negativeMargin = (m_canCollapseMarginBeforeWithChildren && !block->mustDiscardMarginBefore()) ? block->maxNegativeMarginBefore() : LayoutUnit();
    189 }
    190 
    191 // -------------------------------------------------------------------------------------------------------
    192 
    193 RenderBlock::RenderBlock(ContainerNode* node)
    194     : RenderBox(node)
    195     , m_lineHeight(-1)
    196     , m_hasMarginBeforeQuirk(false)
    197     , m_hasMarginAfterQuirk(false)
    198     , m_beingDestroyed(false)
    199     , m_hasMarkupTruncation(false)
    200     , m_hasBorderOrPaddingLogicalWidthChanged(false)
    201 {
    202     setChildrenInline(true);
    203     COMPILE_ASSERT(sizeof(RenderBlock::FloatingObject) == sizeof(SameSizeAsFloatingObject), FloatingObject_should_stay_small);
    204     COMPILE_ASSERT(sizeof(RenderBlock::MarginInfo) == sizeof(SameSizeAsMarginInfo), MarginInfo_should_stay_small);
    205 }
    206 
    207 static void removeBlockFromDescendantAndContainerMaps(RenderBlock* block, TrackedDescendantsMap*& descendantMap, TrackedContainerMap*& containerMap)
    208 {
    209     if (OwnPtr<TrackedRendererListHashSet> descendantSet = descendantMap->take(block)) {
    210         TrackedRendererListHashSet::iterator end = descendantSet->end();
    211         for (TrackedRendererListHashSet::iterator descendant = descendantSet->begin(); descendant != end; ++descendant) {
    212             TrackedContainerMap::iterator it = containerMap->find(*descendant);
    213             ASSERT(it != containerMap->end());
    214             if (it == containerMap->end())
    215                 continue;
    216             HashSet<RenderBlock*>* containerSet = it->value.get();
    217             ASSERT(containerSet->contains(block));
    218             containerSet->remove(block);
    219             if (containerSet->isEmpty())
    220                 containerMap->remove(it);
    221         }
    222     }
    223 }
    224 
    225 RenderBlock::~RenderBlock()
    226 {
    227     if (m_floatingObjects)
    228         deleteAllValues(m_floatingObjects->set());
    229 
    230     if (hasColumns())
    231         gColumnInfoMap->take(this);
    232 
    233     if (gPercentHeightDescendantsMap)
    234         removeBlockFromDescendantAndContainerMaps(this, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
    235     if (gPositionedDescendantsMap)
    236         removeBlockFromDescendantAndContainerMaps(this, gPositionedDescendantsMap, gPositionedContainerMap);
    237 }
    238 
    239 RenderBlock* RenderBlock::createAnonymous(Document* document)
    240 {
    241     RenderBlock* renderer = new RenderBlock(0);
    242     renderer->setDocumentForAnonymous(document);
    243     return renderer;
    244 }
    245 
    246 void RenderBlock::willBeDestroyed()
    247 {
    248     // Mark as being destroyed to avoid trouble with merges in removeChild().
    249     m_beingDestroyed = true;
    250 
    251     // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
    252     // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
    253     children()->destroyLeftoverChildren();
    254 
    255     // Destroy our continuation before anything other than anonymous children.
    256     // The reason we don't destroy it before anonymous children is that they may
    257     // have continuations of their own that are anonymous children of our continuation.
    258     RenderBoxModelObject* continuation = this->continuation();
    259     if (continuation) {
    260         continuation->destroy();
    261         setContinuation(0);
    262     }
    263 
    264     if (!documentBeingDestroyed()) {
    265         if (firstLineBox()) {
    266             // We can't wait for RenderBox::destroy to clear the selection,
    267             // because by then we will have nuked the line boxes.
    268             // FIXME: The FrameSelection should be responsible for this when it
    269             // is notified of DOM mutations.
    270             if (isSelectionBorder())
    271                 view()->clearSelection();
    272 
    273             // If we are an anonymous block, then our line boxes might have children
    274             // that will outlast this block. In the non-anonymous block case those
    275             // children will be destroyed by the time we return from this function.
    276             if (isAnonymousBlock()) {
    277                 for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox()) {
    278                     while (InlineBox* childBox = box->firstChild())
    279                         childBox->remove();
    280                 }
    281             }
    282         } else if (parent())
    283             parent()->dirtyLinesFromChangedChild(this);
    284     }
    285 
    286     m_lineBoxes.deleteLineBoxes();
    287 
    288     if (lineGridBox())
    289         lineGridBox()->destroy();
    290 
    291     if (UNLIKELY(gDelayedUpdateScrollInfoSet != 0))
    292         gDelayedUpdateScrollInfoSet->remove(this);
    293 
    294     RenderBox::willBeDestroyed();
    295 }
    296 
    297 void RenderBlock::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
    298 {
    299     RenderStyle* oldStyle = style();
    300     s_canPropagateFloatIntoSibling = oldStyle ? !isFloatingOrOutOfFlowPositioned() && !avoidsFloats() : false;
    301 
    302     setReplaced(newStyle->isDisplayInlineType());
    303 
    304     if (oldStyle && parent() && diff == StyleDifferenceLayout && oldStyle->position() != newStyle->position()) {
    305         if (newStyle->position() == StaticPosition)
    306             // Clear our positioned objects list. Our absolutely positioned descendants will be
    307             // inserted into our containing block's positioned objects list during layout.
    308             removePositionedObjects(0, NewContainingBlock);
    309         else if (oldStyle->position() == StaticPosition) {
    310             // Remove our absolutely positioned descendants from their current containing block.
    311             // They will be inserted into our positioned objects list during layout.
    312             RenderObject* cb = parent();
    313             while (cb && (cb->style()->position() == StaticPosition || (cb->isInline() && !cb->isReplaced())) && !cb->isRenderView()) {
    314                 if (cb->style()->position() == RelativePosition && cb->isInline() && !cb->isReplaced()) {
    315                     cb = cb->containingBlock();
    316                     break;
    317                 }
    318                 cb = cb->parent();
    319             }
    320 
    321             if (cb->isRenderBlock())
    322                 toRenderBlock(cb)->removePositionedObjects(this, NewContainingBlock);
    323         }
    324 
    325         if (containsFloats() && !isFloating() && !isOutOfFlowPositioned() && newStyle->hasOutOfFlowPosition())
    326             markAllDescendantsWithFloatsForLayout();
    327     }
    328 
    329     RenderBox::styleWillChange(diff, newStyle);
    330 }
    331 
    332 static bool borderOrPaddingLogicalWidthChanged(const RenderStyle* oldStyle, const RenderStyle* newStyle)
    333 {
    334     if (newStyle->isHorizontalWritingMode())
    335         return oldStyle->borderLeftWidth() != newStyle->borderLeftWidth()
    336             || oldStyle->borderRightWidth() != newStyle->borderRightWidth()
    337             || oldStyle->paddingLeft() != newStyle->paddingLeft()
    338             || oldStyle->paddingRight() != newStyle->paddingRight();
    339 
    340     return oldStyle->borderTopWidth() != newStyle->borderTopWidth()
    341         || oldStyle->borderBottomWidth() != newStyle->borderBottomWidth()
    342         || oldStyle->paddingTop() != newStyle->paddingTop()
    343         || oldStyle->paddingBottom() != newStyle->paddingBottom();
    344 }
    345 
    346 void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
    347 {
    348     RenderBox::styleDidChange(diff, oldStyle);
    349 
    350     RenderStyle* newStyle = style();
    351 
    352     updateShapeInsideInfoAfterStyleChange(newStyle->resolvedShapeInside(), oldStyle ? oldStyle->resolvedShapeInside() : 0);
    353 
    354     if (!isAnonymousBlock()) {
    355         // Ensure that all of our continuation blocks pick up the new style.
    356         for (RenderBlock* currCont = blockElementContinuation(); currCont; currCont = currCont->blockElementContinuation()) {
    357             RenderBoxModelObject* nextCont = currCont->continuation();
    358             currCont->setContinuation(0);
    359             currCont->setStyle(newStyle);
    360             currCont->setContinuation(nextCont);
    361         }
    362     }
    363 
    364     propagateStyleToAnonymousChildren(true);
    365     m_lineHeight = -1;
    366 
    367     // After our style changed, if we lose our ability to propagate floats into next sibling
    368     // blocks, then we need to find the top most parent containing that overhanging float and
    369     // then mark its descendants with floats for layout and clear all floats from its next
    370     // sibling blocks that exist in our floating objects list. See bug 56299 and 62875.
    371     bool canPropagateFloatIntoSibling = !isFloatingOrOutOfFlowPositioned() && !avoidsFloats();
    372     if (diff == StyleDifferenceLayout && s_canPropagateFloatIntoSibling && !canPropagateFloatIntoSibling && hasOverhangingFloats()) {
    373         RenderBlock* parentBlock = this;
    374         const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
    375         FloatingObjectSetIterator end = floatingObjectSet.end();
    376 
    377         for (RenderObject* curr = parent(); curr && !curr->isRenderView(); curr = curr->parent()) {
    378             if (curr->isRenderBlock()) {
    379                 RenderBlock* currBlock = toRenderBlock(curr);
    380 
    381                 if (currBlock->hasOverhangingFloats()) {
    382                     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
    383                         RenderBox* renderer = (*it)->renderer();
    384                         if (currBlock->hasOverhangingFloat(renderer)) {
    385                             parentBlock = currBlock;
    386                             break;
    387                         }
    388                     }
    389                 }
    390             }
    391         }
    392 
    393         parentBlock->markAllDescendantsWithFloatsForLayout();
    394         parentBlock->markSiblingsWithFloatsForLayout();
    395     }
    396 
    397     // It's possible for our border/padding to change, but for the overall logical width of the block to
    398     // end up being the same. We keep track of this change so in layoutBlock, we can know to set relayoutChildren=true.
    399     m_hasBorderOrPaddingLogicalWidthChanged = oldStyle && diff == StyleDifferenceLayout && needsLayout() && borderOrPaddingLogicalWidthChanged(oldStyle, newStyle);
    400 }
    401 
    402 RenderBlock* RenderBlock::continuationBefore(RenderObject* beforeChild)
    403 {
    404     if (beforeChild && beforeChild->parent() == this)
    405         return this;
    406 
    407     RenderBlock* curr = toRenderBlock(continuation());
    408     RenderBlock* nextToLast = this;
    409     RenderBlock* last = this;
    410     while (curr) {
    411         if (beforeChild && beforeChild->parent() == curr) {
    412             if (curr->firstChild() == beforeChild)
    413                 return last;
    414             return curr;
    415         }
    416 
    417         nextToLast = last;
    418         last = curr;
    419         curr = toRenderBlock(curr->continuation());
    420     }
    421 
    422     if (!beforeChild && !last->firstChild())
    423         return nextToLast;
    424     return last;
    425 }
    426 
    427 void RenderBlock::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild)
    428 {
    429     RenderBlock* flow = continuationBefore(beforeChild);
    430     ASSERT(!beforeChild || beforeChild->parent()->isAnonymousColumnSpanBlock() || beforeChild->parent()->isRenderBlock());
    431     RenderBoxModelObject* beforeChildParent = 0;
    432     if (beforeChild)
    433         beforeChildParent = toRenderBoxModelObject(beforeChild->parent());
    434     else {
    435         RenderBoxModelObject* cont = flow->continuation();
    436         if (cont)
    437             beforeChildParent = cont;
    438         else
    439             beforeChildParent = flow;
    440     }
    441 
    442     if (newChild->isFloatingOrOutOfFlowPositioned()) {
    443         beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
    444         return;
    445     }
    446 
    447     // A continuation always consists of two potential candidates: a block or an anonymous
    448     // column span box holding column span children.
    449     bool childIsNormal = newChild->isInline() || !newChild->style()->columnSpan();
    450     bool bcpIsNormal = beforeChildParent->isInline() || !beforeChildParent->style()->columnSpan();
    451     bool flowIsNormal = flow->isInline() || !flow->style()->columnSpan();
    452 
    453     if (flow == beforeChildParent) {
    454         flow->addChildIgnoringContinuation(newChild, beforeChild);
    455         return;
    456     }
    457 
    458     // The goal here is to match up if we can, so that we can coalesce and create the
    459     // minimal # of continuations needed for the inline.
    460     if (childIsNormal == bcpIsNormal) {
    461         beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
    462         return;
    463     }
    464     if (flowIsNormal == childIsNormal) {
    465         flow->addChildIgnoringContinuation(newChild, 0); // Just treat like an append.
    466         return;
    467     }
    468     beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
    469 }
    470 
    471 
    472 void RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
    473 {
    474     ASSERT(!continuation()); // We don't yet support column spans that aren't immediate children of the multi-column block.
    475 
    476     // The goal is to locate a suitable box in which to place our child.
    477     RenderBlock* beforeChildParent = 0;
    478     if (beforeChild) {
    479         RenderObject* curr = beforeChild;
    480         while (curr && curr->parent() != this)
    481             curr = curr->parent();
    482         beforeChildParent = toRenderBlock(curr);
    483         ASSERT(beforeChildParent);
    484         ASSERT(beforeChildParent->isAnonymousColumnsBlock() || beforeChildParent->isAnonymousColumnSpanBlock());
    485     } else
    486         beforeChildParent = toRenderBlock(lastChild());
    487 
    488     // If the new child is floating or positioned it can just go in that block.
    489     if (newChild->isFloatingOrOutOfFlowPositioned()) {
    490         beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
    491         return;
    492     }
    493 
    494     // See if the child can be placed in the box.
    495     bool newChildHasColumnSpan = newChild->style()->columnSpan() && !newChild->isInline();
    496     bool beforeChildParentHoldsColumnSpans = beforeChildParent->isAnonymousColumnSpanBlock();
    497 
    498     if (newChildHasColumnSpan == beforeChildParentHoldsColumnSpans) {
    499         beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
    500         return;
    501     }
    502 
    503     if (!beforeChild) {
    504         // Create a new block of the correct type.
    505         RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
    506         children()->appendChildNode(this, newBox);
    507         newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
    508         return;
    509     }
    510 
    511     RenderObject* immediateChild = beforeChild;
    512     bool isPreviousBlockViable = true;
    513     while (immediateChild->parent() != this) {
    514         if (isPreviousBlockViable)
    515             isPreviousBlockViable = !immediateChild->previousSibling();
    516         immediateChild = immediateChild->parent();
    517     }
    518     if (isPreviousBlockViable && immediateChild->previousSibling()) {
    519         toRenderBlock(immediateChild->previousSibling())->addChildIgnoringAnonymousColumnBlocks(newChild, 0); // Treat like an append.
    520         return;
    521     }
    522 
    523     // Split our anonymous blocks.
    524     RenderObject* newBeforeChild = splitAnonymousBoxesAroundChild(beforeChild);
    525 
    526 
    527     // Create a new anonymous box of the appropriate type.
    528     RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
    529     children()->insertChildNode(this, newBox, newBeforeChild);
    530     newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
    531     return;
    532 }
    533 
    534 RenderBlock* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBlock)
    535 {
    536     RenderBlock* firstChildIgnoringAnonymousWrappers = 0;
    537     for (RenderObject* curr = this; curr; curr = curr->parent()) {
    538         if (!curr->isRenderBlock() || curr->isFloatingOrOutOfFlowPositioned() || curr->isTableCell() || curr->isRoot() || curr->isRenderView() || curr->hasOverflowClip()
    539             || curr->isInlineBlockOrInlineTable())
    540             return 0;
    541 
    542         // FIXME: Tables, RenderButtons, and RenderListItems all do special management
    543         // of their children that breaks when the flow is split through them. Disabling
    544         // multi-column for them to avoid this problem.
    545         if (curr->isTable() || curr->isRenderButton() || curr->isListItem())
    546             return 0;
    547 
    548         RenderBlock* currBlock = toRenderBlock(curr);
    549         if (!currBlock->createsAnonymousWrapper())
    550             firstChildIgnoringAnonymousWrappers = currBlock;
    551 
    552         if (currBlock->style()->specifiesColumns() && (allowAnonymousColumnBlock || !currBlock->isAnonymousColumnsBlock()))
    553             return firstChildIgnoringAnonymousWrappers;
    554 
    555         if (currBlock->isAnonymousColumnSpanBlock())
    556             return 0;
    557     }
    558     return 0;
    559 }
    560 
    561 RenderBlock* RenderBlock::clone() const
    562 {
    563     RenderBlock* cloneBlock;
    564     if (isAnonymousBlock()) {
    565         cloneBlock = createAnonymousBlock();
    566         cloneBlock->setChildrenInline(childrenInline());
    567     }
    568     else {
    569         RenderObject* cloneRenderer = toElement(node())->createRenderer(style());
    570         cloneBlock = toRenderBlock(cloneRenderer);
    571         cloneBlock->setStyle(style());
    572 
    573         // This takes care of setting the right value of childrenInline in case
    574         // generated content is added to cloneBlock and 'this' does not have
    575         // generated content added yet.
    576         cloneBlock->setChildrenInline(cloneBlock->firstChild() ? cloneBlock->firstChild()->isInline() : childrenInline());
    577     }
    578     cloneBlock->setFlowThreadState(flowThreadState());
    579     return cloneBlock;
    580 }
    581 
    582 void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
    583                               RenderBlock* middleBlock,
    584                               RenderObject* beforeChild, RenderBoxModelObject* oldCont)
    585 {
    586     // Create a clone of this inline.
    587     RenderBlock* cloneBlock = clone();
    588     if (!isAnonymousBlock())
    589         cloneBlock->setContinuation(oldCont);
    590 
    591     if (!beforeChild && isAfterContent(lastChild()))
    592         beforeChild = lastChild();
    593 
    594     // If we are moving inline children from |this| to cloneBlock, then we need
    595     // to clear our line box tree.
    596     if (beforeChild && childrenInline())
    597         deleteLineBoxTree();
    598 
    599     // Now take all of the children from beforeChild to the end and remove
    600     // them from |this| and place them in the clone.
    601     moveChildrenTo(cloneBlock, beforeChild, 0, true);
    602 
    603     // Hook |clone| up as the continuation of the middle block.
    604     if (!cloneBlock->isAnonymousBlock())
    605         middleBlock->setContinuation(cloneBlock);
    606 
    607     // We have been reparented and are now under the fromBlock.  We need
    608     // to walk up our block parent chain until we hit the containing anonymous columns block.
    609     // Once we hit the anonymous columns block we're done.
    610     RenderBoxModelObject* curr = toRenderBoxModelObject(parent());
    611     RenderBoxModelObject* currChild = this;
    612     RenderObject* currChildNextSibling = currChild->nextSibling();
    613 
    614     while (curr && curr->isDescendantOf(fromBlock) && curr != fromBlock) {
    615         ASSERT_WITH_SECURITY_IMPLICATION(curr->isRenderBlock());
    616 
    617         RenderBlock* blockCurr = toRenderBlock(curr);
    618 
    619         // Create a new clone.
    620         RenderBlock* cloneChild = cloneBlock;
    621         cloneBlock = blockCurr->clone();
    622 
    623         // Insert our child clone as the first child.
    624         cloneBlock->addChildIgnoringContinuation(cloneChild, 0);
    625 
    626         // Hook the clone up as a continuation of |curr|.  Note we do encounter
    627         // anonymous blocks possibly as we walk up the block chain.  When we split an
    628         // anonymous block, there's no need to do any continuation hookup, since we haven't
    629         // actually split a real element.
    630         if (!blockCurr->isAnonymousBlock()) {
    631             oldCont = blockCurr->continuation();
    632             blockCurr->setContinuation(cloneBlock);
    633             cloneBlock->setContinuation(oldCont);
    634         }
    635 
    636         // Now we need to take all of the children starting from the first child
    637         // *after* currChild and append them all to the clone.
    638         blockCurr->moveChildrenTo(cloneBlock, currChildNextSibling, 0, true);
    639 
    640         // Keep walking up the chain.
    641         currChild = curr;
    642         currChildNextSibling = currChild->nextSibling();
    643         curr = toRenderBoxModelObject(curr->parent());
    644     }
    645 
    646     // Now we are at the columns block level. We need to put the clone into the toBlock.
    647     toBlock->children()->appendChildNode(toBlock, cloneBlock);
    648 
    649     // Now take all the children after currChild and remove them from the fromBlock
    650     // and put them in the toBlock.
    651     fromBlock->moveChildrenTo(toBlock, currChildNextSibling, 0, true);
    652 }
    653 
    654 void RenderBlock::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
    655                             RenderObject* newChild, RenderBoxModelObject* oldCont)
    656 {
    657     RenderBlock* pre = 0;
    658     RenderBlock* block = containingColumnsBlock();
    659 
    660     // Delete our line boxes before we do the inline split into continuations.
    661     block->deleteLineBoxTree();
    662 
    663     bool madeNewBeforeBlock = false;
    664     if (block->isAnonymousColumnsBlock()) {
    665         // We can reuse this block and make it the preBlock of the next continuation.
    666         pre = block;
    667         pre->removePositionedObjects(0);
    668         pre->removeFloatingObjects();
    669         block = toRenderBlock(block->parent());
    670     } else {
    671         // No anonymous block available for use.  Make one.
    672         pre = block->createAnonymousColumnsBlock();
    673         pre->setChildrenInline(false);
    674         madeNewBeforeBlock = true;
    675     }
    676 
    677     RenderBlock* post = block->createAnonymousColumnsBlock();
    678     post->setChildrenInline(false);
    679 
    680     RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
    681     if (madeNewBeforeBlock)
    682         block->children()->insertChildNode(block, pre, boxFirst);
    683     block->children()->insertChildNode(block, newBlockBox, boxFirst);
    684     block->children()->insertChildNode(block, post, boxFirst);
    685     block->setChildrenInline(false);
    686 
    687     if (madeNewBeforeBlock)
    688         block->moveChildrenTo(pre, boxFirst, 0, true);
    689 
    690     splitBlocks(pre, post, newBlockBox, beforeChild, oldCont);
    691 
    692     // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
    693     // time in makeChildrenNonInline by just setting this explicitly up front.
    694     newBlockBox->setChildrenInline(false);
    695 
    696     newBlockBox->addChild(newChild);
    697 
    698     // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
    699     // get deleted properly.  Because objects moves from the pre block into the post block, we want to
    700     // make new line boxes instead of leaving the old line boxes around.
    701     pre->setNeedsLayoutAndPrefWidthsRecalc();
    702     block->setNeedsLayoutAndPrefWidthsRecalc();
    703     post->setNeedsLayoutAndPrefWidthsRecalc();
    704 }
    705 
    706 void RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlock* newBlockBox, RenderObject* newChild)
    707 {
    708     RenderBlock* pre = 0;
    709     RenderBlock* post = 0;
    710     RenderBlock* block = this; // Eventually block will not just be |this|, but will also be a block nested inside |this|.  Assign to a variable
    711                                // so that we don't have to patch all of the rest of the code later on.
    712 
    713     // Delete the block's line boxes before we do the split.
    714     block->deleteLineBoxTree();
    715 
    716     if (beforeChild && beforeChild->parent() != this)
    717         beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
    718 
    719     if (beforeChild != firstChild()) {
    720         pre = block->createAnonymousColumnsBlock();
    721         pre->setChildrenInline(block->childrenInline());
    722     }
    723 
    724     if (beforeChild) {
    725         post = block->createAnonymousColumnsBlock();
    726         post->setChildrenInline(block->childrenInline());
    727     }
    728 
    729     RenderObject* boxFirst = block->firstChild();
    730     if (pre)
    731         block->children()->insertChildNode(block, pre, boxFirst);
    732     block->children()->insertChildNode(block, newBlockBox, boxFirst);
    733     if (post)
    734         block->children()->insertChildNode(block, post, boxFirst);
    735     block->setChildrenInline(false);
    736 
    737     // 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).
    738     block->moveChildrenTo(pre, boxFirst, beforeChild, true);
    739     block->moveChildrenTo(post, beforeChild, 0, true);
    740 
    741     // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
    742     // time in makeChildrenNonInline by just setting this explicitly up front.
    743     newBlockBox->setChildrenInline(false);
    744 
    745     newBlockBox->addChild(newChild);
    746 
    747     // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
    748     // get deleted properly.  Because objects moved from the pre block into the post block, we want to
    749     // make new line boxes instead of leaving the old line boxes around.
    750     if (pre)
    751         pre->setNeedsLayoutAndPrefWidthsRecalc();
    752     block->setNeedsLayoutAndPrefWidthsRecalc();
    753     if (post)
    754         post->setNeedsLayoutAndPrefWidthsRecalc();
    755 }
    756 
    757 RenderBlock* RenderBlock::columnsBlockForSpanningElement(RenderObject* newChild)
    758 {
    759     // FIXME: This function is the gateway for the addition of column-span support.  It will
    760     // be added to in three stages:
    761     // (1) Immediate children of a multi-column block can span.
    762     // (2) Nested block-level children with only block-level ancestors between them and the multi-column block can span.
    763     // (3) Nested children with block or inline ancestors between them and the multi-column block can span (this is when we
    764     // cross the streams and have to cope with both types of continuations mixed together).
    765     // This function currently supports (1) and (2).
    766     RenderBlock* columnsBlockAncestor = 0;
    767     if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isBeforeOrAfterContent()
    768         && !newChild->isFloatingOrOutOfFlowPositioned() && !newChild->isInline() && !isAnonymousColumnSpanBlock()) {
    769         columnsBlockAncestor = containingColumnsBlock(false);
    770         if (columnsBlockAncestor) {
    771             // Make sure that none of the parent ancestors have a continuation.
    772             // If yes, we do not want split the block into continuations.
    773             RenderObject* curr = this;
    774             while (curr && curr != columnsBlockAncestor) {
    775                 if (curr->isRenderBlock() && toRenderBlock(curr)->continuation()) {
    776                     columnsBlockAncestor = 0;
    777                     break;
    778                 }
    779                 curr = curr->parent();
    780             }
    781         }
    782     }
    783     return columnsBlockAncestor;
    784 }
    785 
    786 void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
    787 {
    788     if (beforeChild && beforeChild->parent() != this) {
    789         RenderObject* beforeChildContainer = beforeChild->parent();
    790         while (beforeChildContainer->parent() != this)
    791             beforeChildContainer = beforeChildContainer->parent();
    792         ASSERT(beforeChildContainer);
    793 
    794         if (beforeChildContainer->isAnonymous()) {
    795             // If the requested beforeChild is not one of our children, then this is because
    796             // there is an anonymous container within this object that contains the beforeChild.
    797             RenderObject* beforeChildAnonymousContainer = beforeChildContainer;
    798             if (beforeChildAnonymousContainer->isAnonymousBlock()
    799                 // Full screen renderers and full screen placeholders act as anonymous blocks, not tables:
    800                 || beforeChildAnonymousContainer->isRenderFullScreen()
    801                 || beforeChildAnonymousContainer->isRenderFullScreenPlaceholder()
    802                 ) {
    803                 // Insert the child into the anonymous block box instead of here.
    804                 if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)
    805                     beforeChild->parent()->addChild(newChild, beforeChild);
    806                 else
    807                     addChild(newChild, beforeChild->parent());
    808                 return;
    809             }
    810 
    811             ASSERT(beforeChildAnonymousContainer->isTable());
    812             if (newChild->isTablePart()) {
    813                 // Insert into the anonymous table.
    814                 beforeChildAnonymousContainer->addChild(newChild, beforeChild);
    815                 return;
    816             }
    817 
    818             beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
    819 
    820             ASSERT(beforeChild->parent() == this);
    821             if (beforeChild->parent() != this) {
    822                 // We should never reach here. If we do, we need to use the
    823                 // safe fallback to use the topmost beforeChild container.
    824                 beforeChild = beforeChildContainer;
    825             }
    826         } else {
    827             // We will reach here when beforeChild is a run-in element.
    828             // If run-in element precedes a block-level element, it becomes the
    829             // the first inline child of that block level element. The insertion
    830             // point will be before that block-level element.
    831             ASSERT(beforeChild->isRunIn());
    832             beforeChild = beforeChildContainer;
    833         }
    834     }
    835 
    836     // Nothing goes before the intruded run-in.
    837     if (beforeChild && beforeChild->isRunIn() && runInIsPlacedIntoSiblingBlock(beforeChild))
    838         beforeChild = beforeChild->nextSibling();
    839 
    840     // Check for a spanning element in columns.
    841     if (gColumnFlowSplitEnabled) {
    842         RenderBlock* columnsBlockAncestor = columnsBlockForSpanningElement(newChild);
    843         if (columnsBlockAncestor) {
    844             TemporaryChange<bool> columnFlowSplitEnabled(gColumnFlowSplitEnabled, false);
    845             // We are placing a column-span element inside a block.
    846             RenderBlock* newBox = createAnonymousColumnSpanBlock();
    847 
    848             if (columnsBlockAncestor != this && !isRenderFlowThread()) {
    849                 // We are nested inside a multi-column element and are being split by the span. We have to break up
    850                 // our block into continuations.
    851                 RenderBoxModelObject* oldContinuation = continuation();
    852 
    853                 // When we split an anonymous block, there's no need to do any continuation hookup,
    854                 // since we haven't actually split a real element.
    855                 if (!isAnonymousBlock())
    856                     setContinuation(newBox);
    857 
    858                 splitFlow(beforeChild, newBox, newChild, oldContinuation);
    859                 return;
    860             }
    861 
    862             // We have to perform a split of this block's children. This involves creating an anonymous block box to hold
    863             // the column-spanning |newChild|. We take all of the children from before |newChild| and put them into
    864             // one anonymous columns block, and all of the children after |newChild| go into another anonymous block.
    865             makeChildrenAnonymousColumnBlocks(beforeChild, newBox, newChild);
    866             return;
    867         }
    868     }
    869 
    870     bool madeBoxesNonInline = false;
    871 
    872     // A block has to either have all of its children inline, or all of its children as blocks.
    873     // So, if our children are currently inline and a block child has to be inserted, we move all our
    874     // inline children into anonymous block boxes.
    875     if (childrenInline() && !newChild->isInline() && !newChild->isFloatingOrOutOfFlowPositioned()) {
    876         // This is a block with inline content. Wrap the inline content in anonymous blocks.
    877         makeChildrenNonInline(beforeChild);
    878         madeBoxesNonInline = true;
    879 
    880         if (beforeChild && beforeChild->parent() != this) {
    881             beforeChild = beforeChild->parent();
    882             ASSERT(beforeChild->isAnonymousBlock());
    883             ASSERT(beforeChild->parent() == this);
    884         }
    885     } else if (!childrenInline() && (newChild->isFloatingOrOutOfFlowPositioned() || newChild->isInline())) {
    886         // If we're inserting an inline child but all of our children are blocks, then we have to make sure
    887         // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise
    888         // a new one is created and inserted into our list of children in the appropriate position.
    889         RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();
    890 
    891         if (afterChild && afterChild->isAnonymousBlock()) {
    892             afterChild->addChild(newChild);
    893             return;
    894         }
    895 
    896         if (newChild->isInline()) {
    897             // No suitable existing anonymous box - create a new one.
    898             RenderBlock* newBox = createAnonymousBlock();
    899             RenderBox::addChild(newBox, beforeChild);
    900             newBox->addChild(newChild);
    901             return;
    902         }
    903     }
    904 
    905     RenderBox::addChild(newChild, beforeChild);
    906 
    907     // Handle placement of run-ins.
    908     placeRunInIfNeeded(newChild);
    909 
    910     if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRenderBlock())
    911         toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
    912     // this object may be dead here
    913 }
    914 
    915 void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
    916 {
    917     if (continuation() && !isAnonymousBlock())
    918         addChildToContinuation(newChild, beforeChild);
    919     else
    920         addChildIgnoringContinuation(newChild, beforeChild);
    921 }
    922 
    923 void RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild)
    924 {
    925     if (!isAnonymousBlock() && firstChild() && (firstChild()->isAnonymousColumnsBlock() || firstChild()->isAnonymousColumnSpanBlock()))
    926         addChildToAnonymousColumnBlocks(newChild, beforeChild);
    927     else
    928         addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
    929 }
    930 
    931 static void getInlineRun(RenderObject* start, RenderObject* boundary,
    932                          RenderObject*& inlineRunStart,
    933                          RenderObject*& inlineRunEnd)
    934 {
    935     // Beginning at |start| we find the largest contiguous run of inlines that
    936     // we can.  We denote the run with start and end points, |inlineRunStart|
    937     // and |inlineRunEnd|.  Note that these two values may be the same if
    938     // we encounter only one inline.
    939     //
    940     // We skip any non-inlines we encounter as long as we haven't found any
    941     // inlines yet.
    942     //
    943     // |boundary| indicates a non-inclusive boundary point.  Regardless of whether |boundary|
    944     // is inline or not, we will not include it in a run with inlines before it.  It's as though we encountered
    945     // a non-inline.
    946 
    947     // Start by skipping as many non-inlines as we can.
    948     RenderObject * curr = start;
    949     bool sawInline;
    950     do {
    951         while (curr && !(curr->isInline() || curr->isFloatingOrOutOfFlowPositioned()))
    952             curr = curr->nextSibling();
    953 
    954         inlineRunStart = inlineRunEnd = curr;
    955 
    956         if (!curr)
    957             return; // No more inline children to be found.
    958 
    959         sawInline = curr->isInline();
    960 
    961         curr = curr->nextSibling();
    962         while (curr && (curr->isInline() || curr->isFloatingOrOutOfFlowPositioned()) && (curr != boundary)) {
    963             inlineRunEnd = curr;
    964             if (curr->isInline())
    965                 sawInline = true;
    966             curr = curr->nextSibling();
    967         }
    968     } while (!sawInline);
    969 }
    970 
    971 void RenderBlock::deleteLineBoxTree()
    972 {
    973     if (containsFloats()) {
    974         // Clear references to originating lines, since the lines are being deleted
    975         const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
    976         FloatingObjectSetIterator end = floatingObjectSet.end();
    977         for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
    978             ASSERT(!((*it)->m_originatingLine) || (*it)->m_originatingLine->renderer() == this);
    979             (*it)->m_originatingLine = 0;
    980         }
    981     }
    982     m_lineBoxes.deleteLineBoxTree();
    983 
    984     if (AXObjectCache* cache = document()->existingAXObjectCache())
    985         cache->recomputeIsIgnored(this);
    986 }
    987 
    988 RootInlineBox* RenderBlock::createRootInlineBox()
    989 {
    990     return new RootInlineBox(this);
    991 }
    992 
    993 RootInlineBox* RenderBlock::createAndAppendRootInlineBox()
    994 {
    995     RootInlineBox* rootBox = createRootInlineBox();
    996     m_lineBoxes.appendLineBox(rootBox);
    997 
    998     if (UNLIKELY(AXObjectCache::accessibilityEnabled()) && m_lineBoxes.firstLineBox() == rootBox) {
    999         if (AXObjectCache* cache = document()->existingAXObjectCache())
   1000             cache->recomputeIsIgnored(this);
   1001     }
   1002 
   1003     return rootBox;
   1004 }
   1005 
   1006 void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
   1007 {
   1008     // makeChildrenNonInline takes a block whose children are *all* inline and it
   1009     // makes sure that inline children are coalesced under anonymous
   1010     // blocks.  If |insertionPoint| is defined, then it represents the insertion point for
   1011     // the new block child that is causing us to have to wrap all the inlines.  This
   1012     // means that we cannot coalesce inlines before |insertionPoint| with inlines following
   1013     // |insertionPoint|, because the new child is going to be inserted in between the inlines,
   1014     // splitting them.
   1015     ASSERT(isInlineBlockOrInlineTable() || !isInline());
   1016     ASSERT(!insertionPoint || insertionPoint->parent() == this);
   1017 
   1018     setChildrenInline(false);
   1019 
   1020     RenderObject *child = firstChild();
   1021     if (!child)
   1022         return;
   1023 
   1024     deleteLineBoxTree();
   1025 
   1026     // Since we are going to have block children, we have to move
   1027     // back the run-in to its original place.
   1028     if (child->isRunIn()) {
   1029         moveRunInToOriginalPosition(child);
   1030         child = firstChild();
   1031     }
   1032 
   1033     while (child) {
   1034         RenderObject *inlineRunStart, *inlineRunEnd;
   1035         getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);
   1036 
   1037         if (!inlineRunStart)
   1038             break;
   1039 
   1040         child = inlineRunEnd->nextSibling();
   1041 
   1042         RenderBlock* block = createAnonymousBlock();
   1043         children()->insertChildNode(this, block, inlineRunStart);
   1044         moveChildrenTo(block, inlineRunStart, child);
   1045     }
   1046 
   1047 #ifndef NDEBUG
   1048     for (RenderObject *c = firstChild(); c; c = c->nextSibling())
   1049         ASSERT(!c->isInline());
   1050 #endif
   1051 
   1052     repaint();
   1053 }
   1054 
   1055 void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
   1056 {
   1057     ASSERT(child->isAnonymousBlock());
   1058     ASSERT(!child->childrenInline());
   1059 
   1060     if (child->continuation() || (child->firstChild() && (child->isAnonymousColumnSpanBlock() || child->isAnonymousColumnsBlock())))
   1061         return;
   1062 
   1063     RenderObject* firstAnChild = child->m_children.firstChild();
   1064     RenderObject* lastAnChild = child->m_children.lastChild();
   1065     if (firstAnChild) {
   1066         RenderObject* o = firstAnChild;
   1067         while (o) {
   1068             o->setParent(this);
   1069             o = o->nextSibling();
   1070         }
   1071         firstAnChild->setPreviousSibling(child->previousSibling());
   1072         lastAnChild->setNextSibling(child->nextSibling());
   1073         if (child->previousSibling())
   1074             child->previousSibling()->setNextSibling(firstAnChild);
   1075         if (child->nextSibling())
   1076             child->nextSibling()->setPreviousSibling(lastAnChild);
   1077 
   1078         if (child == m_children.firstChild())
   1079             m_children.setFirstChild(firstAnChild);
   1080         if (child == m_children.lastChild())
   1081             m_children.setLastChild(lastAnChild);
   1082     } else {
   1083         if (child == m_children.firstChild())
   1084             m_children.setFirstChild(child->nextSibling());
   1085         if (child == m_children.lastChild())
   1086             m_children.setLastChild(child->previousSibling());
   1087 
   1088         if (child->previousSibling())
   1089             child->previousSibling()->setNextSibling(child->nextSibling());
   1090         if (child->nextSibling())
   1091             child->nextSibling()->setPreviousSibling(child->previousSibling());
   1092     }
   1093 
   1094     child->children()->setFirstChild(0);
   1095     child->m_next = 0;
   1096 
   1097     // Remove all the information in the flow thread associated with the leftover anonymous block.
   1098     child->removeFromRenderFlowThread();
   1099 
   1100     child->setParent(0);
   1101     child->setPreviousSibling(0);
   1102     child->setNextSibling(0);
   1103 
   1104     child->destroy();
   1105 }
   1106 
   1107 static bool canMergeContiguousAnonymousBlocks(RenderObject* oldChild, RenderObject* prev, RenderObject* next)
   1108 {
   1109     if (oldChild->documentBeingDestroyed() || oldChild->isInline() || oldChild->virtualContinuation())
   1110         return false;
   1111 
   1112     if ((prev && (!prev->isAnonymousBlock() || toRenderBlock(prev)->continuation() || toRenderBlock(prev)->beingDestroyed()))
   1113         || (next && (!next->isAnonymousBlock() || toRenderBlock(next)->continuation() || toRenderBlock(next)->beingDestroyed())))
   1114         return false;
   1115 
   1116     // FIXME: This check isn't required when inline run-ins can't be split into continuations.
   1117     if (prev && prev->firstChild() && prev->firstChild()->isInline() && prev->firstChild()->isRunIn())
   1118         return false;
   1119 
   1120     if ((prev && (prev->isRubyRun() || prev->isRubyBase()))
   1121         || (next && (next->isRubyRun() || next->isRubyBase())))
   1122         return false;
   1123 
   1124     if (!prev || !next)
   1125         return true;
   1126 
   1127     // Make sure the types of the anonymous blocks match up.
   1128     return prev->isAnonymousColumnsBlock() == next->isAnonymousColumnsBlock()
   1129            && prev->isAnonymousColumnSpanBlock() == next->isAnonymousColumnSpanBlock();
   1130 }
   1131 
   1132 void RenderBlock::collapseAnonymousBlockChild(RenderBlock* parent, RenderBlock* child)
   1133 {
   1134     // It's possible that this block's destruction may have been triggered by the
   1135     // child's removal. Just bail if the anonymous child block is already being
   1136     // destroyed. See crbug.com/282088
   1137     if (child->beingDestroyed())
   1138         return;
   1139     parent->setNeedsLayoutAndPrefWidthsRecalc();
   1140     parent->setChildrenInline(child->childrenInline());
   1141     RenderObject* nextSibling = child->nextSibling();
   1142 
   1143     RenderFlowThread* childFlowThread = child->flowThreadContainingBlock();
   1144     CurrentRenderFlowThreadMaintainer flowThreadMaintainer(childFlowThread);
   1145 
   1146     parent->children()->removeChildNode(parent, child, child->hasLayer());
   1147     child->moveAllChildrenTo(parent, nextSibling, child->hasLayer());
   1148     // Explicitly delete the child's line box tree, or the special anonymous
   1149     // block handling in willBeDestroyed will cause problems.
   1150     child->deleteLineBoxTree();
   1151     if (childFlowThread && childFlowThread->isRenderNamedFlowThread())
   1152         toRenderNamedFlowThread(childFlowThread)->removeFlowChildInfo(child);
   1153     child->destroy();
   1154 }
   1155 
   1156 void RenderBlock::moveAllChildrenIncludingFloatsTo(RenderBlock* toBlock, bool fullRemoveInsert)
   1157 {
   1158     moveAllChildrenTo(toBlock, fullRemoveInsert);
   1159 
   1160     // When a portion of the render tree is being detached, anonymous blocks
   1161     // will be combined as their children are deleted. In this process, the
   1162     // anonymous block later in the tree is merged into the one preceeding it.
   1163     // It can happen that the later block (this) contains floats that the
   1164     // previous block (toBlock) did not contain, and thus are not in the
   1165     // floating objects list for toBlock. This can result in toBlock containing
   1166     // floats that are not in it's floating objects list, but are in the
   1167     // floating objects lists of siblings and parents. This can cause problems
   1168     // when the float itself is deleted, since the deletion code assumes that
   1169     // if a float is not in it's containing block's floating objects list, it
   1170     // isn't in any floating objects list. In order to preserve this condition
   1171     // (removing it has serious performance implications), we need to copy the
   1172     // floating objects from the old block (this) to the new block (toBlock).
   1173     // The float's metrics will likely all be wrong, but since toBlock is
   1174     // already marked for layout, this will get fixed before anything gets
   1175     // displayed.
   1176     // See bug https://code.google.com/p/chromium/issues/detail?id=230907
   1177     if (m_floatingObjects) {
   1178         if (!toBlock->m_floatingObjects)
   1179             toBlock->createFloatingObjects();
   1180 
   1181         const FloatingObjectSet& fromFloatingObjectSet = m_floatingObjects->set();
   1182         FloatingObjectSetIterator end = fromFloatingObjectSet.end();
   1183 
   1184         for (FloatingObjectSetIterator it = fromFloatingObjectSet.begin(); it != end; ++it) {
   1185             FloatingObject* floatingObject = *it;
   1186 
   1187             // Don't insert the object again if it's already in the list
   1188             if (toBlock->containsFloat(floatingObject->renderer()))
   1189                 continue;
   1190 
   1191             toBlock->m_floatingObjects->add(floatingObject->clone());
   1192         }
   1193     }
   1194 
   1195 }
   1196 
   1197 void RenderBlock::removeChild(RenderObject* oldChild)
   1198 {
   1199     // No need to waste time in merging or removing empty anonymous blocks.
   1200     // We can just bail out if our document is getting destroyed.
   1201     if (documentBeingDestroyed()) {
   1202         RenderBox::removeChild(oldChild);
   1203         return;
   1204     }
   1205 
   1206     // This protects against column split flows when anonymous blocks are getting merged.
   1207     TemporaryChange<bool> columnFlowSplitEnabled(gColumnFlowSplitEnabled, false);
   1208 
   1209     // If this child is a block, and if our previous and next siblings are
   1210     // both anonymous blocks with inline content, then we can go ahead and
   1211     // fold the inline content back together.
   1212     RenderObject* prev = oldChild->previousSibling();
   1213     RenderObject* next = oldChild->nextSibling();
   1214     bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, prev, next);
   1215     if (canMergeAnonymousBlocks && prev && next) {
   1216         prev->setNeedsLayoutAndPrefWidthsRecalc();
   1217         RenderBlock* nextBlock = toRenderBlock(next);
   1218         RenderBlock* prevBlock = toRenderBlock(prev);
   1219 
   1220         if (prev->childrenInline() != next->childrenInline()) {
   1221             RenderBlock* inlineChildrenBlock = prev->childrenInline() ? prevBlock : nextBlock;
   1222             RenderBlock* blockChildrenBlock = prev->childrenInline() ? nextBlock : prevBlock;
   1223 
   1224             // Place the inline children block inside of the block children block instead of deleting it.
   1225             // In order to reuse it, we have to reset it to just be a generic anonymous block.  Make sure
   1226             // to clear out inherited column properties by just making a new style, and to also clear the
   1227             // column span flag if it is set.
   1228             ASSERT(!inlineChildrenBlock->continuation());
   1229             RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK);
   1230             // Cache this value as it might get changed in setStyle() call.
   1231             bool inlineChildrenBlockHasLayer = inlineChildrenBlock->hasLayer();
   1232             inlineChildrenBlock->setStyle(newStyle);
   1233             children()->removeChildNode(this, inlineChildrenBlock, inlineChildrenBlockHasLayer);
   1234 
   1235             // Now just put the inlineChildrenBlock inside the blockChildrenBlock.
   1236             blockChildrenBlock->children()->insertChildNode(blockChildrenBlock, inlineChildrenBlock, prev == inlineChildrenBlock ? blockChildrenBlock->firstChild() : 0,
   1237                                                             inlineChildrenBlockHasLayer || blockChildrenBlock->hasLayer());
   1238             next->setNeedsLayoutAndPrefWidthsRecalc();
   1239 
   1240             // inlineChildrenBlock got reparented to blockChildrenBlock, so it is no longer a child
   1241             // of "this". we null out prev or next so that is not used later in the function.
   1242             if (inlineChildrenBlock == prevBlock)
   1243                 prev = 0;
   1244             else
   1245                 next = 0;
   1246         } else {
   1247             // Take all the children out of the |next| block and put them in
   1248             // the |prev| block.
   1249             nextBlock->moveAllChildrenIncludingFloatsTo(prevBlock, nextBlock->hasLayer() || prevBlock->hasLayer());
   1250 
   1251             // Delete the now-empty block's lines and nuke it.
   1252             nextBlock->deleteLineBoxTree();
   1253             nextBlock->destroy();
   1254             next = 0;
   1255         }
   1256     }
   1257 
   1258     RenderBox::removeChild(oldChild);
   1259 
   1260     RenderObject* child = prev ? prev : next;
   1261     if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && canCollapseAnonymousBlockChild()) {
   1262         // The removal has knocked us down to containing only a single anonymous
   1263         // box.  We can go ahead and pull the content right back up into our
   1264         // box.
   1265         collapseAnonymousBlockChild(this, toRenderBlock(child));
   1266     } else if (((prev && prev->isAnonymousBlock()) || (next && next->isAnonymousBlock())) && canCollapseAnonymousBlockChild()) {
   1267         // It's possible that the removal has knocked us down to a single anonymous
   1268         // block with pseudo-style element siblings (e.g. first-letter). If these
   1269         // are floating, then we need to pull the content up also.
   1270         RenderBlock* anonymousBlock = toRenderBlock((prev && prev->isAnonymousBlock()) ? prev : next);
   1271         if ((anonymousBlock->previousSibling() || anonymousBlock->nextSibling())
   1272             && (!anonymousBlock->previousSibling() || (anonymousBlock->previousSibling()->style()->styleType() != NOPSEUDO && anonymousBlock->previousSibling()->isFloating() && !anonymousBlock->previousSibling()->previousSibling()))
   1273             && (!anonymousBlock->nextSibling() || (anonymousBlock->nextSibling()->style()->styleType() != NOPSEUDO && anonymousBlock->nextSibling()->isFloating() && !anonymousBlock->nextSibling()->nextSibling()))) {
   1274             collapseAnonymousBlockChild(this, anonymousBlock);
   1275         }
   1276     }
   1277 
   1278     if (!firstChild()) {
   1279         // If this was our last child be sure to clear out our line boxes.
   1280         if (childrenInline())
   1281             deleteLineBoxTree();
   1282 
   1283         // If we are an empty anonymous block in the continuation chain,
   1284         // we need to remove ourself and fix the continuation chain.
   1285         if (!beingDestroyed() && isAnonymousBlockContinuation() && !oldChild->isListMarker()) {
   1286             RenderObject* containingBlockIgnoringAnonymous = containingBlock();
   1287             while (containingBlockIgnoringAnonymous && containingBlockIgnoringAnonymous->isAnonymousBlock())
   1288                 containingBlockIgnoringAnonymous = containingBlockIgnoringAnonymous->containingBlock();
   1289             for (RenderObject* curr = this; curr; curr = curr->previousInPreOrder(containingBlockIgnoringAnonymous)) {
   1290                 if (curr->virtualContinuation() != this)
   1291                     continue;
   1292 
   1293                 // Found our previous continuation. We just need to point it to
   1294                 // |this|'s next continuation.
   1295                 RenderBoxModelObject* nextContinuation = continuation();
   1296                 if (curr->isRenderInline())
   1297                     toRenderInline(curr)->setContinuation(nextContinuation);
   1298                 else if (curr->isRenderBlock())
   1299                     toRenderBlock(curr)->setContinuation(nextContinuation);
   1300                 else
   1301                     ASSERT_NOT_REACHED();
   1302 
   1303                 break;
   1304             }
   1305             setContinuation(0);
   1306             destroy();
   1307         }
   1308     }
   1309 }
   1310 
   1311 bool RenderBlock::isSelfCollapsingBlock() const
   1312 {
   1313     // We are not self-collapsing if we
   1314     // (a) have a non-zero height according to layout (an optimization to avoid wasting time)
   1315     // (b) are a table,
   1316     // (c) have border/padding,
   1317     // (d) have a min-height
   1318     // (e) have specified that one of our margins can't collapse using a CSS extension
   1319     if (logicalHeight() > 0
   1320         || isTable() || borderAndPaddingLogicalHeight()
   1321         || style()->logicalMinHeight().isPositive()
   1322         || style()->marginBeforeCollapse() == MSEPARATE || style()->marginAfterCollapse() == MSEPARATE)
   1323         return false;
   1324 
   1325     Length logicalHeightLength = style()->logicalHeight();
   1326     bool hasAutoHeight = logicalHeightLength.isAuto();
   1327     if (logicalHeightLength.isPercent() && !document()->inQuirksMode()) {
   1328         hasAutoHeight = true;
   1329         for (RenderBlock* cb = containingBlock(); !cb->isRenderView(); cb = cb->containingBlock()) {
   1330             if (cb->style()->logicalHeight().isFixed() || cb->isTableCell())
   1331                 hasAutoHeight = false;
   1332         }
   1333     }
   1334 
   1335     // If the height is 0 or auto, then whether or not we are a self-collapsing block depends
   1336     // on whether we have content that is all self-collapsing or not.
   1337     if (hasAutoHeight || ((logicalHeightLength.isFixed() || logicalHeightLength.isPercent()) && logicalHeightLength.isZero())) {
   1338         // If the block has inline children, see if we generated any line boxes.  If we have any
   1339         // line boxes, then we can't be self-collapsing, since we have content.
   1340         if (childrenInline())
   1341             return !firstLineBox();
   1342 
   1343         // Whether or not we collapse is dependent on whether all our normal flow children
   1344         // are also self-collapsing.
   1345         for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
   1346             if (child->isFloatingOrOutOfFlowPositioned())
   1347                 continue;
   1348             if (!child->isSelfCollapsingBlock())
   1349                 return false;
   1350         }
   1351         return true;
   1352     }
   1353     return false;
   1354 }
   1355 
   1356 void RenderBlock::startDelayUpdateScrollInfo()
   1357 {
   1358     if (gDelayUpdateScrollInfo == 0) {
   1359         ASSERT(!gDelayedUpdateScrollInfoSet);
   1360         gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet;
   1361     }
   1362     ASSERT(gDelayedUpdateScrollInfoSet);
   1363     ++gDelayUpdateScrollInfo;
   1364 }
   1365 
   1366 void RenderBlock::finishDelayUpdateScrollInfo()
   1367 {
   1368     --gDelayUpdateScrollInfo;
   1369     ASSERT(gDelayUpdateScrollInfo >= 0);
   1370     if (gDelayUpdateScrollInfo == 0) {
   1371         ASSERT(gDelayedUpdateScrollInfoSet);
   1372 
   1373         OwnPtr<DelayedUpdateScrollInfoSet> infoSet(adoptPtr(gDelayedUpdateScrollInfoSet));
   1374         gDelayedUpdateScrollInfoSet = 0;
   1375 
   1376         for (DelayedUpdateScrollInfoSet::iterator it = infoSet->begin(); it != infoSet->end(); ++it) {
   1377             RenderBlock* block = *it;
   1378             if (block->hasOverflowClip()) {
   1379                 block->layer()->updateScrollInfoAfterLayout();
   1380             }
   1381         }
   1382     }
   1383 }
   1384 
   1385 void RenderBlock::updateScrollInfoAfterLayout()
   1386 {
   1387     if (hasOverflowClip()) {
   1388         if (style()->isFlippedBlocksWritingMode()) {
   1389             // FIXME: https://bugs.webkit.org/show_bug.cgi?id=97937
   1390             // Workaround for now. We cannot delay the scroll info for overflow
   1391             // for items with opposite writing directions, as the contents needs
   1392             // to overflow in that direction
   1393             layer()->updateScrollInfoAfterLayout();
   1394             return;
   1395         }
   1396 
   1397         if (gDelayUpdateScrollInfo)
   1398             gDelayedUpdateScrollInfoSet->add(this);
   1399         else
   1400             layer()->updateScrollInfoAfterLayout();
   1401     }
   1402 }
   1403 
   1404 void RenderBlock::layout()
   1405 {
   1406     StackStats::LayoutCheckPoint layoutCheckPoint;
   1407     OverflowEventDispatcher dispatcher(this);
   1408 
   1409     // Update our first letter info now.
   1410     updateFirstLetter();
   1411 
   1412     // Table cells call layoutBlock directly, so don't add any logic here.  Put code into
   1413     // layoutBlock().
   1414     layoutBlock(false);
   1415 
   1416     // It's safe to check for control clip here, since controls can never be table cells.
   1417     // If we have a lightweight clip, there can never be any overflow from children.
   1418     if (hasControlClip() && m_overflow)
   1419         clearLayoutOverflow();
   1420 
   1421     invalidateBackgroundObscurationStatus();
   1422 }
   1423 
   1424 void RenderBlock::updateShapeInsideInfoAfterStyleChange(const ShapeValue* shapeInside, const ShapeValue* oldShapeInside)
   1425 {
   1426     // FIXME: A future optimization would do a deep comparison for equality.
   1427     if (shapeInside == oldShapeInside)
   1428         return;
   1429 
   1430     if (shapeInside) {
   1431         ShapeInsideInfo* shapeInsideInfo = ensureShapeInsideInfo();
   1432         shapeInsideInfo->dirtyShapeSize();
   1433     } else {
   1434         setShapeInsideInfo(nullptr);
   1435         markShapeInsideDescendantsForLayout();
   1436     }
   1437 }
   1438 
   1439 static inline bool shapeInfoRequiresRelayout(const RenderBlock* block)
   1440 {
   1441     ShapeInsideInfo* info = block->shapeInsideInfo();
   1442     if (info)
   1443         info->setNeedsLayout(info->shapeSizeDirty());
   1444     else
   1445         info = block->layoutShapeInsideInfo();
   1446     return info && info->needsLayout();
   1447 }
   1448 
   1449 bool RenderBlock::updateRegionsAndShapesLogicalSize(RenderFlowThread* flowThread)
   1450 {
   1451     if (!flowThread && !shapeInsideInfo())
   1452         return shapeInfoRequiresRelayout(this);
   1453 
   1454     LayoutUnit oldHeight = logicalHeight();
   1455     LayoutUnit oldTop = logicalTop();
   1456 
   1457     // Compute the maximum logical height content may cause this block to expand to
   1458     // FIXME: These should eventually use the const computeLogicalHeight rather than updateLogicalHeight
   1459     setLogicalHeight(LayoutUnit::max() / 2);
   1460     updateLogicalHeight();
   1461 
   1462     computeShapeSize();
   1463 
   1464     // Set our start and end regions. No regions above or below us will be considered by our children. They are
   1465     // effectively clamped to our region range.
   1466     computeRegionRangeForBlock(flowThread);
   1467 
   1468     setLogicalHeight(oldHeight);
   1469     setLogicalTop(oldTop);
   1470 
   1471     return shapeInfoRequiresRelayout(this);
   1472 }
   1473 
   1474 void RenderBlock::computeShapeSize()
   1475 {
   1476     ShapeInsideInfo* shapeInsideInfo = this->shapeInsideInfo();
   1477     if (shapeInsideInfo) {
   1478         bool percentageLogicalHeightResolvable = percentageLogicalHeightIsResolvableFromBlock(this, false);
   1479         shapeInsideInfo->setShapeSize(logicalWidth(), percentageLogicalHeightResolvable ? logicalHeight() : LayoutUnit());
   1480     }
   1481 }
   1482 
   1483 void RenderBlock::updateRegionsAndShapesAfterChildLayout(RenderFlowThread* flowThread, bool heightChanged)
   1484 {
   1485     // A previous sibling has changed dimension, so we need to relayout the shape with the content
   1486     ShapeInsideInfo* shapeInsideInfo = layoutShapeInsideInfo();
   1487     if (heightChanged && shapeInsideInfo)
   1488         shapeInsideInfo->dirtyShapeSize();
   1489 
   1490     computeRegionRangeForBlock(flowThread);
   1491 }
   1492 
   1493 void RenderBlock::computeRegionRangeForBlock(RenderFlowThread* flowThread)
   1494 {
   1495     if (flowThread)
   1496         flowThread->setRegionRangeForBox(this, offsetFromLogicalTopOfFirstPage());
   1497 }
   1498 
   1499 bool RenderBlock::updateLogicalWidthAndColumnWidth()
   1500 {
   1501     LayoutUnit oldWidth = logicalWidth();
   1502     LayoutUnit oldColumnWidth = desiredColumnWidth();
   1503 
   1504     updateLogicalWidth();
   1505     calcColumnWidth();
   1506 
   1507     bool hasBorderOrPaddingLogicalWidthChanged = m_hasBorderOrPaddingLogicalWidthChanged;
   1508     m_hasBorderOrPaddingLogicalWidthChanged = false;
   1509 
   1510     return oldWidth != logicalWidth() || oldColumnWidth != desiredColumnWidth() || hasBorderOrPaddingLogicalWidthChanged;
   1511 }
   1512 
   1513 void RenderBlock::checkForPaginationLogicalHeightChange(LayoutUnit& pageLogicalHeight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight)
   1514 {
   1515     ColumnInfo* colInfo = columnInfo();
   1516     if (hasColumns()) {
   1517         if (!pageLogicalHeight) {
   1518             // We need to go ahead and set our explicit page height if one exists, so that we can
   1519             // avoid doing two layout passes.
   1520             updateLogicalHeight();
   1521             LayoutUnit columnHeight = contentLogicalHeight();
   1522             if (columnHeight > 0) {
   1523                 pageLogicalHeight = columnHeight;
   1524                 hasSpecifiedPageLogicalHeight = true;
   1525             }
   1526             setLogicalHeight(0);
   1527         }
   1528         if (colInfo->columnHeight() != pageLogicalHeight && everHadLayout()) {
   1529             colInfo->setColumnHeight(pageLogicalHeight);
   1530             pageLogicalHeightChanged = true;
   1531         }
   1532 
   1533         if (!hasSpecifiedPageLogicalHeight && !pageLogicalHeight)
   1534             colInfo->clearForcedBreaks();
   1535 
   1536         colInfo->setPaginationUnit(paginationUnit());
   1537     } else if (isRenderFlowThread()) {
   1538         pageLogicalHeight = 1; // This is just a hack to always make sure we have a page logical height.
   1539         pageLogicalHeightChanged = toRenderFlowThread(this)->pageLogicalSizeChanged();
   1540     }
   1541 }
   1542 
   1543 void RenderBlock::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight)
   1544 {
   1545     ASSERT(needsLayout());
   1546 
   1547     if (isInline() && !isInlineBlockOrInlineTable()) // Inline <form>s inside various table elements can
   1548         return;                                      // cause us to come in here.  Just bail.
   1549 
   1550     if (!relayoutChildren && simplifiedLayout())
   1551         return;
   1552 
   1553     LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
   1554 
   1555     if (updateLogicalWidthAndColumnWidth())
   1556         relayoutChildren = true;
   1557 
   1558     clearFloats();
   1559 
   1560     LayoutUnit previousHeight = logicalHeight();
   1561     // FIXME: should this start out as borderAndPaddingLogicalHeight() + scrollbarLogicalHeight(),
   1562     // for consistency with other render classes?
   1563     setLogicalHeight(0);
   1564 
   1565     bool pageLogicalHeightChanged = false;
   1566     bool hasSpecifiedPageLogicalHeight = false;
   1567     checkForPaginationLogicalHeightChange(pageLogicalHeight, pageLogicalHeightChanged, hasSpecifiedPageLogicalHeight);
   1568 
   1569     RenderView* renderView = view();
   1570     RenderStyle* styleToUse = style();
   1571     LayoutStateMaintainer statePusher(renderView, this, locationOffset(), hasColumns() || hasTransform() || hasReflection() || styleToUse->isFlippedBlocksWritingMode(), pageLogicalHeight, pageLogicalHeightChanged, columnInfo());
   1572 
   1573     // Regions changing widths can force us to relayout our children.
   1574     RenderFlowThread* flowThread = flowThreadContainingBlock();
   1575     if (logicalWidthChangedInRegions(flowThread))
   1576         relayoutChildren = true;
   1577     if (updateRegionsAndShapesLogicalSize(flowThread))
   1578         relayoutChildren = true;
   1579 
   1580     // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track
   1581     // our current maximal positive and negative margins.  These values are used when we
   1582     // are collapsed with adjacent blocks, so for example, if you have block A and B
   1583     // collapsing together, then you'd take the maximal positive margin from both A and B
   1584     // and subtract it from the maximal negative margin from both A and B to get the
   1585     // true collapsed margin.  This algorithm is recursive, so when we finish layout()
   1586     // our block knows its current maximal positive/negative values.
   1587     //
   1588     // Start out by setting our margin values to our current margins.  Table cells have
   1589     // no margins, so we don't fill in the values for table cells.
   1590     bool isCell = isTableCell();
   1591     if (!isCell) {
   1592         initMaxMarginValues();
   1593 
   1594         setHasMarginBeforeQuirk(styleToUse->hasMarginBeforeQuirk());
   1595         setHasMarginAfterQuirk(styleToUse->hasMarginAfterQuirk());
   1596         setPaginationStrut(0);
   1597     }
   1598 
   1599     LayoutUnit repaintLogicalTop = 0;
   1600     LayoutUnit repaintLogicalBottom = 0;
   1601     LayoutUnit maxFloatLogicalBottom = 0;
   1602     if (!firstChild() && !isAnonymousBlock())
   1603         setChildrenInline(true);
   1604     if (childrenInline())
   1605         layoutInlineChildren(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
   1606     else
   1607         layoutBlockChildren(relayoutChildren, maxFloatLogicalBottom);
   1608 
   1609     // Expand our intrinsic height to encompass floats.
   1610     LayoutUnit toAdd = borderAfter() + paddingAfter() + scrollbarLogicalHeight();
   1611     if (lowestFloatLogicalBottom() > (logicalHeight() - toAdd) && expandsToEncloseOverhangingFloats())
   1612         setLogicalHeight(lowestFloatLogicalBottom() + toAdd);
   1613 
   1614     if (relayoutForPagination(hasSpecifiedPageLogicalHeight, pageLogicalHeight, statePusher))
   1615         return;
   1616 
   1617     // Calculate our new height.
   1618     LayoutUnit oldHeight = logicalHeight();
   1619     LayoutUnit oldClientAfterEdge = clientLogicalBottom();
   1620 
   1621     // Before updating the final size of the flow thread make sure a forced break is applied after the content.
   1622     // This ensures the size information is correctly computed for the last auto-height region receiving content.
   1623     if (isRenderFlowThread())
   1624         toRenderFlowThread(this)->applyBreakAfterContent(oldClientAfterEdge);
   1625 
   1626     updateLogicalHeight();
   1627     LayoutUnit newHeight = logicalHeight();
   1628     if (oldHeight != newHeight) {
   1629         if (oldHeight > newHeight && maxFloatLogicalBottom > newHeight && !childrenInline()) {
   1630             // One of our children's floats may have become an overhanging float for us. We need to look for it.
   1631             for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
   1632                 if (child->isBlockFlow() && !child->isFloatingOrOutOfFlowPositioned()) {
   1633                     RenderBlock* block = toRenderBlock(child);
   1634                     if (block->lowestFloatLogicalBottom() + block->logicalTop() > newHeight)
   1635                         addOverhangingFloats(block, false);
   1636                 }
   1637             }
   1638         }
   1639     }
   1640 
   1641     bool heightChanged = (previousHeight != newHeight);
   1642     if (heightChanged)
   1643         relayoutChildren = true;
   1644 
   1645     layoutPositionedObjects(relayoutChildren || isRoot());
   1646 
   1647     updateRegionsAndShapesAfterChildLayout(flowThread, heightChanged);
   1648 
   1649     // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway).
   1650     computeOverflow(oldClientAfterEdge);
   1651 
   1652     statePusher.pop();
   1653 
   1654     fitBorderToLinesIfNeeded();
   1655 
   1656     if (renderView->layoutState()->m_pageLogicalHeight)
   1657         setPageLogicalOffset(renderView->layoutState()->pageLogicalOffset(this, logicalTop()));
   1658 
   1659     updateLayerTransform();
   1660 
   1661     // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
   1662     // we overflow or not.
   1663     updateScrollInfoAfterLayout();
   1664 
   1665     // FIXME: This repaint logic should be moved into a separate helper function!
   1666     // Repaint with our new bounds if they are different from our old bounds.
   1667     bool didFullRepaint = repainter.repaintAfterLayout();
   1668     if (!didFullRepaint && repaintLogicalTop != repaintLogicalBottom && (styleToUse->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) {
   1669         // FIXME: We could tighten up the left and right invalidation points if we let layoutInlineChildren fill them in based off the particular lines
   1670         // it had to lay out.  We wouldn't need the hasOverflowClip() hack in that case either.
   1671         LayoutUnit repaintLogicalLeft = logicalLeftVisualOverflow();
   1672         LayoutUnit repaintLogicalRight = logicalRightVisualOverflow();
   1673         if (hasOverflowClip()) {
   1674             // 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.
   1675             // 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.
   1676             // layoutInlineChildren should be patched to compute the entire repaint rect.
   1677             repaintLogicalLeft = min(repaintLogicalLeft, logicalLeftLayoutOverflow());
   1678             repaintLogicalRight = max(repaintLogicalRight, logicalRightLayoutOverflow());
   1679         }
   1680 
   1681         LayoutRect repaintRect;
   1682         if (isHorizontalWritingMode())
   1683             repaintRect = LayoutRect(repaintLogicalLeft, repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop);
   1684         else
   1685             repaintRect = LayoutRect(repaintLogicalTop, repaintLogicalLeft, repaintLogicalBottom - repaintLogicalTop, repaintLogicalRight - repaintLogicalLeft);
   1686 
   1687         // The repaint rect may be split across columns, in which case adjustRectForColumns() will return the union.
   1688         adjustRectForColumns(repaintRect);
   1689 
   1690         repaintRect.inflate(maximalOutlineSize(PaintPhaseOutline));
   1691 
   1692         if (hasOverflowClip()) {
   1693             // Adjust repaint rect for scroll offset
   1694             repaintRect.move(-scrolledContentOffset());
   1695 
   1696             // Don't allow this rect to spill out of our overflow box.
   1697             repaintRect.intersect(LayoutRect(LayoutPoint(), size()));
   1698         }
   1699 
   1700         // Make sure the rect is still non-empty after intersecting for overflow above
   1701         if (!repaintRect.isEmpty()) {
   1702             repaintRectangle(repaintRect); // We need to do a partial repaint of our content.
   1703             if (hasReflection())
   1704                 repaintRectangle(reflectedRect(repaintRect));
   1705         }
   1706     }
   1707 
   1708     clearNeedsLayout();
   1709 }
   1710 
   1711 void RenderBlock::addOverflowFromChildren()
   1712 {
   1713     if (!hasColumns()) {
   1714         if (childrenInline())
   1715             addOverflowFromInlineChildren();
   1716         else
   1717             addOverflowFromBlockChildren();
   1718     } else {
   1719         ColumnInfo* colInfo = columnInfo();
   1720         if (columnCount(colInfo)) {
   1721             LayoutRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
   1722             addLayoutOverflow(lastRect);
   1723             addContentsVisualOverflow(lastRect);
   1724         }
   1725     }
   1726 }
   1727 
   1728 void RenderBlock::computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeFloats)
   1729 {
   1730     m_overflow.clear();
   1731 
   1732     // Add overflow from children.
   1733     addOverflowFromChildren();
   1734 
   1735     if (!hasColumns() && (recomputeFloats || isRoot() || expandsToEncloseOverhangingFloats() || hasSelfPaintingLayer()))
   1736         addOverflowFromFloats();
   1737 
   1738     // Add in the overflow from positioned objects.
   1739     addOverflowFromPositionedObjects();
   1740 
   1741     if (hasOverflowClip()) {
   1742         // When we have overflow clip, propagate the original spillout since it will include collapsed bottom margins
   1743         // and bottom padding.  Set the axis we don't care about to be 1, since we want this overflow to always
   1744         // be considered reachable.
   1745         LayoutRect clientRect(noOverflowRect());
   1746         LayoutRect rectToApply;
   1747         if (isHorizontalWritingMode())
   1748             rectToApply = LayoutRect(clientRect.x(), clientRect.y(), 1, max<LayoutUnit>(0, oldClientAfterEdge - clientRect.y()));
   1749         else
   1750             rectToApply = LayoutRect(clientRect.x(), clientRect.y(), max<LayoutUnit>(0, oldClientAfterEdge - clientRect.x()), 1);
   1751         addLayoutOverflow(rectToApply);
   1752         if (hasRenderOverflow())
   1753             m_overflow->setLayoutClientAfterEdge(oldClientAfterEdge);
   1754     }
   1755 
   1756     // Allow our overflow to catch cases where the caret in an empty editable element with negative text indent needs to get painted.
   1757     LayoutUnit textIndent = textIndentOffset();
   1758     if (textIndent < 0) {
   1759         LayoutRect clientRect(noOverflowRect());
   1760         LayoutRect rectToApply = LayoutRect(clientRect.x() + textIndent, clientRect.y(), clientRect.width() - textIndent, clientRect.height());
   1761         addContentsVisualOverflow(rectToApply);
   1762     }
   1763 
   1764     // Add visual overflow from box-shadow and border-image-outset.
   1765     addVisualEffectOverflow();
   1766 
   1767     // Add visual overflow from theme.
   1768     addVisualOverflowFromTheme();
   1769 
   1770     if (isRenderNamedFlowThread())
   1771         toRenderNamedFlowThread(this)->computeOversetStateForRegions(oldClientAfterEdge);
   1772 }
   1773 
   1774 void RenderBlock::addOverflowFromBlockChildren()
   1775 {
   1776     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
   1777         if (!child->isFloatingOrOutOfFlowPositioned())
   1778             addOverflowFromChild(child);
   1779     }
   1780 }
   1781 
   1782 void RenderBlock::addOverflowFromFloats()
   1783 {
   1784     if (!m_floatingObjects)
   1785         return;
   1786 
   1787     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   1788     FloatingObjectSetIterator end = floatingObjectSet.end();
   1789     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   1790         FloatingObject* r = *it;
   1791         if (r->isDescendant())
   1792             addOverflowFromChild(r->m_renderer, IntSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r)));
   1793     }
   1794 }
   1795 
   1796 void RenderBlock::addOverflowFromPositionedObjects()
   1797 {
   1798     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
   1799     if (!positionedDescendants)
   1800         return;
   1801 
   1802     RenderBox* positionedObject;
   1803     TrackedRendererListHashSet::iterator end = positionedDescendants->end();
   1804     for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
   1805         positionedObject = *it;
   1806 
   1807         // Fixed positioned elements don't contribute to layout overflow, since they don't scroll with the content.
   1808         if (positionedObject->style()->position() != FixedPosition) {
   1809             LayoutUnit x = positionedObject->x();
   1810             if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
   1811                 x -= verticalScrollbarWidth();
   1812             addOverflowFromChild(positionedObject, LayoutSize(x, positionedObject->y()));
   1813         }
   1814     }
   1815 }
   1816 
   1817 void RenderBlock::addVisualOverflowFromTheme()
   1818 {
   1819     if (!style()->hasAppearance())
   1820         return;
   1821 
   1822     IntRect inflatedRect = pixelSnappedBorderBoxRect();
   1823     theme()->adjustRepaintRect(this, inflatedRect);
   1824     addVisualOverflow(inflatedRect);
   1825 }
   1826 
   1827 bool RenderBlock::expandsToEncloseOverhangingFloats() const
   1828 {
   1829     return isInlineBlockOrInlineTable() || isFloatingOrOutOfFlowPositioned() || hasOverflowClip() || (parent() && parent()->isFlexibleBoxIncludingDeprecated())
   1830            || hasColumns() || isTableCell() || isTableCaption() || isFieldset() || isWritingModeRoot() || isRoot();
   1831 }
   1832 
   1833 void RenderBlock::adjustPositionedBlock(RenderBox* child, const MarginInfo& marginInfo)
   1834 {
   1835     bool isHorizontal = isHorizontalWritingMode();
   1836     bool hasStaticBlockPosition = child->style()->hasStaticBlockPosition(isHorizontal);
   1837 
   1838     LayoutUnit logicalTop = logicalHeight();
   1839     updateStaticInlinePositionForChild(child, logicalTop);
   1840 
   1841     if (!marginInfo.canCollapseWithMarginBefore()) {
   1842         // Positioned blocks don't collapse margins, so add the margin provided by
   1843         // the container now. The child's own margin is added later when calculating its logical top.
   1844         LayoutUnit collapsedBeforePos = marginInfo.positiveMargin();
   1845         LayoutUnit collapsedBeforeNeg = marginInfo.negativeMargin();
   1846         logicalTop += collapsedBeforePos - collapsedBeforeNeg;
   1847     }
   1848 
   1849     RenderLayer* childLayer = child->layer();
   1850     if (childLayer->staticBlockPosition() != logicalTop) {
   1851         childLayer->setStaticBlockPosition(logicalTop);
   1852         if (hasStaticBlockPosition)
   1853             child->setChildNeedsLayout(MarkOnlyThis);
   1854     }
   1855 }
   1856 
   1857 void RenderBlock::adjustFloatingBlock(const MarginInfo& marginInfo)
   1858 {
   1859     // The float should be positioned taking into account the bottom margin
   1860     // of the previous flow.  We add that margin into the height, get the
   1861     // float positioned properly, and then subtract the margin out of the
   1862     // height again.  In the case of self-collapsing blocks, we always just
   1863     // use the top margins, since the self-collapsing block collapsed its
   1864     // own bottom margin into its top margin.
   1865     //
   1866     // Note also that the previous flow may collapse its margin into the top of
   1867     // our block.  If this is the case, then we do not add the margin in to our
   1868     // height when computing the position of the float.   This condition can be tested
   1869     // for by simply calling canCollapseWithMarginBefore.  See
   1870     // http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html for
   1871     // an example of this scenario.
   1872     LayoutUnit marginOffset = marginInfo.canCollapseWithMarginBefore() ? LayoutUnit() : marginInfo.margin();
   1873     setLogicalHeight(logicalHeight() + marginOffset);
   1874     positionNewFloats();
   1875     setLogicalHeight(logicalHeight() - marginOffset);
   1876 }
   1877 
   1878 static void destroyRunIn(RenderBoxModelObject* runIn)
   1879 {
   1880     ASSERT(runIn->isRunIn());
   1881     ASSERT(!runIn->firstChild());
   1882 
   1883     // Delete our line box tree. This is needed as our children got moved
   1884     // and our line box tree is no longer valid.
   1885     if (runIn->isRenderBlock())
   1886         toRenderBlock(runIn)->deleteLineBoxTree();
   1887     else if (runIn->isRenderInline())
   1888         toRenderInline(runIn)->deleteLineBoxTree();
   1889     else
   1890         ASSERT_NOT_REACHED();
   1891 
   1892     runIn->destroy();
   1893 }
   1894 
   1895 void RenderBlock::placeRunInIfNeeded(RenderObject* newChild)
   1896 {
   1897     if (newChild->isRunIn())
   1898         moveRunInUnderSiblingBlockIfNeeded(newChild);
   1899     else if (RenderObject* prevSibling = newChild->previousSibling()) {
   1900         if (prevSibling->isRunIn())
   1901             moveRunInUnderSiblingBlockIfNeeded(prevSibling);
   1902     }
   1903 }
   1904 
   1905 RenderBoxModelObject* RenderBlock::createReplacementRunIn(RenderBoxModelObject* runIn)
   1906 {
   1907     ASSERT(runIn->isRunIn());
   1908     ASSERT(runIn->node());
   1909 
   1910     RenderBoxModelObject* newRunIn = 0;
   1911     if (!runIn->isRenderBlock())
   1912         newRunIn = new RenderBlock(runIn->node());
   1913     else
   1914         newRunIn = new RenderInline(toElement(runIn->node()));
   1915 
   1916     runIn->node()->setRenderer(newRunIn);
   1917     newRunIn->setStyle(runIn->style());
   1918 
   1919     runIn->moveAllChildrenTo(newRunIn, true);
   1920 
   1921     return newRunIn;
   1922 }
   1923 
   1924 void RenderBlock::moveRunInUnderSiblingBlockIfNeeded(RenderObject* runIn)
   1925 {
   1926     ASSERT(runIn->isRunIn());
   1927 
   1928     // See if we have inline children. If the children aren't inline,
   1929     // then just treat the run-in as a normal block.
   1930     if (!runIn->childrenInline())
   1931         return;
   1932 
   1933     // FIXME: We don't handle non-block elements with run-in for now.
   1934     if (!runIn->isRenderBlock())
   1935         return;
   1936 
   1937     // FIXME: We don't support run-ins with or as part of a continuation
   1938     // as it makes the back-and-forth placing complex.
   1939     if (runIn->isElementContinuation() || runIn->virtualContinuation())
   1940         return;
   1941 
   1942     // Check if this node is allowed to run-in. E.g. <select> expects its renderer to
   1943     // be a RenderListBox or RenderMenuList, and hence cannot be a RenderInline run-in.
   1944     if (!runIn->canBeReplacedWithInlineRunIn())
   1945         return;
   1946 
   1947     RenderObject* curr = runIn->nextSibling();
   1948     if (!curr || !curr->isRenderBlock() || !curr->childrenInline())
   1949         return;
   1950 
   1951     // Per CSS3, "A run-in cannot run in to a block that already starts with a
   1952     // run-in or that itself is a run-in".
   1953     if (curr->isRunIn() || (curr->firstChild() && curr->firstChild()->isRunIn()))
   1954         return;
   1955 
   1956     if (curr->isAnonymous() || curr->isFloatingOrOutOfFlowPositioned())
   1957         return;
   1958 
   1959     // FIXME: We don't support run-ins with or as part of a continuation
   1960     // as it makes the back-and-forth placing complex.
   1961     if (curr->isElementContinuation() || curr->virtualContinuation())
   1962         return;
   1963 
   1964     RenderBoxModelObject* oldRunIn = toRenderBoxModelObject(runIn);
   1965     RenderBoxModelObject* newRunIn = createReplacementRunIn(oldRunIn);
   1966     destroyRunIn(oldRunIn);
   1967 
   1968     // Now insert the new child under |curr| block. Use addChild instead of insertChildNode
   1969     // since it handles correct placement of the children, especially where we cannot insert
   1970     // anything before the first child. e.g. details tag. See https://bugs.webkit.org/show_bug.cgi?id=58228.
   1971     curr->addChild(newRunIn, curr->firstChild());
   1972 
   1973     // Make sure that |this| get a layout since its run-in child moved.
   1974     curr->setNeedsLayoutAndPrefWidthsRecalc();
   1975 }
   1976 
   1977 bool RenderBlock::runInIsPlacedIntoSiblingBlock(RenderObject* runIn)
   1978 {
   1979     ASSERT(runIn->isRunIn());
   1980 
   1981     // If we don't have a parent, we can't be moved into our sibling block.
   1982     if (!parent())
   1983         return false;
   1984 
   1985     // An intruded run-in needs to be an inline.
   1986     if (!runIn->isRenderInline())
   1987         return false;
   1988 
   1989     return true;
   1990 }
   1991 
   1992 void RenderBlock::moveRunInToOriginalPosition(RenderObject* runIn)
   1993 {
   1994     ASSERT(runIn->isRunIn());
   1995 
   1996     if (!runInIsPlacedIntoSiblingBlock(runIn))
   1997         return;
   1998 
   1999     // FIXME: Run-in that are now placed in sibling block can break up into continuation
   2000     // chains when new children are added to it. We cannot easily send them back to their
   2001     // original place since that requires writing integration logic with RenderInline::addChild
   2002     // and all other places that might cause continuations to be created (without blowing away
   2003     // |this|). Disabling this feature for now to prevent crashes.
   2004     if (runIn->isElementContinuation() || runIn->virtualContinuation())
   2005         return;
   2006 
   2007     RenderBoxModelObject* oldRunIn = toRenderBoxModelObject(runIn);
   2008     RenderBoxModelObject* newRunIn = createReplacementRunIn(oldRunIn);
   2009     destroyRunIn(oldRunIn);
   2010 
   2011     // Add the run-in block as our previous sibling.
   2012     parent()->addChild(newRunIn, this);
   2013 
   2014     // Make sure that the parent holding the new run-in gets layout.
   2015     parent()->setNeedsLayoutAndPrefWidthsRecalc();
   2016 }
   2017 
   2018 LayoutUnit RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo)
   2019 {
   2020     bool childDiscardMarginBefore = mustDiscardMarginBeforeForChild(child);
   2021     bool childDiscardMarginAfter = mustDiscardMarginAfterForChild(child);
   2022     bool childIsSelfCollapsing = child->isSelfCollapsingBlock();
   2023 
   2024     // The child discards the before margin when the the after margin has discard in the case of a self collapsing block.
   2025     childDiscardMarginBefore = childDiscardMarginBefore || (childDiscardMarginAfter && childIsSelfCollapsing);
   2026 
   2027     // Get the four margin values for the child and cache them.
   2028     const MarginValues childMargins = marginValuesForChild(child);
   2029 
   2030     // Get our max pos and neg top margins.
   2031     LayoutUnit posTop = childMargins.positiveMarginBefore();
   2032     LayoutUnit negTop = childMargins.negativeMarginBefore();
   2033 
   2034     // For self-collapsing blocks, collapse our bottom margins into our
   2035     // top to get new posTop and negTop values.
   2036     if (childIsSelfCollapsing) {
   2037         posTop = max(posTop, childMargins.positiveMarginAfter());
   2038         negTop = max(negTop, childMargins.negativeMarginAfter());
   2039     }
   2040 
   2041     // See if the top margin is quirky. We only care if this child has
   2042     // margins that will collapse with us.
   2043     bool topQuirk = hasMarginBeforeQuirk(child);
   2044 
   2045     if (marginInfo.canCollapseWithMarginBefore()) {
   2046         if (!childDiscardMarginBefore && !marginInfo.discardMargin()) {
   2047             // This child is collapsing with the top of the
   2048             // block. If it has larger margin values, then we need to update
   2049             // our own maximal values.
   2050             if (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !topQuirk)
   2051                 setMaxMarginBeforeValues(max(posTop, maxPositiveMarginBefore()), max(negTop, maxNegativeMarginBefore()));
   2052 
   2053             // The minute any of the margins involved isn't a quirk, don't
   2054             // collapse it away, even if the margin is smaller (www.webreference.com
   2055             // has an example of this, a <dt> with 0.8em author-specified inside
   2056             // a <dl> inside a <td>.
   2057             if (!marginInfo.determinedMarginBeforeQuirk() && !topQuirk && (posTop - negTop)) {
   2058                 setHasMarginBeforeQuirk(false);
   2059                 marginInfo.setDeterminedMarginBeforeQuirk(true);
   2060             }
   2061 
   2062             if (!marginInfo.determinedMarginBeforeQuirk() && topQuirk && !marginBefore())
   2063                 // We have no top margin and our top child has a quirky margin.
   2064                 // We will pick up this quirky margin and pass it through.
   2065                 // This deals with the <td><div><p> case.
   2066                 // Don't do this for a block that split two inlines though. You do
   2067                 // still apply margins in this case.
   2068                 setHasMarginBeforeQuirk(true);
   2069         } else
   2070             // The before margin of the container will also discard all the margins it is collapsing with.
   2071             setMustDiscardMarginBefore();
   2072     }
   2073 
   2074     // Once we find a child with discardMarginBefore all the margins collapsing with us must also discard.
   2075     if (childDiscardMarginBefore) {
   2076         marginInfo.setDiscardMargin(true);
   2077         marginInfo.clearMargin();
   2078     }
   2079 
   2080     if (marginInfo.quirkContainer() && marginInfo.atBeforeSideOfBlock() && (posTop - negTop))
   2081         marginInfo.setHasMarginBeforeQuirk(topQuirk);
   2082 
   2083     LayoutUnit beforeCollapseLogicalTop = logicalHeight();
   2084     LayoutUnit logicalTop = beforeCollapseLogicalTop;
   2085     if (childIsSelfCollapsing) {
   2086         // For a self collapsing block both the before and after margins get discarded. The block doesn't contribute anything to the height of the block.
   2087         // Also, the child's top position equals the logical height of the container.
   2088         if (!childDiscardMarginBefore && !marginInfo.discardMargin()) {
   2089             // This child has no height. We need to compute our
   2090             // position before we collapse the child's margins together,
   2091             // so that we can get an accurate position for the zero-height block.
   2092             LayoutUnit collapsedBeforePos = max(marginInfo.positiveMargin(), childMargins.positiveMarginBefore());
   2093             LayoutUnit collapsedBeforeNeg = max(marginInfo.negativeMargin(), childMargins.negativeMarginBefore());
   2094             marginInfo.setMargin(collapsedBeforePos, collapsedBeforeNeg);
   2095 
   2096             // Now collapse the child's margins together, which means examining our
   2097             // bottom margin values as well.
   2098             marginInfo.setPositiveMarginIfLarger(childMargins.positiveMarginAfter());
   2099             marginInfo.setNegativeMarginIfLarger(childMargins.negativeMarginAfter());
   2100 
   2101             if (!marginInfo.canCollapseWithMarginBefore())
   2102                 // We need to make sure that the position of the self-collapsing block
   2103                 // is correct, since it could have overflowing content
   2104                 // that needs to be positioned correctly (e.g., a block that
   2105                 // had a specified height of 0 but that actually had subcontent).
   2106                 logicalTop = logicalHeight() + collapsedBeforePos - collapsedBeforeNeg;
   2107         }
   2108     } else {
   2109         if (mustSeparateMarginBeforeForChild(child)) {
   2110             ASSERT(!marginInfo.discardMargin() || (marginInfo.discardMargin() && !marginInfo.margin()));
   2111             // If we are at the before side of the block and we collapse, ignore the computed margin
   2112             // and just add the child margin to the container height. This will correctly position
   2113             // the child inside the container.
   2114             LayoutUnit separateMargin = !marginInfo.canCollapseWithMarginBefore() ? marginInfo.margin() : LayoutUnit(0);
   2115             setLogicalHeight(logicalHeight() + separateMargin + marginBeforeForChild(child));
   2116             logicalTop = logicalHeight();
   2117         } else if (!marginInfo.discardMargin() && (!marginInfo.atBeforeSideOfBlock()
   2118             || (!marginInfo.canCollapseMarginBeforeWithChildren()
   2119             && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.hasMarginBeforeQuirk())))) {
   2120             // We're collapsing with a previous sibling's margins and not
   2121             // with the top of the block.
   2122             setLogicalHeight(logicalHeight() + max(marginInfo.positiveMargin(), posTop) - max(marginInfo.negativeMargin(), negTop));
   2123             logicalTop = logicalHeight();
   2124         }
   2125 
   2126         marginInfo.setDiscardMargin(childDiscardMarginAfter);
   2127 
   2128         if (!marginInfo.discardMargin()) {
   2129             marginInfo.setPositiveMargin(childMargins.positiveMarginAfter());
   2130             marginInfo.setNegativeMargin(childMargins.negativeMarginAfter());
   2131         } else
   2132             marginInfo.clearMargin();
   2133 
   2134         if (marginInfo.margin())
   2135             marginInfo.setHasMarginAfterQuirk(hasMarginAfterQuirk(child));
   2136     }
   2137 
   2138     // If margins would pull us past the top of the next page, then we need to pull back and pretend like the margins
   2139     // collapsed into the page edge.
   2140     LayoutState* layoutState = view()->layoutState();
   2141     if (layoutState->isPaginated() && layoutState->pageLogicalHeight() && logicalTop > beforeCollapseLogicalTop
   2142         && hasNextPage(beforeCollapseLogicalTop)) {
   2143         LayoutUnit oldLogicalTop = logicalTop;
   2144         logicalTop = min(logicalTop, nextPageLogicalTop(beforeCollapseLogicalTop));
   2145         setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop));
   2146     }
   2147 
   2148     // If we have collapsed into a previous sibling and so reduced the height of the parent, ensure any floats that now
   2149     // overhang from the previous sibling are added to our parent. If the child's previous sibling itself is a float the child will avoid
   2150     // or clear it anyway, so don't worry about any floating children it may contain.
   2151     LayoutUnit oldLogicalHeight = logicalHeight();
   2152     setLogicalHeight(logicalTop);
   2153     RenderObject* prev = child->previousSibling();
   2154     if (prev && prev->isBlockFlow() && !prev->isFloatingOrOutOfFlowPositioned()) {
   2155         RenderBlock* block = toRenderBlock(prev);
   2156         if (block->containsFloats() && !block->avoidsFloats() && (block->logicalTop() + block->lowestFloatLogicalBottom()) > logicalTop)
   2157             addOverhangingFloats(block, false);
   2158     }
   2159     setLogicalHeight(oldLogicalHeight);
   2160 
   2161     return logicalTop;
   2162 }
   2163 
   2164 LayoutUnit RenderBlock::clearFloatsIfNeeded(RenderBox* child, MarginInfo& marginInfo, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPos)
   2165 {
   2166     LayoutUnit heightIncrease = getClearDelta(child, yPos);
   2167     if (!heightIncrease)
   2168         return yPos;
   2169 
   2170     if (child->isSelfCollapsingBlock()) {
   2171         bool childDiscardMargin = mustDiscardMarginBeforeForChild(child) || mustDiscardMarginAfterForChild(child);
   2172 
   2173         // For self-collapsing blocks that clear, they can still collapse their
   2174         // margins with following siblings.  Reset the current margins to represent
   2175         // the self-collapsing block's margins only.
   2176         // If DISCARD is specified for -webkit-margin-collapse, reset the margin values.
   2177         if (!childDiscardMargin) {
   2178             MarginValues childMargins = marginValuesForChild(child);
   2179             marginInfo.setPositiveMargin(max(childMargins.positiveMarginBefore(), childMargins.positiveMarginAfter()));
   2180             marginInfo.setNegativeMargin(max(childMargins.negativeMarginBefore(), childMargins.negativeMarginAfter()));
   2181         } else
   2182             marginInfo.clearMargin();
   2183         marginInfo.setDiscardMargin(childDiscardMargin);
   2184 
   2185         // CSS2.1 states:
   2186         // "If the top and bottom margins of an element with clearance are adjoining, its margins collapse with
   2187         // the adjoining margins of following siblings but that resulting margin does not collapse with the bottom margin of the parent block."
   2188         // So the parent's bottom margin cannot collapse through this block or any subsequent self-collapsing blocks. Check subsequent siblings
   2189         // for a block with height - if none is found then don't allow the margins to collapse with the parent.
   2190         bool wouldCollapseMarginsWithParent = marginInfo.canCollapseMarginAfterWithChildren();
   2191         for (RenderBox* curr = child->nextSiblingBox(); curr && wouldCollapseMarginsWithParent; curr = curr->nextSiblingBox()) {
   2192             if (!curr->isFloatingOrOutOfFlowPositioned() && !curr->isSelfCollapsingBlock())
   2193                 wouldCollapseMarginsWithParent = false;
   2194         }
   2195         if (wouldCollapseMarginsWithParent)
   2196             marginInfo.setCanCollapseMarginAfterWithChildren(false);
   2197 
   2198         // CSS2.1: "the amount of clearance is set so that clearance + margin-top = [height of float], i.e., clearance = [height of float] - margin-top"
   2199         // Move the top of the child box to the bottom of the float ignoring the child's top margin.
   2200         LayoutUnit collapsedMargin = collapsedMarginBeforeForChild(child);
   2201         setLogicalHeight(child->logicalTop() - collapsedMargin);
   2202         // A negative collapsed margin-top value cancels itself out as it has already been factored into |yPos| above.
   2203         heightIncrease -= max(LayoutUnit(), collapsedMargin);
   2204     } else
   2205         // Increase our height by the amount we had to clear.
   2206         setLogicalHeight(logicalHeight() + heightIncrease);
   2207 
   2208     if (marginInfo.canCollapseWithMarginBefore()) {
   2209         // We can no longer collapse with the top of the block since a clear
   2210         // occurred.  The empty blocks collapse into the cleared block.
   2211         // FIXME: This isn't quite correct.  Need clarification for what to do
   2212         // if the height the cleared block is offset by is smaller than the
   2213         // margins involved.
   2214         setMaxMarginBeforeValues(oldTopPosMargin, oldTopNegMargin);
   2215         marginInfo.setAtBeforeSideOfBlock(false);
   2216 
   2217         // In case the child discarded the before margin of the block we need to reset the mustDiscardMarginBefore flag to the initial value.
   2218         setMustDiscardMarginBefore(style()->marginBeforeCollapse() == MDISCARD);
   2219     }
   2220 
   2221     LayoutUnit logicalTop = yPos + heightIncrease;
   2222     // After margin collapsing, one of our floats may now intrude into the child. If the child doesn't contain floats of its own it
   2223     // won't get picked up for relayout even though the logical top estimate was wrong - so add the newly intruding float now.
   2224     if (containsFloats() && child->isRenderBlock() && !toRenderBlock(child)->containsFloats() && !child->avoidsFloats() && lowestFloatLogicalBottom() > logicalTop)
   2225         toRenderBlock(child)->addIntrudingFloats(this, logicalLeftOffsetForContent(), logicalTop);
   2226 
   2227     return logicalTop;
   2228 }
   2229 
   2230 void RenderBlock::marginBeforeEstimateForChild(RenderBox* child, LayoutUnit& positiveMarginBefore, LayoutUnit& negativeMarginBefore, bool& discardMarginBefore) const
   2231 {
   2232     // Give up if in quirks mode and we're a body/table cell and the top margin of the child box is quirky.
   2233     // Give up if the child specified -webkit-margin-collapse: separate that prevents collapsing.
   2234     // FIXME: Use writing mode independent accessor for marginBeforeCollapse.
   2235     if ((document()->inQuirksMode() && hasMarginAfterQuirk(child) && (isTableCell() || isBody())) || child->style()->marginBeforeCollapse() == MSEPARATE)
   2236         return;
   2237 
   2238     // The margins are discarded by a child that specified -webkit-margin-collapse: discard.
   2239     // FIXME: Use writing mode independent accessor for marginBeforeCollapse.
   2240     if (child->style()->marginBeforeCollapse() == MDISCARD) {
   2241         positiveMarginBefore = 0;
   2242         negativeMarginBefore = 0;
   2243         discardMarginBefore = true;
   2244         return;
   2245     }
   2246 
   2247     LayoutUnit beforeChildMargin = marginBeforeForChild(child);
   2248     positiveMarginBefore = max(positiveMarginBefore, beforeChildMargin);
   2249     negativeMarginBefore = max(negativeMarginBefore, -beforeChildMargin);
   2250 
   2251     if (!child->isRenderBlock())
   2252         return;
   2253 
   2254     RenderBlock* childBlock = toRenderBlock(child);
   2255     if (childBlock->childrenInline() || childBlock->isWritingModeRoot())
   2256         return;
   2257 
   2258     MarginInfo childMarginInfo(childBlock, childBlock->borderBefore() + childBlock->paddingBefore(), childBlock->borderAfter() + childBlock->paddingAfter());
   2259     if (!childMarginInfo.canCollapseMarginBeforeWithChildren())
   2260         return;
   2261 
   2262     RenderBox* grandchildBox = childBlock->firstChildBox();
   2263     for ( ; grandchildBox; grandchildBox = grandchildBox->nextSiblingBox()) {
   2264         if (!grandchildBox->isFloatingOrOutOfFlowPositioned())
   2265             break;
   2266     }
   2267 
   2268     // Give up if there is clearance on the box, since it probably won't collapse into us.
   2269     if (!grandchildBox || grandchildBox->style()->clear() != CNONE)
   2270         return;
   2271 
   2272     // Make sure to update the block margins now for the grandchild box so that we're looking at current values.
   2273     if (grandchildBox->needsLayout()) {
   2274         grandchildBox->computeAndSetBlockDirectionMargins(this);
   2275         if (grandchildBox->isRenderBlock()) {
   2276             RenderBlock* grandchildBlock = toRenderBlock(grandchildBox);
   2277             grandchildBlock->setHasMarginBeforeQuirk(grandchildBox->style()->hasMarginBeforeQuirk());
   2278             grandchildBlock->setHasMarginAfterQuirk(grandchildBox->style()->hasMarginAfterQuirk());
   2279         }
   2280     }
   2281 
   2282     // Collapse the margin of the grandchild box with our own to produce an estimate.
   2283     childBlock->marginBeforeEstimateForChild(grandchildBox, positiveMarginBefore, negativeMarginBefore, discardMarginBefore);
   2284 }
   2285 
   2286 LayoutUnit RenderBlock::estimateLogicalTopPosition(RenderBox* child, const MarginInfo& marginInfo, LayoutUnit& estimateWithoutPagination)
   2287 {
   2288     // FIXME: We need to eliminate the estimation of vertical position, because when it's wrong we sometimes trigger a pathological
   2289     // relayout if there are intruding floats.
   2290     LayoutUnit logicalTopEstimate = logicalHeight();
   2291     if (!marginInfo.canCollapseWithMarginBefore()) {
   2292         LayoutUnit positiveMarginBefore = 0;
   2293         LayoutUnit negativeMarginBefore = 0;
   2294         bool discardMarginBefore = false;
   2295         if (child->selfNeedsLayout()) {
   2296             // Try to do a basic estimation of how the collapse is going to go.
   2297             marginBeforeEstimateForChild(child, positiveMarginBefore, negativeMarginBefore, discardMarginBefore);
   2298         } else {
   2299             // Use the cached collapsed margin values from a previous layout. Most of the time they
   2300             // will be right.
   2301             MarginValues marginValues = marginValuesForChild(child);
   2302             positiveMarginBefore = max(positiveMarginBefore, marginValues.positiveMarginBefore());
   2303             negativeMarginBefore = max(negativeMarginBefore, marginValues.negativeMarginBefore());
   2304             discardMarginBefore = mustDiscardMarginBeforeForChild(child);
   2305         }
   2306 
   2307         // Collapse the result with our current margins.
   2308         if (!discardMarginBefore)
   2309             logicalTopEstimate += max(marginInfo.positiveMargin(), positiveMarginBefore) - max(marginInfo.negativeMargin(), negativeMarginBefore);
   2310     }
   2311 
   2312     // Adjust logicalTopEstimate down to the next page if the margins are so large that we don't fit on the current
   2313     // page.
   2314     LayoutState* layoutState = view()->layoutState();
   2315     if (layoutState->isPaginated() && layoutState->pageLogicalHeight() && logicalTopEstimate > logicalHeight()
   2316         && hasNextPage(logicalHeight()))
   2317         logicalTopEstimate = min(logicalTopEstimate, nextPageLogicalTop(logicalHeight()));
   2318 
   2319     logicalTopEstimate += getClearDelta(child, logicalTopEstimate);
   2320 
   2321     estimateWithoutPagination = logicalTopEstimate;
   2322 
   2323     if (layoutState->isPaginated()) {
   2324         // If the object has a page or column break value of "before", then we should shift to the top of the next page.
   2325         logicalTopEstimate = applyBeforeBreak(child, logicalTopEstimate);
   2326 
   2327         // For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one.
   2328         logicalTopEstimate = adjustForUnsplittableChild(child, logicalTopEstimate);
   2329 
   2330         if (!child->selfNeedsLayout() && child->isRenderBlock())
   2331             logicalTopEstimate += toRenderBlock(child)->paginationStrut();
   2332     }
   2333 
   2334     return logicalTopEstimate;
   2335 }
   2336 
   2337 LayoutUnit RenderBlock::computeStartPositionDeltaForChildAvoidingFloats(const RenderBox* child, LayoutUnit childMarginStart,
   2338     RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage)
   2339 {
   2340     LayoutUnit startPosition = startOffsetForContent(region, offsetFromLogicalTopOfFirstPage);
   2341 
   2342     // Add in our start margin.
   2343     LayoutUnit oldPosition = startPosition + childMarginStart;
   2344     LayoutUnit newPosition = oldPosition;
   2345 
   2346     LayoutUnit blockOffset = logicalTopForChild(child);
   2347     if (region)
   2348         blockOffset = max(blockOffset, blockOffset + (region->logicalTopForFlowThreadContent() - offsetFromLogicalTopOfFirstPage));
   2349 
   2350     LayoutUnit startOff = startOffsetForLine(blockOffset, false, region, offsetFromLogicalTopOfFirstPage, logicalHeightForChild(child));
   2351 
   2352     if (style()->textAlign() != WEBKIT_CENTER && !child->style()->marginStartUsing(style()).isAuto()) {
   2353         if (childMarginStart < 0)
   2354             startOff += childMarginStart;
   2355         newPosition = max(newPosition, startOff); // Let the float sit in the child's margin if it can fit.
   2356     } else if (startOff != startPosition)
   2357         newPosition = startOff + childMarginStart;
   2358 
   2359     return newPosition - oldPosition;
   2360 }
   2361 
   2362 void RenderBlock::determineLogicalLeftPositionForChild(RenderBox* child, ApplyLayoutDeltaMode applyDelta)
   2363 {
   2364     LayoutUnit startPosition = borderStart() + paddingStart();
   2365     if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
   2366         startPosition -= verticalScrollbarWidth();
   2367     LayoutUnit totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + availableLogicalWidth();
   2368 
   2369     // Add in our start margin.
   2370     LayoutUnit childMarginStart = marginStartForChild(child);
   2371     LayoutUnit newPosition = startPosition + childMarginStart;
   2372 
   2373     // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats.  They need
   2374     // to shift over as necessary to dodge any floats that might get in the way.
   2375     if (child->avoidsFloats() && containsFloats() && !flowThreadContainingBlock())
   2376         newPosition += computeStartPositionDeltaForChildAvoidingFloats(child, marginStartForChild(child));
   2377 
   2378     setLogicalLeftForChild(child, style()->isLeftToRightDirection() ? newPosition : totalAvailableLogicalWidth - newPosition - logicalWidthForChild(child), applyDelta);
   2379 }
   2380 
   2381 void RenderBlock::setCollapsedBottomMargin(const MarginInfo& marginInfo)
   2382 {
   2383     if (marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()) {
   2384         // Update the after side margin of the container to discard if the after margin of the last child also discards and we collapse with it.
   2385         // Don't update the max margin values because we won't need them anyway.
   2386         if (marginInfo.discardMargin()) {
   2387             setMustDiscardMarginAfter();
   2388             return;
   2389         }
   2390 
   2391         // Update our max pos/neg bottom margins, since we collapsed our bottom margins
   2392         // with our children.
   2393         setMaxMarginAfterValues(max(maxPositiveMarginAfter(), marginInfo.positiveMargin()), max(maxNegativeMarginAfter(), marginInfo.negativeMargin()));
   2394 
   2395         if (!marginInfo.hasMarginAfterQuirk())
   2396             setHasMarginAfterQuirk(false);
   2397 
   2398         if (marginInfo.hasMarginAfterQuirk() && !marginAfter())
   2399             // We have no bottom margin and our last child has a quirky margin.
   2400             // We will pick up this quirky margin and pass it through.
   2401             // This deals with the <td><div><p> case.
   2402             setHasMarginAfterQuirk(true);
   2403     }
   2404 }
   2405 
   2406 void RenderBlock::handleAfterSideOfBlock(LayoutUnit beforeSide, LayoutUnit afterSide, MarginInfo& marginInfo)
   2407 {
   2408     marginInfo.setAtAfterSideOfBlock(true);
   2409 
   2410     // If we can't collapse with children then go ahead and add in the bottom margin.
   2411     if (!marginInfo.discardMargin() && (!marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()
   2412         && (!document()->inQuirksMode() || !marginInfo.quirkContainer() || !marginInfo.hasMarginAfterQuirk())))
   2413         setLogicalHeight(logicalHeight() + marginInfo.margin());
   2414 
   2415     // Now add in our bottom border/padding.
   2416     setLogicalHeight(logicalHeight() + afterSide);
   2417 
   2418     // Negative margins can cause our height to shrink below our minimal height (border/padding).
   2419     // If this happens, ensure that the computed height is increased to the minimal height.
   2420     setLogicalHeight(max(logicalHeight(), beforeSide + afterSide));
   2421 
   2422     // Update our bottom collapsed margin info.
   2423     setCollapsedBottomMargin(marginInfo);
   2424 }
   2425 
   2426 void RenderBlock::setLogicalLeftForChild(RenderBox* child, LayoutUnit logicalLeft, ApplyLayoutDeltaMode applyDelta)
   2427 {
   2428     if (isHorizontalWritingMode()) {
   2429         if (applyDelta == ApplyLayoutDelta)
   2430             view()->addLayoutDelta(LayoutSize(child->x() - logicalLeft, 0));
   2431         child->setX(logicalLeft);
   2432     } else {
   2433         if (applyDelta == ApplyLayoutDelta)
   2434             view()->addLayoutDelta(LayoutSize(0, child->y() - logicalLeft));
   2435         child->setY(logicalLeft);
   2436     }
   2437 }
   2438 
   2439 void RenderBlock::setLogicalTopForChild(RenderBox* child, LayoutUnit logicalTop, ApplyLayoutDeltaMode applyDelta)
   2440 {
   2441     if (isHorizontalWritingMode()) {
   2442         if (applyDelta == ApplyLayoutDelta)
   2443             view()->addLayoutDelta(LayoutSize(0, child->y() - logicalTop));
   2444         child->setY(logicalTop);
   2445     } else {
   2446         if (applyDelta == ApplyLayoutDelta)
   2447             view()->addLayoutDelta(LayoutSize(child->x() - logicalTop, 0));
   2448         child->setX(logicalTop);
   2449     }
   2450 }
   2451 
   2452 void RenderBlock::updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, RenderBox* child)
   2453 {
   2454     // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into
   2455     // an auto value. Add a method to determine this, so that we can avoid the relayout.
   2456     if (relayoutChildren || (child->hasRelativeLogicalHeight() && !isRenderView()))
   2457         child->setChildNeedsLayout(MarkOnlyThis);
   2458 
   2459     // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.
   2460     if (relayoutChildren && child->needsPreferredWidthsRecalculation())
   2461         child->setPreferredLogicalWidthsDirty(true, MarkOnlyThis);
   2462 }
   2463 
   2464 void RenderBlock::layoutBlockChildren(bool relayoutChildren, LayoutUnit& maxFloatLogicalBottom)
   2465 {
   2466     if (gPercentHeightDescendantsMap) {
   2467         if (TrackedRendererListHashSet* descendants = gPercentHeightDescendantsMap->get(this)) {
   2468             TrackedRendererListHashSet::iterator end = descendants->end();
   2469             for (TrackedRendererListHashSet::iterator it = descendants->begin(); it != end; ++it) {
   2470                 RenderBox* box = *it;
   2471                 while (box != this) {
   2472                     if (box->normalChildNeedsLayout())
   2473                         break;
   2474                     box->setChildNeedsLayout(MarkOnlyThis);
   2475                     box = box->containingBlock();
   2476                     ASSERT(box);
   2477                     if (!box)
   2478                         break;
   2479                 }
   2480             }
   2481         }
   2482     }
   2483 
   2484     LayoutUnit beforeEdge = borderBefore() + paddingBefore();
   2485     LayoutUnit afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeight();
   2486 
   2487     setLogicalHeight(beforeEdge);
   2488 
   2489     // Lay out our hypothetical grid line as though it occurs at the top of the block.
   2490     if (view()->layoutState()->lineGrid() == this)
   2491         layoutLineGridBox();
   2492 
   2493     // The margin struct caches all our current margin collapsing state.  The compact struct caches state when we encounter compacts,
   2494     MarginInfo marginInfo(this, beforeEdge, afterEdge);
   2495 
   2496     // Fieldsets need to find their legend and position it inside the border of the object.
   2497     // The legend then gets skipped during normal layout.  The same is true for ruby text.
   2498     // It doesn't get included in the normal layout process but is instead skipped.
   2499     RenderObject* childToExclude = layoutSpecialExcludedChild(relayoutChildren);
   2500 
   2501     LayoutUnit previousFloatLogicalBottom = 0;
   2502     maxFloatLogicalBottom = 0;
   2503 
   2504     RenderBox* next = firstChildBox();
   2505 
   2506     while (next) {
   2507         RenderBox* child = next;
   2508         next = child->nextSiblingBox();
   2509 
   2510         if (childToExclude == child)
   2511             continue; // Skip this child, since it will be positioned by the specialized subclass (fieldsets and ruby runs).
   2512 
   2513         updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, child);
   2514 
   2515         if (child->isOutOfFlowPositioned()) {
   2516             child->containingBlock()->insertPositionedObject(child);
   2517             adjustPositionedBlock(child, marginInfo);
   2518             continue;
   2519         }
   2520         if (child->isFloating()) {
   2521             insertFloatingObject(child);
   2522             adjustFloatingBlock(marginInfo);
   2523             continue;
   2524         }
   2525 
   2526         // Lay out the child.
   2527         layoutBlockChild(child, marginInfo, previousFloatLogicalBottom, maxFloatLogicalBottom);
   2528     }
   2529 
   2530     // Now do the handling of the bottom of the block, adding in our bottom border/padding and
   2531     // determining the correct collapsed bottom margin information.
   2532     handleAfterSideOfBlock(beforeEdge, afterEdge, marginInfo);
   2533 }
   2534 
   2535 void RenderBlock::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom)
   2536 {
   2537     LayoutUnit oldPosMarginBefore = maxPositiveMarginBefore();
   2538     LayoutUnit oldNegMarginBefore = maxNegativeMarginBefore();
   2539 
   2540     // The child is a normal flow object.  Compute the margins we will use for collapsing now.
   2541     child->computeAndSetBlockDirectionMargins(this);
   2542 
   2543     // Try to guess our correct logical top position.  In most cases this guess will
   2544     // be correct.  Only if we're wrong (when we compute the real logical top position)
   2545     // will we have to potentially relayout.
   2546     LayoutUnit estimateWithoutPagination;
   2547     LayoutUnit logicalTopEstimate = estimateLogicalTopPosition(child, marginInfo, estimateWithoutPagination);
   2548 
   2549     // Cache our old rect so that we can dirty the proper repaint rects if the child moves.
   2550     LayoutRect oldRect = child->frameRect();
   2551     LayoutUnit oldLogicalTop = logicalTopForChild(child);
   2552 
   2553 #if !ASSERT_DISABLED
   2554     LayoutSize oldLayoutDelta = view()->layoutDelta();
   2555 #endif
   2556     // Go ahead and position the child as though it didn't collapse with the top.
   2557     setLogicalTopForChild(child, logicalTopEstimate, ApplyLayoutDelta);
   2558 
   2559     RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0;
   2560     bool markDescendantsWithFloats = false;
   2561     if (logicalTopEstimate != oldLogicalTop && !child->avoidsFloats() && childRenderBlock && childRenderBlock->containsFloats())
   2562         markDescendantsWithFloats = true;
   2563     else if (UNLIKELY(logicalTopEstimate.mightBeSaturated()))
   2564         // logicalTopEstimate, returned by estimateLogicalTopPosition, might be saturated for
   2565         // very large elements. If it does the comparison with oldLogicalTop might yield a
   2566         // false negative as adding and removing margins, borders etc from a saturated number
   2567         // might yield incorrect results. If this is the case always mark for layout.
   2568         markDescendantsWithFloats = true;
   2569     else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) {
   2570         // If an element might be affected by the presence of floats, then always mark it for
   2571         // layout.
   2572         LayoutUnit fb = max(previousFloatLogicalBottom, lowestFloatLogicalBottom());
   2573         if (fb > logicalTopEstimate)
   2574             markDescendantsWithFloats = true;
   2575     }
   2576 
   2577     if (childRenderBlock) {
   2578         if (markDescendantsWithFloats)
   2579             childRenderBlock->markAllDescendantsWithFloatsForLayout();
   2580         if (!child->isWritingModeRoot())
   2581             previousFloatLogicalBottom = max(previousFloatLogicalBottom, oldLogicalTop + childRenderBlock->lowestFloatLogicalBottom());
   2582     }
   2583 
   2584     if (!child->needsLayout())
   2585         child->markForPaginationRelayoutIfNeeded();
   2586 
   2587     bool childHadLayout = child->everHadLayout();
   2588     bool childNeededLayout = child->needsLayout();
   2589     if (childNeededLayout)
   2590         child->layout();
   2591 
   2592     // Cache if we are at the top of the block right now.
   2593     bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock();
   2594 
   2595     // Now determine the correct ypos based off examination of collapsing margin
   2596     // values.
   2597     LayoutUnit logicalTopBeforeClear = collapseMargins(child, marginInfo);
   2598 
   2599     // Now check for clear.
   2600     LayoutUnit logicalTopAfterClear = clearFloatsIfNeeded(child, marginInfo, oldPosMarginBefore, oldNegMarginBefore, logicalTopBeforeClear);
   2601 
   2602     bool paginated = view()->layoutState()->isPaginated();
   2603     if (paginated)
   2604         logicalTopAfterClear = adjustBlockChildForPagination(logicalTopAfterClear, estimateWithoutPagination, child,
   2605             atBeforeSideOfBlock && logicalTopBeforeClear == logicalTopAfterClear);
   2606 
   2607     setLogicalTopForChild(child, logicalTopAfterClear, ApplyLayoutDelta);
   2608 
   2609     // Now we have a final top position.  See if it really does end up being different from our estimate.
   2610     // clearFloatsIfNeeded can also mark the child as needing a layout even though we didn't move. This happens
   2611     // when collapseMargins dynamically adds overhanging floats because of a child with negative margins.
   2612     if (logicalTopAfterClear != logicalTopEstimate || child->needsLayout() || (paginated && childRenderBlock && childRenderBlock->shouldBreakAtLineToAvoidWidow())) {
   2613         if (child->shrinkToAvoidFloats()) {
   2614             // The child's width depends on the line width.
   2615             // When the child shifts to clear an item, its width can
   2616             // change (because it has more available line width).
   2617             // So go ahead and mark the item as dirty.
   2618             child->setChildNeedsLayout(MarkOnlyThis);
   2619         }
   2620 
   2621         if (childRenderBlock) {
   2622             if (!child->avoidsFloats() && childRenderBlock->containsFloats())
   2623                 childRenderBlock->markAllDescendantsWithFloatsForLayout();
   2624             if (!child->needsLayout())
   2625                 child->markForPaginationRelayoutIfNeeded();
   2626         }
   2627 
   2628         // Our guess was wrong. Make the child lay itself out again.
   2629         child->layoutIfNeeded();
   2630     }
   2631 
   2632     // We are no longer at the top of the block if we encounter a non-empty child.
   2633     // This has to be done after checking for clear, so that margins can be reset if a clear occurred.
   2634     if (marginInfo.atBeforeSideOfBlock() && !child->isSelfCollapsingBlock())
   2635         marginInfo.setAtBeforeSideOfBlock(false);
   2636 
   2637     // Now place the child in the correct left position
   2638     determineLogicalLeftPositionForChild(child, ApplyLayoutDelta);
   2639 
   2640     // Update our height now that the child has been placed in the correct position.
   2641     setLogicalHeight(logicalHeight() + logicalHeightForChild(child));
   2642     if (mustSeparateMarginAfterForChild(child)) {
   2643         setLogicalHeight(logicalHeight() + marginAfterForChild(child));
   2644         marginInfo.clearMargin();
   2645     }
   2646     // If the child has overhanging floats that intrude into following siblings (or possibly out
   2647     // of this block), then the parent gets notified of the floats now.
   2648     if (childRenderBlock && childRenderBlock->containsFloats())
   2649         maxFloatLogicalBottom = max(maxFloatLogicalBottom, addOverhangingFloats(toRenderBlock(child), !childNeededLayout));
   2650 
   2651     LayoutSize childOffset = child->location() - oldRect.location();
   2652     if (childOffset.width() || childOffset.height()) {
   2653         view()->addLayoutDelta(childOffset);
   2654 
   2655         // If the child moved, we have to repaint it as well as any floating/positioned
   2656         // descendants.  An exception is if we need a layout.  In this case, we know we're going to
   2657         // repaint ourselves (and the child) anyway.
   2658         if (childHadLayout && !selfNeedsLayout() && child->checkForRepaintDuringLayout())
   2659             child->repaintDuringLayoutIfMoved(oldRect);
   2660     }
   2661 
   2662     if (!childHadLayout && child->checkForRepaintDuringLayout()) {
   2663         child->repaint();
   2664         child->repaintOverhangingFloats(true);
   2665     }
   2666 
   2667     if (paginated) {
   2668         // Check for an after page/column break.
   2669         LayoutUnit newHeight = applyAfterBreak(child, logicalHeight(), marginInfo);
   2670         if (newHeight != height())
   2671             setLogicalHeight(newHeight);
   2672     }
   2673 
   2674     ASSERT(view()->layoutDeltaMatches(oldLayoutDelta));
   2675 }
   2676 
   2677 void RenderBlock::simplifiedNormalFlowLayout()
   2678 {
   2679     if (childrenInline()) {
   2680         ListHashSet<RootInlineBox*> lineBoxes;
   2681         for (InlineWalker walker(this); !walker.atEnd(); walker.advance()) {
   2682             RenderObject* o = walker.current();
   2683             if (!o->isOutOfFlowPositioned() && (o->isReplaced() || o->isFloating())) {
   2684                 o->layoutIfNeeded();
   2685                 if (toRenderBox(o)->inlineBoxWrapper()) {
   2686                     RootInlineBox* box = toRenderBox(o)->inlineBoxWrapper()->root();
   2687                     lineBoxes.add(box);
   2688                 }
   2689             } else if (o->isText() || (o->isRenderInline() && !walker.atEndOfInline())) {
   2690                 o->clearNeedsLayout();
   2691             }
   2692         }
   2693 
   2694         // FIXME: Glyph overflow will get lost in this case, but not really a big deal.
   2695         GlyphOverflowAndFallbackFontsMap textBoxDataMap;
   2696         for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it != lineBoxes.end(); ++it) {
   2697             RootInlineBox* box = *it;
   2698             box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap);
   2699         }
   2700     } else {
   2701         for (RenderBox* box = firstChildBox(); box; box = box->nextSiblingBox()) {
   2702             if (!box->isOutOfFlowPositioned())
   2703                 box->layoutIfNeeded();
   2704         }
   2705     }
   2706 }
   2707 
   2708 bool RenderBlock::simplifiedLayout()
   2709 {
   2710     if ((!posChildNeedsLayout() && !needsSimplifiedNormalFlowLayout()) || normalChildNeedsLayout() || selfNeedsLayout())
   2711         return false;
   2712 
   2713     LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
   2714 
   2715     if (needsPositionedMovementLayout() && !tryLayoutDoingPositionedMovementOnly())
   2716         return false;
   2717 
   2718     // Lay out positioned descendants or objects that just need to recompute overflow.
   2719     if (needsSimplifiedNormalFlowLayout())
   2720         simplifiedNormalFlowLayout();
   2721 
   2722     // Lay out our positioned objects if our positioned child bit is set.
   2723     // Also, if an absolute position element inside a relative positioned container moves, and the absolute element has a fixed position
   2724     // child, neither the fixed element nor its container learn of the movement since posChildNeedsLayout() is only marked as far as the
   2725     // relative positioned container. So if we can have fixed pos objects in our positioned objects list check if any of them
   2726     // are statically positioned and thus need to move with their absolute ancestors.
   2727     bool canContainFixedPosObjects = canContainFixedPositionObjects();
   2728     if (posChildNeedsLayout() || canContainFixedPosObjects)
   2729         layoutPositionedObjects(false, !posChildNeedsLayout() && canContainFixedPosObjects);
   2730 
   2731     // Recompute our overflow information.
   2732     // FIXME: We could do better here by computing a temporary overflow object from layoutPositionedObjects and only
   2733     // updating our overflow if we either used to have overflow or if the new temporary object has overflow.
   2734     // For now just always recompute overflow.  This is no worse performance-wise than the old code that called rightmostPosition and
   2735     // lowestPosition on every relayout so it's not a regression.
   2736     // computeOverflow expects the bottom edge before we clamp our height. Since this information isn't available during
   2737     // simplifiedLayout, we cache the value in m_overflow.
   2738     LayoutUnit oldClientAfterEdge = hasRenderOverflow() ? m_overflow->layoutClientAfterEdge() : clientLogicalBottom();
   2739     computeOverflow(oldClientAfterEdge, true);
   2740 
   2741     statePusher.pop();
   2742 
   2743     updateLayerTransform();
   2744 
   2745     updateScrollInfoAfterLayout();
   2746 
   2747     clearNeedsLayout();
   2748     return true;
   2749 }
   2750 
   2751 void RenderBlock::markFixedPositionObjectForLayoutIfNeeded(RenderObject* child)
   2752 {
   2753     if (child->style()->position() != FixedPosition)
   2754         return;
   2755 
   2756     bool hasStaticBlockPosition = child->style()->hasStaticBlockPosition(isHorizontalWritingMode());
   2757     bool hasStaticInlinePosition = child->style()->hasStaticInlinePosition(isHorizontalWritingMode());
   2758     if (!hasStaticBlockPosition && !hasStaticInlinePosition)
   2759         return;
   2760 
   2761     RenderObject* o = child->parent();
   2762     while (o && !o->isRenderView() && o->style()->position() != AbsolutePosition)
   2763         o = o->parent();
   2764     if (o->style()->position() != AbsolutePosition)
   2765         return;
   2766 
   2767     RenderBox* box = toRenderBox(child);
   2768     if (hasStaticInlinePosition) {
   2769         LayoutUnit oldLeft = box->logicalLeft();
   2770         box->updateLogicalWidth();
   2771         if (box->logicalLeft() != oldLeft)
   2772             child->setChildNeedsLayout(MarkOnlyThis);
   2773     } else if (hasStaticBlockPosition) {
   2774         LayoutUnit oldTop = box->logicalTop();
   2775         box->updateLogicalHeight();
   2776         if (box->logicalTop() != oldTop)
   2777             child->setChildNeedsLayout(MarkOnlyThis);
   2778     }
   2779 }
   2780 
   2781 void RenderBlock::layoutPositionedObjects(bool relayoutChildren, bool fixedPositionObjectsOnly)
   2782 {
   2783     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
   2784     if (!positionedDescendants)
   2785         return;
   2786 
   2787     if (hasColumns())
   2788         view()->layoutState()->clearPaginationInformation(); // Positioned objects are not part of the column flow, so they don't paginate with the columns.
   2789 
   2790     RenderBox* r;
   2791     TrackedRendererListHashSet::iterator end = positionedDescendants->end();
   2792     for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
   2793         r = *it;
   2794 
   2795         // A fixed position element with an absolute positioned ancestor has no way of knowing if the latter has changed position. So
   2796         // if this is a fixed position element, mark it for layout if it has an abspos ancestor and needs to move with that ancestor, i.e.
   2797         // it has static position.
   2798         markFixedPositionObjectForLayoutIfNeeded(r);
   2799         if (fixedPositionObjectsOnly) {
   2800             r->layoutIfNeeded();
   2801             continue;
   2802         }
   2803 
   2804         // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the
   2805         // non-positioned block.  Rather than trying to detect all of these movement cases, we just always lay out positioned
   2806         // objects that are positioned implicitly like this.  Such objects are rare, and so in typical DHTML menu usage (where everything is
   2807         // positioned explicitly) this should not incur a performance penalty.
   2808         if (relayoutChildren || (r->style()->hasStaticBlockPosition(isHorizontalWritingMode()) && r->parent() != this))
   2809             r->setChildNeedsLayout(MarkOnlyThis);
   2810 
   2811         // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.
   2812         if (relayoutChildren && r->needsPreferredWidthsRecalculation())
   2813             r->setPreferredLogicalWidthsDirty(true, MarkOnlyThis);
   2814 
   2815         if (!r->needsLayout())
   2816             r->markForPaginationRelayoutIfNeeded();
   2817 
   2818         // 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
   2819         // and we hit the available width constraint, the layoutIfNeeded() will catch it and do a full layout.
   2820         if (r->needsPositionedMovementLayoutOnly() && r->tryLayoutDoingPositionedMovementOnly())
   2821             r->clearNeedsLayout();
   2822 
   2823         // If we are paginated or in a line grid, go ahead and compute a vertical position for our object now.
   2824         // If it's wrong we'll lay out again.
   2825         LayoutUnit oldLogicalTop = 0;
   2826         bool needsBlockDirectionLocationSetBeforeLayout = r->needsLayout() && view()->layoutState()->needsBlockDirectionLocationSetBeforeLayout();
   2827         if (needsBlockDirectionLocationSetBeforeLayout) {
   2828             if (isHorizontalWritingMode() == r->isHorizontalWritingMode())
   2829                 r->updateLogicalHeight();
   2830             else
   2831                 r->updateLogicalWidth();
   2832             oldLogicalTop = logicalTopForChild(r);
   2833         }
   2834 
   2835         r->layoutIfNeeded();
   2836 
   2837         // Lay out again if our estimate was wrong.
   2838         if (needsBlockDirectionLocationSetBeforeLayout && logicalTopForChild(r) != oldLogicalTop)
   2839             r->forceChildLayout();
   2840     }
   2841 
   2842     if (hasColumns())
   2843         view()->layoutState()->m_columnInfo = columnInfo(); // FIXME: Kind of gross. We just put this back into the layout state so that pop() will work.
   2844 }
   2845 
   2846 void RenderBlock::markPositionedObjectsForLayout()
   2847 {
   2848     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
   2849     if (positionedDescendants) {
   2850         RenderBox* r;
   2851         TrackedRendererListHashSet::iterator end = positionedDescendants->end();
   2852         for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
   2853             r = *it;
   2854             r->setChildNeedsLayout();
   2855         }
   2856     }
   2857 }
   2858 
   2859 void RenderBlock::markForPaginationRelayoutIfNeeded()
   2860 {
   2861     ASSERT(!needsLayout());
   2862     if (needsLayout())
   2863         return;
   2864 
   2865     if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(this, logicalTop()) != pageLogicalOffset()) || shouldBreakAtLineToAvoidWidow())
   2866         setChildNeedsLayout(MarkOnlyThis);
   2867 }
   2868 
   2869 void RenderBlock::repaintOverhangingFloats(bool paintAllDescendants)
   2870 {
   2871     // Repaint any overhanging floats (if we know we're the one to paint them).
   2872     // Otherwise, bail out.
   2873     if (!hasOverhangingFloats())
   2874         return;
   2875 
   2876     // FIXME: Avoid disabling LayoutState. At the very least, don't disable it for floats originating
   2877     // in this block. Better yet would be to push extra state for the containers of other floats.
   2878     LayoutStateDisabler layoutStateDisabler(view());
   2879     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   2880     FloatingObjectSetIterator end = floatingObjectSet.end();
   2881     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   2882         FloatingObject* r = *it;
   2883         // Only repaint the object if it is overhanging, is not in its own layer, and
   2884         // is our responsibility to paint (m_shouldPaint is set). When paintAllDescendants is true, the latter
   2885         // condition is replaced with being a descendant of us.
   2886         if (logicalBottomForFloat(r) > logicalHeight() && ((paintAllDescendants && r->m_renderer->isDescendantOf(this)) || r->shouldPaint()) && !r->m_renderer->hasSelfPaintingLayer()) {
   2887             r->m_renderer->repaint();
   2888             r->m_renderer->repaintOverhangingFloats(false);
   2889         }
   2890     }
   2891 }
   2892 
   2893 void RenderBlock::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
   2894 {
   2895     ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this);
   2896 
   2897     LayoutPoint adjustedPaintOffset = paintOffset + location();
   2898 
   2899     PaintPhase phase = paintInfo.phase;
   2900 
   2901     // Check if we need to do anything at all.
   2902     // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
   2903     // paints the root's background.
   2904     if (!isRoot()) {
   2905         LayoutRect overflowBox = overflowRectForPaintRejection();
   2906         flipForWritingMode(overflowBox);
   2907         overflowBox.inflate(maximalOutlineSize(paintInfo.phase));
   2908         overflowBox.moveBy(adjustedPaintOffset);
   2909         if (!overflowBox.intersects(paintInfo.rect))
   2910             return;
   2911     }
   2912 
   2913     // There are some cases where not all clipped visual overflow is accounted for.
   2914     // FIXME: reduce the number of such cases.
   2915     ContentsClipBehavior contentsClipBehavior = ForceContentsClip;
   2916     if (hasOverflowClip() && !hasControlClip() && !(shouldPaintSelectionGaps() && phase == PaintPhaseForeground) && !hasCaret())
   2917         contentsClipBehavior = SkipContentsClipIfPossible;
   2918 
   2919     bool pushedClip = pushContentsClip(paintInfo, adjustedPaintOffset, contentsClipBehavior);
   2920     paintObject(paintInfo, adjustedPaintOffset);
   2921     if (pushedClip)
   2922         popContentsClip(paintInfo, phase, adjustedPaintOffset);
   2923 
   2924     // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
   2925     // z-index.  We paint after we painted the background/border, so that the scrollbars will
   2926     // sit above the background/border.
   2927     if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && paintInfo.shouldPaintWithinRoot(this) && !paintInfo.paintRootBackgroundOnly())
   2928         layer()->paintOverflowControls(paintInfo.context, roundedIntPoint(adjustedPaintOffset), paintInfo.rect);
   2929 }
   2930 
   2931 void RenderBlock::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
   2932 {
   2933     if (paintInfo.context->paintingDisabled())
   2934         return;
   2935 
   2936     const Color& ruleColor = resolveColor(CSSPropertyWebkitColumnRuleColor);
   2937     bool ruleTransparent = style()->columnRuleIsTransparent();
   2938     EBorderStyle ruleStyle = style()->columnRuleStyle();
   2939     LayoutUnit ruleThickness = style()->columnRuleWidth();
   2940     LayoutUnit colGap = columnGap();
   2941     bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent;
   2942     if (!renderRule)
   2943         return;
   2944 
   2945     ColumnInfo* colInfo = columnInfo();
   2946     unsigned colCount = columnCount(colInfo);
   2947 
   2948     bool antialias = shouldAntialiasLines(paintInfo.context);
   2949 
   2950     if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
   2951         bool leftToRight = style()->isLeftToRightDirection() ^ colInfo->progressionIsReversed();
   2952         LayoutUnit currLogicalLeftOffset = leftToRight ? LayoutUnit() : contentLogicalWidth();
   2953         LayoutUnit ruleAdd = logicalLeftOffsetForContent();
   2954         LayoutUnit ruleLogicalLeft = leftToRight ? LayoutUnit() : contentLogicalWidth();
   2955         LayoutUnit inlineDirectionSize = colInfo->desiredColumnWidth();
   2956         BoxSide boxSide = isHorizontalWritingMode()
   2957             ? leftToRight ? BSLeft : BSRight
   2958             : leftToRight ? BSTop : BSBottom;
   2959 
   2960         for (unsigned i = 0; i < colCount; i++) {
   2961             // Move to the next position.
   2962             if (leftToRight) {
   2963                 ruleLogicalLeft += inlineDirectionSize + colGap / 2;
   2964                 currLogicalLeftOffset += inlineDirectionSize + colGap;
   2965             } else {
   2966                 ruleLogicalLeft -= (inlineDirectionSize + colGap / 2);
   2967                 currLogicalLeftOffset -= (inlineDirectionSize + colGap);
   2968             }
   2969 
   2970             // Now paint the column rule.
   2971             if (i < colCount - 1) {
   2972                 LayoutUnit ruleLeft = isHorizontalWritingMode() ? paintOffset.x() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd : paintOffset.x() + borderLeft() + paddingLeft();
   2973                 LayoutUnit ruleRight = isHorizontalWritingMode() ? ruleLeft + ruleThickness : ruleLeft + contentWidth();
   2974                 LayoutUnit ruleTop = isHorizontalWritingMode() ? paintOffset.y() + borderTop() + paddingTop() : paintOffset.y() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd;
   2975                 LayoutUnit ruleBottom = isHorizontalWritingMode() ? ruleTop + contentHeight() : ruleTop + ruleThickness;
   2976                 IntRect pixelSnappedRuleRect = pixelSnappedIntRectFromEdges(ruleLeft, ruleTop, ruleRight, ruleBottom);
   2977                 drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
   2978             }
   2979 
   2980             ruleLogicalLeft = currLogicalLeftOffset;
   2981         }
   2982     } else {
   2983         bool topToBottom = !style()->isFlippedBlocksWritingMode() ^ colInfo->progressionIsReversed();
   2984         LayoutUnit ruleLeft = isHorizontalWritingMode()
   2985             ? borderLeft() + paddingLeft()
   2986             : colGap / 2 - colGap - ruleThickness / 2 + (!colInfo->progressionIsReversed() ? borderBefore() + paddingBefore() : borderAfter() + paddingAfter());
   2987         LayoutUnit ruleWidth = isHorizontalWritingMode() ? contentWidth() : ruleThickness;
   2988         LayoutUnit ruleTop = isHorizontalWritingMode()
   2989             ? colGap / 2 - colGap - ruleThickness / 2 + (!colInfo->progressionIsReversed() ? borderBefore() + paddingBefore() : borderAfter() + paddingAfter())
   2990             : borderStart() + paddingStart();
   2991         LayoutUnit ruleHeight = isHorizontalWritingMode() ? ruleThickness : contentHeight();
   2992         LayoutRect ruleRect(ruleLeft, ruleTop, ruleWidth, ruleHeight);
   2993 
   2994         if (!topToBottom) {
   2995             if (isHorizontalWritingMode())
   2996                 ruleRect.setY(height() - ruleRect.maxY());
   2997             else
   2998                 ruleRect.setX(width() - ruleRect.maxX());
   2999         }
   3000 
   3001         ruleRect.moveBy(paintOffset);
   3002 
   3003         BoxSide boxSide = isHorizontalWritingMode()
   3004             ? topToBottom ? BSTop : BSBottom
   3005             : topToBottom ? BSLeft : BSRight;
   3006 
   3007         LayoutSize step(0, topToBottom ? colInfo->columnHeight() + colGap : -(colInfo->columnHeight() + colGap));
   3008         if (!isHorizontalWritingMode())
   3009             step = step.transposedSize();
   3010 
   3011         for (unsigned i = 1; i < colCount; i++) {
   3012             ruleRect.move(step);
   3013             IntRect pixelSnappedRuleRect = pixelSnappedIntRect(ruleRect);
   3014             drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
   3015         }
   3016     }
   3017 }
   3018 
   3019 void RenderBlock::paintColumnContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset, bool paintingFloats)
   3020 {
   3021     // We need to do multiple passes, breaking up our child painting into strips.
   3022     GraphicsContext* context = paintInfo.context;
   3023     ColumnInfo* colInfo = columnInfo();
   3024     unsigned colCount = columnCount(colInfo);
   3025     if (!colCount)
   3026         return;
   3027     LayoutUnit currLogicalTopOffset = 0;
   3028     LayoutUnit colGap = columnGap();
   3029     for (unsigned i = 0; i < colCount; i++) {
   3030         // For each rect, we clip to the rect, and then we adjust our coords.
   3031         LayoutRect colRect = columnRectAt(colInfo, i);
   3032         flipForWritingMode(colRect);
   3033         LayoutUnit logicalLeftOffset = (isHorizontalWritingMode() ? colRect.x() : colRect.y()) - logicalLeftOffsetForContent();
   3034         LayoutSize offset = isHorizontalWritingMode() ? LayoutSize(logicalLeftOffset, currLogicalTopOffset) : LayoutSize(currLogicalTopOffset, logicalLeftOffset);
   3035         if (colInfo->progressionAxis() == ColumnInfo::BlockAxis) {
   3036             if (isHorizontalWritingMode())
   3037                 offset.expand(0, colRect.y() - borderTop() - paddingTop());
   3038             else
   3039                 offset.expand(colRect.x() - borderLeft() - paddingLeft(), 0);
   3040         }
   3041         colRect.moveBy(paintOffset);
   3042         PaintInfo info(paintInfo);
   3043         info.rect.intersect(pixelSnappedIntRect(colRect));
   3044 
   3045         if (!info.rect.isEmpty()) {
   3046             GraphicsContextStateSaver stateSaver(*context);
   3047             LayoutRect clipRect(colRect);
   3048 
   3049             if (i < colCount - 1) {
   3050                 if (isHorizontalWritingMode())
   3051                     clipRect.expand(colGap / 2, 0);
   3052                 else
   3053                     clipRect.expand(0, colGap / 2);
   3054             }
   3055             // Each strip pushes a clip, since column boxes are specified as being
   3056             // like overflow:hidden.
   3057             // FIXME: Content and column rules that extend outside column boxes at the edges of the multi-column element
   3058             // are clipped according to the 'overflow' property.
   3059             context->clip(pixelSnappedIntRect(clipRect));
   3060 
   3061             // Adjust our x and y when painting.
   3062             LayoutPoint adjustedPaintOffset = paintOffset + offset;
   3063             if (paintingFloats)
   3064                 paintFloats(info, adjustedPaintOffset, paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip);
   3065             else
   3066                 paintContents(info, adjustedPaintOffset);
   3067         }
   3068 
   3069         LayoutUnit blockDelta = (isHorizontalWritingMode() ? colRect.height() : colRect.width());
   3070         if (style()->isFlippedBlocksWritingMode())
   3071             currLogicalTopOffset += blockDelta;
   3072         else
   3073             currLogicalTopOffset -= blockDelta;
   3074     }
   3075 }
   3076 
   3077 void RenderBlock::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
   3078 {
   3079     // Avoid painting descendants of the root element when stylesheets haven't loaded.  This eliminates FOUC.
   3080     // It's ok not to draw, because later on, when all the stylesheets do load, styleResolverChanged() on the Document
   3081     // will do a full repaint.
   3082     if (document()->didLayoutWithPendingStylesheets() && !isRenderView())
   3083         return;
   3084 
   3085     if (childrenInline())
   3086         m_lineBoxes.paint(this, paintInfo, paintOffset);
   3087     else {
   3088         PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase;
   3089         newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase;
   3090 
   3091         // We don't paint our own background, but we do let the kids paint their backgrounds.
   3092         PaintInfo paintInfoForChild(paintInfo);
   3093         paintInfoForChild.phase = newPhase;
   3094         paintInfoForChild.updatePaintingRootForChildren(this);
   3095         paintChildren(paintInfoForChild, paintOffset);
   3096     }
   3097 }
   3098 
   3099 void RenderBlock::paintChildren(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
   3100 {
   3101     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox())
   3102         paintChild(child, paintInfo, paintOffset);
   3103 }
   3104 
   3105 void RenderBlock::paintChild(RenderBox* child, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
   3106 {
   3107     LayoutPoint childPoint = flipForWritingModeForChild(child, paintOffset);
   3108     if (!child->hasSelfPaintingLayer() && !child->isFloating())
   3109         child->paint(paintInfo, childPoint);
   3110 }
   3111 
   3112 bool RenderBlock::hasCaret(CaretType type) const
   3113 {
   3114     // Paint the caret if the FrameSelection says so or if caret browsing is enabled
   3115     bool caretBrowsing = frame()->settings() && frame()->settings()->caretBrowsingEnabled();
   3116     RenderObject* caretPainter;
   3117     bool isContentEditable;
   3118     if (type == CursorCaret) {
   3119         caretPainter = frame()->selection()->caretRenderer();
   3120         isContentEditable = frame()->selection()->rendererIsEditable();
   3121     } else {
   3122         caretPainter = frame()->page()->dragCaretController().caretRenderer();
   3123         isContentEditable = frame()->page()->dragCaretController().isContentEditable();
   3124     }
   3125     return caretPainter == this && (isContentEditable || caretBrowsing);
   3126 }
   3127 
   3128 void RenderBlock::paintCaret(PaintInfo& paintInfo, const LayoutPoint& paintOffset, CaretType type)
   3129 {
   3130     if (!hasCaret(type))
   3131         return;
   3132 
   3133     if (type == CursorCaret)
   3134         frame()->selection()->paintCaret(paintInfo.context, paintOffset, paintInfo.rect);
   3135     else
   3136         frame()->page()->dragCaretController().paintDragCaret(frame(), paintInfo.context, paintOffset, paintInfo.rect);
   3137 }
   3138 
   3139 void RenderBlock::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
   3140 {
   3141     PaintPhase paintPhase = paintInfo.phase;
   3142 
   3143     // 1. paint background, borders etc
   3144     if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && style()->visibility() == VISIBLE) {
   3145         if (hasBoxDecorations())
   3146             paintBoxDecorations(paintInfo, paintOffset);
   3147         if (hasColumns() && !paintInfo.paintRootBackgroundOnly())
   3148             paintColumnRules(paintInfo, paintOffset);
   3149     }
   3150 
   3151     if (paintPhase == PaintPhaseMask && style()->visibility() == VISIBLE) {
   3152         paintMask(paintInfo, paintOffset);
   3153         return;
   3154     }
   3155 
   3156     // We're done.  We don't bother painting any children.
   3157     if (paintPhase == PaintPhaseBlockBackground || paintInfo.paintRootBackgroundOnly())
   3158         return;
   3159 
   3160     // Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div).
   3161     LayoutPoint scrolledOffset = paintOffset;
   3162     if (hasOverflowClip())
   3163         scrolledOffset.move(-scrolledContentOffset());
   3164 
   3165     // 2. paint contents
   3166     if (paintPhase != PaintPhaseSelfOutline) {
   3167         if (hasColumns())
   3168             paintColumnContents(paintInfo, scrolledOffset);
   3169         else
   3170             paintContents(paintInfo, scrolledOffset);
   3171     }
   3172 
   3173     // 3. paint selection
   3174     // FIXME: Make this work with multi column layouts.  For now don't fill gaps.
   3175     bool isPrinting = document()->printing();
   3176     if (!isPrinting && !hasColumns())
   3177         paintSelection(paintInfo, scrolledOffset); // Fill in gaps in selection on lines and between blocks.
   3178 
   3179     // 4. paint floats.
   3180     if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip) {
   3181         if (hasColumns())
   3182             paintColumnContents(paintInfo, scrolledOffset, true);
   3183         else
   3184             paintFloats(paintInfo, scrolledOffset, paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip);
   3185     }
   3186 
   3187     // 5. paint outline.
   3188     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
   3189         paintOutline(paintInfo, LayoutRect(paintOffset, size()));
   3190 
   3191     // 6. paint continuation outlines.
   3192     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) {
   3193         RenderInline* inlineCont = inlineElementContinuation();
   3194         if (inlineCont && inlineCont->hasOutline() && inlineCont->style()->visibility() == VISIBLE) {
   3195             RenderInline* inlineRenderer = toRenderInline(inlineCont->node()->renderer());
   3196             RenderBlock* cb = containingBlock();
   3197 
   3198             bool inlineEnclosedInSelfPaintingLayer = false;
   3199             for (RenderBoxModelObject* box = inlineRenderer; box != cb; box = box->parent()->enclosingBoxModelObject()) {
   3200                 if (box->hasSelfPaintingLayer()) {
   3201                     inlineEnclosedInSelfPaintingLayer = true;
   3202                     break;
   3203                 }
   3204             }
   3205 
   3206             // Do not add continuations for outline painting by our containing block if we are a relative positioned
   3207             // anonymous block (i.e. have our own layer), paint them straightaway instead. This is because a block depends on renderers in its continuation table being
   3208             // in the same layer.
   3209             if (!inlineEnclosedInSelfPaintingLayer && !hasLayer())
   3210                 cb->addContinuationWithOutline(inlineRenderer);
   3211             else if (!inlineRenderer->firstLineBox() || (!inlineEnclosedInSelfPaintingLayer && hasLayer()))
   3212                 inlineRenderer->paintOutline(paintInfo, paintOffset - locationOffset() + inlineRenderer->containingBlock()->location());
   3213         }
   3214         paintContinuationOutlines(paintInfo, paintOffset);
   3215     }
   3216 
   3217     // 7. paint caret.
   3218     // If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground,
   3219     // then paint the caret.
   3220     if (paintPhase == PaintPhaseForeground) {
   3221         paintCaret(paintInfo, paintOffset, CursorCaret);
   3222         paintCaret(paintInfo, paintOffset, DragCaret);
   3223     }
   3224 }
   3225 
   3226 LayoutPoint RenderBlock::flipFloatForWritingModeForChild(const FloatingObject* child, const LayoutPoint& point) const
   3227 {
   3228     if (!style()->isFlippedBlocksWritingMode())
   3229         return point;
   3230 
   3231     // This is similar to RenderBox::flipForWritingModeForChild. We have to subtract out our left/top offsets twice, since
   3232     // it's going to get added back in. We hide this complication here so that the calling code looks normal for the unflipped
   3233     // case.
   3234     if (isHorizontalWritingMode())
   3235         return LayoutPoint(point.x(), point.y() + height() - child->renderer()->height() - 2 * yPositionForFloatIncludingMargin(child));
   3236     return LayoutPoint(point.x() + width() - child->renderer()->width() - 2 * xPositionForFloatIncludingMargin(child), point.y());
   3237 }
   3238 
   3239 void RenderBlock::paintFloats(PaintInfo& paintInfo, const LayoutPoint& paintOffset, bool preservePhase)
   3240 {
   3241     if (!m_floatingObjects)
   3242         return;
   3243 
   3244     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3245     FloatingObjectSetIterator end = floatingObjectSet.end();
   3246     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   3247         FloatingObject* r = *it;
   3248         // Only paint the object if our m_shouldPaint flag is set.
   3249         if (r->shouldPaint() && !r->m_renderer->hasSelfPaintingLayer()) {
   3250             PaintInfo currentPaintInfo(paintInfo);
   3251             currentPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
   3252             LayoutPoint childPoint = flipFloatForWritingModeForChild(r, LayoutPoint(paintOffset.x() + xPositionForFloatIncludingMargin(r) - r->m_renderer->x(), paintOffset.y() + yPositionForFloatIncludingMargin(r) - r->m_renderer->y()));
   3253             r->m_renderer->paint(currentPaintInfo, childPoint);
   3254             if (!preservePhase) {
   3255                 currentPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
   3256                 r->m_renderer->paint(currentPaintInfo, childPoint);
   3257                 currentPaintInfo.phase = PaintPhaseFloat;
   3258                 r->m_renderer->paint(currentPaintInfo, childPoint);
   3259                 currentPaintInfo.phase = PaintPhaseForeground;
   3260                 r->m_renderer->paint(currentPaintInfo, childPoint);
   3261                 currentPaintInfo.phase = PaintPhaseOutline;
   3262                 r->m_renderer->paint(currentPaintInfo, childPoint);
   3263             }
   3264         }
   3265     }
   3266 }
   3267 
   3268 RenderInline* RenderBlock::inlineElementContinuation() const
   3269 {
   3270     RenderBoxModelObject* continuation = this->continuation();
   3271     return continuation && continuation->isInline() ? toRenderInline(continuation) : 0;
   3272 }
   3273 
   3274 RenderBlock* RenderBlock::blockElementContinuation() const
   3275 {
   3276     RenderBoxModelObject* currentContinuation = continuation();
   3277     if (!currentContinuation || currentContinuation->isInline())
   3278         return 0;
   3279     RenderBlock* nextContinuation = toRenderBlock(currentContinuation);
   3280     if (nextContinuation->isAnonymousBlock())
   3281         return nextContinuation->blockElementContinuation();
   3282     return nextContinuation;
   3283 }
   3284 
   3285 static ContinuationOutlineTableMap* continuationOutlineTable()
   3286 {
   3287     DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ());
   3288     return &table;
   3289 }
   3290 
   3291 void RenderBlock::addContinuationWithOutline(RenderInline* flow)
   3292 {
   3293     // We can't make this work if the inline is in a layer.  We'll just rely on the broken
   3294     // way of painting.
   3295     ASSERT(!flow->layer() && !flow->isInlineElementContinuation());
   3296 
   3297     ContinuationOutlineTableMap* table = continuationOutlineTable();
   3298     ListHashSet<RenderInline*>* continuations = table->get(this);
   3299     if (!continuations) {
   3300         continuations = new ListHashSet<RenderInline*>;
   3301         table->set(this, adoptPtr(continuations));
   3302     }
   3303 
   3304     continuations->add(flow);
   3305 }
   3306 
   3307 bool RenderBlock::paintsContinuationOutline(RenderInline* flow)
   3308 {
   3309     ContinuationOutlineTableMap* table = continuationOutlineTable();
   3310     if (table->isEmpty())
   3311         return false;
   3312 
   3313     ListHashSet<RenderInline*>* continuations = table->get(this);
   3314     if (!continuations)
   3315         return false;
   3316 
   3317     return continuations->contains(flow);
   3318 }
   3319 
   3320 void RenderBlock::paintContinuationOutlines(PaintInfo& info, const LayoutPoint& paintOffset)
   3321 {
   3322     ContinuationOutlineTableMap* table = continuationOutlineTable();
   3323     if (table->isEmpty())
   3324         return;
   3325 
   3326     OwnPtr<ListHashSet<RenderInline*> > continuations = table->take(this);
   3327     if (!continuations)
   3328         return;
   3329 
   3330     LayoutPoint accumulatedPaintOffset = paintOffset;
   3331     // Paint each continuation outline.
   3332     ListHashSet<RenderInline*>::iterator end = continuations->end();
   3333     for (ListHashSet<RenderInline*>::iterator it = continuations->begin(); it != end; ++it) {
   3334         // Need to add in the coordinates of the intervening blocks.
   3335         RenderInline* flow = *it;
   3336         RenderBlock* block = flow->containingBlock();
   3337         for ( ; block && block != this; block = block->containingBlock())
   3338             accumulatedPaintOffset.moveBy(block->location());
   3339         ASSERT(block);
   3340         flow->paintOutline(info, accumulatedPaintOffset);
   3341     }
   3342 }
   3343 
   3344 bool RenderBlock::shouldPaintSelectionGaps() const
   3345 {
   3346     return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot();
   3347 }
   3348 
   3349 bool RenderBlock::isSelectionRoot() const
   3350 {
   3351     if (isPseudoElement())
   3352         return false;
   3353     ASSERT(node() || isAnonymous());
   3354 
   3355     // FIXME: Eventually tables should have to learn how to fill gaps between cells, at least in simple non-spanning cases.
   3356     if (isTable())
   3357         return false;
   3358 
   3359     if (isBody() || isRoot() || hasOverflowClip()
   3360         || isPositioned() || isFloating()
   3361         || isTableCell() || isInlineBlockOrInlineTable()
   3362         || hasTransform() || hasReflection() || hasMask() || isWritingModeRoot()
   3363         || isRenderFlowThread())
   3364         return true;
   3365 
   3366     if (view() && view()->selectionStart()) {
   3367         Node* startElement = view()->selectionStart()->node();
   3368         if (startElement && startElement->rootEditableElement() == node())
   3369             return true;
   3370     }
   3371 
   3372     return false;
   3373 }
   3374 
   3375 GapRects RenderBlock::selectionGapRectsForRepaint(const RenderLayerModelObject* repaintContainer)
   3376 {
   3377     ASSERT(!needsLayout());
   3378 
   3379     if (!shouldPaintSelectionGaps())
   3380         return GapRects();
   3381 
   3382     TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
   3383     mapLocalToContainer(repaintContainer, transformState, ApplyContainerFlip | UseTransforms);
   3384     LayoutPoint offsetFromRepaintContainer = roundedLayoutPoint(transformState.mappedPoint());
   3385 
   3386     if (hasOverflowClip())
   3387         offsetFromRepaintContainer -= scrolledContentOffset();
   3388 
   3389     LayoutUnit lastTop = 0;
   3390     LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop);
   3391     LayoutUnit lastRight = logicalRightSelectionOffset(this, lastTop);
   3392 
   3393     return selectionGaps(this, offsetFromRepaintContainer, IntSize(), lastTop, lastLeft, lastRight);
   3394 }
   3395 
   3396 void RenderBlock::paintSelection(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
   3397 {
   3398     if (shouldPaintSelectionGaps() && paintInfo.phase == PaintPhaseForeground) {
   3399         LayoutUnit lastTop = 0;
   3400         LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop);
   3401         LayoutUnit lastRight = logicalRightSelectionOffset(this, lastTop);
   3402         GraphicsContextStateSaver stateSaver(*paintInfo.context);
   3403 
   3404         LayoutRect gapRectsBounds = selectionGaps(this, paintOffset, LayoutSize(), lastTop, lastLeft, lastRight, &paintInfo);
   3405         if (!gapRectsBounds.isEmpty()) {
   3406             if (RenderLayer* layer = enclosingLayer()) {
   3407                 gapRectsBounds.moveBy(-paintOffset);
   3408                 if (!hasLayer()) {
   3409                     LayoutRect localBounds(gapRectsBounds);
   3410                     flipForWritingMode(localBounds);
   3411                     gapRectsBounds = localToContainerQuad(FloatRect(localBounds), layer->renderer()).enclosingBoundingBox();
   3412                     if (layer->renderer()->hasOverflowClip())
   3413                         gapRectsBounds.move(layer->renderBox()->scrolledContentOffset());
   3414                 }
   3415                 layer->addBlockSelectionGapsBounds(gapRectsBounds);
   3416             }
   3417         }
   3418     }
   3419 }
   3420 
   3421 static void clipOutPositionedObjects(const PaintInfo* paintInfo, const LayoutPoint& offset, TrackedRendererListHashSet* positionedObjects)
   3422 {
   3423     if (!positionedObjects)
   3424         return;
   3425 
   3426     TrackedRendererListHashSet::const_iterator end = positionedObjects->end();
   3427     for (TrackedRendererListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
   3428         RenderBox* r = *it;
   3429         paintInfo->context->clipOut(IntRect(offset.x() + r->x(), offset.y() + r->y(), r->width(), r->height()));
   3430     }
   3431 }
   3432 
   3433 static LayoutUnit blockDirectionOffset(RenderBlock* rootBlock, const LayoutSize& offsetFromRootBlock)
   3434 {
   3435     return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.height() : offsetFromRootBlock.width();
   3436 }
   3437 
   3438 static LayoutUnit inlineDirectionOffset(RenderBlock* rootBlock, const LayoutSize& offsetFromRootBlock)
   3439 {
   3440     return rootBlock->isHorizontalWritingMode() ? offsetFromRootBlock.width() : offsetFromRootBlock.height();
   3441 }
   3442 
   3443 LayoutRect RenderBlock::logicalRectToPhysicalRect(const LayoutPoint& rootBlockPhysicalPosition, const LayoutRect& logicalRect)
   3444 {
   3445     LayoutRect result;
   3446     if (isHorizontalWritingMode())
   3447         result = logicalRect;
   3448     else
   3449         result = LayoutRect(logicalRect.y(), logicalRect.x(), logicalRect.height(), logicalRect.width());
   3450     flipForWritingMode(result);
   3451     result.moveBy(rootBlockPhysicalPosition);
   3452     return result;
   3453 }
   3454 
   3455 GapRects RenderBlock::selectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
   3456                                     LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* paintInfo)
   3457 {
   3458     // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore.
   3459     // Clip out floating and positioned objects when painting selection gaps.
   3460     if (paintInfo) {
   3461         // Note that we don't clip out overflow for positioned objects.  We just stick to the border box.
   3462         LayoutRect flippedBlockRect(offsetFromRootBlock.width(), offsetFromRootBlock.height(), width(), height());
   3463         rootBlock->flipForWritingMode(flippedBlockRect);
   3464         flippedBlockRect.moveBy(rootBlockPhysicalPosition);
   3465         clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), positionedObjects());
   3466         if (isBody() || isRoot()) // The <body> must make sure to examine its containingBlock's positioned objects.
   3467             for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock())
   3468                 clipOutPositionedObjects(paintInfo, LayoutPoint(cb->x(), cb->y()), cb->positionedObjects()); // FIXME: Not right for flipped writing modes.
   3469         if (m_floatingObjects) {
   3470             const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3471             FloatingObjectSetIterator end = floatingObjectSet.end();
   3472             for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   3473                 FloatingObject* r = *it;
   3474                 LayoutRect floatBox(offsetFromRootBlock.width() + xPositionForFloatIncludingMargin(r),
   3475                                     offsetFromRootBlock.height() + yPositionForFloatIncludingMargin(r),
   3476                                     r->m_renderer->width(), r->m_renderer->height());
   3477                 rootBlock->flipForWritingMode(floatBox);
   3478                 floatBox.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
   3479                 paintInfo->context->clipOut(pixelSnappedIntRect(floatBox));
   3480             }
   3481         }
   3482     }
   3483 
   3484     // 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
   3485     // fixed).
   3486     GapRects result;
   3487     if (!isBlockFlow()) // FIXME: Make multi-column selection gap filling work someday.
   3488         return result;
   3489 
   3490     if (hasColumns() || hasTransform() || style()->columnSpan()) {
   3491         // FIXME: We should learn how to gap fill multiple columns and transforms eventually.
   3492         lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
   3493         lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight());
   3494         lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight());
   3495         return result;
   3496     }
   3497 
   3498     if (childrenInline())
   3499         result = inlineSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
   3500     else
   3501         result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
   3502 
   3503     // Go ahead and fill the vertical gap all the way to the bottom of our block if the selection extends past our block.
   3504     if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd))
   3505         result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
   3506                                              logicalHeight(), paintInfo));
   3507     return result;
   3508 }
   3509 
   3510 GapRects RenderBlock::inlineSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
   3511                                           LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* paintInfo)
   3512 {
   3513     GapRects result;
   3514 
   3515     bool containsStart = selectionState() == SelectionStart || selectionState() == SelectionBoth;
   3516 
   3517     if (!firstLineBox()) {
   3518         if (containsStart) {
   3519             // Go ahead and update our lastLogicalTop to be the bottom of the block.  <hr>s or empty blocks with height can trip this
   3520             // case.
   3521             lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalHeight();
   3522             lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight());
   3523             lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight());
   3524         }
   3525         return result;
   3526     }
   3527 
   3528     RootInlineBox* lastSelectedLine = 0;
   3529     RootInlineBox* curr;
   3530     for (curr = firstRootBox(); curr && !curr->hasSelectedChildren(); curr = curr->nextRootBox()) { }
   3531 
   3532     // Now paint the gaps for the lines.
   3533     for (; curr && curr->hasSelectedChildren(); curr = curr->nextRootBox()) {
   3534         LayoutUnit selTop =  curr->selectionTopAdjustedForPrecedingBlock();
   3535         LayoutUnit selHeight = curr->selectionHeightAdjustedForPrecedingBlock();
   3536 
   3537         if (!containsStart && !lastSelectedLine &&
   3538             selectionState() != SelectionStart && selectionState() != SelectionBoth)
   3539             result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
   3540                                                  selTop, paintInfo));
   3541 
   3542         LayoutRect logicalRect(curr->logicalLeft(), selTop, curr->logicalWidth(), selTop + selHeight);
   3543         logicalRect.move(isHorizontalWritingMode() ? offsetFromRootBlock : offsetFromRootBlock.transposedSize());
   3544         LayoutRect physicalRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect);
   3545         if (!paintInfo || (isHorizontalWritingMode() && physicalRect.y() < paintInfo->rect.maxY() && physicalRect.maxY() > paintInfo->rect.y())
   3546             || (!isHorizontalWritingMode() && physicalRect.x() < paintInfo->rect.maxX() && physicalRect.maxX() > paintInfo->rect.x()))
   3547             result.unite(curr->lineSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, selTop, selHeight, paintInfo));
   3548 
   3549         lastSelectedLine = curr;
   3550     }
   3551 
   3552     if (containsStart && !lastSelectedLine)
   3553         // VisibleSelection must start just after our last line.
   3554         lastSelectedLine = lastRootBox();
   3555 
   3556     if (lastSelectedLine && selectionState() != SelectionEnd && selectionState() != SelectionBoth) {
   3557         // Go ahead and update our lastY to be the bottom of the last selected line.
   3558         lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + lastSelectedLine->selectionBottom();
   3559         lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
   3560         lastLogicalRight = logicalRightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom());
   3561     }
   3562     return result;
   3563 }
   3564 
   3565 GapRects RenderBlock::blockSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
   3566                                          LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* paintInfo)
   3567 {
   3568     GapRects result;
   3569 
   3570     // Go ahead and jump right to the first block child that contains some selected objects.
   3571     RenderBox* curr;
   3572     for (curr = firstChildBox(); curr && curr->selectionState() == SelectionNone; curr = curr->nextSiblingBox()) { }
   3573 
   3574     for (bool sawSelectionEnd = false; curr && !sawSelectionEnd; curr = curr->nextSiblingBox()) {
   3575         SelectionState childState = curr->selectionState();
   3576         if (childState == SelectionBoth || childState == SelectionEnd)
   3577             sawSelectionEnd = true;
   3578 
   3579         if (curr->isFloatingOrOutOfFlowPositioned())
   3580             continue; // We must be a normal flow object in order to even be considered.
   3581 
   3582         if (curr->isInFlowPositioned() && curr->hasLayer()) {
   3583             // If the relposition offset is anything other than 0, then treat this just like an absolute positioned element.
   3584             // Just disregard it completely.
   3585             LayoutSize relOffset = curr->layer()->offsetForInFlowPosition();
   3586             if (relOffset.width() || relOffset.height())
   3587                 continue;
   3588         }
   3589 
   3590         bool paintsOwnSelection = curr->shouldPaintSelectionGaps() || curr->isTable(); // FIXME: Eventually we won't special-case table like this.
   3591         bool fillBlockGaps = paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone);
   3592         if (fillBlockGaps) {
   3593             // We need to fill the vertical gap above this object.
   3594             if (childState == SelectionEnd || childState == SelectionInside)
   3595                 // Fill the gap above the object.
   3596                 result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
   3597                                                      curr->logicalTop(), paintInfo));
   3598 
   3599             // 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*
   3600             // our object.  We know this if the selection did not end inside our object.
   3601             if (paintsOwnSelection && (childState == SelectionStart || sawSelectionEnd))
   3602                 childState = SelectionNone;
   3603 
   3604             // Fill side gaps on this object based off its state.
   3605             bool leftGap, rightGap;
   3606             getSelectionGapInfo(childState, leftGap, rightGap);
   3607 
   3608             if (leftGap)
   3609                 result.uniteLeft(logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalLeft(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
   3610             if (rightGap)
   3611                 result.uniteRight(logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalRight(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
   3612 
   3613             // Update lastLogicalTop to be just underneath the object.  lastLogicalLeft and lastLogicalRight extend as far as
   3614             // they can without bumping into floating or positioned objects.  Ideally they will go right up
   3615             // to the border of the root selection block.
   3616             lastLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + curr->logicalBottom();
   3617             lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, curr->logicalBottom());
   3618             lastLogicalRight = logicalRightSelectionOffset(rootBlock, curr->logicalBottom());
   3619         } else if (childState != SelectionNone)
   3620             // We must be a block that has some selected object inside it.  Go ahead and recur.
   3621             result.unite(toRenderBlock(curr)->selectionGaps(rootBlock, rootBlockPhysicalPosition, LayoutSize(offsetFromRootBlock.width() + curr->x(), offsetFromRootBlock.height() + curr->y()),
   3622                                                             lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo));
   3623     }
   3624     return result;
   3625 }
   3626 
   3627 LayoutRect RenderBlock::blockSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
   3628                                           LayoutUnit lastLogicalTop, LayoutUnit lastLogicalLeft, LayoutUnit lastLogicalRight, LayoutUnit logicalBottom, const PaintInfo* paintInfo)
   3629 {
   3630     LayoutUnit logicalTop = lastLogicalTop;
   3631     LayoutUnit logicalHeight = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalBottom - logicalTop;
   3632     if (logicalHeight <= 0)
   3633         return LayoutRect();
   3634 
   3635     // Get the selection offsets for the bottom of the gap
   3636     LayoutUnit logicalLeft = max(lastLogicalLeft, logicalLeftSelectionOffset(rootBlock, logicalBottom));
   3637     LayoutUnit logicalRight = min(lastLogicalRight, logicalRightSelectionOffset(rootBlock, logicalBottom));
   3638     LayoutUnit logicalWidth = logicalRight - logicalLeft;
   3639     if (logicalWidth <= 0)
   3640         return LayoutRect();
   3641 
   3642     LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(logicalLeft, logicalTop, logicalWidth, logicalHeight));
   3643     if (paintInfo)
   3644         paintInfo->context->fillRect(pixelSnappedIntRect(gapRect), selectionBackgroundColor());
   3645     return gapRect;
   3646 }
   3647 
   3648 LayoutRect RenderBlock::logicalLeftSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
   3649                                                 RenderObject* selObj, LayoutUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo* paintInfo)
   3650 {
   3651     LayoutUnit rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
   3652     LayoutUnit rootBlockLogicalLeft = max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight));
   3653     LayoutUnit rootBlockLogicalRight = min(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + floorToInt(logicalLeft), min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight)));
   3654     LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
   3655     if (rootBlockLogicalWidth <= 0)
   3656         return LayoutRect();
   3657 
   3658     LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
   3659     if (paintInfo)
   3660         paintInfo->context->fillRect(pixelSnappedIntRect(gapRect), selObj->selectionBackgroundColor());
   3661     return gapRect;
   3662 }
   3663 
   3664 LayoutRect RenderBlock::logicalRightSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
   3665                                                  RenderObject* selObj, LayoutUnit logicalRight, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo* paintInfo)
   3666 {
   3667     LayoutUnit rootBlockLogicalTop = blockDirectionOffset(rootBlock, offsetFromRootBlock) + logicalTop;
   3668     LayoutUnit rootBlockLogicalLeft = max(inlineDirectionOffset(rootBlock, offsetFromRootBlock) + floorToInt(logicalRight), max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight)));
   3669     LayoutUnit rootBlockLogicalRight = min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight));
   3670     LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
   3671     if (rootBlockLogicalWidth <= 0)
   3672         return LayoutRect();
   3673 
   3674     LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
   3675     if (paintInfo)
   3676         paintInfo->context->fillRect(pixelSnappedIntRect(gapRect), selObj->selectionBackgroundColor());
   3677     return gapRect;
   3678 }
   3679 
   3680 void RenderBlock::getSelectionGapInfo(SelectionState state, bool& leftGap, bool& rightGap)
   3681 {
   3682     bool ltr = style()->isLeftToRightDirection();
   3683     leftGap = (state == RenderObject::SelectionInside) ||
   3684               (state == RenderObject::SelectionEnd && ltr) ||
   3685               (state == RenderObject::SelectionStart && !ltr);
   3686     rightGap = (state == RenderObject::SelectionInside) ||
   3687                (state == RenderObject::SelectionStart && ltr) ||
   3688                (state == RenderObject::SelectionEnd && !ltr);
   3689 }
   3690 
   3691 LayoutUnit RenderBlock::logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position)
   3692 {
   3693     LayoutUnit logicalLeft = logicalLeftOffsetForLine(position, false);
   3694     if (logicalLeft == logicalLeftOffsetForContent()) {
   3695         if (rootBlock != this)
   3696             // The border can potentially be further extended by our containingBlock().
   3697             return containingBlock()->logicalLeftSelectionOffset(rootBlock, position + logicalTop());
   3698         return logicalLeft;
   3699     } else {
   3700         RenderBlock* cb = this;
   3701         while (cb != rootBlock) {
   3702             logicalLeft += cb->logicalLeft();
   3703             cb = cb->containingBlock();
   3704         }
   3705     }
   3706     return logicalLeft;
   3707 }
   3708 
   3709 LayoutUnit RenderBlock::logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position)
   3710 {
   3711     LayoutUnit logicalRight = logicalRightOffsetForLine(position, false);
   3712     if (logicalRight == logicalRightOffsetForContent()) {
   3713         if (rootBlock != this)
   3714             // The border can potentially be further extended by our containingBlock().
   3715             return containingBlock()->logicalRightSelectionOffset(rootBlock, position + logicalTop());
   3716         return logicalRight;
   3717     } else {
   3718         RenderBlock* cb = this;
   3719         while (cb != rootBlock) {
   3720             logicalRight += cb->logicalLeft();
   3721             cb = cb->containingBlock();
   3722         }
   3723     }
   3724     return logicalRight;
   3725 }
   3726 
   3727 RenderBlock* RenderBlock::blockBeforeWithinSelectionRoot(LayoutSize& offset) const
   3728 {
   3729     if (isSelectionRoot())
   3730         return 0;
   3731 
   3732     const RenderObject* object = this;
   3733     RenderObject* sibling;
   3734     do {
   3735         sibling = object->previousSibling();
   3736         while (sibling && (!sibling->isRenderBlock() || toRenderBlock(sibling)->isSelectionRoot()))
   3737             sibling = sibling->previousSibling();
   3738 
   3739         offset -= LayoutSize(toRenderBlock(object)->logicalLeft(), toRenderBlock(object)->logicalTop());
   3740         object = object->parent();
   3741     } while (!sibling && object && object->isRenderBlock() && !toRenderBlock(object)->isSelectionRoot());
   3742 
   3743     if (!sibling)
   3744         return 0;
   3745 
   3746     RenderBlock* beforeBlock = toRenderBlock(sibling);
   3747 
   3748     offset += LayoutSize(beforeBlock->logicalLeft(), beforeBlock->logicalTop());
   3749 
   3750     RenderObject* child = beforeBlock->lastChild();
   3751     while (child && child->isRenderBlock()) {
   3752         beforeBlock = toRenderBlock(child);
   3753         offset += LayoutSize(beforeBlock->logicalLeft(), beforeBlock->logicalTop());
   3754         child = beforeBlock->lastChild();
   3755     }
   3756     return beforeBlock;
   3757 }
   3758 
   3759 void RenderBlock::insertIntoTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*& descendantsMap, TrackedContainerMap*& containerMap)
   3760 {
   3761     if (!descendantsMap) {
   3762         descendantsMap = new TrackedDescendantsMap;
   3763         containerMap = new TrackedContainerMap;
   3764     }
   3765 
   3766     TrackedRendererListHashSet* descendantSet = descendantsMap->get(this);
   3767     if (!descendantSet) {
   3768         descendantSet = new TrackedRendererListHashSet;
   3769         descendantsMap->set(this, adoptPtr(descendantSet));
   3770     }
   3771     bool added = descendantSet->add(descendant).isNewEntry;
   3772     if (!added) {
   3773         ASSERT(containerMap->get(descendant));
   3774         ASSERT(containerMap->get(descendant)->contains(this));
   3775         return;
   3776     }
   3777 
   3778     HashSet<RenderBlock*>* containerSet = containerMap->get(descendant);
   3779     if (!containerSet) {
   3780         containerSet = new HashSet<RenderBlock*>;
   3781         containerMap->set(descendant, adoptPtr(containerSet));
   3782     }
   3783     ASSERT(!containerSet->contains(this));
   3784     containerSet->add(this);
   3785 }
   3786 
   3787 void RenderBlock::removeFromTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*& descendantsMap, TrackedContainerMap*& containerMap)
   3788 {
   3789     if (!descendantsMap)
   3790         return;
   3791 
   3792     OwnPtr<HashSet<RenderBlock*> > containerSet = containerMap->take(descendant);
   3793     if (!containerSet)
   3794         return;
   3795 
   3796     HashSet<RenderBlock*>::iterator end = containerSet->end();
   3797     for (HashSet<RenderBlock*>::iterator it = containerSet->begin(); it != end; ++it) {
   3798         RenderBlock* container = *it;
   3799 
   3800         // FIXME: Disabling this assert temporarily until we fix the layout
   3801         // bugs associated with positioned objects not properly cleared from
   3802         // their ancestor chain before being moved. See webkit bug 93766.
   3803         // ASSERT(descendant->isDescendantOf(container));
   3804 
   3805         TrackedDescendantsMap::iterator descendantsMapIterator = descendantsMap->find(container);
   3806         ASSERT(descendantsMapIterator != descendantsMap->end());
   3807         if (descendantsMapIterator == descendantsMap->end())
   3808             continue;
   3809         TrackedRendererListHashSet* descendantSet = descendantsMapIterator->value.get();
   3810         ASSERT(descendantSet->contains(descendant));
   3811         descendantSet->remove(descendant);
   3812         if (descendantSet->isEmpty())
   3813             descendantsMap->remove(descendantsMapIterator);
   3814     }
   3815 }
   3816 
   3817 TrackedRendererListHashSet* RenderBlock::positionedObjects() const
   3818 {
   3819     if (gPositionedDescendantsMap)
   3820         return gPositionedDescendantsMap->get(this);
   3821     return 0;
   3822 }
   3823 
   3824 void RenderBlock::insertPositionedObject(RenderBox* o)
   3825 {
   3826     ASSERT(!isAnonymousBlock());
   3827 
   3828     if (o->isRenderFlowThread())
   3829         return;
   3830 
   3831     insertIntoTrackedRendererMaps(o, gPositionedDescendantsMap, gPositionedContainerMap);
   3832 }
   3833 
   3834 void RenderBlock::removePositionedObject(RenderBox* o)
   3835 {
   3836     removeFromTrackedRendererMaps(o, gPositionedDescendantsMap, gPositionedContainerMap);
   3837 }
   3838 
   3839 void RenderBlock::removePositionedObjects(RenderBlock* o, ContainingBlockState containingBlockState)
   3840 {
   3841     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
   3842     if (!positionedDescendants)
   3843         return;
   3844 
   3845     RenderBox* r;
   3846 
   3847     TrackedRendererListHashSet::iterator end = positionedDescendants->end();
   3848 
   3849     Vector<RenderBox*, 16> deadObjects;
   3850 
   3851     for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
   3852         r = *it;
   3853         if (!o || r->isDescendantOf(o)) {
   3854             if (containingBlockState == NewContainingBlock)
   3855                 r->setChildNeedsLayout(MarkOnlyThis);
   3856 
   3857             // It is parent blocks job to add positioned child to positioned objects list of its containing block
   3858             // Parent layout needs to be invalidated to ensure this happens.
   3859             RenderObject* p = r->parent();
   3860             while (p && !p->isRenderBlock())
   3861                 p = p->parent();
   3862             if (p)
   3863                 p->setChildNeedsLayout();
   3864 
   3865             deadObjects.append(r);
   3866         }
   3867     }
   3868 
   3869     for (unsigned i = 0; i < deadObjects.size(); i++)
   3870         removePositionedObject(deadObjects.at(i));
   3871 }
   3872 
   3873 void RenderBlock::removeFloatingObjects()
   3874 {
   3875     if (!m_floatingObjects)
   3876         return;
   3877 
   3878     deleteAllValues(m_floatingObjects->set());
   3879     m_floatingObjects->clear();
   3880 }
   3881 
   3882 RenderBlock::FloatingObject* RenderBlock::insertFloatingObject(RenderBox* o)
   3883 {
   3884     ASSERT(o->isFloating());
   3885 
   3886     // Create the list of special objects if we don't aleady have one
   3887     if (!m_floatingObjects)
   3888         createFloatingObjects();
   3889     else {
   3890         // Don't insert the object again if it's already in the list
   3891         const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3892         FloatingObjectSetIterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(o);
   3893         if (it != floatingObjectSet.end())
   3894             return *it;
   3895     }
   3896 
   3897     // Create the special object entry & append it to the list
   3898 
   3899     FloatingObject* newObj = new FloatingObject(o->style()->floating());
   3900 
   3901     // Our location is irrelevant if we're unsplittable or no pagination is in effect.
   3902     // Just go ahead and lay out the float.
   3903     bool isChildRenderBlock = o->isRenderBlock();
   3904     if (isChildRenderBlock && !o->needsLayout() && view()->layoutState()->pageLogicalHeightChanged())
   3905         o->setChildNeedsLayout(MarkOnlyThis);
   3906 
   3907     bool needsBlockDirectionLocationSetBeforeLayout = isChildRenderBlock && view()->layoutState()->needsBlockDirectionLocationSetBeforeLayout();
   3908     if (!needsBlockDirectionLocationSetBeforeLayout || isWritingModeRoot()) // We are unsplittable if we're a block flow root.
   3909         o->layoutIfNeeded();
   3910     else {
   3911         o->updateLogicalWidth();
   3912         o->computeAndSetBlockDirectionMargins(this);
   3913     }
   3914 
   3915     setLogicalWidthForFloat(newObj, logicalWidthForChild(o) + marginStartForChild(o) + marginEndForChild(o));
   3916 
   3917     if (ShapeOutsideInfo* shapeOutside = o->shapeOutsideInfo())
   3918         shapeOutside->setShapeSize(logicalWidthForChild(o), logicalHeightForChild(o));
   3919 
   3920     newObj->setShouldPaint(!o->hasSelfPaintingLayer()); // If a layer exists, the float will paint itself. Otherwise someone else will.
   3921     newObj->setIsDescendant(true);
   3922     newObj->m_renderer = o;
   3923 
   3924     m_floatingObjects->add(newObj);
   3925 
   3926     return newObj;
   3927 }
   3928 
   3929 void RenderBlock::removeFloatingObject(RenderBox* o)
   3930 {
   3931     if (m_floatingObjects) {
   3932         const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3933         FloatingObjectSetIterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(o);
   3934         if (it != floatingObjectSet.end()) {
   3935             FloatingObject* r = *it;
   3936             if (childrenInline()) {
   3937                 LayoutUnit logicalTop = logicalTopForFloat(r);
   3938                 LayoutUnit logicalBottom = logicalBottomForFloat(r);
   3939 
   3940                 // Fix for https://bugs.webkit.org/show_bug.cgi?id=54995.
   3941                 if (logicalBottom < 0 || logicalBottom < logicalTop || logicalTop == LayoutUnit::max())
   3942                     logicalBottom = LayoutUnit::max();
   3943                 else {
   3944                     // Special-case zero- and less-than-zero-height floats: those don't touch
   3945                     // the line that they're on, but it still needs to be dirtied. This is
   3946                     // accomplished by pretending they have a height of 1.
   3947                     logicalBottom = max(logicalBottom, logicalTop + 1);
   3948                 }
   3949                 if (r->m_originatingLine) {
   3950                     if (!selfNeedsLayout()) {
   3951                         ASSERT(r->m_originatingLine->renderer() == this);
   3952                         r->m_originatingLine->markDirty();
   3953                     }
   3954 #if !ASSERT_DISABLED
   3955                     r->m_originatingLine = 0;
   3956 #endif
   3957                 }
   3958                 markLinesDirtyInBlockRange(0, logicalBottom);
   3959             }
   3960             m_floatingObjects->remove(r);
   3961             ASSERT(!r->m_originatingLine);
   3962             delete r;
   3963         }
   3964     }
   3965 }
   3966 
   3967 void RenderBlock::removeFloatingObjectsBelow(FloatingObject* lastFloat, int logicalOffset)
   3968 {
   3969     if (!containsFloats())
   3970         return;
   3971 
   3972     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   3973     FloatingObject* curr = floatingObjectSet.last();
   3974     while (curr != lastFloat && (!curr->isPlaced() || logicalTopForFloat(curr) >= logicalOffset)) {
   3975         m_floatingObjects->remove(curr);
   3976         ASSERT(!curr->m_originatingLine);
   3977         delete curr;
   3978         if (floatingObjectSet.isEmpty())
   3979             break;
   3980         curr = floatingObjectSet.last();
   3981     }
   3982 }
   3983 
   3984 LayoutPoint RenderBlock::computeLogicalLocationForFloat(const FloatingObject* floatingObject, LayoutUnit logicalTopOffset) const
   3985 {
   3986     RenderBox* childBox = floatingObject->renderer();
   3987     LayoutUnit logicalLeftOffset = logicalLeftOffsetForContent(logicalTopOffset); // Constant part of left offset.
   3988     LayoutUnit logicalRightOffset; // Constant part of right offset.
   3989     // FIXME Bug 102948: This only works for shape outside directly set on this block.
   3990     ShapeInsideInfo* shapeInsideInfo = this->shapeInsideInfo();
   3991     // FIXME Bug 102846: Take into account the height of the content. The offset should be
   3992     // equal to the maximum segment length.
   3993     if (shapeInsideInfo && shapeInsideInfo->hasSegments() && shapeInsideInfo->segments().size() == 1) {
   3994         // FIXME Bug 102949: Add support for shapes with multipe segments.
   3995 
   3996         // The segment offsets are relative to the content box.
   3997         logicalRightOffset = logicalLeftOffset + shapeInsideInfo->segments()[0].logicalRight;
   3998         logicalLeftOffset += shapeInsideInfo->segments()[0].logicalLeft;
   3999     } else
   4000         logicalRightOffset = logicalRightOffsetForContent(logicalTopOffset);
   4001 
   4002     LayoutUnit floatLogicalWidth = min(logicalWidthForFloat(floatingObject), logicalRightOffset - logicalLeftOffset); // The width we look for.
   4003 
   4004     LayoutUnit floatLogicalLeft;
   4005 
   4006     bool insideFlowThread = flowThreadContainingBlock();
   4007 
   4008     if (childBox->style()->floating() == LeftFloat) {
   4009         LayoutUnit heightRemainingLeft = 1;
   4010         LayoutUnit heightRemainingRight = 1;
   4011         floatLogicalLeft = logicalLeftOffsetForLineIgnoringShapeOutside(logicalTopOffset, logicalLeftOffset, false, &heightRemainingLeft);
   4012         while (logicalRightOffsetForLineIgnoringShapeOutside(logicalTopOffset, logicalRightOffset, false, &heightRemainingRight) - floatLogicalLeft < floatLogicalWidth) {
   4013             logicalTopOffset += min(heightRemainingLeft, heightRemainingRight);
   4014             floatLogicalLeft = logicalLeftOffsetForLineIgnoringShapeOutside(logicalTopOffset, logicalLeftOffset, false, &heightRemainingLeft);
   4015             if (insideFlowThread) {
   4016                 // Have to re-evaluate all of our offsets, since they may have changed.
   4017                 logicalRightOffset = logicalRightOffsetForContent(logicalTopOffset); // Constant part of right offset.
   4018                 logicalLeftOffset = logicalLeftOffsetForContent(logicalTopOffset); // Constant part of left offset.
   4019                 floatLogicalWidth = min(logicalWidthForFloat(floatingObject), logicalRightOffset - logicalLeftOffset);
   4020             }
   4021         }
   4022         floatLogicalLeft = max(logicalLeftOffset - borderAndPaddingLogicalLeft(), floatLogicalLeft);
   4023     } else {
   4024         LayoutUnit heightRemainingLeft = 1;
   4025         LayoutUnit heightRemainingRight = 1;
   4026         floatLogicalLeft = logicalRightOffsetForLineIgnoringShapeOutside(logicalTopOffset, logicalRightOffset, false, &heightRemainingRight);
   4027         while (floatLogicalLeft - logicalLeftOffsetForLineIgnoringShapeOutside(logicalTopOffset, logicalLeftOffset, false, &heightRemainingLeft) < floatLogicalWidth) {
   4028             logicalTopOffset += min(heightRemainingLeft, heightRemainingRight);
   4029             floatLogicalLeft = logicalRightOffsetForLineIgnoringShapeOutside(logicalTopOffset, logicalRightOffset, false, &heightRemainingRight);
   4030             if (insideFlowThread) {
   4031                 // Have to re-evaluate all of our offsets, since they may have changed.
   4032                 logicalRightOffset = logicalRightOffsetForContent(logicalTopOffset); // Constant part of right offset.
   4033                 logicalLeftOffset = logicalLeftOffsetForContent(logicalTopOffset); // Constant part of left offset.
   4034                 floatLogicalWidth = min(logicalWidthForFloat(floatingObject), logicalRightOffset - logicalLeftOffset);
   4035             }
   4036         }
   4037         floatLogicalLeft -= logicalWidthForFloat(floatingObject); // Use the original width of the float here, since the local variable
   4038                                                                   // |floatLogicalWidth| was capped to the available line width.
   4039                                                                   // See fast/block/float/clamped-right-float.html.
   4040     }
   4041 
   4042     return LayoutPoint(floatLogicalLeft, logicalTopOffset);
   4043 }
   4044 
   4045 bool RenderBlock::positionNewFloats()
   4046 {
   4047     if (!m_floatingObjects)
   4048         return false;
   4049 
   4050     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   4051     if (floatingObjectSet.isEmpty())
   4052         return false;
   4053 
   4054     // If all floats have already been positioned, then we have no work to do.
   4055     if (floatingObjectSet.last()->isPlaced())
   4056         return false;
   4057 
   4058     // Move backwards through our floating object list until we find a float that has
   4059     // already been positioned.  Then we'll be able to move forward, positioning all of
   4060     // the new floats that need it.
   4061     FloatingObjectSetIterator it = floatingObjectSet.end();
   4062     --it; // Go to last item.
   4063     FloatingObjectSetIterator begin = floatingObjectSet.begin();
   4064     FloatingObject* lastPlacedFloatingObject = 0;
   4065     while (it != begin) {
   4066         --it;
   4067         if ((*it)->isPlaced()) {
   4068             lastPlacedFloatingObject = *it;
   4069             ++it;
   4070             break;
   4071         }
   4072     }
   4073 
   4074     LayoutUnit logicalTop = logicalHeight();
   4075 
   4076     // The float cannot start above the top position of the last positioned float.
   4077     if (lastPlacedFloatingObject)
   4078         logicalTop = max(logicalTopForFloat(lastPlacedFloatingObject), logicalTop);
   4079 
   4080     FloatingObjectSetIterator end = floatingObjectSet.end();
   4081     // Now walk through the set of unpositioned floats and place them.
   4082     for (; it != end; ++it) {
   4083         FloatingObject* floatingObject = *it;
   4084         // The containing block is responsible for positioning floats, so if we have floats in our
   4085         // list that come from somewhere else, do not attempt to position them.
   4086         if (floatingObject->renderer()->containingBlock() != this)
   4087             continue;
   4088 
   4089         RenderBox* childBox = floatingObject->renderer();
   4090         LayoutUnit childLogicalLeftMargin = style()->isLeftToRightDirection() ? marginStartForChild(childBox) : marginEndForChild(childBox);
   4091 
   4092         LayoutRect oldRect = childBox->frameRect();
   4093 
   4094         if (childBox->style()->clear() & CLEFT)
   4095             logicalTop = max(lowestFloatLogicalBottom(FloatingObject::FloatLeft), logicalTop);
   4096         if (childBox->style()->clear() & CRIGHT)
   4097             logicalTop = max(lowestFloatLogicalBottom(FloatingObject::FloatRight), logicalTop);
   4098 
   4099         LayoutPoint floatLogicalLocation = computeLogicalLocationForFloat(floatingObject, logicalTop);
   4100 
   4101         setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x());
   4102 
   4103         setLogicalLeftForChild(childBox, floatLogicalLocation.x() + childLogicalLeftMargin);
   4104         setLogicalTopForChild(childBox, floatLogicalLocation.y() + marginBeforeForChild(childBox));
   4105 
   4106         LayoutState* layoutState = view()->layoutState();
   4107         bool isPaginated = layoutState->isPaginated();
   4108         if (isPaginated && !childBox->needsLayout())
   4109             childBox->markForPaginationRelayoutIfNeeded();
   4110 
   4111         childBox->layoutIfNeeded();
   4112 
   4113         if (isPaginated) {
   4114             // If we are unsplittable and don't fit, then we need to move down.
   4115             // We include our margins as part of the unsplittable area.
   4116             LayoutUnit newLogicalTop = adjustForUnsplittableChild(childBox, floatLogicalLocation.y(), true);
   4117 
   4118             // See if we have a pagination strut that is making us move down further.
   4119             // Note that an unsplittable child can't also have a pagination strut, so this is
   4120             // exclusive with the case above.
   4121             RenderBlock* childBlock = childBox->isRenderBlock() ? toRenderBlock(childBox) : 0;
   4122             if (childBlock && childBlock->paginationStrut()) {
   4123                 newLogicalTop += childBlock->paginationStrut();
   4124                 childBlock->setPaginationStrut(0);
   4125             }
   4126 
   4127             if (newLogicalTop != floatLogicalLocation.y()) {
   4128                 floatingObject->m_paginationStrut = newLogicalTop - floatLogicalLocation.y();
   4129 
   4130                 floatLogicalLocation = computeLogicalLocationForFloat(floatingObject, newLogicalTop);
   4131                 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x());
   4132 
   4133                 setLogicalLeftForChild(childBox, floatLogicalLocation.x() + childLogicalLeftMargin);
   4134                 setLogicalTopForChild(childBox, floatLogicalLocation.y() + marginBeforeForChild(childBox));
   4135 
   4136                 if (childBlock)
   4137                     childBlock->setChildNeedsLayout(MarkOnlyThis);
   4138                 childBox->layoutIfNeeded();
   4139             }
   4140         }
   4141 
   4142         setLogicalTopForFloat(floatingObject, floatLogicalLocation.y());
   4143 
   4144         setLogicalHeightForFloat(floatingObject, logicalHeightForChild(childBox) + marginBeforeForChild(childBox) + marginAfterForChild(childBox));
   4145 
   4146         m_floatingObjects->addPlacedObject(floatingObject);
   4147 
   4148         // If the child moved, we have to repaint it.
   4149         if (childBox->checkForRepaintDuringLayout())
   4150             childBox->repaintDuringLayoutIfMoved(oldRect);
   4151     }
   4152     return true;
   4153 }
   4154 
   4155 void RenderBlock::newLine(EClear clear)
   4156 {
   4157     positionNewFloats();
   4158     // set y position
   4159     LayoutUnit newY = 0;
   4160     switch (clear)
   4161     {
   4162         case CLEFT:
   4163             newY = lowestFloatLogicalBottom(FloatingObject::FloatLeft);
   4164             break;
   4165         case CRIGHT:
   4166             newY = lowestFloatLogicalBottom(FloatingObject::FloatRight);
   4167             break;
   4168         case CBOTH:
   4169             newY = lowestFloatLogicalBottom();
   4170         default:
   4171             break;
   4172     }
   4173     if (height() < newY)
   4174         setLogicalHeight(newY);
   4175 }
   4176 
   4177 void RenderBlock::addPercentHeightDescendant(RenderBox* descendant)
   4178 {
   4179     insertIntoTrackedRendererMaps(descendant, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
   4180 }
   4181 
   4182 void RenderBlock::removePercentHeightDescendant(RenderBox* descendant)
   4183 {
   4184     removeFromTrackedRendererMaps(descendant, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
   4185 }
   4186 
   4187 TrackedRendererListHashSet* RenderBlock::percentHeightDescendants() const
   4188 {
   4189     return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0;
   4190 }
   4191 
   4192 bool RenderBlock::hasPercentHeightContainerMap()
   4193 {
   4194     return gPercentHeightContainerMap;
   4195 }
   4196 
   4197 bool RenderBlock::hasPercentHeightDescendant(RenderBox* descendant)
   4198 {
   4199     // We don't null check gPercentHeightContainerMap since the caller
   4200     // already ensures this and we need to call this function on every
   4201     // descendant in clearPercentHeightDescendantsFrom().
   4202     ASSERT(gPercentHeightContainerMap);
   4203     return gPercentHeightContainerMap->contains(descendant);
   4204 }
   4205 
   4206 void RenderBlock::removePercentHeightDescendantIfNeeded(RenderBox* descendant)
   4207 {
   4208     // We query the map directly, rather than looking at style's
   4209     // logicalHeight()/logicalMinHeight()/logicalMaxHeight() since those
   4210     // can change with writing mode/directional changes.
   4211     if (!hasPercentHeightContainerMap())
   4212         return;
   4213 
   4214     if (!hasPercentHeightDescendant(descendant))
   4215         return;
   4216 
   4217     removePercentHeightDescendant(descendant);
   4218 }
   4219 
   4220 void RenderBlock::clearPercentHeightDescendantsFrom(RenderBox* parent)
   4221 {
   4222     ASSERT(gPercentHeightContainerMap);
   4223     for (RenderObject* curr = parent->firstChild(); curr; curr = curr->nextInPreOrder(parent)) {
   4224         if (!curr->isBox())
   4225             continue;
   4226 
   4227         RenderBox* box = toRenderBox(curr);
   4228         if (!hasPercentHeightDescendant(box))
   4229             continue;
   4230 
   4231         removePercentHeightDescendant(box);
   4232     }
   4233 }
   4234 
   4235 static bool rangesIntersect(int floatTop, int floatBottom, int objectTop, int objectBottom)
   4236 {
   4237     if (objectTop >= floatBottom || objectBottom < floatTop)
   4238         return false;
   4239 
   4240     // The top of the object overlaps the float
   4241     if (objectTop >= floatTop)
   4242         return true;
   4243 
   4244     // The object encloses the float
   4245     if (objectTop < floatTop && objectBottom > floatBottom)
   4246         return true;
   4247 
   4248     // The bottom of the object overlaps the float
   4249     if (objectBottom > objectTop && objectBottom > floatTop && objectBottom <= floatBottom)
   4250         return true;
   4251 
   4252     return false;
   4253 }
   4254 
   4255 template<>
   4256 bool RenderBlock::FloatIntervalSearchAdapter<RenderBlock::FloatingObject::FloatLeft>::updateOffsetIfNeeded(const FloatingObject* floatingObject) const
   4257 {
   4258     if (m_renderer->logicalRightForFloat(floatingObject) > m_offset) {
   4259         m_offset = m_renderer->logicalRightForFloat(floatingObject);
   4260         return true;
   4261     }
   4262     return false;
   4263 }
   4264 
   4265 template<>
   4266 bool RenderBlock::FloatIntervalSearchAdapter<RenderBlock::FloatingObject::FloatRight>::updateOffsetIfNeeded(const FloatingObject* floatingObject) const
   4267 {
   4268     if (m_renderer->logicalLeftForFloat(floatingObject) < m_offset) {
   4269         m_offset = m_renderer->logicalLeftForFloat(floatingObject);
   4270         return true;
   4271     }
   4272     return false;
   4273 }
   4274 
   4275 template <RenderBlock::FloatingObject::Type FloatTypeValue>
   4276 inline void RenderBlock::FloatIntervalSearchAdapter<FloatTypeValue>::collectIfNeeded(const IntervalType& interval) const
   4277 {
   4278     const FloatingObject* floatingObject = interval.data();
   4279     if (floatingObject->type() != FloatTypeValue || !rangesIntersect(interval.low(), interval.high(), m_lowValue, m_highValue))
   4280         return;
   4281 
   4282     // All the objects returned from the tree should be already placed.
   4283     ASSERT(floatingObject->isPlaced());
   4284     ASSERT(rangesIntersect(m_renderer->pixelSnappedLogicalTopForFloat(floatingObject), m_renderer->pixelSnappedLogicalBottomForFloat(floatingObject), m_lowValue, m_highValue));
   4285 
   4286     bool floatIsNewExtreme = updateOffsetIfNeeded(floatingObject);
   4287     if (floatIsNewExtreme && m_heightRemaining)
   4288         *m_heightRemaining = m_renderer->logicalBottomForFloat(floatingObject) - m_lowValue;
   4289 
   4290     m_last = floatingObject;
   4291 }
   4292 
   4293 LayoutUnit RenderBlock::textIndentOffset() const
   4294 {
   4295     LayoutUnit cw = 0;
   4296     RenderView* renderView = 0;
   4297     if (style()->textIndent().isPercent())
   4298         cw = containingBlock()->availableLogicalWidth();
   4299     else if (style()->textIndent().isViewportPercentage())
   4300         renderView = view();
   4301     return minimumValueForLength(style()->textIndent(), cw, renderView);
   4302 }
   4303 
   4304 LayoutUnit RenderBlock::logicalLeftOffsetForContent(RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage) const
   4305 {
   4306     LayoutUnit logicalLeftOffset = style()->isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop();
   4307     if (!region)
   4308         return logicalLeftOffset;
   4309     LayoutRect boxRect = borderBoxRectInRegion(region, offsetFromLogicalTopOfFirstPage);
   4310     return logicalLeftOffset + (isHorizontalWritingMode() ? boxRect.x() : boxRect.y());
   4311 }
   4312 
   4313 LayoutUnit RenderBlock::logicalRightOffsetForContent(RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage) const
   4314 {
   4315     LayoutUnit logicalRightOffset = style()->isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop();
   4316     logicalRightOffset += availableLogicalWidth();
   4317     if (!region)
   4318         return logicalRightOffset;
   4319     LayoutRect boxRect = borderBoxRectInRegion(region, offsetFromLogicalTopOfFirstPage);
   4320     return logicalRightOffset - (logicalWidth() - (isHorizontalWritingMode() ? boxRect.maxX() : boxRect.maxY()));
   4321 }
   4322 
   4323 LayoutUnit RenderBlock::logicalLeftFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit* heightRemaining, LayoutUnit logicalHeight, ShapeOutsideFloatOffsetMode offsetMode) const
   4324 {
   4325     LayoutUnit left = fixedOffset;
   4326     if (m_floatingObjects && m_floatingObjects->hasLeftObjects()) {
   4327         if (heightRemaining)
   4328             *heightRemaining = 1;
   4329 
   4330         FloatIntervalSearchAdapter<FloatingObject::FloatLeft> adapter(this, roundToInt(logicalTop), roundToInt(logicalTop + logicalHeight), left, heightRemaining);
   4331         m_floatingObjects->placedFloatsTree().allOverlapsWithAdapter(adapter);
   4332 
   4333         const FloatingObject* lastFloat = adapter.lastFloat();
   4334         if (offsetMode == ShapeOutsideFloatShapeOffset && lastFloat) {
   4335             if (ShapeOutsideInfo* shapeOutside = lastFloat->renderer()->shapeOutsideInfo()) {
   4336                 shapeOutside->computeSegmentsForContainingBlockLine(logicalTop, logicalTopForFloat(lastFloat), logicalHeight);
   4337                 left += shapeOutside->rightSegmentMarginBoxDelta();
   4338             }
   4339         }
   4340     }
   4341 
   4342     return left;
   4343 }
   4344 
   4345 LayoutUnit RenderBlock::adjustLogicalLeftOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const
   4346 {
   4347     LayoutUnit left = offsetFromFloats;
   4348 
   4349     if (applyTextIndent && style()->isLeftToRightDirection())
   4350         left += textIndentOffset();
   4351 
   4352     if (style()->lineAlign() == LineAlignNone)
   4353         return left;
   4354 
   4355     // Push in our left offset so that it is aligned with the character grid.
   4356     LayoutState* layoutState = view()->layoutState();
   4357     if (!layoutState)
   4358         return left;
   4359 
   4360     RenderBlock* lineGrid = layoutState->lineGrid();
   4361     if (!lineGrid || lineGrid->style()->writingMode() != style()->writingMode())
   4362         return left;
   4363 
   4364     // FIXME: Should letter-spacing apply? This is complicated since it doesn't apply at the edge?
   4365     float maxCharWidth = lineGrid->style()->font().primaryFont()->maxCharWidth();
   4366     if (!maxCharWidth)
   4367         return left;
   4368 
   4369     LayoutUnit lineGridOffset = lineGrid->isHorizontalWritingMode() ? layoutState->lineGridOffset().width(): layoutState->lineGridOffset().height();
   4370     LayoutUnit layoutOffset = lineGrid->isHorizontalWritingMode() ? layoutState->layoutOffset().width() : layoutState->layoutOffset().height();
   4371 
   4372     // Push in to the nearest character width.
   4373     // FIXME: This is wrong for RTL (https://bugs.webkit.org/show_bug.cgi?id=79945).
   4374     // FIXME: This doesn't work with columns or regions (https://bugs.webkit.org/show_bug.cgi?id=79942).
   4375     // FIXME: This doesn't work when the inline position of the object isn't set ahead of time.
   4376     // FIXME: Dynamic changes to the font or to the inline position need to result in a deep relayout.
   4377     // (https://bugs.webkit.org/show_bug.cgi?id=79944)
   4378     float remainder = fmodf(maxCharWidth - fmodf(left + layoutOffset - lineGridOffset, maxCharWidth), maxCharWidth);
   4379     left += remainder;
   4380     return left;
   4381 }
   4382 
   4383 LayoutUnit RenderBlock::logicalRightFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit* heightRemaining, LayoutUnit logicalHeight, ShapeOutsideFloatOffsetMode offsetMode) const
   4384 {
   4385     LayoutUnit right = fixedOffset;
   4386     if (m_floatingObjects && m_floatingObjects->hasRightObjects()) {
   4387         if (heightRemaining)
   4388             *heightRemaining = 1;
   4389 
   4390         LayoutUnit rightFloatOffset = fixedOffset;
   4391         FloatIntervalSearchAdapter<FloatingObject::FloatRight> adapter(this, roundToInt(logicalTop), roundToInt(logicalTop + logicalHeight), rightFloatOffset, heightRemaining);
   4392         m_floatingObjects->placedFloatsTree().allOverlapsWithAdapter(adapter);
   4393 
   4394         const FloatingObject* lastFloat = adapter.lastFloat();
   4395         if (offsetMode == ShapeOutsideFloatShapeOffset && lastFloat) {
   4396             if (ShapeOutsideInfo* shapeOutside = lastFloat->renderer()->shapeOutsideInfo()) {
   4397                 shapeOutside->computeSegmentsForContainingBlockLine(logicalTop, logicalTopForFloat(lastFloat), logicalHeight);
   4398                 rightFloatOffset += shapeOutside->leftSegmentMarginBoxDelta();
   4399             }
   4400         }
   4401 
   4402         right = min(right, rightFloatOffset);
   4403     }
   4404     return right;
   4405 }
   4406 
   4407 LayoutUnit RenderBlock::adjustLogicalRightOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const
   4408 {
   4409     LayoutUnit right = offsetFromFloats;
   4410 
   4411     if (applyTextIndent && !style()->isLeftToRightDirection())
   4412         right -= textIndentOffset();
   4413 
   4414     if (style()->lineAlign() == LineAlignNone)
   4415         return right;
   4416 
   4417     // Push in our right offset so that it is aligned with the character grid.
   4418     LayoutState* layoutState = view()->layoutState();
   4419     if (!layoutState)
   4420         return right;
   4421 
   4422     RenderBlock* lineGrid = layoutState->lineGrid();
   4423     if (!lineGrid || lineGrid->style()->writingMode() != style()->writingMode())
   4424         return right;
   4425 
   4426     // FIXME: Should letter-spacing apply? This is complicated since it doesn't apply at the edge?
   4427     float maxCharWidth = lineGrid->style()->font().primaryFont()->maxCharWidth();
   4428     if (!maxCharWidth)
   4429         return right;
   4430 
   4431     LayoutUnit lineGridOffset = lineGrid->isHorizontalWritingMode() ? layoutState->lineGridOffset().width(): layoutState->lineGridOffset().height();
   4432     LayoutUnit layoutOffset = lineGrid->isHorizontalWritingMode() ? layoutState->layoutOffset().width() : layoutState->layoutOffset().height();
   4433 
   4434     // Push in to the nearest character width.
   4435     // FIXME: This is wrong for RTL (https://bugs.webkit.org/show_bug.cgi?id=79945).
   4436     // FIXME: This doesn't work with columns or regions (https://bugs.webkit.org/show_bug.cgi?id=79942).
   4437     // FIXME: This doesn't work when the inline position of the object isn't set ahead of time.
   4438     // FIXME: Dynamic changes to the font or to the inline position need to result in a deep relayout.
   4439     // (https://bugs.webkit.org/show_bug.cgi?id=79944)
   4440     float remainder = fmodf(fmodf(right + layoutOffset - lineGridOffset, maxCharWidth), maxCharWidth);
   4441     right -= LayoutUnit::fromFloatCeil(remainder);
   4442     return right;
   4443 }
   4444 
   4445 LayoutUnit RenderBlock::nextFloatLogicalBottomBelow(LayoutUnit logicalHeight) const
   4446 {
   4447     if (!m_floatingObjects)
   4448         return logicalHeight;
   4449 
   4450     LayoutUnit bottom = LayoutUnit::max();
   4451     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   4452     FloatingObjectSetIterator end = floatingObjectSet.end();
   4453     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   4454         FloatingObject* r = *it;
   4455         LayoutUnit floatBottom = logicalBottomForFloat(r);
   4456         if (floatBottom > logicalHeight)
   4457             bottom = min(floatBottom, bottom);
   4458     }
   4459 
   4460     return bottom == LayoutUnit::max() ? LayoutUnit() : bottom;
   4461 }
   4462 
   4463 LayoutUnit RenderBlock::lowestFloatLogicalBottom(FloatingObject::Type floatType) const
   4464 {
   4465     if (!m_floatingObjects)
   4466         return 0;
   4467     LayoutUnit lowestFloatBottom = 0;
   4468     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   4469     FloatingObjectSetIterator end = floatingObjectSet.end();
   4470     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   4471         FloatingObject* r = *it;
   4472         if (r->isPlaced() && r->type() & floatType)
   4473             lowestFloatBottom = max(lowestFloatBottom, logicalBottomForFloat(r));
   4474     }
   4475     return lowestFloatBottom;
   4476 }
   4477 
   4478 void RenderBlock::markLinesDirtyInBlockRange(LayoutUnit logicalTop, LayoutUnit logicalBottom, RootInlineBox* highest)
   4479 {
   4480     if (logicalTop >= logicalBottom)
   4481         return;
   4482 
   4483     RootInlineBox* lowestDirtyLine = lastRootBox();
   4484     RootInlineBox* afterLowest = lowestDirtyLine;
   4485     while (lowestDirtyLine && lowestDirtyLine->lineBottomWithLeading() >= logicalBottom && logicalBottom < LayoutUnit::max()) {
   4486         afterLowest = lowestDirtyLine;
   4487         lowestDirtyLine = lowestDirtyLine->prevRootBox();
   4488     }
   4489 
   4490     while (afterLowest && afterLowest != highest && (afterLowest->lineBottomWithLeading() >= logicalTop || afterLowest->lineBottomWithLeading() < 0)) {
   4491         afterLowest->markDirty();
   4492         afterLowest = afterLowest->prevRootBox();
   4493     }
   4494 }
   4495 
   4496 void RenderBlock::clearFloats()
   4497 {
   4498     if (m_floatingObjects)
   4499         m_floatingObjects->setHorizontalWritingMode(isHorizontalWritingMode());
   4500 
   4501     HashSet<RenderBox*> oldIntrudingFloatSet;
   4502     if (!childrenInline() && m_floatingObjects) {
   4503         const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   4504         FloatingObjectSetIterator end = floatingObjectSet.end();
   4505         for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   4506             FloatingObject* floatingObject = *it;
   4507             if (!floatingObject->isDescendant())
   4508                 oldIntrudingFloatSet.add(floatingObject->m_renderer);
   4509         }
   4510     }
   4511 
   4512     // Inline blocks are covered by the isReplaced() check in the avoidFloats method.
   4513     if (avoidsFloats() || isRoot() || isRenderView() || isFloatingOrOutOfFlowPositioned() || isTableCell()) {
   4514         if (m_floatingObjects) {
   4515             deleteAllValues(m_floatingObjects->set());
   4516             m_floatingObjects->clear();
   4517         }
   4518         if (!oldIntrudingFloatSet.isEmpty())
   4519             markAllDescendantsWithFloatsForLayout();
   4520         return;
   4521     }
   4522 
   4523     typedef HashMap<RenderObject*, FloatingObject*> RendererToFloatInfoMap;
   4524     RendererToFloatInfoMap floatMap;
   4525 
   4526     if (m_floatingObjects) {
   4527         const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   4528         if (childrenInline()) {
   4529             FloatingObjectSetIterator end = floatingObjectSet.end();
   4530             for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   4531                 FloatingObject* f = *it;
   4532                 floatMap.add(f->m_renderer, f);
   4533             }
   4534         } else {
   4535             deleteAllValues(floatingObjectSet);
   4536         }
   4537         m_floatingObjects->clear();
   4538     }
   4539 
   4540     // We should not process floats if the parent node is not a RenderBlock. Otherwise, we will add
   4541     // floats in an invalid context. This will cause a crash arising from a bad cast on the parent.
   4542     // See <rdar://problem/8049753>, where float property is applied on a text node in a SVG.
   4543     if (!parent() || !parent()->isRenderBlock())
   4544         return;
   4545 
   4546     // Attempt to locate a previous sibling with overhanging floats.  We skip any elements that are
   4547     // out of flow (like floating/positioned elements), and we also skip over any objects that may have shifted
   4548     // to avoid floats.
   4549     RenderBlock* parentBlock = toRenderBlock(parent());
   4550     bool parentHasFloats = false;
   4551     RenderObject* prev = previousSibling();
   4552     while (prev && (prev->isFloatingOrOutOfFlowPositioned() || !prev->isBox() || !prev->isRenderBlock() || toRenderBlock(prev)->avoidsFloats())) {
   4553         if (prev->isFloating())
   4554             parentHasFloats = true;
   4555         prev = prev->previousSibling();
   4556     }
   4557 
   4558     // First add in floats from the parent.
   4559     LayoutUnit logicalTopOffset = logicalTop();
   4560     if (parentHasFloats)
   4561         addIntrudingFloats(parentBlock, parentBlock->logicalLeftOffsetForContent(), logicalTopOffset);
   4562 
   4563     LayoutUnit logicalLeftOffset = 0;
   4564     if (prev)
   4565         logicalTopOffset -= toRenderBox(prev)->logicalTop();
   4566     else {
   4567         prev = parentBlock;
   4568         logicalLeftOffset += parentBlock->logicalLeftOffsetForContent();
   4569     }
   4570 
   4571     // Add overhanging floats from the previous RenderBlock, but only if it has a float that intrudes into our space.
   4572     RenderBlock* block = toRenderBlock(prev);
   4573     if (block->m_floatingObjects && block->lowestFloatLogicalBottom() > logicalTopOffset)
   4574         addIntrudingFloats(block, logicalLeftOffset, logicalTopOffset);
   4575 
   4576     if (childrenInline()) {
   4577         LayoutUnit changeLogicalTop = LayoutUnit::max();
   4578         LayoutUnit changeLogicalBottom = LayoutUnit::min();
   4579         if (m_floatingObjects) {
   4580             const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   4581             FloatingObjectSetIterator end = floatingObjectSet.end();
   4582             for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   4583                 FloatingObject* f = *it;
   4584                 FloatingObject* oldFloatingObject = floatMap.get(f->m_renderer);
   4585                 LayoutUnit logicalBottom = logicalBottomForFloat(f);
   4586                 if (oldFloatingObject) {
   4587                     LayoutUnit oldLogicalBottom = logicalBottomForFloat(oldFloatingObject);
   4588                     if (logicalWidthForFloat(f) != logicalWidthForFloat(oldFloatingObject) || logicalLeftForFloat(f) != logicalLeftForFloat(oldFloatingObject)) {
   4589                         changeLogicalTop = 0;
   4590                         changeLogicalBottom = max(changeLogicalBottom, max(logicalBottom, oldLogicalBottom));
   4591                     } else {
   4592                         if (logicalBottom != oldLogicalBottom) {
   4593                             changeLogicalTop = min(changeLogicalTop, min(logicalBottom, oldLogicalBottom));
   4594                             changeLogicalBottom = max(changeLogicalBottom, max(logicalBottom, oldLogicalBottom));
   4595                         }
   4596                         LayoutUnit logicalTop = logicalTopForFloat(f);
   4597                         LayoutUnit oldLogicalTop = logicalTopForFloat(oldFloatingObject);
   4598                         if (logicalTop != oldLogicalTop) {
   4599                             changeLogicalTop = min(changeLogicalTop, min(logicalTop, oldLogicalTop));
   4600                             changeLogicalBottom = max(changeLogicalBottom, max(logicalTop, oldLogicalTop));
   4601                         }
   4602                     }
   4603 
   4604                     floatMap.remove(f->m_renderer);
   4605                     if (oldFloatingObject->m_originatingLine && !selfNeedsLayout()) {
   4606                         ASSERT(oldFloatingObject->m_originatingLine->renderer() == this);
   4607                         oldFloatingObject->m_originatingLine->markDirty();
   4608                     }
   4609                     delete oldFloatingObject;
   4610                 } else {
   4611                     changeLogicalTop = 0;
   4612                     changeLogicalBottom = max(changeLogicalBottom, logicalBottom);
   4613                 }
   4614             }
   4615         }
   4616 
   4617         RendererToFloatInfoMap::iterator end = floatMap.end();
   4618         for (RendererToFloatInfoMap::iterator it = floatMap.begin(); it != end; ++it) {
   4619             FloatingObject* floatingObject = (*it).value;
   4620             if (!floatingObject->isDescendant()) {
   4621                 changeLogicalTop = 0;
   4622                 changeLogicalBottom = max(changeLogicalBottom, logicalBottomForFloat(floatingObject));
   4623             }
   4624         }
   4625         deleteAllValues(floatMap);
   4626 
   4627         markLinesDirtyInBlockRange(changeLogicalTop, changeLogicalBottom);
   4628     } else if (!oldIntrudingFloatSet.isEmpty()) {
   4629         // If there are previously intruding floats that no longer intrude, then children with floats
   4630         // should also get layout because they might need their floating object lists cleared.
   4631         if (m_floatingObjects->set().size() < oldIntrudingFloatSet.size())
   4632             markAllDescendantsWithFloatsForLayout();
   4633         else {
   4634             const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   4635             FloatingObjectSetIterator end = floatingObjectSet.end();
   4636             for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end && !oldIntrudingFloatSet.isEmpty(); ++it)
   4637                 oldIntrudingFloatSet.remove((*it)->m_renderer);
   4638             if (!oldIntrudingFloatSet.isEmpty())
   4639                 markAllDescendantsWithFloatsForLayout();
   4640         }
   4641     }
   4642 }
   4643 
   4644 LayoutUnit RenderBlock::addOverhangingFloats(RenderBlock* child, bool makeChildPaintOtherFloats)
   4645 {
   4646     // Prevent floats from being added to the canvas by the root element, e.g., <html>.
   4647     if (child->hasOverflowClip() || !child->containsFloats() || child->isRoot() || child->hasColumns() || child->isWritingModeRoot())
   4648         return 0;
   4649 
   4650     LayoutUnit childLogicalTop = child->logicalTop();
   4651     LayoutUnit childLogicalLeft = child->logicalLeft();
   4652     LayoutUnit lowestFloatLogicalBottom = 0;
   4653 
   4654     // Floats that will remain the child's responsibility to paint should factor into its
   4655     // overflow.
   4656     FloatingObjectSetIterator childEnd = child->m_floatingObjects->set().end();
   4657     for (FloatingObjectSetIterator childIt = child->m_floatingObjects->set().begin(); childIt != childEnd; ++childIt) {
   4658         FloatingObject* r = *childIt;
   4659         LayoutUnit logicalBottomForFloat = min(this->logicalBottomForFloat(r), LayoutUnit::max() - childLogicalTop);
   4660         LayoutUnit logicalBottom = childLogicalTop + logicalBottomForFloat;
   4661         lowestFloatLogicalBottom = max(lowestFloatLogicalBottom, logicalBottom);
   4662 
   4663         if (logicalBottom > logicalHeight()) {
   4664             // If the object is not in the list, we add it now.
   4665             if (!containsFloat(r->m_renderer)) {
   4666                 LayoutSize offset = isHorizontalWritingMode() ? LayoutSize(-childLogicalLeft, -childLogicalTop) : LayoutSize(-childLogicalTop, -childLogicalLeft);
   4667                 FloatingObject* floatingObj = new FloatingObject(r->type(), LayoutRect(r->frameRect().location() - offset, r->frameRect().size()));
   4668                 floatingObj->m_renderer = r->m_renderer;
   4669 
   4670                 // The nearest enclosing layer always paints the float (so that zindex and stacking
   4671                 // behaves properly).  We always want to propagate the desire to paint the float as
   4672                 // far out as we can, to the outermost block that overlaps the float, stopping only
   4673                 // if we hit a self-painting layer boundary.
   4674                 if (r->m_renderer->enclosingFloatPaintingLayer() == enclosingFloatPaintingLayer())
   4675                     r->setShouldPaint(false);
   4676                 else
   4677                     floatingObj->setShouldPaint(false);
   4678 
   4679                 floatingObj->setIsDescendant(true);
   4680 
   4681                 // We create the floating object list lazily.
   4682                 if (!m_floatingObjects)
   4683                     createFloatingObjects();
   4684                 m_floatingObjects->add(floatingObj);
   4685             }
   4686         } else {
   4687             if (makeChildPaintOtherFloats && !r->shouldPaint() && !r->m_renderer->hasSelfPaintingLayer()
   4688                 && r->m_renderer->isDescendantOf(child) && r->m_renderer->enclosingFloatPaintingLayer() == child->enclosingFloatPaintingLayer()) {
   4689                 // The float is not overhanging from this block, so if it is a descendant of the child, the child should
   4690                 // paint it (the other case is that it is intruding into the child), unless it has its own layer or enclosing
   4691                 // layer.
   4692                 // If makeChildPaintOtherFloats is false, it means that the child must already know about all the floats
   4693                 // it should paint.
   4694                 r->setShouldPaint(true);
   4695             }
   4696 
   4697             // 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
   4698             // child now.
   4699             if (r->isDescendant())
   4700                 child->addOverflowFromChild(r->m_renderer, LayoutSize(xPositionForFloatIncludingMargin(r), yPositionForFloatIncludingMargin(r)));
   4701         }
   4702     }
   4703     return lowestFloatLogicalBottom;
   4704 }
   4705 
   4706 bool RenderBlock::hasOverhangingFloat(RenderBox* renderer)
   4707 {
   4708     if (!m_floatingObjects || hasColumns() || !parent())
   4709         return false;
   4710 
   4711     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   4712     FloatingObjectSetIterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(renderer);
   4713     if (it == floatingObjectSet.end())
   4714         return false;
   4715 
   4716     return logicalBottomForFloat(*it) > logicalHeight();
   4717 }
   4718 
   4719 void RenderBlock::addIntrudingFloats(RenderBlock* prev, LayoutUnit logicalLeftOffset, LayoutUnit logicalTopOffset)
   4720 {
   4721     ASSERT(!avoidsFloats());
   4722 
   4723     // If the parent or previous sibling doesn't have any floats to add, don't bother.
   4724     if (!prev->m_floatingObjects)
   4725         return;
   4726 
   4727     logicalLeftOffset += marginLogicalLeft();
   4728 
   4729     const FloatingObjectSet& prevSet = prev->m_floatingObjects->set();
   4730     FloatingObjectSetIterator prevEnd = prevSet.end();
   4731     for (FloatingObjectSetIterator prevIt = prevSet.begin(); prevIt != prevEnd; ++prevIt) {
   4732         FloatingObject* r = *prevIt;
   4733         if (logicalBottomForFloat(r) > logicalTopOffset) {
   4734             if (!m_floatingObjects || !m_floatingObjects->set().contains(r)) {
   4735                 LayoutSize offset = isHorizontalWritingMode() ? LayoutSize(logicalLeftOffset, logicalTopOffset) : LayoutSize(logicalTopOffset, logicalLeftOffset);
   4736                 FloatingObject* floatingObj = new FloatingObject(r->type(), LayoutRect(r->frameRect().location() - offset, r->frameRect().size()));
   4737 
   4738                 // Applying the child's margin makes no sense in the case where the child was passed in.
   4739                 // since this margin was added already through the modification of the |logicalLeftOffset| variable
   4740                 // above.  |logicalLeftOffset| will equal the margin in this case, so it's already been taken
   4741                 // into account.  Only apply this code if prev is the parent, since otherwise the left margin
   4742                 // will get applied twice.
   4743                 if (prev != parent()) {
   4744                     if (isHorizontalWritingMode())
   4745                         floatingObj->setX(floatingObj->x() + prev->marginLeft());
   4746                     else
   4747                         floatingObj->setY(floatingObj->y() + prev->marginTop());
   4748                 }
   4749 
   4750                 floatingObj->setShouldPaint(false); // We are not in the direct inheritance chain for this float. We will never paint it.
   4751                 floatingObj->m_renderer = r->m_renderer;
   4752 
   4753                 // We create the floating object list lazily.
   4754                 if (!m_floatingObjects)
   4755                     createFloatingObjects();
   4756                 m_floatingObjects->add(floatingObj);
   4757             }
   4758         }
   4759     }
   4760 }
   4761 
   4762 bool RenderBlock::avoidsFloats() const
   4763 {
   4764     // Floats can't intrude into our box if we have a non-auto column count or width.
   4765     return RenderBox::avoidsFloats() || !style()->hasAutoColumnCount() || !style()->hasAutoColumnWidth();
   4766 }
   4767 
   4768 bool RenderBlock::containsFloat(RenderBox* renderer) const
   4769 {
   4770     return m_floatingObjects && m_floatingObjects->set().contains<RenderBox*, FloatingObjectHashTranslator>(renderer);
   4771 }
   4772 
   4773 void RenderBlock::markShapeInsideDescendantsForLayout()
   4774 {
   4775     if (!everHadLayout())
   4776         return;
   4777     if (childrenInline()) {
   4778         setNeedsLayout();
   4779         return;
   4780     }
   4781     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
   4782         if (!child->isRenderBlock())
   4783             continue;
   4784         RenderBlock* childBlock = toRenderBlock(child);
   4785         childBlock->markShapeInsideDescendantsForLayout();
   4786     }
   4787 }
   4788 
   4789 void RenderBlock::markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove, bool inLayout)
   4790 {
   4791     if (!everHadLayout() && !containsFloats())
   4792         return;
   4793 
   4794     MarkingBehavior markParents = inLayout ? MarkOnlyThis : MarkContainingBlockChain;
   4795     setChildNeedsLayout(markParents);
   4796 
   4797     if (floatToRemove)
   4798         removeFloatingObject(floatToRemove);
   4799 
   4800     // Iterate over our children and mark them as needed.
   4801     if (!childrenInline()) {
   4802         for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
   4803             if ((!floatToRemove && child->isFloatingOrOutOfFlowPositioned()) || !child->isRenderBlock())
   4804                 continue;
   4805             RenderBlock* childBlock = toRenderBlock(child);
   4806             if ((floatToRemove ? childBlock->containsFloat(floatToRemove) : childBlock->containsFloats()) || childBlock->shrinkToAvoidFloats())
   4807                 childBlock->markAllDescendantsWithFloatsForLayout(floatToRemove, inLayout);
   4808         }
   4809     }
   4810 }
   4811 
   4812 void RenderBlock::markSiblingsWithFloatsForLayout(RenderBox* floatToRemove)
   4813 {
   4814     if (!m_floatingObjects)
   4815         return;
   4816 
   4817     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   4818     FloatingObjectSetIterator end = floatingObjectSet.end();
   4819 
   4820     for (RenderObject* next = nextSibling(); next; next = next->nextSibling()) {
   4821         if (!next->isRenderBlock() || next->isFloatingOrOutOfFlowPositioned() || toRenderBlock(next)->avoidsFloats())
   4822             continue;
   4823 
   4824         RenderBlock* nextBlock = toRenderBlock(next);
   4825         for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   4826             RenderBox* floatingBox = (*it)->renderer();
   4827             if (floatToRemove && floatingBox != floatToRemove)
   4828                 continue;
   4829             if (nextBlock->containsFloat(floatingBox))
   4830                 nextBlock->markAllDescendantsWithFloatsForLayout(floatingBox);
   4831         }
   4832     }
   4833 }
   4834 
   4835 LayoutUnit RenderBlock::getClearDelta(RenderBox* child, LayoutUnit logicalTop)
   4836 {
   4837     // There is no need to compute clearance if we have no floats.
   4838     if (!containsFloats())
   4839         return 0;
   4840 
   4841     // At least one float is present.  We need to perform the clearance computation.
   4842     bool clearSet = child->style()->clear() != CNONE;
   4843     LayoutUnit logicalBottom = 0;
   4844     switch (child->style()->clear()) {
   4845         case CNONE:
   4846             break;
   4847         case CLEFT:
   4848             logicalBottom = lowestFloatLogicalBottom(FloatingObject::FloatLeft);
   4849             break;
   4850         case CRIGHT:
   4851             logicalBottom = lowestFloatLogicalBottom(FloatingObject::FloatRight);
   4852             break;
   4853         case CBOTH:
   4854             logicalBottom = lowestFloatLogicalBottom();
   4855             break;
   4856     }
   4857 
   4858     // 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).
   4859     LayoutUnit result = clearSet ? max<LayoutUnit>(0, logicalBottom - logicalTop) : LayoutUnit();
   4860     if (!result && child->avoidsFloats()) {
   4861         LayoutUnit newLogicalTop = logicalTop;
   4862         while (true) {
   4863             LayoutUnit availableLogicalWidthAtNewLogicalTopOffset = availableLogicalWidthForLine(newLogicalTop, false, logicalHeightForChild(child));
   4864             if (availableLogicalWidthAtNewLogicalTopOffset == availableLogicalWidthForContent(newLogicalTop))
   4865                 return newLogicalTop - logicalTop;
   4866 
   4867             RenderRegion* region = regionAtBlockOffset(logicalTopForChild(child));
   4868             LayoutRect borderBox = child->borderBoxRectInRegion(region, offsetFromLogicalTopOfFirstPage() + logicalTopForChild(child), DoNotCacheRenderBoxRegionInfo);
   4869             LayoutUnit childLogicalWidthAtOldLogicalTopOffset = isHorizontalWritingMode() ? borderBox.width() : borderBox.height();
   4870 
   4871             // FIXME: None of this is right for perpendicular writing-mode children.
   4872             LayoutUnit childOldLogicalWidth = child->logicalWidth();
   4873             LayoutUnit childOldMarginLeft = child->marginLeft();
   4874             LayoutUnit childOldMarginRight = child->marginRight();
   4875             LayoutUnit childOldLogicalTop = child->logicalTop();
   4876 
   4877             child->setLogicalTop(newLogicalTop);
   4878             child->updateLogicalWidth();
   4879             region = regionAtBlockOffset(logicalTopForChild(child));
   4880             borderBox = child->borderBoxRectInRegion(region, offsetFromLogicalTopOfFirstPage() + logicalTopForChild(child), DoNotCacheRenderBoxRegionInfo);
   4881             LayoutUnit childLogicalWidthAtNewLogicalTopOffset = isHorizontalWritingMode() ? borderBox.width() : borderBox.height();
   4882 
   4883             child->setLogicalTop(childOldLogicalTop);
   4884             child->setLogicalWidth(childOldLogicalWidth);
   4885             child->setMarginLeft(childOldMarginLeft);
   4886             child->setMarginRight(childOldMarginRight);
   4887 
   4888             if (childLogicalWidthAtNewLogicalTopOffset <= availableLogicalWidthAtNewLogicalTopOffset) {
   4889                 // Even though we may not be moving, if the logical width did shrink because of the presence of new floats, then
   4890                 // we need to force a relayout as though we shifted. This happens because of the dynamic addition of overhanging floats
   4891                 // from previous siblings when negative margins exist on a child (see the addOverhangingFloats call at the end of collapseMargins).
   4892                 if (childLogicalWidthAtOldLogicalTopOffset != childLogicalWidthAtNewLogicalTopOffset)
   4893                     child->setChildNeedsLayout(MarkOnlyThis);
   4894                 return newLogicalTop - logicalTop;
   4895             }
   4896 
   4897             newLogicalTop = nextFloatLogicalBottomBelow(newLogicalTop);
   4898             ASSERT(newLogicalTop >= logicalTop);
   4899             if (newLogicalTop < logicalTop)
   4900                 break;
   4901         }
   4902         ASSERT_NOT_REACHED();
   4903     }
   4904     return result;
   4905 }
   4906 
   4907 bool RenderBlock::isPointInOverflowControl(HitTestResult& result, const LayoutPoint& locationInContainer, const LayoutPoint& accumulatedOffset)
   4908 {
   4909     if (!scrollsOverflow())
   4910         return false;
   4911 
   4912     return layer()->hitTestOverflowControls(result, roundedIntPoint(locationInContainer - toLayoutSize(accumulatedOffset)));
   4913 }
   4914 
   4915 Node* RenderBlock::nodeForHitTest() const
   4916 {
   4917     // If we are in the margins of block elements that are part of a
   4918     // continuation we're actually still inside the enclosing element
   4919     // that was split. Use the appropriate inner node.
   4920     return isAnonymousBlockContinuation() ? continuation()->node() : node();
   4921 }
   4922 
   4923 bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
   4924 {
   4925     LayoutPoint adjustedLocation(accumulatedOffset + location());
   4926     LayoutSize localOffset = toLayoutSize(adjustedLocation);
   4927 
   4928     if (!isRenderView()) {
   4929         // Check if we need to do anything at all.
   4930         LayoutRect overflowBox = visualOverflowRect();
   4931         flipForWritingMode(overflowBox);
   4932         overflowBox.moveBy(adjustedLocation);
   4933         if (!locationInContainer.intersects(overflowBox))
   4934             return false;
   4935     }
   4936 
   4937     if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) && isPointInOverflowControl(result, locationInContainer.point(), adjustedLocation)) {
   4938         updateHitTestResult(result, locationInContainer.point() - localOffset);
   4939         // FIXME: isPointInOverflowControl() doesn't handle rect-based tests yet.
   4940         if (!result.addNodeToRectBasedTestResult(nodeForHitTest(), request, locationInContainer))
   4941            return true;
   4942     }
   4943 
   4944     // If we have clipping, then we can't have any spillout.
   4945     bool useOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer();
   4946     bool useClip = (hasControlClip() || useOverflowClip);
   4947     bool checkChildren = !useClip || (hasControlClip() ? locationInContainer.intersects(controlClipRect(adjustedLocation)) : locationInContainer.intersects(overflowClipRect(adjustedLocation, locationInContainer.region(), IncludeOverlayScrollbarSize)));
   4948     if (checkChildren) {
   4949         // Hit test descendants first.
   4950         LayoutSize scrolledOffset(localOffset);
   4951         if (hasOverflowClip())
   4952             scrolledOffset -= scrolledContentOffset();
   4953 
   4954         // Hit test contents if we don't have columns.
   4955         if (!hasColumns()) {
   4956             if (hitTestContents(request, result, locationInContainer, toLayoutPoint(scrolledOffset), hitTestAction)) {
   4957                 updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - localOffset));
   4958                 return true;
   4959             }
   4960             if (hitTestAction == HitTestFloat && hitTestFloats(request, result, locationInContainer, toLayoutPoint(scrolledOffset)))
   4961                 return true;
   4962         } else if (hitTestColumns(request, result, locationInContainer, toLayoutPoint(scrolledOffset), hitTestAction)) {
   4963             updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - localOffset));
   4964             return true;
   4965         }
   4966     }
   4967 
   4968     // Check if the point is outside radii.
   4969     if (!isRenderView() && style()->hasBorderRadius()) {
   4970         LayoutRect borderRect = borderBoxRect();
   4971         borderRect.moveBy(adjustedLocation);
   4972         RoundedRect border = style()->getRoundedBorderFor(borderRect, view());
   4973         if (!locationInContainer.intersects(border))
   4974             return false;
   4975     }
   4976 
   4977     // Now hit test our background
   4978     if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) {
   4979         LayoutRect boundsRect(adjustedLocation, size());
   4980         if (visibleToHitTestRequest(request) && locationInContainer.intersects(boundsRect)) {
   4981             updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - localOffset));
   4982             if (!result.addNodeToRectBasedTestResult(nodeForHitTest(), request, locationInContainer, boundsRect))
   4983                 return true;
   4984         }
   4985     }
   4986 
   4987     return false;
   4988 }
   4989 
   4990 bool RenderBlock::hitTestFloats(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset)
   4991 {
   4992     if (!m_floatingObjects)
   4993         return false;
   4994 
   4995     LayoutPoint adjustedLocation = accumulatedOffset;
   4996     if (isRenderView()) {
   4997         adjustedLocation += toLayoutSize(toRenderView(this)->frameView()->scrollPosition());
   4998     }
   4999 
   5000     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   5001     FloatingObjectSetIterator begin = floatingObjectSet.begin();
   5002     for (FloatingObjectSetIterator it = floatingObjectSet.end(); it != begin;) {
   5003         --it;
   5004         FloatingObject* floatingObject = *it;
   5005         if (floatingObject->shouldPaint() && !floatingObject->m_renderer->hasSelfPaintingLayer()) {
   5006             LayoutUnit xOffset = xPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->x();
   5007             LayoutUnit yOffset = yPositionForFloatIncludingMargin(floatingObject) - floatingObject->m_renderer->y();
   5008             LayoutPoint childPoint = flipFloatForWritingModeForChild(floatingObject, adjustedLocation + LayoutSize(xOffset, yOffset));
   5009             if (floatingObject->m_renderer->hitTest(request, result, locationInContainer, childPoint)) {
   5010                 updateHitTestResult(result, locationInContainer.point() - toLayoutSize(childPoint));
   5011                 return true;
   5012             }
   5013         }
   5014     }
   5015 
   5016     return false;
   5017 }
   5018 
   5019 class ColumnRectIterator {
   5020     WTF_MAKE_NONCOPYABLE(ColumnRectIterator);
   5021 public:
   5022     ColumnRectIterator(const RenderBlock& block)
   5023         : m_block(block)
   5024         , m_colInfo(block.columnInfo())
   5025         , m_direction(m_block.style()->isFlippedBlocksWritingMode() ? 1 : -1)
   5026         , m_isHorizontal(block.isHorizontalWritingMode())
   5027         , m_logicalLeft(block.logicalLeftOffsetForContent())
   5028     {
   5029         int colCount = m_colInfo->columnCount();
   5030         m_colIndex = colCount - 1;
   5031         m_currLogicalTopOffset = colCount * m_colInfo->columnHeight() * m_direction;
   5032         update();
   5033     }
   5034 
   5035     void advance()
   5036     {
   5037         ASSERT(hasMore());
   5038         m_colIndex--;
   5039         update();
   5040     }
   5041 
   5042     LayoutRect columnRect() const { return m_colRect; }
   5043     bool hasMore() const { return m_colIndex >= 0; }
   5044 
   5045     void adjust(LayoutSize& offset) const
   5046     {
   5047         LayoutUnit currLogicalLeftOffset = (m_isHorizontal ? m_colRect.x() : m_colRect.y()) - m_logicalLeft;
   5048         offset += m_isHorizontal ? LayoutSize(currLogicalLeftOffset, m_currLogicalTopOffset) : LayoutSize(m_currLogicalTopOffset, currLogicalLeftOffset);
   5049         if (m_colInfo->progressionAxis() == ColumnInfo::BlockAxis) {
   5050             if (m_isHorizontal)
   5051                 offset.expand(0, m_colRect.y() - m_block.borderTop() - m_block.paddingTop());
   5052             else
   5053                 offset.expand(m_colRect.x() - m_block.borderLeft() - m_block.paddingLeft(), 0);
   5054         }
   5055     }
   5056 
   5057 private:
   5058     void update()
   5059     {
   5060         if (m_colIndex < 0)
   5061             return;
   5062 
   5063         m_colRect = m_block.columnRectAt(const_cast<ColumnInfo*>(m_colInfo), m_colIndex);
   5064         m_block.flipForWritingMode(m_colRect);
   5065         m_currLogicalTopOffset -= (m_isHorizontal ? m_colRect.height() : m_colRect.width()) * m_direction;
   5066     }
   5067 
   5068     const RenderBlock& m_block;
   5069     const ColumnInfo* const m_colInfo;
   5070     const int m_direction;
   5071     const bool m_isHorizontal;
   5072     const LayoutUnit m_logicalLeft;
   5073     int m_colIndex;
   5074     LayoutUnit m_currLogicalTopOffset;
   5075     LayoutRect m_colRect;
   5076 };
   5077 
   5078 bool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
   5079 {
   5080     // We need to do multiple passes, breaking up our hit testing into strips.
   5081     if (!hasColumns())
   5082         return false;
   5083 
   5084     for (ColumnRectIterator it(*this); it.hasMore(); it.advance()) {
   5085         LayoutRect hitRect = locationInContainer.boundingBox();
   5086         LayoutRect colRect = it.columnRect();
   5087         colRect.moveBy(accumulatedOffset);
   5088         if (locationInContainer.intersects(colRect)) {
   5089             // The point is inside this column.
   5090             // Adjust accumulatedOffset to change where we hit test.
   5091             LayoutSize offset;
   5092             it.adjust(offset);
   5093             LayoutPoint finalLocation = accumulatedOffset + offset;
   5094             if (!result.isRectBasedTest() || colRect.contains(hitRect))
   5095                 return hitTestContents(request, result, locationInContainer, finalLocation, hitTestAction) || (hitTestAction == HitTestFloat && hitTestFloats(request, result, locationInContainer, finalLocation));
   5096 
   5097             hitTestContents(request, result, locationInContainer, finalLocation, hitTestAction);
   5098         }
   5099     }
   5100 
   5101     return false;
   5102 }
   5103 
   5104 void RenderBlock::adjustForColumnRect(LayoutSize& offset, const LayoutPoint& locationInContainer) const
   5105 {
   5106     for (ColumnRectIterator it(*this); it.hasMore(); it.advance()) {
   5107         LayoutRect colRect = it.columnRect();
   5108         if (colRect.contains(locationInContainer)) {
   5109             it.adjust(offset);
   5110             return;
   5111         }
   5112     }
   5113 }
   5114 
   5115 bool RenderBlock::hitTestContents(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
   5116 {
   5117     if (isRenderRegion())
   5118         return toRenderRegion(this)->hitTestFlowThreadContents(request, result, locationInContainer, accumulatedOffset, hitTestAction);
   5119 
   5120     if (childrenInline() && !isTable()) {
   5121         // We have to hit-test our line boxes.
   5122         if (m_lineBoxes.hitTest(this, request, result, locationInContainer, accumulatedOffset, hitTestAction))
   5123             return true;
   5124     } else {
   5125         // Hit test our children.
   5126         HitTestAction childHitTest = hitTestAction;
   5127         if (hitTestAction == HitTestChildBlockBackgrounds)
   5128             childHitTest = HitTestChildBlockBackground;
   5129         for (RenderBox* child = lastChildBox(); child; child = child->previousSiblingBox()) {
   5130             LayoutPoint childPoint = flipForWritingModeForChild(child, accumulatedOffset);
   5131             if (!child->hasSelfPaintingLayer() && !child->isFloating() && child->nodeAtPoint(request, result, locationInContainer, childPoint, childHitTest))
   5132                 return true;
   5133         }
   5134     }
   5135 
   5136     return false;
   5137 }
   5138 
   5139 Position RenderBlock::positionForBox(InlineBox *box, bool start) const
   5140 {
   5141     if (!box)
   5142         return Position();
   5143 
   5144     if (!box->renderer()->nonPseudoNode())
   5145         return createLegacyEditingPosition(nonPseudoNode(), start ? caretMinOffset() : caretMaxOffset());
   5146 
   5147     if (!box->isInlineTextBox())
   5148         return createLegacyEditingPosition(box->renderer()->nonPseudoNode(), start ? box->renderer()->caretMinOffset() : box->renderer()->caretMaxOffset());
   5149 
   5150     InlineTextBox* textBox = toInlineTextBox(box);
   5151     return createLegacyEditingPosition(box->renderer()->nonPseudoNode(), start ? textBox->start() : textBox->start() + textBox->len());
   5152 }
   5153 
   5154 static inline bool isEditingBoundary(RenderObject* ancestor, RenderObject* child)
   5155 {
   5156     ASSERT(!ancestor || ancestor->nonPseudoNode());
   5157     ASSERT(child && child->nonPseudoNode());
   5158     return !ancestor || !ancestor->parent() || (ancestor->hasLayer() && ancestor->parent()->isRenderView())
   5159         || ancestor->nonPseudoNode()->rendererIsEditable() == child->nonPseudoNode()->rendererIsEditable();
   5160 }
   5161 
   5162 // FIXME: This function should go on RenderObject as an instance method. Then
   5163 // all cases in which positionForPoint recurs could call this instead to
   5164 // prevent crossing editable boundaries. This would require many tests.
   5165 static PositionWithAffinity positionForPointRespectingEditingBoundaries(RenderBlock* parent, RenderBox* child, const LayoutPoint& pointInParentCoordinates)
   5166 {
   5167     LayoutPoint childLocation = child->location();
   5168     if (child->isInFlowPositioned())
   5169         childLocation += child->offsetForInFlowPosition();
   5170 
   5171     // FIXME: This is wrong if the child's writing-mode is different from the parent's.
   5172     LayoutPoint pointInChildCoordinates(toLayoutPoint(pointInParentCoordinates - childLocation));
   5173 
   5174     // If this is an anonymous renderer, we just recur normally
   5175     Node* childNode = child->nonPseudoNode();
   5176     if (!childNode)
   5177         return child->positionForPoint(pointInChildCoordinates);
   5178 
   5179     // Otherwise, first make sure that the editability of the parent and child agree.
   5180     // If they don't agree, then we return a visible position just before or after the child
   5181     RenderObject* ancestor = parent;
   5182     while (ancestor && !ancestor->nonPseudoNode())
   5183         ancestor = ancestor->parent();
   5184 
   5185     // If we can't find an ancestor to check editability on, or editability is unchanged, we recur like normal
   5186     if (isEditingBoundary(ancestor, child))
   5187         return child->positionForPoint(pointInChildCoordinates);
   5188 
   5189     // Otherwise return before or after the child, depending on if the click was to the logical left or logical right of the child
   5190     LayoutUnit childMiddle = parent->logicalWidthForChild(child) / 2;
   5191     LayoutUnit logicalLeft = parent->isHorizontalWritingMode() ? pointInChildCoordinates.x() : pointInChildCoordinates.y();
   5192     if (logicalLeft < childMiddle)
   5193         return ancestor->createPositionWithAffinity(childNode->nodeIndex(), DOWNSTREAM);
   5194     return ancestor->createPositionWithAffinity(childNode->nodeIndex() + 1, UPSTREAM);
   5195 }
   5196 
   5197 PositionWithAffinity RenderBlock::positionForPointWithInlineChildren(const LayoutPoint& pointInLogicalContents)
   5198 {
   5199     ASSERT(childrenInline());
   5200 
   5201     if (!firstRootBox())
   5202         return createPositionWithAffinity(0, DOWNSTREAM);
   5203 
   5204     bool linesAreFlipped = style()->isFlippedLinesWritingMode();
   5205     bool blocksAreFlipped = style()->isFlippedBlocksWritingMode();
   5206 
   5207     // look for the closest line box in the root box which is at the passed-in y coordinate
   5208     InlineBox* closestBox = 0;
   5209     RootInlineBox* firstRootBoxWithChildren = 0;
   5210     RootInlineBox* lastRootBoxWithChildren = 0;
   5211     for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
   5212         if (!root->firstLeafChild())
   5213             continue;
   5214         if (!firstRootBoxWithChildren)
   5215             firstRootBoxWithChildren = root;
   5216 
   5217         if (!linesAreFlipped && root->isFirstAfterPageBreak() && (pointInLogicalContents.y() < root->lineTopWithLeading()
   5218             || (blocksAreFlipped && pointInLogicalContents.y() == root->lineTopWithLeading())))
   5219             break;
   5220 
   5221         lastRootBoxWithChildren = root;
   5222 
   5223         // check if this root line box is located at this y coordinate
   5224         if (pointInLogicalContents.y() < root->selectionBottom() || (blocksAreFlipped && pointInLogicalContents.y() == root->selectionBottom())) {
   5225             if (linesAreFlipped) {
   5226                 RootInlineBox* nextRootBoxWithChildren = root->nextRootBox();
   5227                 while (nextRootBoxWithChildren && !nextRootBoxWithChildren->firstLeafChild())
   5228                     nextRootBoxWithChildren = nextRootBoxWithChildren->nextRootBox();
   5229 
   5230                 if (nextRootBoxWithChildren && nextRootBoxWithChildren->isFirstAfterPageBreak() && (pointInLogicalContents.y() > nextRootBoxWithChildren->lineTopWithLeading()
   5231                     || (!blocksAreFlipped && pointInLogicalContents.y() == nextRootBoxWithChildren->lineTopWithLeading())))
   5232                     continue;
   5233             }
   5234             closestBox = root->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
   5235             if (closestBox)
   5236                 break;
   5237         }
   5238     }
   5239 
   5240     bool moveCaretToBoundary = document()->frame()->editor()->behavior().shouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom();
   5241 
   5242     if (!moveCaretToBoundary && !closestBox && lastRootBoxWithChildren) {
   5243         // y coordinate is below last root line box, pretend we hit it
   5244         closestBox = lastRootBoxWithChildren->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
   5245     }
   5246 
   5247     if (closestBox) {
   5248         if (moveCaretToBoundary) {
   5249             LayoutUnit firstRootBoxWithChildrenTop = min<LayoutUnit>(firstRootBoxWithChildren->selectionTop(), firstRootBoxWithChildren->logicalTop());
   5250             if (pointInLogicalContents.y() < firstRootBoxWithChildrenTop
   5251                 || (blocksAreFlipped && pointInLogicalContents.y() == firstRootBoxWithChildrenTop)) {
   5252                 InlineBox* box = firstRootBoxWithChildren->firstLeafChild();
   5253                 if (box->isLineBreak()) {
   5254                     if (InlineBox* newBox = box->nextLeafChildIgnoringLineBreak())
   5255                         box = newBox;
   5256                 }
   5257                 // y coordinate is above first root line box, so return the start of the first
   5258                 return PositionWithAffinity(positionForBox(box, true), DOWNSTREAM);
   5259             }
   5260         }
   5261 
   5262         // pass the box a top position that is inside it
   5263         LayoutPoint point(pointInLogicalContents.x(), closestBox->root()->blockDirectionPointInLine());
   5264         if (!isHorizontalWritingMode())
   5265             point = point.transposedPoint();
   5266         if (closestBox->renderer()->isReplaced())
   5267             return positionForPointRespectingEditingBoundaries(this, toRenderBox(closestBox->renderer()), point);
   5268         return closestBox->renderer()->positionForPoint(point);
   5269     }
   5270 
   5271     if (lastRootBoxWithChildren) {
   5272         // We hit this case for Mac behavior when the Y coordinate is below the last box.
   5273         ASSERT(moveCaretToBoundary);
   5274         InlineBox* logicallyLastBox;
   5275         if (lastRootBoxWithChildren->getLogicalEndBoxWithNode(logicallyLastBox))
   5276             return PositionWithAffinity(positionForBox(logicallyLastBox, false), DOWNSTREAM);
   5277     }
   5278 
   5279     // Can't reach this. We have a root line box, but it has no kids.
   5280     // FIXME: This should ASSERT_NOT_REACHED(), but clicking on placeholder text
   5281     // seems to hit this code path.
   5282     return createPositionWithAffinity(0, DOWNSTREAM);
   5283 }
   5284 
   5285 static inline bool isChildHitTestCandidate(RenderBox* box)
   5286 {
   5287     return box->height() && box->style()->visibility() == VISIBLE && !box->isFloatingOrOutOfFlowPositioned();
   5288 }
   5289 
   5290 PositionWithAffinity RenderBlock::positionForPoint(const LayoutPoint& point)
   5291 {
   5292     if (isTable())
   5293         return RenderBox::positionForPoint(point);
   5294 
   5295     if (isReplaced()) {
   5296         // FIXME: This seems wrong when the object's writing-mode doesn't match the line's writing-mode.
   5297         LayoutUnit pointLogicalLeft = isHorizontalWritingMode() ? point.x() : point.y();
   5298         LayoutUnit pointLogicalTop = isHorizontalWritingMode() ? point.y() : point.x();
   5299 
   5300         if (pointLogicalTop < 0 || (pointLogicalTop < logicalHeight() && pointLogicalLeft < 0))
   5301             return createPositionWithAffinity(caretMinOffset(), DOWNSTREAM);
   5302         if (pointLogicalTop >= logicalHeight() || (pointLogicalTop >= 0 && pointLogicalLeft >= logicalWidth()))
   5303             return createPositionWithAffinity(caretMaxOffset(), DOWNSTREAM);
   5304     }
   5305 
   5306     LayoutPoint pointInContents = point;
   5307     offsetForContents(pointInContents);
   5308     LayoutPoint pointInLogicalContents(pointInContents);
   5309     if (!isHorizontalWritingMode())
   5310         pointInLogicalContents = pointInLogicalContents.transposedPoint();
   5311 
   5312     if (childrenInline())
   5313         return positionForPointWithInlineChildren(pointInLogicalContents);
   5314 
   5315     RenderBox* lastCandidateBox = lastChildBox();
   5316     while (lastCandidateBox && !isChildHitTestCandidate(lastCandidateBox))
   5317         lastCandidateBox = lastCandidateBox->previousSiblingBox();
   5318 
   5319     bool blocksAreFlipped = style()->isFlippedBlocksWritingMode();
   5320     if (lastCandidateBox) {
   5321         if (pointInLogicalContents.y() > logicalTopForChild(lastCandidateBox)
   5322             || (!blocksAreFlipped && pointInLogicalContents.y() == logicalTopForChild(lastCandidateBox)))
   5323             return positionForPointRespectingEditingBoundaries(this, lastCandidateBox, pointInContents);
   5324 
   5325         for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
   5326             if (!isChildHitTestCandidate(childBox))
   5327                 continue;
   5328             LayoutUnit childLogicalBottom = logicalTopForChild(childBox) + logicalHeightForChild(childBox);
   5329             // We hit child if our click is above the bottom of its padding box (like IE6/7 and FF3).
   5330             if (isChildHitTestCandidate(childBox) && (pointInLogicalContents.y() < childLogicalBottom
   5331                 || (blocksAreFlipped && pointInLogicalContents.y() == childLogicalBottom)))
   5332                 return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents);
   5333         }
   5334     }
   5335 
   5336     // We only get here if there are no hit test candidate children below the click.
   5337     return RenderBox::positionForPoint(point);
   5338 }
   5339 
   5340 void RenderBlock::offsetForContents(LayoutPoint& offset) const
   5341 {
   5342     offset = flipForWritingMode(offset);
   5343 
   5344     if (hasOverflowClip())
   5345         offset += scrolledContentOffset();
   5346 
   5347     if (hasColumns())
   5348         adjustPointToColumnContents(offset);
   5349 
   5350     offset = flipForWritingMode(offset);
   5351 }
   5352 
   5353 LayoutUnit RenderBlock::availableLogicalWidth() const
   5354 {
   5355     // If we have multiple columns, then the available logical width is reduced to our column width.
   5356     if (hasColumns())
   5357         return desiredColumnWidth();
   5358     return RenderBox::availableLogicalWidth();
   5359 }
   5360 
   5361 int RenderBlock::columnGap() const
   5362 {
   5363     if (style()->hasNormalColumnGap())
   5364         return style()->fontDescription().computedPixelSize(); // "1em" is recommended as the normal gap setting. Matches <p> margins.
   5365     return static_cast<int>(style()->columnGap());
   5366 }
   5367 
   5368 void RenderBlock::calcColumnWidth()
   5369 {
   5370     if (document()->regionBasedColumnsEnabled())
   5371         return;
   5372 
   5373     // Calculate our column width and column count.
   5374     // FIXME: Can overflow on fast/block/float/float-not-removed-from-next-sibling4.html, see https://bugs.webkit.org/show_bug.cgi?id=68744
   5375     unsigned desiredColumnCount = 1;
   5376     LayoutUnit desiredColumnWidth = contentLogicalWidth();
   5377 
   5378     // For now, we don't support multi-column layouts when printing, since we have to do a lot of work for proper pagination.
   5379     if (document()->paginated() || (style()->hasAutoColumnCount() && style()->hasAutoColumnWidth()) || !style()->hasInlineColumnAxis()) {
   5380         setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
   5381         return;
   5382     }
   5383 
   5384     LayoutUnit availWidth = desiredColumnWidth;
   5385     LayoutUnit colGap = columnGap();
   5386     LayoutUnit colWidth = max<LayoutUnit>(1, LayoutUnit(style()->columnWidth()));
   5387     int colCount = max<int>(1, style()->columnCount());
   5388 
   5389     if (style()->hasAutoColumnWidth() && !style()->hasAutoColumnCount()) {
   5390         desiredColumnCount = colCount;
   5391         desiredColumnWidth = max<LayoutUnit>(0, (availWidth - ((desiredColumnCount - 1) * colGap)) / desiredColumnCount);
   5392     } else if (!style()->hasAutoColumnWidth() && style()->hasAutoColumnCount()) {
   5393         desiredColumnCount = max<LayoutUnit>(1, (availWidth + colGap) / (colWidth + colGap));
   5394         desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colGap;
   5395     } else {
   5396         desiredColumnCount = max<LayoutUnit>(min<LayoutUnit>(colCount, (availWidth + colGap) / (colWidth + colGap)), 1);
   5397         desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colGap;
   5398     }
   5399     setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
   5400 }
   5401 
   5402 bool RenderBlock::requiresColumns(int desiredColumnCount) const
   5403 {
   5404     // If overflow-y is set to paged-x or paged-y on the body or html element, we'll handle the paginating
   5405     // in the RenderView instead.
   5406     bool isPaginated = (style()->overflowY() == OPAGEDX || style()->overflowY() == OPAGEDY) && !(isRoot() || isBody());
   5407 
   5408     return firstChild()
   5409         && (desiredColumnCount != 1 || !style()->hasAutoColumnWidth() || !style()->hasInlineColumnAxis() || isPaginated)
   5410         && !firstChild()->isAnonymousColumnsBlock()
   5411         && !firstChild()->isAnonymousColumnSpanBlock();
   5412 }
   5413 
   5414 void RenderBlock::setDesiredColumnCountAndWidth(int count, LayoutUnit width)
   5415 {
   5416     bool destroyColumns = !requiresColumns(count);
   5417     if (destroyColumns) {
   5418         if (hasColumns()) {
   5419             gColumnInfoMap->take(this);
   5420             setHasColumns(false);
   5421         }
   5422     } else {
   5423         ColumnInfo* info;
   5424         if (hasColumns())
   5425             info = gColumnInfoMap->get(this);
   5426         else {
   5427             if (!gColumnInfoMap)
   5428                 gColumnInfoMap = new ColumnInfoMap;
   5429             info = new ColumnInfo;
   5430             gColumnInfoMap->add(this, adoptPtr(info));
   5431             setHasColumns(true);
   5432         }
   5433         info->setDesiredColumnCount(count);
   5434         info->setDesiredColumnWidth(width);
   5435         info->setProgressionAxis(style()->hasInlineColumnAxis() ? ColumnInfo::InlineAxis : ColumnInfo::BlockAxis);
   5436         info->setProgressionIsReversed(style()->columnProgression() == ReverseColumnProgression);
   5437     }
   5438 }
   5439 
   5440 void RenderBlock::updateColumnInfoFromStyle(RenderStyle* style)
   5441 {
   5442     if (!hasColumns())
   5443         return;
   5444 
   5445     ColumnInfo* info = gColumnInfoMap->get(this);
   5446 
   5447     bool needsLayout = false;
   5448     ColumnInfo::Axis oldAxis = info->progressionAxis();
   5449     ColumnInfo::Axis newAxis = style->hasInlineColumnAxis() ? ColumnInfo::InlineAxis : ColumnInfo::BlockAxis;
   5450     if (oldAxis != newAxis) {
   5451         info->setProgressionAxis(newAxis);
   5452         needsLayout = true;
   5453     }
   5454 
   5455     bool oldProgressionIsReversed = info->progressionIsReversed();
   5456     bool newProgressionIsReversed = style->columnProgression() == ReverseColumnProgression;
   5457     if (oldProgressionIsReversed != newProgressionIsReversed) {
   5458         info->setProgressionIsReversed(newProgressionIsReversed);
   5459         needsLayout = true;
   5460     }
   5461 
   5462     if (needsLayout)
   5463         setNeedsLayoutAndPrefWidthsRecalc();
   5464 }
   5465 
   5466 LayoutUnit RenderBlock::desiredColumnWidth() const
   5467 {
   5468     if (!hasColumns())
   5469         return contentLogicalWidth();
   5470     return gColumnInfoMap->get(this)->desiredColumnWidth();
   5471 }
   5472 
   5473 unsigned RenderBlock::desiredColumnCount() const
   5474 {
   5475     if (!hasColumns())
   5476         return 1;
   5477     return gColumnInfoMap->get(this)->desiredColumnCount();
   5478 }
   5479 
   5480 ColumnInfo* RenderBlock::columnInfo() const
   5481 {
   5482     if (!hasColumns())
   5483         return 0;
   5484     return gColumnInfoMap->get(this);
   5485 }
   5486 
   5487 unsigned RenderBlock::columnCount(ColumnInfo* colInfo) const
   5488 {
   5489     ASSERT(hasColumns());
   5490     ASSERT(gColumnInfoMap->get(this) == colInfo);
   5491     return colInfo->columnCount();
   5492 }
   5493 
   5494 LayoutRect RenderBlock::columnRectAt(ColumnInfo* colInfo, unsigned index) const
   5495 {
   5496     ASSERT(hasColumns() && gColumnInfoMap->get(this) == colInfo);
   5497 
   5498     // Compute the appropriate rect based off our information.
   5499     LayoutUnit colLogicalWidth = colInfo->desiredColumnWidth();
   5500     LayoutUnit colLogicalHeight = colInfo->columnHeight();
   5501     LayoutUnit colLogicalTop = borderBefore() + paddingBefore();
   5502     LayoutUnit colLogicalLeft = logicalLeftOffsetForContent();
   5503     LayoutUnit colGap = columnGap();
   5504     if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
   5505         if (style()->isLeftToRightDirection() ^ colInfo->progressionIsReversed())
   5506             colLogicalLeft += index * (colLogicalWidth + colGap);
   5507         else
   5508             colLogicalLeft += contentLogicalWidth() - colLogicalWidth - index * (colLogicalWidth + colGap);
   5509     } else {
   5510         if (!colInfo->progressionIsReversed())
   5511             colLogicalTop += index * (colLogicalHeight + colGap);
   5512         else
   5513             colLogicalTop += contentLogicalHeight() - colLogicalHeight - index * (colLogicalHeight + colGap);
   5514     }
   5515 
   5516     if (isHorizontalWritingMode())
   5517         return LayoutRect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
   5518     return LayoutRect(colLogicalTop, colLogicalLeft, colLogicalHeight, colLogicalWidth);
   5519 }
   5520 
   5521 bool RenderBlock::relayoutForPagination(bool hasSpecifiedPageLogicalHeight, LayoutUnit pageLogicalHeight, LayoutStateMaintainer& statePusher)
   5522 {
   5523     if (!hasColumns())
   5524         return false;
   5525 
   5526     OwnPtr<RenderOverflow> savedOverflow = m_overflow.release();
   5527     if (childrenInline())
   5528         addOverflowFromInlineChildren();
   5529     else
   5530         addOverflowFromBlockChildren();
   5531     LayoutUnit layoutOverflowLogicalBottom = (isHorizontalWritingMode() ? layoutOverflowRect().maxY() : layoutOverflowRect().maxX()) - borderBefore() - paddingBefore();
   5532 
   5533     // FIXME: We don't balance properly at all in the presence of forced page breaks.  We need to understand what
   5534     // the distance between forced page breaks is so that we can avoid making the minimum column height too tall.
   5535     ColumnInfo* colInfo = columnInfo();
   5536     if (!hasSpecifiedPageLogicalHeight) {
   5537         LayoutUnit columnHeight = pageLogicalHeight;
   5538         int minColumnCount = colInfo->forcedBreaks() + 1;
   5539         int desiredColumnCount = colInfo->desiredColumnCount();
   5540         if (minColumnCount >= desiredColumnCount) {
   5541             // The forced page breaks are in control of the balancing.  Just set the column height to the
   5542             // maximum page break distance.
   5543             if (!pageLogicalHeight) {
   5544                 LayoutUnit distanceBetweenBreaks = max<LayoutUnit>(colInfo->maximumDistanceBetweenForcedBreaks(),
   5545                                                                    view()->layoutState()->pageLogicalOffset(this, borderBefore() + paddingBefore() + layoutOverflowLogicalBottom) - colInfo->forcedBreakOffset());
   5546                 columnHeight = max(colInfo->minimumColumnHeight(), distanceBetweenBreaks);
   5547             }
   5548         } else if (layoutOverflowLogicalBottom > boundedMultiply(pageLogicalHeight, desiredColumnCount)) {
   5549             // Now that we know the intrinsic height of the columns, we have to rebalance them.
   5550             columnHeight = max<LayoutUnit>(colInfo->minimumColumnHeight(), ceilf((float)layoutOverflowLogicalBottom / desiredColumnCount));
   5551         }
   5552 
   5553         if (columnHeight && columnHeight != pageLogicalHeight) {
   5554             statePusher.pop();
   5555             setEverHadLayout(true);
   5556             layoutBlock(false, columnHeight);
   5557             return true;
   5558         }
   5559     }
   5560 
   5561     if (pageLogicalHeight)
   5562         colInfo->setColumnCountAndHeight(ceilf((float)layoutOverflowLogicalBottom / pageLogicalHeight), pageLogicalHeight);
   5563 
   5564     if (columnCount(colInfo)) {
   5565         setLogicalHeight(borderBefore() + paddingBefore() + colInfo->columnHeight() + borderAfter() + paddingAfter() + scrollbarLogicalHeight());
   5566         m_overflow.clear();
   5567     } else
   5568         m_overflow = savedOverflow.release();
   5569 
   5570     return false;
   5571 }
   5572 
   5573 void RenderBlock::adjustPointToColumnContents(LayoutPoint& point) const
   5574 {
   5575     // Just bail if we have no columns.
   5576     if (!hasColumns())
   5577         return;
   5578 
   5579     ColumnInfo* colInfo = columnInfo();
   5580     if (!columnCount(colInfo))
   5581         return;
   5582 
   5583     // Determine which columns we intersect.
   5584     LayoutUnit colGap = columnGap();
   5585     LayoutUnit halfColGap = colGap / 2;
   5586     LayoutPoint columnPoint(columnRectAt(colInfo, 0).location());
   5587     LayoutUnit logicalOffset = 0;
   5588     for (unsigned i = 0; i < colInfo->columnCount(); i++) {
   5589         // Add in half the column gap to the left and right of the rect.
   5590         LayoutRect colRect = columnRectAt(colInfo, i);
   5591         flipForWritingMode(colRect);
   5592         if (isHorizontalWritingMode() == (colInfo->progressionAxis() == ColumnInfo::InlineAxis)) {
   5593             LayoutRect gapAndColumnRect(colRect.x() - halfColGap, colRect.y(), colRect.width() + colGap, colRect.height());
   5594             if (point.x() >= gapAndColumnRect.x() && point.x() < gapAndColumnRect.maxX()) {
   5595                 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
   5596                     // FIXME: The clamping that follows is not completely right for right-to-left
   5597                     // content.
   5598                     // Clamp everything above the column to its top left.
   5599                     if (point.y() < gapAndColumnRect.y())
   5600                         point = gapAndColumnRect.location();
   5601                     // Clamp everything below the column to the next column's top left. If there is
   5602                     // no next column, this still maps to just after this column.
   5603                     else if (point.y() >= gapAndColumnRect.maxY()) {
   5604                         point = gapAndColumnRect.location();
   5605                         point.move(0, gapAndColumnRect.height());
   5606                     }
   5607                 } else {
   5608                     if (point.x() < colRect.x())
   5609                         point.setX(colRect.x());
   5610                     else if (point.x() >= colRect.maxX())
   5611                         point.setX(colRect.maxX() - 1);
   5612                 }
   5613 
   5614                 // We're inside the column.  Translate the x and y into our column coordinate space.
   5615                 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
   5616                     point.move(columnPoint.x() - colRect.x(), (!style()->isFlippedBlocksWritingMode() ? logicalOffset : -logicalOffset));
   5617                 else
   5618                     point.move((!style()->isFlippedBlocksWritingMode() ? logicalOffset : -logicalOffset) - colRect.x() + borderLeft() + paddingLeft(), 0);
   5619                 return;
   5620             }
   5621 
   5622             // Move to the next position.
   5623             logicalOffset += colInfo->progressionAxis() == ColumnInfo::InlineAxis ? colRect.height() : colRect.width();
   5624         } else {
   5625             LayoutRect gapAndColumnRect(colRect.x(), colRect.y() - halfColGap, colRect.width(), colRect.height() + colGap);
   5626             if (point.y() >= gapAndColumnRect.y() && point.y() < gapAndColumnRect.maxY()) {
   5627                 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
   5628                     // FIXME: The clamping that follows is not completely right for right-to-left
   5629                     // content.
   5630                     // Clamp everything above the column to its top left.
   5631                     if (point.x() < gapAndColumnRect.x())
   5632                         point = gapAndColumnRect.location();
   5633                     // Clamp everything below the column to the next column's top left. If there is
   5634                     // no next column, this still maps to just after this column.
   5635                     else if (point.x() >= gapAndColumnRect.maxX()) {
   5636                         point = gapAndColumnRect.location();
   5637                         point.move(gapAndColumnRect.width(), 0);
   5638                     }
   5639                 } else {
   5640                     if (point.y() < colRect.y())
   5641                         point.setY(colRect.y());
   5642                     else if (point.y() >= colRect.maxY())
   5643                         point.setY(colRect.maxY() - 1);
   5644                 }
   5645 
   5646                 // We're inside the column.  Translate the x and y into our column coordinate space.
   5647                 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
   5648                     point.move((!style()->isFlippedBlocksWritingMode() ? logicalOffset : -logicalOffset), columnPoint.y() - colRect.y());
   5649                 else
   5650                     point.move(0, (!style()->isFlippedBlocksWritingMode() ? logicalOffset : -logicalOffset) - colRect.y() + borderTop() + paddingTop());
   5651                 return;
   5652             }
   5653 
   5654             // Move to the next position.
   5655             logicalOffset += colInfo->progressionAxis() == ColumnInfo::InlineAxis ? colRect.width() : colRect.height();
   5656         }
   5657     }
   5658 }
   5659 
   5660 void RenderBlock::adjustRectForColumns(LayoutRect& r) const
   5661 {
   5662     // Just bail if we have no columns.
   5663     if (!hasColumns())
   5664         return;
   5665 
   5666     ColumnInfo* colInfo = columnInfo();
   5667 
   5668     // Determine which columns we intersect.
   5669     unsigned colCount = columnCount(colInfo);
   5670     if (!colCount)
   5671         return;
   5672 
   5673     // Begin with a result rect that is empty.
   5674     LayoutRect result;
   5675 
   5676     bool isHorizontal = isHorizontalWritingMode();
   5677     LayoutUnit beforeBorderPadding = borderBefore() + paddingBefore();
   5678     LayoutUnit colHeight = colInfo->columnHeight();
   5679     if (!colHeight)
   5680         return;
   5681 
   5682     LayoutUnit startOffset = max(isHorizontal ? r.y() : r.x(), beforeBorderPadding);
   5683     LayoutUnit endOffset = max(min<LayoutUnit>(isHorizontal ? r.maxY() : r.maxX(), beforeBorderPadding + colCount * colHeight), beforeBorderPadding);
   5684 
   5685     // FIXME: Can overflow on fast/block/float/float-not-removed-from-next-sibling4.html, see https://bugs.webkit.org/show_bug.cgi?id=68744
   5686     unsigned startColumn = (startOffset - beforeBorderPadding) / colHeight;
   5687     unsigned endColumn = (endOffset - beforeBorderPadding) / colHeight;
   5688 
   5689     if (startColumn == endColumn) {
   5690         // The rect is fully contained within one column. Adjust for our offsets
   5691         // and repaint only that portion.
   5692         LayoutUnit logicalLeftOffset = logicalLeftOffsetForContent();
   5693         LayoutRect colRect = columnRectAt(colInfo, startColumn);
   5694         LayoutRect repaintRect = r;
   5695 
   5696         if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
   5697             if (isHorizontal)
   5698                 repaintRect.move(colRect.x() - logicalLeftOffset, - static_cast<int>(startColumn) * colHeight);
   5699             else
   5700                 repaintRect.move(- static_cast<int>(startColumn) * colHeight, colRect.y() - logicalLeftOffset);
   5701         } else {
   5702             if (isHorizontal)
   5703                 repaintRect.move(0, colRect.y() - startColumn * colHeight - beforeBorderPadding);
   5704             else
   5705                 repaintRect.move(colRect.x() - startColumn * colHeight - beforeBorderPadding, 0);
   5706         }
   5707         repaintRect.intersect(colRect);
   5708         result.unite(repaintRect);
   5709     } else {
   5710         // We span multiple columns. We can just unite the start and end column to get the final
   5711         // repaint rect.
   5712         result.unite(columnRectAt(colInfo, startColumn));
   5713         result.unite(columnRectAt(colInfo, endColumn));
   5714     }
   5715 
   5716     r = result;
   5717 }
   5718 
   5719 LayoutPoint RenderBlock::flipForWritingModeIncludingColumns(const LayoutPoint& point) const
   5720 {
   5721     ASSERT(hasColumns());
   5722     if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
   5723         return point;
   5724     ColumnInfo* colInfo = columnInfo();
   5725     LayoutUnit columnLogicalHeight = colInfo->columnHeight();
   5726     LayoutUnit expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
   5727     if (isHorizontalWritingMode())
   5728         return LayoutPoint(point.x(), expandedLogicalHeight - point.y());
   5729     return LayoutPoint(expandedLogicalHeight - point.x(), point.y());
   5730 }
   5731 
   5732 void RenderBlock::adjustStartEdgeForWritingModeIncludingColumns(LayoutRect& rect) const
   5733 {
   5734     ASSERT(hasColumns());
   5735     if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
   5736         return;
   5737 
   5738     ColumnInfo* colInfo = columnInfo();
   5739     LayoutUnit columnLogicalHeight = colInfo->columnHeight();
   5740     LayoutUnit expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
   5741 
   5742     if (isHorizontalWritingMode())
   5743         rect.setY(expandedLogicalHeight - rect.maxY());
   5744     else
   5745         rect.setX(expandedLogicalHeight - rect.maxX());
   5746 }
   5747 
   5748 void RenderBlock::adjustForColumns(LayoutSize& offset, const LayoutPoint& point) const
   5749 {
   5750     if (!hasColumns())
   5751         return;
   5752 
   5753     ColumnInfo* colInfo = columnInfo();
   5754 
   5755     LayoutUnit logicalLeft = logicalLeftOffsetForContent();
   5756     unsigned colCount = columnCount(colInfo);
   5757     LayoutUnit colLogicalWidth = colInfo->desiredColumnWidth();
   5758     LayoutUnit colLogicalHeight = colInfo->columnHeight();
   5759 
   5760     for (unsigned i = 0; i < colCount; ++i) {
   5761         // Compute the edges for a given column in the block progression direction.
   5762         LayoutRect sliceRect = LayoutRect(logicalLeft, borderBefore() + paddingBefore() + i * colLogicalHeight, colLogicalWidth, colLogicalHeight);
   5763         if (!isHorizontalWritingMode())
   5764             sliceRect = sliceRect.transposedRect();
   5765 
   5766         LayoutUnit logicalOffset = i * colLogicalHeight;
   5767 
   5768         // Now we're in the same coordinate space as the point.  See if it is inside the rectangle.
   5769         if (isHorizontalWritingMode()) {
   5770             if (point.y() >= sliceRect.y() && point.y() < sliceRect.maxY()) {
   5771                 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
   5772                     offset.expand(columnRectAt(colInfo, i).x() - logicalLeft, -logicalOffset);
   5773                 else
   5774                     offset.expand(0, columnRectAt(colInfo, i).y() - logicalOffset - borderBefore() - paddingBefore());
   5775                 return;
   5776             }
   5777         } else {
   5778             if (point.x() >= sliceRect.x() && point.x() < sliceRect.maxX()) {
   5779                 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
   5780                     offset.expand(-logicalOffset, columnRectAt(colInfo, i).y() - logicalLeft);
   5781                 else
   5782                     offset.expand(columnRectAt(colInfo, i).x() - logicalOffset - borderBefore() - paddingBefore(), 0);
   5783                 return;
   5784             }
   5785         }
   5786     }
   5787 }
   5788 
   5789 void RenderBlock::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
   5790 {
   5791     if (childrenInline()) {
   5792         // FIXME: Remove this const_cast.
   5793         const_cast<RenderBlock*>(this)->computeInlinePreferredLogicalWidths(minLogicalWidth, maxLogicalWidth);
   5794     } else
   5795         computeBlockPreferredLogicalWidths(minLogicalWidth, maxLogicalWidth);
   5796 
   5797     maxLogicalWidth = max(minLogicalWidth, maxLogicalWidth);
   5798 
   5799     // A horizontal marquee with inline children has no minimum width.
   5800     if (childrenInline() && isMarquee() && toRenderMarquee(this)->isHorizontal())
   5801         minLogicalWidth = 0;
   5802 
   5803     if (isTableCell()) {
   5804         Length tableCellWidth = toRenderTableCell(this)->styleOrColLogicalWidth();
   5805         if (tableCellWidth.isFixed() && tableCellWidth.value() > 0)
   5806             maxLogicalWidth = max(minLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(tableCellWidth.value()));
   5807     }
   5808 
   5809     int scrollbarWidth = instrinsicScrollbarLogicalWidth();
   5810     maxLogicalWidth += scrollbarWidth;
   5811     minLogicalWidth += scrollbarWidth;
   5812 }
   5813 
   5814 void RenderBlock::computePreferredLogicalWidths()
   5815 {
   5816     ASSERT(preferredLogicalWidthsDirty());
   5817 
   5818     updateFirstLetter();
   5819 
   5820     m_minPreferredLogicalWidth = 0;
   5821     m_maxPreferredLogicalWidth = 0;
   5822 
   5823     // FIXME: The isFixed() calls here should probably be checking for isSpecified since you
   5824     // should be able to use percentage, calc or viewport relative values for width.
   5825     RenderStyle* styleToUse = style();
   5826     if (!isTableCell() && styleToUse->logicalWidth().isFixed() && styleToUse->logicalWidth().value() >= 0
   5827         && !(isDeprecatedFlexItem() && !styleToUse->logicalWidth().intValue()))
   5828         m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalWidth().value());
   5829     else
   5830         computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
   5831 
   5832     if (styleToUse->logicalMinWidth().isFixed() && styleToUse->logicalMinWidth().value() > 0) {
   5833         m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMinWidth().value()));
   5834         m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMinWidth().value()));
   5835     }
   5836 
   5837     if (styleToUse->logicalMaxWidth().isFixed()) {
   5838         m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMaxWidth().value()));
   5839         m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMaxWidth().value()));
   5840     }
   5841 
   5842     // Table layout uses integers, ceil the preferred widths to ensure that they can contain the contents.
   5843     if (isTableCell()) {
   5844         m_minPreferredLogicalWidth = m_minPreferredLogicalWidth.ceil();
   5845         m_maxPreferredLogicalWidth = m_maxPreferredLogicalWidth.ceil();
   5846     }
   5847 
   5848     LayoutUnit borderAndPadding = borderAndPaddingLogicalWidth();
   5849     m_minPreferredLogicalWidth += borderAndPadding;
   5850     m_maxPreferredLogicalWidth += borderAndPadding;
   5851 
   5852     setPreferredLogicalWidthsDirty(false);
   5853 }
   5854 
   5855 struct InlineMinMaxIterator {
   5856 /* InlineMinMaxIterator is a class that will iterate over all render objects that contribute to
   5857    inline min/max width calculations.  Note the following about the way it walks:
   5858    (1) Positioned content is skipped (since it does not contribute to min/max width of a block)
   5859    (2) We do not drill into the children of floats or replaced elements, since you can't break
   5860        in the middle of such an element.
   5861    (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side can have
   5862        distinct borders/margin/padding that contribute to the min/max width.
   5863 */
   5864     RenderObject* parent;
   5865     RenderObject* current;
   5866     bool endOfInline;
   5867 
   5868     InlineMinMaxIterator(RenderObject* p, bool end = false)
   5869         :parent(p), current(p), endOfInline(end) {}
   5870 
   5871     RenderObject* next();
   5872 };
   5873 
   5874 RenderObject* InlineMinMaxIterator::next()
   5875 {
   5876     RenderObject* result = 0;
   5877     bool oldEndOfInline = endOfInline;
   5878     endOfInline = false;
   5879     while (current || current == parent) {
   5880         if (!oldEndOfInline &&
   5881             (current == parent ||
   5882              (!current->isFloating() && !current->isReplaced() && !current->isOutOfFlowPositioned())))
   5883             result = current->firstChild();
   5884         if (!result) {
   5885             // We hit the end of our inline. (It was empty, e.g., <span></span>.)
   5886             if (!oldEndOfInline && current->isRenderInline()) {
   5887                 result = current;
   5888                 endOfInline = true;
   5889                 break;
   5890             }
   5891 
   5892             while (current && current != parent) {
   5893                 result = current->nextSibling();
   5894                 if (result) break;
   5895                 current = current->parent();
   5896                 if (current && current != parent && current->isRenderInline()) {
   5897                     result = current;
   5898                     endOfInline = true;
   5899                     break;
   5900                 }
   5901             }
   5902         }
   5903 
   5904         if (!result)
   5905             break;
   5906 
   5907         if (!result->isOutOfFlowPositioned() && (result->isText() || result->isFloating() || result->isReplaced() || result->isRenderInline()))
   5908              break;
   5909 
   5910         current = result;
   5911         result = 0;
   5912     }
   5913 
   5914     // Update our position.
   5915     current = result;
   5916     return current;
   5917 }
   5918 
   5919 static LayoutUnit getBPMWidth(LayoutUnit childValue, Length cssUnit)
   5920 {
   5921     if (cssUnit.type() != Auto)
   5922         return (cssUnit.isFixed() ? static_cast<LayoutUnit>(cssUnit.value()) : childValue);
   5923     return 0;
   5924 }
   5925 
   5926 static LayoutUnit getBorderPaddingMargin(const RenderBoxModelObject* child, bool endOfInline)
   5927 {
   5928     RenderStyle* childStyle = child->style();
   5929     if (endOfInline)
   5930         return getBPMWidth(child->marginEnd(), childStyle->marginEnd()) +
   5931                getBPMWidth(child->paddingEnd(), childStyle->paddingEnd()) +
   5932                child->borderEnd();
   5933     return getBPMWidth(child->marginStart(), childStyle->marginStart()) +
   5934                getBPMWidth(child->paddingStart(), childStyle->paddingStart()) +
   5935                child->borderStart();
   5936 }
   5937 
   5938 static inline void stripTrailingSpace(float& inlineMax, float& inlineMin,
   5939                                       RenderObject* trailingSpaceChild)
   5940 {
   5941     if (trailingSpaceChild && trailingSpaceChild->isText()) {
   5942         // Collapse away the trailing space at the end of a block.
   5943         RenderText* t = toRenderText(trailingSpaceChild);
   5944         const UChar space = ' ';
   5945         const Font& font = t->style()->font(); // FIXME: This ignores first-line.
   5946         float spaceWidth = font.width(RenderBlock::constructTextRun(t, font, &space, 1, t->style()));
   5947         inlineMax -= spaceWidth + font.wordSpacing();
   5948         if (inlineMin > inlineMax)
   5949             inlineMin = inlineMax;
   5950     }
   5951 }
   5952 
   5953 static inline void updatePreferredWidth(LayoutUnit& preferredWidth, float& result)
   5954 {
   5955     LayoutUnit snappedResult = LayoutUnit::fromFloatCeil(result);
   5956     preferredWidth = max(snappedResult, preferredWidth);
   5957 }
   5958 
   5959 // When converting between floating point and LayoutUnits we risk losing precision
   5960 // with each conversion. When this occurs while accumulating our preferred widths,
   5961 // we can wind up with a line width that's larger than our maxPreferredWidth due to
   5962 // pure float accumulation.
   5963 static inline LayoutUnit adjustFloatForSubPixelLayout(float value)
   5964 {
   5965     return LayoutUnit::fromFloatCeil(value);
   5966 }
   5967 
   5968 
   5969 void RenderBlock::computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth)
   5970 {
   5971     float inlineMax = 0;
   5972     float inlineMin = 0;
   5973 
   5974     RenderStyle* styleToUse = style();
   5975     RenderBlock* containingBlock = this->containingBlock();
   5976     LayoutUnit cw = containingBlock ? containingBlock->contentLogicalWidth() : LayoutUnit();
   5977 
   5978     // If we are at the start of a line, we want to ignore all white-space.
   5979     // Also strip spaces if we previously had text that ended in a trailing space.
   5980     bool stripFrontSpaces = true;
   5981     RenderObject* trailingSpaceChild = 0;
   5982 
   5983     // Firefox and Opera will allow a table cell to grow to fit an image inside it under
   5984     // very specific cirucumstances (in order to match common WinIE renderings).
   5985     // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
   5986     bool allowImagesToBreak = !document()->inQuirksMode() || !isTableCell() || !styleToUse->logicalWidth().isIntrinsicOrAuto();
   5987 
   5988     bool autoWrap, oldAutoWrap;
   5989     autoWrap = oldAutoWrap = styleToUse->autoWrap();
   5990 
   5991     InlineMinMaxIterator childIterator(this);
   5992 
   5993     // Only gets added to the max preffered width once.
   5994     bool addedTextIndent = false;
   5995     // Signals the text indent was more negative than the min preferred width
   5996     bool hasRemainingNegativeTextIndent = false;
   5997 
   5998     LayoutUnit textIndent = minimumValueForLength(styleToUse->textIndent(), cw, view());
   5999     RenderObject* prevFloat = 0;
   6000     bool isPrevChildInlineFlow = false;
   6001     bool shouldBreakLineAfterText = false;
   6002     while (RenderObject* child = childIterator.next()) {
   6003         autoWrap = child->isReplaced() ? child->parent()->style()->autoWrap() :
   6004             child->style()->autoWrap();
   6005 
   6006         if (!child->isBR()) {
   6007             // Step One: determine whether or not we need to go ahead and
   6008             // terminate our current line.  Each discrete chunk can become
   6009             // the new min-width, if it is the widest chunk seen so far, and
   6010             // it can also become the max-width.
   6011 
   6012             // Children fall into three categories:
   6013             // (1) An inline flow object.  These objects always have a min/max of 0,
   6014             // and are included in the iteration solely so that their margins can
   6015             // be added in.
   6016             //
   6017             // (2) An inline non-text non-flow object, e.g., an inline replaced element.
   6018             // These objects can always be on a line by themselves, so in this situation
   6019             // we need to go ahead and break the current line, and then add in our own
   6020             // margins and min/max width on its own line, and then terminate the line.
   6021             //
   6022             // (3) A text object.  Text runs can have breakable characters at the start,
   6023             // the middle or the end.  They may also lose whitespace off the front if
   6024             // we're already ignoring whitespace.  In order to compute accurate min-width
   6025             // information, we need three pieces of information.
   6026             // (a) the min-width of the first non-breakable run.  Should be 0 if the text string
   6027             // starts with whitespace.
   6028             // (b) the min-width of the last non-breakable run. Should be 0 if the text string
   6029             // ends with whitespace.
   6030             // (c) the min/max width of the string (trimmed for whitespace).
   6031             //
   6032             // If the text string starts with whitespace, then we need to go ahead and
   6033             // terminate our current line (unless we're already in a whitespace stripping
   6034             // mode.
   6035             //
   6036             // If the text string has a breakable character in the middle, but didn't start
   6037             // with whitespace, then we add the width of the first non-breakable run and
   6038             // then end the current line.  We then need to use the intermediate min/max width
   6039             // values (if any of them are larger than our current min/max).  We then look at
   6040             // the width of the last non-breakable run and use that to start a new line
   6041             // (unless we end in whitespace).
   6042             RenderStyle* childStyle = child->style();
   6043             float childMin = 0;
   6044             float childMax = 0;
   6045 
   6046             if (!child->isText()) {
   6047                 // Case (1) and (2).  Inline replaced and inline flow elements.
   6048                 if (child->isRenderInline()) {
   6049                     // Add in padding/border/margin from the appropriate side of
   6050                     // the element.
   6051                     float bpm = getBorderPaddingMargin(toRenderInline(child), childIterator.endOfInline);
   6052                     childMin += bpm;
   6053                     childMax += bpm;
   6054 
   6055                     inlineMin += childMin;
   6056                     inlineMax += childMax;
   6057 
   6058                     child->setPreferredLogicalWidthsDirty(false);
   6059                 } else {
   6060                     // Inline replaced elts add in their margins to their min/max values.
   6061                     LayoutUnit margins = 0;
   6062                     Length startMargin = childStyle->marginStart();
   6063                     Length endMargin = childStyle->marginEnd();
   6064                     if (startMargin.isFixed())
   6065                         margins += adjustFloatForSubPixelLayout(startMargin.value());
   6066                     if (endMargin.isFixed())
   6067                         margins += adjustFloatForSubPixelLayout(endMargin.value());
   6068                     childMin += margins.ceilToFloat();
   6069                     childMax += margins.ceilToFloat();
   6070                 }
   6071             }
   6072 
   6073             if (!child->isRenderInline() && !child->isText()) {
   6074                 // Case (2). Inline replaced elements and floats.
   6075                 // Go ahead and terminate the current line as far as
   6076                 // minwidth is concerned.
   6077                 childMin += child->minPreferredLogicalWidth().ceilToFloat();
   6078                 childMax += child->maxPreferredLogicalWidth().ceilToFloat();
   6079 
   6080                 bool clearPreviousFloat;
   6081                 if (child->isFloating()) {
   6082                     clearPreviousFloat = (prevFloat
   6083                         && ((prevFloat->style()->floating() == LeftFloat && (childStyle->clear() & CLEFT))
   6084                             || (prevFloat->style()->floating() == RightFloat && (childStyle->clear() & CRIGHT))));
   6085                     prevFloat = child;
   6086                 } else
   6087                     clearPreviousFloat = false;
   6088 
   6089                 bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak;
   6090                 if ((canBreakReplacedElement && (autoWrap || oldAutoWrap) && (!isPrevChildInlineFlow || shouldBreakLineAfterText)) || clearPreviousFloat) {
   6091                     updatePreferredWidth(minLogicalWidth, inlineMin);
   6092                     inlineMin = 0;
   6093                 }
   6094 
   6095                 // If we're supposed to clear the previous float, then terminate maxwidth as well.
   6096                 if (clearPreviousFloat) {
   6097                     updatePreferredWidth(maxLogicalWidth, inlineMax);
   6098                     inlineMax = 0;
   6099                 }
   6100 
   6101                 // Add in text-indent.  This is added in only once.
   6102                 if (!addedTextIndent && !child->isFloating()) {
   6103                     float ceiledTextIndent = textIndent.ceilToFloat();
   6104                     childMin += ceiledTextIndent;
   6105                     childMax += ceiledTextIndent;
   6106 
   6107                     if (childMin < 0)
   6108                         textIndent = adjustFloatForSubPixelLayout(childMin);
   6109                     else
   6110                         addedTextIndent = true;
   6111                 }
   6112 
   6113                 // Add our width to the max.
   6114                 inlineMax += max<float>(0, childMax);
   6115 
   6116                 if (!autoWrap || !canBreakReplacedElement || (isPrevChildInlineFlow && !shouldBreakLineAfterText)) {
   6117                     if (child->isFloating())
   6118                         updatePreferredWidth(minLogicalWidth, childMin);
   6119                     else
   6120                         inlineMin += childMin;
   6121                 } else {
   6122                     // Now check our line.
   6123                     updatePreferredWidth(minLogicalWidth, childMin);
   6124 
   6125                     // Now start a new line.
   6126                     inlineMin = 0;
   6127                 }
   6128 
   6129                 if (autoWrap && canBreakReplacedElement && isPrevChildInlineFlow) {
   6130                     updatePreferredWidth(minLogicalWidth, inlineMin);
   6131                     inlineMin = 0;
   6132                 }
   6133 
   6134                 // We are no longer stripping whitespace at the start of
   6135                 // a line.
   6136                 if (!child->isFloating()) {
   6137                     stripFrontSpaces = false;
   6138                     trailingSpaceChild = 0;
   6139                 }
   6140             } else if (child->isText()) {
   6141                 // Case (3). Text.
   6142                 RenderText* t = toRenderText(child);
   6143 
   6144                 if (t->isWordBreak()) {
   6145                     updatePreferredWidth(minLogicalWidth, inlineMin);
   6146                     inlineMin = 0;
   6147                     continue;
   6148                 }
   6149 
   6150                 if (t->style()->hasTextCombine() && t->isCombineText())
   6151                     toRenderCombineText(t)->combineText();
   6152 
   6153                 // Determine if we have a breakable character.  Pass in
   6154                 // whether or not we should ignore any spaces at the front
   6155                 // of the string.  If those are going to be stripped out,
   6156                 // then they shouldn't be considered in the breakable char
   6157                 // check.
   6158                 bool hasBreakableChar, hasBreak;
   6159                 float firstLineMinWidth, lastLineMinWidth;
   6160                 bool hasBreakableStart, hasBreakableEnd;
   6161                 float firstLineMaxWidth, lastLineMaxWidth;
   6162                 t->trimmedPrefWidths(inlineMax,
   6163                     firstLineMinWidth, hasBreakableStart, lastLineMinWidth, hasBreakableEnd,
   6164                     hasBreakableChar, hasBreak, firstLineMaxWidth, lastLineMaxWidth,
   6165                     childMin, childMax, stripFrontSpaces);
   6166 
   6167                 // This text object will not be rendered, but it may still provide a breaking opportunity.
   6168                 if (!hasBreak && childMax == 0) {
   6169                     if (autoWrap && (hasBreakableStart || hasBreakableEnd)) {
   6170                         updatePreferredWidth(minLogicalWidth, inlineMin);
   6171                         inlineMin = 0;
   6172                     }
   6173                     continue;
   6174                 }
   6175 
   6176                 if (stripFrontSpaces)
   6177                     trailingSpaceChild = child;
   6178                 else
   6179                     trailingSpaceChild = 0;
   6180 
   6181                 // Add in text-indent.  This is added in only once.
   6182                 float ti = 0;
   6183                 if (!addedTextIndent || hasRemainingNegativeTextIndent) {
   6184                     ti = textIndent.ceilToFloat();
   6185                     childMin += ti;
   6186                     firstLineMinWidth += ti;
   6187 
   6188                     // It the text indent negative and larger than the child minimum, we re-use the remainder
   6189                     // in future minimum calculations, but using the negative value again on the maximum
   6190                     // will lead to under-counting the max pref width.
   6191                     if (!addedTextIndent) {
   6192                         childMax += ti;
   6193                         firstLineMaxWidth += ti;
   6194                         addedTextIndent = true;
   6195                     }
   6196 
   6197                     if (childMin < 0) {
   6198                         textIndent = childMin;
   6199                         hasRemainingNegativeTextIndent = true;
   6200                     }
   6201                 }
   6202 
   6203                 // If we have no breakable characters at all,
   6204                 // then this is the easy case. We add ourselves to the current
   6205                 // min and max and continue.
   6206                 if (!hasBreakableChar) {
   6207                     inlineMin += childMin;
   6208                 } else {
   6209                     if (hasBreakableStart) {
   6210                         updatePreferredWidth(minLogicalWidth, inlineMin);
   6211                     } else {
   6212                         inlineMin += firstLineMinWidth;
   6213                         updatePreferredWidth(minLogicalWidth, inlineMin);
   6214                         childMin -= ti;
   6215                     }
   6216 
   6217                     inlineMin = childMin;
   6218 
   6219                     if (hasBreakableEnd) {
   6220                         updatePreferredWidth(minLogicalWidth, inlineMin);
   6221                         inlineMin = 0;
   6222                         shouldBreakLineAfterText = false;
   6223                     } else {
   6224                         updatePreferredWidth(minLogicalWidth, inlineMin);
   6225                         inlineMin = lastLineMinWidth;
   6226                         shouldBreakLineAfterText = true;
   6227                     }
   6228                 }
   6229 
   6230                 if (hasBreak) {
   6231                     inlineMax += firstLineMaxWidth;
   6232                     updatePreferredWidth(maxLogicalWidth, inlineMax);
   6233                     updatePreferredWidth(maxLogicalWidth, childMax);
   6234                     inlineMax = lastLineMaxWidth;
   6235                     addedTextIndent = true;
   6236                 } else {
   6237                     inlineMax += max<float>(0, childMax);
   6238                 }
   6239             }
   6240 
   6241             // Ignore spaces after a list marker.
   6242             if (child->isListMarker())
   6243                 stripFrontSpaces = true;
   6244         } else {
   6245             updatePreferredWidth(minLogicalWidth, inlineMin);
   6246             updatePreferredWidth(maxLogicalWidth, inlineMax);
   6247             inlineMin = inlineMax = 0;
   6248             stripFrontSpaces = true;
   6249             trailingSpaceChild = 0;
   6250             addedTextIndent = true;
   6251         }
   6252 
   6253         if (!child->isText() && child->isRenderInline())
   6254             isPrevChildInlineFlow = true;
   6255         else
   6256             isPrevChildInlineFlow = false;
   6257 
   6258         oldAutoWrap = autoWrap;
   6259     }
   6260 
   6261     if (styleToUse->collapseWhiteSpace())
   6262         stripTrailingSpace(inlineMax, inlineMin, trailingSpaceChild);
   6263 
   6264     updatePreferredWidth(minLogicalWidth, inlineMin);
   6265     updatePreferredWidth(maxLogicalWidth, inlineMax);
   6266 }
   6267 
   6268 void RenderBlock::computeBlockPreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
   6269 {
   6270     RenderStyle* styleToUse = style();
   6271     bool nowrap = styleToUse->whiteSpace() == NOWRAP;
   6272 
   6273     RenderObject* child = firstChild();
   6274     RenderBlock* containingBlock = this->containingBlock();
   6275     LayoutUnit floatLeftWidth = 0, floatRightWidth = 0;
   6276     while (child) {
   6277         // Positioned children don't affect the min/max width
   6278         if (child->isOutOfFlowPositioned()) {
   6279             child = child->nextSibling();
   6280             continue;
   6281         }
   6282 
   6283         RenderStyle* childStyle = child->style();
   6284         if (child->isFloating() || (child->isBox() && toRenderBox(child)->avoidsFloats())) {
   6285             LayoutUnit floatTotalWidth = floatLeftWidth + floatRightWidth;
   6286             if (childStyle->clear() & CLEFT) {
   6287                 maxLogicalWidth = max(floatTotalWidth, maxLogicalWidth);
   6288                 floatLeftWidth = 0;
   6289             }
   6290             if (childStyle->clear() & CRIGHT) {
   6291                 maxLogicalWidth = max(floatTotalWidth, maxLogicalWidth);
   6292                 floatRightWidth = 0;
   6293             }
   6294         }
   6295 
   6296         // A margin basically has three types: fixed, percentage, and auto (variable).
   6297         // Auto and percentage margins simply become 0 when computing min/max width.
   6298         // Fixed margins can be added in as is.
   6299         Length startMarginLength = childStyle->marginStartUsing(styleToUse);
   6300         Length endMarginLength = childStyle->marginEndUsing(styleToUse);
   6301         LayoutUnit margin = 0;
   6302         LayoutUnit marginStart = 0;
   6303         LayoutUnit marginEnd = 0;
   6304         if (startMarginLength.isFixed())
   6305             marginStart += startMarginLength.value();
   6306         if (endMarginLength.isFixed())
   6307             marginEnd += endMarginLength.value();
   6308         margin = marginStart + marginEnd;
   6309 
   6310         LayoutUnit childMinPreferredLogicalWidth, childMaxPreferredLogicalWidth;
   6311         if (child->isBox() && child->isHorizontalWritingMode() != isHorizontalWritingMode()) {
   6312             RenderBox* childBox = toRenderBox(child);
   6313             LogicalExtentComputedValues computedValues;
   6314             childBox->computeLogicalHeight(childBox->borderAndPaddingLogicalHeight(), 0, computedValues);
   6315             childMinPreferredLogicalWidth = childMaxPreferredLogicalWidth = computedValues.m_extent;
   6316         } else {
   6317             childMinPreferredLogicalWidth = child->minPreferredLogicalWidth();
   6318             childMaxPreferredLogicalWidth = child->maxPreferredLogicalWidth();
   6319         }
   6320 
   6321         LayoutUnit w = childMinPreferredLogicalWidth + margin;
   6322         minLogicalWidth = max(w, minLogicalWidth);
   6323 
   6324         // IE ignores tables for calculation of nowrap. Makes some sense.
   6325         if (nowrap && !child->isTable())
   6326             maxLogicalWidth = max(w, maxLogicalWidth);
   6327 
   6328         w = childMaxPreferredLogicalWidth + margin;
   6329 
   6330         if (!child->isFloating()) {
   6331             if (child->isBox() && toRenderBox(child)->avoidsFloats()) {
   6332                 // Determine a left and right max value based off whether or not the floats can fit in the
   6333                 // margins of the object.  For negative margins, we will attempt to overlap the float if the negative margin
   6334                 // is smaller than the float width.
   6335                 bool ltr = containingBlock ? containingBlock->style()->isLeftToRightDirection() : styleToUse->isLeftToRightDirection();
   6336                 LayoutUnit marginLogicalLeft = ltr ? marginStart : marginEnd;
   6337                 LayoutUnit marginLogicalRight = ltr ? marginEnd : marginStart;
   6338                 LayoutUnit maxLeft = marginLogicalLeft > 0 ? max(floatLeftWidth, marginLogicalLeft) : floatLeftWidth + marginLogicalLeft;
   6339                 LayoutUnit maxRight = marginLogicalRight > 0 ? max(floatRightWidth, marginLogicalRight) : floatRightWidth + marginLogicalRight;
   6340                 w = childMaxPreferredLogicalWidth + maxLeft + maxRight;
   6341                 w = max(w, floatLeftWidth + floatRightWidth);
   6342             }
   6343             else
   6344                 maxLogicalWidth = max(floatLeftWidth + floatRightWidth, maxLogicalWidth);
   6345             floatLeftWidth = floatRightWidth = 0;
   6346         }
   6347 
   6348         if (child->isFloating()) {
   6349             if (childStyle->floating() == LeftFloat)
   6350                 floatLeftWidth += w;
   6351             else
   6352                 floatRightWidth += w;
   6353         } else
   6354             maxLogicalWidth = max(w, maxLogicalWidth);
   6355 
   6356         child = child->nextSibling();
   6357     }
   6358 
   6359     // Always make sure these values are non-negative.
   6360     minLogicalWidth = max<LayoutUnit>(0, minLogicalWidth);
   6361     maxLogicalWidth = max<LayoutUnit>(0, maxLogicalWidth);
   6362 
   6363     maxLogicalWidth = max(floatLeftWidth + floatRightWidth, maxLogicalWidth);
   6364 }
   6365 
   6366 bool RenderBlock::hasLineIfEmpty() const
   6367 {
   6368     if (!node())
   6369         return false;
   6370 
   6371     if (node()->isRootEditableElement())
   6372         return true;
   6373 
   6374     if (node()->isShadowRoot() && toShadowRoot(node())->host()->hasTagName(inputTag))
   6375         return true;
   6376 
   6377     return false;
   6378 }
   6379 
   6380 LayoutUnit RenderBlock::lineHeight(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
   6381 {
   6382     // Inline blocks are replaced elements. Otherwise, just pass off to
   6383     // the base class.  If we're being queried as though we're the root line
   6384     // box, then the fact that we're an inline-block is irrelevant, and we behave
   6385     // just like a block.
   6386     if (isReplaced() && linePositionMode == PositionOnContainingLine)
   6387         return RenderBox::lineHeight(firstLine, direction, linePositionMode);
   6388 
   6389     if (firstLine && document()->styleSheetCollection()->usesFirstLineRules()) {
   6390         RenderStyle* s = style(firstLine);
   6391         if (s != style())
   6392             return s->computedLineHeight(view());
   6393     }
   6394 
   6395     if (m_lineHeight == -1)
   6396         m_lineHeight = style()->computedLineHeight(view());
   6397 
   6398     return m_lineHeight;
   6399 }
   6400 
   6401 int RenderBlock::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
   6402 {
   6403     // Inline blocks are replaced elements. Otherwise, just pass off to
   6404     // the base class.  If we're being queried as though we're the root line
   6405     // box, then the fact that we're an inline-block is irrelevant, and we behave
   6406     // just like a block.
   6407     if (isReplaced() && linePositionMode == PositionOnContainingLine) {
   6408         // For "leaf" theme objects, let the theme decide what the baseline position is.
   6409         // FIXME: Might be better to have a custom CSS property instead, so that if the theme
   6410         // is turned off, checkboxes/radios will still have decent baselines.
   6411         // FIXME: Need to patch form controls to deal with vertical lines.
   6412         if (style()->hasAppearance() && !theme()->isControlContainer(style()->appearance()))
   6413             return theme()->baselinePosition(this);
   6414 
   6415         // CSS2.1 states that the baseline of an inline block is the baseline of the last line box in
   6416         // the normal flow.  We make an exception for marquees, since their baselines are meaningless
   6417         // (the content inside them moves).  This matches WinIE as well, which just bottom-aligns them.
   6418         // We also give up on finding a baseline if we have a vertical scrollbar, or if we are scrolled
   6419         // vertically (e.g., an overflow:hidden block that has had scrollTop moved).
   6420         bool ignoreBaseline = (layer() && (isMarquee() || (direction == HorizontalLine ? (layer()->verticalScrollbar() || layer()->scrollYOffset())
   6421             : (layer()->horizontalScrollbar() || layer()->scrollXOffset())))) || (isWritingModeRoot() && !isRubyRun());
   6422 
   6423         int baselinePos = ignoreBaseline ? -1 : inlineBlockBaseline(direction);
   6424 
   6425         if (isDeprecatedFlexibleBox()) {
   6426             // Historically, we did this check for all baselines. But we can't
   6427             // remove this code from deprecated flexbox, because it effectively
   6428             // breaks -webkit-line-clamp, which is used in the wild -- we would
   6429             // calculate the baseline as if -webkit-line-clamp wasn't used.
   6430             // For simplicity, we use this for all uses of deprecated flexbox.
   6431             LayoutUnit bottomOfContent = direction == HorizontalLine ? borderTop() + paddingTop() + contentHeight() : borderRight() + paddingRight() + contentWidth();
   6432             if (baselinePos > bottomOfContent)
   6433                 baselinePos = -1;
   6434         }
   6435         if (baselinePos != -1)
   6436             return direction == HorizontalLine ? marginTop() + baselinePos : marginRight() + baselinePos;
   6437 
   6438         return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
   6439     }
   6440 
   6441     // If we're not replaced, we'll only get called with PositionOfInteriorLineBoxes.
   6442     // Note that inline-block counts as replaced here.
   6443     ASSERT(linePositionMode == PositionOfInteriorLineBoxes);
   6444 
   6445     const FontMetrics& fontMetrics = style(firstLine)->fontMetrics();
   6446     return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2;
   6447 }
   6448 
   6449 int RenderBlock::firstLineBoxBaseline() const
   6450 {
   6451     if (!isBlockFlow() || (isWritingModeRoot() && !isRubyRun()))
   6452         return -1;
   6453 
   6454     if (childrenInline()) {
   6455         if (firstLineBox())
   6456             return firstLineBox()->logicalTop() + style(true)->fontMetrics().ascent(firstRootBox()->baselineType());
   6457         else
   6458             return -1;
   6459     }
   6460     else {
   6461         for (RenderBox* curr = firstChildBox(); curr; curr = curr->nextSiblingBox()) {
   6462             if (!curr->isFloatingOrOutOfFlowPositioned()) {
   6463                 int result = curr->firstLineBoxBaseline();
   6464                 if (result != -1)
   6465                     return curr->logicalTop() + result; // Translate to our coordinate space.
   6466             }
   6467         }
   6468     }
   6469 
   6470     return -1;
   6471 }
   6472 
   6473 int RenderBlock::inlineBlockBaseline(LineDirectionMode direction) const
   6474 {
   6475     if (style()->overflowY() != OVISIBLE) {
   6476         // We are not calling RenderBox::baselinePosition here because the caller should add the margin-top/margin-right, not us.
   6477         return direction == HorizontalLine ? height() + m_marginBox.bottom() : width() + m_marginBox.left();
   6478     }
   6479 
   6480     return lastLineBoxBaseline(direction);
   6481 }
   6482 
   6483 int RenderBlock::lastLineBoxBaseline(LineDirectionMode lineDirection) const
   6484 {
   6485     if (!isBlockFlow() || (isWritingModeRoot() && !isRubyRun()))
   6486         return -1;
   6487 
   6488     if (childrenInline()) {
   6489         if (!firstLineBox() && hasLineIfEmpty()) {
   6490             const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
   6491             return fontMetrics.ascent()
   6492                  + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
   6493                  + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
   6494         }
   6495         if (lastLineBox())
   6496             return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->fontMetrics().ascent(lastRootBox()->baselineType());
   6497         return -1;
   6498     } else {
   6499         bool haveNormalFlowChild = false;
   6500         for (RenderBox* curr = lastChildBox(); curr; curr = curr->previousSiblingBox()) {
   6501             if (!curr->isFloatingOrOutOfFlowPositioned()) {
   6502                 haveNormalFlowChild = true;
   6503                 int result = curr->inlineBlockBaseline(lineDirection);
   6504                 if (result != -1)
   6505                     return curr->logicalTop() + result; // Translate to our coordinate space.
   6506             }
   6507         }
   6508         if (!haveNormalFlowChild && hasLineIfEmpty()) {
   6509             const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
   6510             return fontMetrics.ascent()
   6511                  + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
   6512                  + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
   6513         }
   6514     }
   6515 
   6516     return -1;
   6517 }
   6518 
   6519 RenderBlock* RenderBlock::firstLineBlock() const
   6520 {
   6521     RenderBlock* firstLineBlock = const_cast<RenderBlock*>(this);
   6522     bool hasPseudo = false;
   6523     while (true) {
   6524         hasPseudo = firstLineBlock->style()->hasPseudoStyle(FIRST_LINE);
   6525         if (hasPseudo)
   6526             break;
   6527         RenderObject* parentBlock = firstLineBlock->parent();
   6528         // We include isRenderButton in this check because buttons are
   6529         // implemented using flex box but should still support first-line. The
   6530         // flex box spec requires that flex box does not support first-line,
   6531         // though.
   6532         // FIXME: Remove when buttons are implemented with align-items instead
   6533         // of flexbox.
   6534         if (firstLineBlock->isReplaced() || firstLineBlock->isFloating()
   6535             || !parentBlock || parentBlock->firstChild() != firstLineBlock || !parentBlock->isBlockFlow()
   6536             || (parentBlock->isFlexibleBox() && !parentBlock->isRenderButton()))
   6537             break;
   6538         ASSERT_WITH_SECURITY_IMPLICATION(parentBlock->isRenderBlock());
   6539         firstLineBlock = toRenderBlock(parentBlock);
   6540     }
   6541 
   6542     if (!hasPseudo)
   6543         return 0;
   6544 
   6545     return firstLineBlock;
   6546 }
   6547 
   6548 static RenderStyle* styleForFirstLetter(RenderObject* firstLetterBlock, RenderObject* firstLetterContainer)
   6549 {
   6550     RenderStyle* pseudoStyle = firstLetterBlock->getCachedPseudoStyle(FIRST_LETTER, firstLetterContainer->firstLineStyle());
   6551     // Force inline display (except for floating first-letters).
   6552     pseudoStyle->setDisplay(pseudoStyle->isFloating() ? BLOCK : INLINE);
   6553     // CSS2 says first-letter can't be positioned.
   6554     pseudoStyle->setPosition(StaticPosition);
   6555     return pseudoStyle;
   6556 }
   6557 
   6558 // CSS 2.1 http://www.w3.org/TR/CSS21/selector.html#first-letter
   6559 // "Punctuation (i.e, characters defined in Unicode [UNICODE] in the "open" (Ps), "close" (Pe),
   6560 // "initial" (Pi). "final" (Pf) and "other" (Po) punctuation classes), that precedes or follows the first letter should be included"
   6561 static inline bool isPunctuationForFirstLetter(UChar c)
   6562 {
   6563     CharCategory charCategory = category(c);
   6564     return charCategory == Punctuation_Open
   6565         || charCategory == Punctuation_Close
   6566         || charCategory == Punctuation_InitialQuote
   6567         || charCategory == Punctuation_FinalQuote
   6568         || charCategory == Punctuation_Other;
   6569 }
   6570 
   6571 static inline bool shouldSkipForFirstLetter(UChar c)
   6572 {
   6573     return isSpaceOrNewline(c) || c == noBreakSpace || isPunctuationForFirstLetter(c);
   6574 }
   6575 
   6576 static inline RenderObject* findFirstLetterBlock(RenderBlock* start)
   6577 {
   6578     RenderObject* firstLetterBlock = start;
   6579     while (true) {
   6580         // We include isRenderButton in these two checks because buttons are
   6581         // implemented using flex box but should still support first-letter.
   6582         // The flex box spec requires that flex box does not support
   6583         // first-letter, though.
   6584         // FIXME: Remove when buttons are implemented with align-items instead
   6585         // of flexbox.
   6586         bool canHaveFirstLetterRenderer = firstLetterBlock->style()->hasPseudoStyle(FIRST_LETTER)
   6587             && firstLetterBlock->canHaveGeneratedChildren()
   6588             && (!firstLetterBlock->isFlexibleBox() || firstLetterBlock->isRenderButton());
   6589         if (canHaveFirstLetterRenderer)
   6590             return firstLetterBlock;
   6591 
   6592         RenderObject* parentBlock = firstLetterBlock->parent();
   6593         if (firstLetterBlock->isReplaced() || !parentBlock || parentBlock->firstChild() != firstLetterBlock ||
   6594             !parentBlock->isBlockFlow() || (parentBlock->isFlexibleBox() && !parentBlock->isRenderButton()))
   6595             return 0;
   6596         firstLetterBlock = parentBlock;
   6597     }
   6598 
   6599     return 0;
   6600 }
   6601 
   6602 void RenderBlock::updateFirstLetterStyle(RenderObject* firstLetterBlock, RenderObject* currentChild)
   6603 {
   6604     RenderObject* firstLetter = currentChild->parent();
   6605     RenderObject* firstLetterContainer = firstLetter->parent();
   6606     RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
   6607     ASSERT(firstLetter->isFloating() || firstLetter->isInline());
   6608 
   6609     if (Node::diff(firstLetter->style(), pseudoStyle, document()) == Node::Detach) {
   6610         // The first-letter renderer needs to be replaced. Create a new renderer of the right type.
   6611         RenderObject* newFirstLetter;
   6612         if (pseudoStyle->display() == INLINE)
   6613             newFirstLetter = RenderInline::createAnonymous(document());
   6614         else
   6615             newFirstLetter = RenderBlock::createAnonymous(document());
   6616         newFirstLetter->setStyle(pseudoStyle);
   6617 
   6618         // Move the first letter into the new renderer.
   6619         LayoutStateDisabler layoutStateDisabler(view());
   6620         while (RenderObject* child = firstLetter->firstChild()) {
   6621             if (child->isText())
   6622                 toRenderText(child)->removeAndDestroyTextBoxes();
   6623             firstLetter->removeChild(child);
   6624             newFirstLetter->addChild(child, 0);
   6625         }
   6626 
   6627         RenderTextFragment* remainingText = 0;
   6628         RenderObject* nextSibling = firstLetter->nextSibling();
   6629         RenderObject* remainingTextObject = toRenderBoxModelObject(firstLetter)->firstLetterRemainingText();
   6630         if (remainingTextObject && remainingTextObject->isText() && toRenderText(remainingTextObject)->isTextFragment())
   6631             remainingText = toRenderTextFragment(remainingTextObject);
   6632         if (remainingText) {
   6633             ASSERT(remainingText->isAnonymous() || remainingText->node()->renderer() == remainingText);
   6634             // Replace the old renderer with the new one.
   6635             remainingText->setFirstLetter(newFirstLetter);
   6636             toRenderBoxModelObject(newFirstLetter)->setFirstLetterRemainingText(remainingText);
   6637         }
   6638         // To prevent removal of single anonymous block in RenderBlock::removeChild and causing
   6639         // |nextSibling| to go stale, we remove the old first letter using removeChildNode first.
   6640         firstLetterContainer->virtualChildren()->removeChildNode(firstLetterContainer, firstLetter);
   6641         firstLetter->destroy();
   6642         firstLetter = newFirstLetter;
   6643         firstLetterContainer->addChild(firstLetter, nextSibling);
   6644     } else
   6645         firstLetter->setStyle(pseudoStyle);
   6646 
   6647     for (RenderObject* genChild = firstLetter->firstChild(); genChild; genChild = genChild->nextSibling()) {
   6648         if (genChild->isText())
   6649             genChild->setStyle(pseudoStyle);
   6650     }
   6651 }
   6652 
   6653 void RenderBlock::createFirstLetterRenderer(RenderObject* firstLetterBlock, RenderObject* currentChild)
   6654 {
   6655     RenderObject* firstLetterContainer = currentChild->parent();
   6656     RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
   6657     RenderObject* firstLetter = 0;
   6658     if (pseudoStyle->display() == INLINE)
   6659         firstLetter = RenderInline::createAnonymous(document());
   6660     else
   6661         firstLetter = RenderBlock::createAnonymous(document());
   6662     firstLetter->setStyle(pseudoStyle);
   6663     firstLetterContainer->addChild(firstLetter, currentChild);
   6664 
   6665     RenderText* textObj = toRenderText(currentChild);
   6666 
   6667     // The original string is going to be either a generated content string or a DOM node's
   6668     // string.  We want the original string before it got transformed in case first-letter has
   6669     // no text-transform or a different text-transform applied to it.
   6670     RefPtr<StringImpl> oldText = textObj->originalText();
   6671     ASSERT(oldText);
   6672 
   6673     if (oldText && oldText->length() > 0) {
   6674         unsigned length = 0;
   6675 
   6676         // Account for leading spaces and punctuation.
   6677         while (length < oldText->length() && shouldSkipForFirstLetter((*oldText)[length]))
   6678             length++;
   6679 
   6680         // Account for first letter.
   6681         length++;
   6682 
   6683         // Keep looking for whitespace and allowed punctuation, but avoid
   6684         // accumulating just whitespace into the :first-letter.
   6685         for (unsigned scanLength = length; scanLength < oldText->length(); ++scanLength) {
   6686             UChar c = (*oldText)[scanLength];
   6687 
   6688             if (!shouldSkipForFirstLetter(c))
   6689                 break;
   6690 
   6691             if (isPunctuationForFirstLetter(c))
   6692                 length = scanLength + 1;
   6693          }
   6694 
   6695         // Construct a text fragment for the text after the first letter.
   6696         // This text fragment might be empty.
   6697         RenderTextFragment* remainingText =
   6698             new RenderTextFragment(textObj->node() ? textObj->node() : textObj->document(), oldText.get(), length, oldText->length() - length);
   6699         remainingText->setStyle(textObj->style());
   6700         if (remainingText->node())
   6701             remainingText->node()->setRenderer(remainingText);
   6702 
   6703         firstLetterContainer->addChild(remainingText, textObj);
   6704         firstLetterContainer->removeChild(textObj);
   6705         remainingText->setFirstLetter(firstLetter);
   6706         toRenderBoxModelObject(firstLetter)->setFirstLetterRemainingText(remainingText);
   6707 
   6708         // construct text fragment for the first letter
   6709         RenderTextFragment* letter =
   6710             new RenderTextFragment(remainingText->node() ? remainingText->node() : remainingText->document(), oldText.get(), 0, length);
   6711         letter->setStyle(pseudoStyle);
   6712         firstLetter->addChild(letter);
   6713 
   6714         textObj->destroy();
   6715     }
   6716 }
   6717 
   6718 void RenderBlock::updateFirstLetter()
   6719 {
   6720     if (!document()->styleSheetCollection()->usesFirstLetterRules())
   6721         return;
   6722     // Don't recur
   6723     if (style()->styleType() == FIRST_LETTER)
   6724         return;
   6725 
   6726     // FIXME: We need to destroy the first-letter object if it is no longer the first child. Need to find
   6727     // an efficient way to check for that situation though before implementing anything.
   6728     RenderObject* firstLetterBlock = findFirstLetterBlock(this);
   6729     if (!firstLetterBlock)
   6730         return;
   6731 
   6732     // Drill into inlines looking for our first text child.
   6733     RenderObject* currChild = firstLetterBlock->firstChild();
   6734     while (currChild) {
   6735         if (currChild->isText())
   6736             break;
   6737         if (currChild->isListMarker())
   6738             currChild = currChild->nextSibling();
   6739         else if (currChild->isFloatingOrOutOfFlowPositioned()) {
   6740             if (currChild->style()->styleType() == FIRST_LETTER) {
   6741                 currChild = currChild->firstChild();
   6742                 break;
   6743             }
   6744             currChild = currChild->nextSibling();
   6745         } else if (currChild->isReplaced() || currChild->isRenderButton() || currChild->isMenuList())
   6746             break;
   6747         else if (currChild->style()->hasPseudoStyle(FIRST_LETTER) && currChild->canHaveGeneratedChildren())  {
   6748             // We found a lower-level node with first-letter, which supersedes the higher-level style
   6749             firstLetterBlock = currChild;
   6750             currChild = currChild->firstChild();
   6751         } else
   6752             currChild = currChild->firstChild();
   6753     }
   6754 
   6755     if (!currChild)
   6756         return;
   6757 
   6758     // If the child already has style, then it has already been created, so we just want
   6759     // to update it.
   6760     if (currChild->parent()->style()->styleType() == FIRST_LETTER) {
   6761         updateFirstLetterStyle(firstLetterBlock, currChild);
   6762         return;
   6763     }
   6764 
   6765     if (!currChild->isText() || currChild->isBR())
   6766         return;
   6767 
   6768     // Our layout state is not valid for the repaints we are going to trigger by
   6769     // adding and removing children of firstLetterContainer.
   6770     LayoutStateDisabler layoutStateDisabler(view());
   6771 
   6772     createFirstLetterRenderer(firstLetterBlock, currChild);
   6773 }
   6774 
   6775 // Helper methods for obtaining the last line, computing line counts and heights for line counts
   6776 // (crawling into blocks).
   6777 static bool shouldCheckLines(RenderObject* obj)
   6778 {
   6779     return !obj->isFloatingOrOutOfFlowPositioned() && !obj->isRunIn()
   6780             && obj->isBlockFlow() && obj->style()->height().isAuto()
   6781             && (!obj->isDeprecatedFlexibleBox() || obj->style()->boxOrient() == VERTICAL);
   6782 }
   6783 
   6784 static int getHeightForLineCount(RenderBlock* block, int l, bool includeBottom, int& count)
   6785 {
   6786     if (block->style()->visibility() == VISIBLE) {
   6787         if (block->childrenInline()) {
   6788             for (RootInlineBox* box = block->firstRootBox(); box; box = box->nextRootBox()) {
   6789                 if (++count == l)
   6790                     return box->lineBottom() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : LayoutUnit());
   6791             }
   6792         }
   6793         else {
   6794             RenderBox* normalFlowChildWithoutLines = 0;
   6795             for (RenderBox* obj = block->firstChildBox(); obj; obj = obj->nextSiblingBox()) {
   6796                 if (shouldCheckLines(obj)) {
   6797                     int result = getHeightForLineCount(toRenderBlock(obj), l, false, count);
   6798                     if (result != -1)
   6799                         return result + obj->y() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : LayoutUnit());
   6800                 } else if (!obj->isFloatingOrOutOfFlowPositioned() && !obj->isRunIn())
   6801                     normalFlowChildWithoutLines = obj;
   6802             }
   6803             if (normalFlowChildWithoutLines && l == 0)
   6804                 return normalFlowChildWithoutLines->y() + normalFlowChildWithoutLines->height();
   6805         }
   6806     }
   6807 
   6808     return -1;
   6809 }
   6810 
   6811 RootInlineBox* RenderBlock::lineAtIndex(int i) const
   6812 {
   6813     ASSERT(i >= 0);
   6814 
   6815     if (style()->visibility() != VISIBLE)
   6816         return 0;
   6817 
   6818     if (childrenInline()) {
   6819         for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
   6820             if (!i--)
   6821                 return box;
   6822     } else {
   6823         for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
   6824             if (!shouldCheckLines(child))
   6825                 continue;
   6826             if (RootInlineBox* box = toRenderBlock(child)->lineAtIndex(i))
   6827                 return box;
   6828         }
   6829     }
   6830 
   6831     return 0;
   6832 }
   6833 
   6834 int RenderBlock::lineCount(const RootInlineBox* stopRootInlineBox, bool* found) const
   6835 {
   6836     int count = 0;
   6837 
   6838     if (style()->visibility() == VISIBLE) {
   6839         if (childrenInline())
   6840             for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) {
   6841                 count++;
   6842                 if (box == stopRootInlineBox) {
   6843                     if (found)
   6844                         *found = true;
   6845                     break;
   6846                 }
   6847             }
   6848         else
   6849             for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling())
   6850                 if (shouldCheckLines(obj)) {
   6851                     bool recursiveFound = false;
   6852                     count += toRenderBlock(obj)->lineCount(stopRootInlineBox, &recursiveFound);
   6853                     if (recursiveFound) {
   6854                         if (found)
   6855                             *found = true;
   6856                         break;
   6857                     }
   6858                 }
   6859     }
   6860     return count;
   6861 }
   6862 
   6863 int RenderBlock::heightForLineCount(int l)
   6864 {
   6865     int count = 0;
   6866     return getHeightForLineCount(this, l, true, count);
   6867 }
   6868 
   6869 void RenderBlock::adjustForBorderFit(LayoutUnit x, LayoutUnit& left, LayoutUnit& right) const
   6870 {
   6871     // We don't deal with relative positioning.  Our assumption is that you shrink to fit the lines without accounting
   6872     // for either overflow or translations via relative positioning.
   6873     if (style()->visibility() == VISIBLE) {
   6874         if (childrenInline()) {
   6875             for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) {
   6876                 if (box->firstChild())
   6877                     left = min(left, x + static_cast<LayoutUnit>(box->firstChild()->x()));
   6878                 if (box->lastChild())
   6879                     right = max(right, x + static_cast<LayoutUnit>(ceilf(box->lastChild()->logicalRight())));
   6880             }
   6881         }
   6882         else {
   6883             for (RenderBox* obj = firstChildBox(); obj; obj = obj->nextSiblingBox()) {
   6884                 if (!obj->isFloatingOrOutOfFlowPositioned()) {
   6885                     if (obj->isBlockFlow() && !obj->hasOverflowClip())
   6886                         toRenderBlock(obj)->adjustForBorderFit(x + obj->x(), left, right);
   6887                     else if (obj->style()->visibility() == VISIBLE) {
   6888                         // We are a replaced element or some kind of non-block-flow object.
   6889                         left = min(left, x + obj->x());
   6890                         right = max(right, x + obj->x() + obj->width());
   6891                     }
   6892                 }
   6893             }
   6894         }
   6895 
   6896         if (m_floatingObjects) {
   6897             const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
   6898             FloatingObjectSetIterator end = floatingObjectSet.end();
   6899             for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
   6900                 FloatingObject* r = *it;
   6901                 // Only examine the object if our m_shouldPaint flag is set.
   6902                 if (r->shouldPaint()) {
   6903                     LayoutUnit floatLeft = xPositionForFloatIncludingMargin(r) - r->m_renderer->x();
   6904                     LayoutUnit floatRight = floatLeft + r->m_renderer->width();
   6905                     left = min(left, floatLeft);
   6906                     right = max(right, floatRight);
   6907                 }
   6908             }
   6909         }
   6910     }
   6911 }
   6912 
   6913 void RenderBlock::fitBorderToLinesIfNeeded()
   6914 {
   6915     if (style()->borderFit() == BorderFitBorder || hasOverrideWidth())
   6916         return;
   6917 
   6918     // Walk any normal flow lines to snugly fit.
   6919     LayoutUnit left = LayoutUnit::max();
   6920     LayoutUnit right = LayoutUnit::min();
   6921     LayoutUnit oldWidth = contentWidth();
   6922     adjustForBorderFit(0, left, right);
   6923 
   6924     // Clamp to our existing edges. We can never grow. We only shrink.
   6925     LayoutUnit leftEdge = borderLeft() + paddingLeft();
   6926     LayoutUnit rightEdge = leftEdge + oldWidth;
   6927     left = min(rightEdge, max(leftEdge, left));
   6928     right = max(leftEdge, min(rightEdge, right));
   6929 
   6930     LayoutUnit newContentWidth = right - left;
   6931     if (newContentWidth == oldWidth)
   6932         return;
   6933 
   6934     setOverrideLogicalContentWidth(newContentWidth);
   6935     layoutBlock(false);
   6936     clearOverrideLogicalContentWidth();
   6937 }
   6938 
   6939 void RenderBlock::clearTruncation()
   6940 {
   6941     if (style()->visibility() == VISIBLE) {
   6942         if (childrenInline() && hasMarkupTruncation()) {
   6943             setHasMarkupTruncation(false);
   6944             for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
   6945                 box->clearTruncation();
   6946         } else {
   6947             for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling()) {
   6948                 if (shouldCheckLines(obj))
   6949                     toRenderBlock(obj)->clearTruncation();
   6950             }
   6951         }
   6952     }
   6953 }
   6954 
   6955 void RenderBlock::setMaxMarginBeforeValues(LayoutUnit pos, LayoutUnit neg)
   6956 {
   6957     if (!m_rareData) {
   6958         if (pos == RenderBlockRareData::positiveMarginBeforeDefault(this) && neg == RenderBlockRareData::negativeMarginBeforeDefault(this))
   6959             return;
   6960         m_rareData = adoptPtr(new RenderBlockRareData(this));
   6961     }
   6962     m_rareData->m_margins.setPositiveMarginBefore(pos);
   6963     m_rareData->m_margins.setNegativeMarginBefore(neg);
   6964 }
   6965 
   6966 void RenderBlock::setMaxMarginAfterValues(LayoutUnit pos, LayoutUnit neg)
   6967 {
   6968     if (!m_rareData) {
   6969         if (pos == RenderBlockRareData::positiveMarginAfterDefault(this) && neg == RenderBlockRareData::negativeMarginAfterDefault(this))
   6970             return;
   6971         m_rareData = adoptPtr(new RenderBlockRareData(this));
   6972     }
   6973     m_rareData->m_margins.setPositiveMarginAfter(pos);
   6974     m_rareData->m_margins.setNegativeMarginAfter(neg);
   6975 }
   6976 
   6977 void RenderBlock::setMustDiscardMarginBefore(bool value)
   6978 {
   6979     if (style()->marginBeforeCollapse() == MDISCARD) {
   6980         ASSERT(value);
   6981         return;
   6982     }
   6983 
   6984     if (!m_rareData && !value)
   6985         return;
   6986 
   6987     if (!m_rareData)
   6988         m_rareData = adoptPtr(new RenderBlockRareData(this));
   6989 
   6990     m_rareData->m_discardMarginBefore = value;
   6991 }
   6992 
   6993 void RenderBlock::setMustDiscardMarginAfter(bool value)
   6994 {
   6995     if (style()->marginAfterCollapse() == MDISCARD) {
   6996         ASSERT(value);
   6997         return;
   6998     }
   6999 
   7000     if (!m_rareData && !value)
   7001         return;
   7002 
   7003     if (!m_rareData)
   7004         m_rareData = adoptPtr(new RenderBlockRareData(this));
   7005 
   7006     m_rareData->m_discardMarginAfter = value;
   7007 }
   7008 
   7009 bool RenderBlock::mustDiscardMarginBefore() const
   7010 {
   7011     return style()->marginBeforeCollapse() == MDISCARD || (m_rareData && m_rareData->m_discardMarginBefore);
   7012 }
   7013 
   7014 bool RenderBlock::mustDiscardMarginAfter() const
   7015 {
   7016     return style()->marginAfterCollapse() == MDISCARD || (m_rareData && m_rareData->m_discardMarginAfter);
   7017 }
   7018 
   7019 bool RenderBlock::mustDiscardMarginBeforeForChild(const RenderBox* child) const
   7020 {
   7021     ASSERT(!child->selfNeedsLayout());
   7022     if (!child->isWritingModeRoot())
   7023         return child->isRenderBlock() ? toRenderBlock(child)->mustDiscardMarginBefore() : (child->style()->marginBeforeCollapse() == MDISCARD);
   7024     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
   7025         return child->isRenderBlock() ? toRenderBlock(child)->mustDiscardMarginAfter() : (child->style()->marginAfterCollapse() == MDISCARD);
   7026 
   7027     // FIXME: We return false here because the implementation is not geometrically complete. We have values only for before/after, not start/end.
   7028     // In case the boxes are perpendicular we assume the property is not specified.
   7029     return false;
   7030 }
   7031 
   7032 bool RenderBlock::mustDiscardMarginAfterForChild(const RenderBox* child) const
   7033 {
   7034     ASSERT(!child->selfNeedsLayout());
   7035     if (!child->isWritingModeRoot())
   7036         return child->isRenderBlock() ? toRenderBlock(child)->mustDiscardMarginAfter() : (child->style()->marginAfterCollapse() == MDISCARD);
   7037     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
   7038         return child->isRenderBlock() ? toRenderBlock(child)->mustDiscardMarginBefore() : (child->style()->marginBeforeCollapse() == MDISCARD);
   7039 
   7040     // FIXME: See |mustDiscardMarginBeforeForChild| above.
   7041     return false;
   7042 }
   7043 
   7044 bool RenderBlock::mustSeparateMarginBeforeForChild(const RenderBox* child) const
   7045 {
   7046     ASSERT(!child->selfNeedsLayout());
   7047     const RenderStyle* childStyle = child->style();
   7048     if (!child->isWritingModeRoot())
   7049         return childStyle->marginBeforeCollapse() == MSEPARATE;
   7050     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
   7051         return childStyle->marginAfterCollapse() == MSEPARATE;
   7052 
   7053     // FIXME: See |mustDiscardMarginBeforeForChild| above.
   7054     return false;
   7055 }
   7056 
   7057 bool RenderBlock::mustSeparateMarginAfterForChild(const RenderBox* child) const
   7058 {
   7059     ASSERT(!child->selfNeedsLayout());
   7060     const RenderStyle* childStyle = child->style();
   7061     if (!child->isWritingModeRoot())
   7062         return childStyle->marginAfterCollapse() == MSEPARATE;
   7063     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
   7064         return childStyle->marginBeforeCollapse() == MSEPARATE;
   7065 
   7066     // FIXME: See |mustDiscardMarginBeforeForChild| above.
   7067     return false;
   7068 }
   7069 
   7070 void RenderBlock::setPaginationStrut(LayoutUnit strut)
   7071 {
   7072     if (!m_rareData) {
   7073         if (!strut)
   7074             return;
   7075         m_rareData = adoptPtr(new RenderBlockRareData(this));
   7076     }
   7077     m_rareData->m_paginationStrut = strut;
   7078 }
   7079 
   7080 void RenderBlock::setPageLogicalOffset(LayoutUnit logicalOffset)
   7081 {
   7082     if (!m_rareData) {
   7083         if (!logicalOffset)
   7084             return;
   7085         m_rareData = adoptPtr(new RenderBlockRareData(this));
   7086     }
   7087     m_rareData->m_pageLogicalOffset = logicalOffset;
   7088 }
   7089 
   7090 void RenderBlock::setBreakAtLineToAvoidWidow(RootInlineBox* lineToBreak)
   7091 {
   7092     ASSERT(lineToBreak);
   7093     if (!m_rareData)
   7094         m_rareData = adoptPtr(new RenderBlockRareData(this));
   7095     m_rareData->m_shouldBreakAtLineToAvoidWidow = true;
   7096     m_rareData->m_lineBreakToAvoidWidow = lineToBreak;
   7097 }
   7098 
   7099 void RenderBlock::clearShouldBreakAtLineToAvoidWidow() const
   7100 {
   7101     if (!m_rareData)
   7102         return;
   7103     m_rareData->m_shouldBreakAtLineToAvoidWidow = false;
   7104     m_rareData->m_lineBreakToAvoidWidow = 0;
   7105 }
   7106 
   7107 void RenderBlock::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const
   7108 {
   7109     // For blocks inside inlines, we go ahead and include margins so that we run right up to the
   7110     // inline boxes above and below us (thus getting merged with them to form a single irregular
   7111     // shape).
   7112     if (isAnonymousBlockContinuation()) {
   7113         // FIXME: This is wrong for block-flows that are horizontal.
   7114         // https://bugs.webkit.org/show_bug.cgi?id=46781
   7115         rects.append(pixelSnappedIntRect(accumulatedOffset.x(), accumulatedOffset.y() - collapsedMarginBefore(),
   7116                                 width(), height() + collapsedMarginBefore() + collapsedMarginAfter()));
   7117         continuation()->absoluteRects(rects, accumulatedOffset - toLayoutSize(location() +
   7118                 inlineElementContinuation()->containingBlock()->location()));
   7119     } else
   7120         rects.append(pixelSnappedIntRect(accumulatedOffset, size()));
   7121 }
   7122 
   7123 void RenderBlock::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
   7124 {
   7125     // For blocks inside inlines, we go ahead and include margins so that we run right up to the
   7126     // inline boxes above and below us (thus getting merged with them to form a single irregular
   7127     // shape).
   7128     if (isAnonymousBlockContinuation()) {
   7129         // FIXME: This is wrong for block-flows that are horizontal.
   7130         // https://bugs.webkit.org/show_bug.cgi?id=46781
   7131         FloatRect localRect(0, -collapsedMarginBefore(),
   7132                             width(), height() + collapsedMarginBefore() + collapsedMarginAfter());
   7133         quads.append(localToAbsoluteQuad(localRect, 0 /* mode */, wasFixed));
   7134         continuation()->absoluteQuads(quads, wasFixed);
   7135     } else
   7136         quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width(), height()), 0 /* mode */, wasFixed));
   7137 }
   7138 
   7139 LayoutRect RenderBlock::rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const
   7140 {
   7141     LayoutRect r(RenderBox::rectWithOutlineForRepaint(repaintContainer, outlineWidth));
   7142     if (isAnonymousBlockContinuation())
   7143         r.inflateY(collapsedMarginBefore()); // FIXME: This is wrong for block-flows that are horizontal.
   7144     return r;
   7145 }
   7146 
   7147 RenderObject* RenderBlock::hoverAncestor() const
   7148 {
   7149     return isAnonymousBlockContinuation() ? continuation() : RenderBox::hoverAncestor();
   7150 }
   7151 
   7152 void RenderBlock::updateDragState(bool dragOn)
   7153 {
   7154     RenderBox::updateDragState(dragOn);
   7155     if (continuation())
   7156         continuation()->updateDragState(dragOn);
   7157 }
   7158 
   7159 RenderStyle* RenderBlock::outlineStyleForRepaint() const
   7160 {
   7161     return isAnonymousBlockContinuation() ? continuation()->style() : style();
   7162 }
   7163 
   7164 void RenderBlock::childBecameNonInline(RenderObject*)
   7165 {
   7166     makeChildrenNonInline();
   7167     if (isAnonymousBlock() && parent() && parent()->isRenderBlock())
   7168         toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
   7169     // |this| may be dead here
   7170 }
   7171 
   7172 void RenderBlock::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
   7173 {
   7174     if (result.innerNode())
   7175         return;
   7176 
   7177     if (Node* n = nodeForHitTest()) {
   7178         result.setInnerNode(n);
   7179         if (!result.innerNonSharedNode())
   7180             result.setInnerNonSharedNode(n);
   7181         result.setLocalPoint(point);
   7182     }
   7183 }
   7184 
   7185 LayoutRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, LayoutUnit* extraWidthToEndOfLine)
   7186 {
   7187     // Do the normal calculation in most cases.
   7188     if (firstChild())
   7189         return RenderBox::localCaretRect(inlineBox, caretOffset, extraWidthToEndOfLine);
   7190 
   7191     LayoutRect caretRect = localCaretRectForEmptyElement(width(), textIndentOffset());
   7192 
   7193     if (extraWidthToEndOfLine) {
   7194         if (isRenderBlock()) {
   7195             *extraWidthToEndOfLine = width() - caretRect.maxX();
   7196         } else {
   7197             // FIXME: This code looks wrong.
   7198             // myRight and containerRight are set up, but then clobbered.
   7199             // So *extraWidthToEndOfLine will always be 0 here.
   7200 
   7201             LayoutUnit myRight = caretRect.maxX();
   7202             // FIXME: why call localToAbsoluteForContent() twice here, too?
   7203             FloatPoint absRightPoint = localToAbsolute(FloatPoint(myRight, 0));
   7204 
   7205             LayoutUnit containerRight = containingBlock()->x() + containingBlockLogicalWidthForContent();
   7206             FloatPoint absContainerPoint = localToAbsolute(FloatPoint(containerRight, 0));
   7207 
   7208             *extraWidthToEndOfLine = absContainerPoint.x() - absRightPoint.x();
   7209         }
   7210     }
   7211 
   7212     return caretRect;
   7213 }
   7214 
   7215 void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer)
   7216 {
   7217     // For blocks inside inlines, we go ahead and include margins so that we run right up to the
   7218     // inline boxes above and below us (thus getting merged with them to form a single irregular
   7219     // shape).
   7220     if (inlineElementContinuation()) {
   7221         // FIXME: This check really isn't accurate.
   7222         bool nextInlineHasLineBox = inlineElementContinuation()->firstLineBox();
   7223         // FIXME: This is wrong. The principal renderer may not be the continuation preceding this block.
   7224         // FIXME: This is wrong for block-flows that are horizontal.
   7225         // https://bugs.webkit.org/show_bug.cgi?id=46781
   7226         bool prevInlineHasLineBox = toRenderInline(inlineElementContinuation()->node()->renderer())->firstLineBox();
   7227         float topMargin = prevInlineHasLineBox ? collapsedMarginBefore() : LayoutUnit();
   7228         float bottomMargin = nextInlineHasLineBox ? collapsedMarginAfter() : LayoutUnit();
   7229         LayoutRect rect(additionalOffset.x(), additionalOffset.y() - topMargin, width(), height() + topMargin + bottomMargin);
   7230         if (!rect.isEmpty())
   7231             rects.append(pixelSnappedIntRect(rect));
   7232     } else if (width() && height())
   7233         rects.append(pixelSnappedIntRect(additionalOffset, size()));
   7234 
   7235     if (!hasOverflowClip() && !hasControlClip()) {
   7236         for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
   7237             LayoutUnit top = max<LayoutUnit>(curr->lineTop(), curr->top());
   7238             LayoutUnit bottom = min<LayoutUnit>(curr->lineBottom(), curr->top() + curr->height());
   7239             LayoutRect rect(additionalOffset.x() + curr->x(), additionalOffset.y() + top, curr->width(), bottom - top);
   7240             if (!rect.isEmpty())
   7241                 rects.append(pixelSnappedIntRect(rect));
   7242         }
   7243 
   7244         for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
   7245             if (!curr->isText() && !curr->isListMarker() && curr->isBox()) {
   7246                 RenderBox* box = toRenderBox(curr);
   7247                 FloatPoint pos;
   7248                 // FIXME: This doesn't work correctly with transforms.
   7249                 if (box->layer())
   7250                     pos = curr->localToContainerPoint(FloatPoint(), paintContainer);
   7251                 else
   7252                     pos = FloatPoint(additionalOffset.x() + box->x(), additionalOffset.y() + box->y());
   7253                 box->addFocusRingRects(rects, flooredLayoutPoint(pos), paintContainer);
   7254             }
   7255         }
   7256     }
   7257 
   7258     if (inlineElementContinuation())
   7259         inlineElementContinuation()->addFocusRingRects(rects, flooredLayoutPoint(additionalOffset + inlineElementContinuation()->containingBlock()->location() - location()), paintContainer);
   7260 }
   7261 
   7262 void RenderBlock::computeSelfHitTestRects(Vector<LayoutRect>& rects, const LayoutPoint& layerOffset) const
   7263 {
   7264     RenderBox::computeSelfHitTestRects(rects, layerOffset);
   7265 
   7266     if (hasHorizontalLayoutOverflow() || hasVerticalLayoutOverflow()) {
   7267         for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
   7268             LayoutUnit top = max<LayoutUnit>(curr->lineTop(), curr->top());
   7269             LayoutUnit bottom = min<LayoutUnit>(curr->lineBottom(), curr->top() + curr->height());
   7270             LayoutRect rect(layerOffset.x() + curr->x(), layerOffset.y() + top, curr->width(), bottom - top);
   7271             // It's common for this rect to be entirely contained in our box, so exclude that simple case.
   7272             if (!rect.isEmpty() && (rects.isEmpty() || !rects[0].contains(rect)))
   7273                 rects.append(rect);
   7274         }
   7275     }
   7276 }
   7277 
   7278 RenderBox* RenderBlock::createAnonymousBoxWithSameTypeAs(const RenderObject* parent) const
   7279 {
   7280     if (isAnonymousColumnsBlock())
   7281         return createAnonymousColumnsWithParentRenderer(parent);
   7282     if (isAnonymousColumnSpanBlock())
   7283         return createAnonymousColumnSpanWithParentRenderer(parent);
   7284     return createAnonymousWithParentRendererAndDisplay(parent, style()->display());
   7285 }
   7286 
   7287 bool RenderBlock::hasNextPage(LayoutUnit logicalOffset, PageBoundaryRule pageBoundaryRule) const
   7288 {
   7289     ASSERT(view()->layoutState() && view()->layoutState()->isPaginated());
   7290 
   7291     RenderFlowThread* flowThread = flowThreadContainingBlock();
   7292     if (!flowThread)
   7293         return true; // Printing and multi-column both make new pages to accommodate content.
   7294 
   7295     // See if we're in the last region.
   7296     LayoutUnit pageOffset = offsetFromLogicalTopOfFirstPage() + logicalOffset;
   7297     RenderRegion* region = flowThread->regionAtBlockOffset(pageOffset, this);
   7298     if (!region)
   7299         return false;
   7300     if (region->isLastRegion())
   7301         return region->isRenderRegionSet() || region->style()->regionFragment() == BreakRegionFragment
   7302             || (pageBoundaryRule == IncludePageBoundary && pageOffset == region->logicalTopForFlowThreadContent());
   7303     return true;
   7304 }
   7305 
   7306 LayoutUnit RenderBlock::nextPageLogicalTop(LayoutUnit logicalOffset, PageBoundaryRule pageBoundaryRule) const
   7307 {
   7308     LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
   7309     if (!pageLogicalHeight)
   7310         return logicalOffset;
   7311 
   7312     // The logicalOffset is in our coordinate space.  We can add in our pushed offset.
   7313     LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset);
   7314     if (pageBoundaryRule == ExcludePageBoundary)
   7315         return logicalOffset + (remainingLogicalHeight ? remainingLogicalHeight : pageLogicalHeight);
   7316     return logicalOffset + remainingLogicalHeight;
   7317 }
   7318 
   7319 static bool inNormalFlow(RenderBox* child)
   7320 {
   7321     RenderBlock* curr = child->containingBlock();
   7322     RenderView* renderView = child->view();
   7323     while (curr && curr != renderView) {
   7324         if (curr->hasColumns() || curr->isRenderFlowThread())
   7325             return true;
   7326         if (curr->isFloatingOrOutOfFlowPositioned())
   7327             return false;
   7328         curr = curr->containingBlock();
   7329     }
   7330     return true;
   7331 }
   7332 
   7333 ColumnInfo::PaginationUnit RenderBlock::paginationUnit() const
   7334 {
   7335     return ColumnInfo::Column;
   7336 }
   7337 
   7338 LayoutUnit RenderBlock::applyBeforeBreak(RenderBox* child, LayoutUnit logicalOffset)
   7339 {
   7340     // FIXME: Add page break checking here when we support printing.
   7341     bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
   7342     bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight; // FIXME: Once columns can print we have to check this.
   7343     RenderFlowThread* flowThread = flowThreadContainingBlock();
   7344     bool checkRegionBreaks = flowThread && flowThread->isRenderNamedFlowThread();
   7345     bool checkBeforeAlways = (checkColumnBreaks && child->style()->columnBreakBefore() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakBefore() == PBALWAYS)
   7346                              || (checkRegionBreaks && child->style()->regionBreakBefore() == PBALWAYS);
   7347     if (checkBeforeAlways && inNormalFlow(child) && hasNextPage(logicalOffset, IncludePageBoundary)) {
   7348         if (checkColumnBreaks)
   7349             view()->layoutState()->addForcedColumnBreak(child, logicalOffset);
   7350         if (checkRegionBreaks) {
   7351             LayoutUnit offsetBreakAdjustment = 0;
   7352             if (flowThread->addForcedRegionBreak(offsetFromLogicalTopOfFirstPage() + logicalOffset, child, true, &offsetBreakAdjustment))
   7353                 return logicalOffset + offsetBreakAdjustment;
   7354         }
   7355         return nextPageLogicalTop(logicalOffset, IncludePageBoundary);
   7356     }
   7357     return logicalOffset;
   7358 }
   7359 
   7360 LayoutUnit RenderBlock::applyAfterBreak(RenderBox* child, LayoutUnit logicalOffset, MarginInfo& marginInfo)
   7361 {
   7362     // FIXME: Add page break checking here when we support printing.
   7363     bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
   7364     bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight; // FIXME: Once columns can print we have to check this.
   7365     RenderFlowThread* flowThread = flowThreadContainingBlock();
   7366     bool checkRegionBreaks = flowThread && flowThread->isRenderNamedFlowThread();
   7367     bool checkAfterAlways = (checkColumnBreaks && child->style()->columnBreakAfter() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakAfter() == PBALWAYS)
   7368                             || (checkRegionBreaks && child->style()->regionBreakAfter() == PBALWAYS);
   7369     if (checkAfterAlways && inNormalFlow(child) && hasNextPage(logicalOffset, IncludePageBoundary)) {
   7370         LayoutUnit marginOffset = marginInfo.canCollapseWithMarginBefore() ? LayoutUnit() : marginInfo.margin();
   7371 
   7372         // So our margin doesn't participate in the next collapsing steps.
   7373         marginInfo.clearMargin();
   7374 
   7375         if (checkColumnBreaks)
   7376             view()->layoutState()->addForcedColumnBreak(child, logicalOffset);
   7377         if (checkRegionBreaks) {
   7378             LayoutUnit offsetBreakAdjustment = 0;
   7379             if (flowThread->addForcedRegionBreak(offsetFromLogicalTopOfFirstPage() + logicalOffset + marginOffset, child, false, &offsetBreakAdjustment))
   7380                 return logicalOffset + marginOffset + offsetBreakAdjustment;
   7381         }
   7382         return nextPageLogicalTop(logicalOffset, IncludePageBoundary);
   7383     }
   7384     return logicalOffset;
   7385 }
   7386 
   7387 LayoutUnit RenderBlock::pageLogicalTopForOffset(LayoutUnit offset) const
   7388 {
   7389     RenderView* renderView = view();
   7390     LayoutUnit firstPageLogicalTop = isHorizontalWritingMode() ? renderView->layoutState()->m_pageOffset.height() : renderView->layoutState()->m_pageOffset.width();
   7391     LayoutUnit blockLogicalTop = isHorizontalWritingMode() ? renderView->layoutState()->m_layoutOffset.height() : renderView->layoutState()->m_layoutOffset.width();
   7392 
   7393     LayoutUnit cumulativeOffset = offset + blockLogicalTop;
   7394     RenderFlowThread* flowThread = flowThreadContainingBlock();
   7395     if (!flowThread) {
   7396         LayoutUnit pageLogicalHeight = renderView->layoutState()->pageLogicalHeight();
   7397         if (!pageLogicalHeight)
   7398             return 0;
   7399         return cumulativeOffset - roundToInt(cumulativeOffset - firstPageLogicalTop) % roundToInt(pageLogicalHeight);
   7400     }
   7401     return flowThread->pageLogicalTopForOffset(cumulativeOffset);
   7402 }
   7403 
   7404 LayoutUnit RenderBlock::pageLogicalHeightForOffset(LayoutUnit offset) const
   7405 {
   7406     RenderView* renderView = view();
   7407     RenderFlowThread* flowThread = flowThreadContainingBlock();
   7408     if (!flowThread)
   7409         return renderView->layoutState()->m_pageLogicalHeight;
   7410     return flowThread->pageLogicalHeightForOffset(offset + offsetFromLogicalTopOfFirstPage());
   7411 }
   7412 
   7413 LayoutUnit RenderBlock::pageRemainingLogicalHeightForOffset(LayoutUnit offset, PageBoundaryRule pageBoundaryRule) const
   7414 {
   7415     RenderView* renderView = view();
   7416     offset += offsetFromLogicalTopOfFirstPage();
   7417 
   7418     RenderFlowThread* flowThread = flowThreadContainingBlock();
   7419     if (!flowThread) {
   7420         LayoutUnit pageLogicalHeight = renderView->layoutState()->m_pageLogicalHeight;
   7421         LayoutUnit remainingHeight = pageLogicalHeight - intMod(offset, pageLogicalHeight);
   7422         if (pageBoundaryRule == IncludePageBoundary) {
   7423             // If includeBoundaryPoint is true the line exactly on the top edge of a
   7424             // column will act as being part of the previous column.
   7425             remainingHeight = intMod(remainingHeight, pageLogicalHeight);
   7426         }
   7427         return remainingHeight;
   7428     }
   7429 
   7430     return flowThread->pageRemainingLogicalHeightForOffset(offset, pageBoundaryRule);
   7431 }
   7432 
   7433 LayoutUnit RenderBlock::adjustForUnsplittableChild(RenderBox* child, LayoutUnit logicalOffset, bool includeMargins)
   7434 {
   7435     bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
   7436     bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight;
   7437     RenderFlowThread* flowThread = flowThreadContainingBlock();
   7438     bool checkRegionBreaks = flowThread && flowThread->isRenderNamedFlowThread();
   7439     bool isUnsplittable = child->isUnsplittableForPagination() || (checkColumnBreaks && child->style()->columnBreakInside() == PBAVOID)
   7440         || (checkPageBreaks && child->style()->pageBreakInside() == PBAVOID)
   7441         || (checkRegionBreaks && child->style()->regionBreakInside() == PBAVOID);
   7442     if (!isUnsplittable)
   7443         return logicalOffset;
   7444     LayoutUnit childLogicalHeight = logicalHeightForChild(child) + (includeMargins ? marginBeforeForChild(child) + marginAfterForChild(child) : LayoutUnit());
   7445     LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
   7446     bool hasUniformPageLogicalHeight = !flowThread || flowThread->regionsHaveUniformLogicalHeight();
   7447     updateMinimumPageHeight(logicalOffset, childLogicalHeight);
   7448     if (!pageLogicalHeight || (hasUniformPageLogicalHeight && childLogicalHeight > pageLogicalHeight)
   7449         || !hasNextPage(logicalOffset))
   7450         return logicalOffset;
   7451     LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset, ExcludePageBoundary);
   7452     if (remainingLogicalHeight < childLogicalHeight) {
   7453         if (!hasUniformPageLogicalHeight && !pushToNextPageWithMinimumLogicalHeight(remainingLogicalHeight, logicalOffset, childLogicalHeight))
   7454             return logicalOffset;
   7455         return logicalOffset + remainingLogicalHeight;
   7456     }
   7457     return logicalOffset;
   7458 }
   7459 
   7460 bool RenderBlock::pushToNextPageWithMinimumLogicalHeight(LayoutUnit& adjustment, LayoutUnit logicalOffset, LayoutUnit minimumLogicalHeight) const
   7461 {
   7462     bool checkRegion = false;
   7463     for (LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset + adjustment); pageLogicalHeight;
   7464         pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset + adjustment)) {
   7465         if (minimumLogicalHeight <= pageLogicalHeight)
   7466             return true;
   7467         if (!hasNextPage(logicalOffset + adjustment))
   7468             return false;
   7469         adjustment += pageLogicalHeight;
   7470         checkRegion = true;
   7471     }
   7472     return !checkRegion;
   7473 }
   7474 
   7475 void RenderBlock::setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage)
   7476 {
   7477     if (RenderFlowThread* flowThread = flowThreadContainingBlock())
   7478         flowThread->setPageBreak(offsetFromLogicalTopOfFirstPage() + offset, spaceShortage);
   7479 }
   7480 
   7481 void RenderBlock::updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight)
   7482 {
   7483     if (RenderFlowThread* flowThread = flowThreadContainingBlock())
   7484         flowThread->updateMinimumPageHeight(offsetFromLogicalTopOfFirstPage() + offset, minHeight);
   7485     else if (ColumnInfo* colInfo = view()->layoutState()->m_columnInfo)
   7486         colInfo->updateMinimumColumnHeight(minHeight);
   7487 }
   7488 
   7489 static inline LayoutUnit calculateMinimumPageHeight(RenderStyle* renderStyle, RootInlineBox* lastLine, LayoutUnit lineTop, LayoutUnit lineBottom)
   7490 {
   7491     // We may require a certain minimum number of lines per page in order to satisfy
   7492     // orphans and widows, and that may affect the minimum page height.
   7493     unsigned lineCount = max<unsigned>(renderStyle->hasAutoOrphans() ? 1 : renderStyle->orphans(), renderStyle->hasAutoWidows() ? 1 : renderStyle->widows());
   7494     if (lineCount > 1) {
   7495         RootInlineBox* line = lastLine;
   7496         for (unsigned i = 1; i < lineCount && line->prevRootBox(); i++)
   7497             line = line->prevRootBox();
   7498 
   7499         // FIXME: Paginating using line overflow isn't all fine. See FIXME in
   7500         // adjustLinePositionForPagination() for more details.
   7501         LayoutRect overflow = line->logicalVisualOverflowRect(line->lineTop(), line->lineBottom());
   7502         lineTop = min(line->lineTopWithLeading(), overflow.y());
   7503     }
   7504     return lineBottom - lineTop;
   7505 }
   7506 
   7507 void RenderBlock::adjustLinePositionForPagination(RootInlineBox* lineBox, LayoutUnit& delta, RenderFlowThread* flowThread)
   7508 {
   7509     // FIXME: For now we paginate using line overflow.  This ensures that lines don't overlap at all when we
   7510     // put a strut between them for pagination purposes.  However, this really isn't the desired rendering, since
   7511     // the line on the top of the next page will appear too far down relative to the same kind of line at the top
   7512     // of the first column.
   7513     //
   7514     // The rendering we would like to see is one where the lineTopWithLeading is at the top of the column, and any line overflow
   7515     // simply spills out above the top of the column.  This effect would match what happens at the top of the first column.
   7516     // We can't achieve this rendering, however, until we stop columns from clipping to the column bounds (thus allowing
   7517     // for overflow to occur), and then cache visible overflow for each column rect.
   7518     //
   7519     // Furthermore, the paint we have to do when a column has overflow has to be special.  We need to exclude
   7520     // content that paints in a previous column (and content that paints in the following column).
   7521     //
   7522     // For now we'll at least honor the lineTopWithLeading when paginating if it is above the logical top overflow. This will
   7523     // at least make positive leading work in typical cases.
   7524     //
   7525     // FIXME: Another problem with simply moving lines is that the available line width may change (because of floats).
   7526     // Technically if the location we move the line to has a different line width than our old position, then we need to dirty the
   7527     // line and all following lines.
   7528     LayoutRect logicalVisualOverflow = lineBox->logicalVisualOverflowRect(lineBox->lineTop(), lineBox->lineBottom());
   7529     LayoutUnit logicalOffset = min(lineBox->lineTopWithLeading(), logicalVisualOverflow.y());
   7530     LayoutUnit logicalBottom = max(lineBox->lineBottomWithLeading(), logicalVisualOverflow.maxY());
   7531     LayoutUnit lineHeight = logicalBottom - logicalOffset;
   7532     updateMinimumPageHeight(logicalOffset, calculateMinimumPageHeight(style(), lineBox, logicalOffset, logicalBottom));
   7533     logicalOffset += delta;
   7534     lineBox->setPaginationStrut(0);
   7535     lineBox->setIsFirstAfterPageBreak(false);
   7536     LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
   7537     bool hasUniformPageLogicalHeight = !flowThread || flowThread->regionsHaveUniformLogicalHeight();
   7538     // If lineHeight is greater than pageLogicalHeight, but logicalVisualOverflow.height() still fits, we are
   7539     // still going to add a strut, so that the visible overflow fits on a single page.
   7540     if (!pageLogicalHeight || (hasUniformPageLogicalHeight && logicalVisualOverflow.height() > pageLogicalHeight)
   7541         || !hasNextPage(logicalOffset))
   7542         return;
   7543     LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset, ExcludePageBoundary);
   7544 
   7545     if (remainingLogicalHeight < lineHeight || (shouldBreakAtLineToAvoidWidow() && lineBreakToAvoidWidow() == lineBox)) {
   7546         if (shouldBreakAtLineToAvoidWidow() && lineBreakToAvoidWidow() == lineBox)
   7547             clearShouldBreakAtLineToAvoidWidow();
   7548         // If we have a non-uniform page height, then we have to shift further possibly.
   7549         if (!hasUniformPageLogicalHeight && !pushToNextPageWithMinimumLogicalHeight(remainingLogicalHeight, logicalOffset, lineHeight))
   7550             return;
   7551         if (lineHeight > pageLogicalHeight) {
   7552             // Split the top margin in order to avoid splitting the visible part of the line.
   7553             remainingLogicalHeight -= min(lineHeight - pageLogicalHeight, max<LayoutUnit>(0, logicalVisualOverflow.y() - lineBox->lineTopWithLeading()));
   7554         }
   7555         LayoutUnit totalLogicalHeight = lineHeight + max<LayoutUnit>(0, logicalOffset);
   7556         LayoutUnit pageLogicalHeightAtNewOffset = hasUniformPageLogicalHeight ? pageLogicalHeight : pageLogicalHeightForOffset(logicalOffset + remainingLogicalHeight);
   7557         setPageBreak(logicalOffset, lineHeight - remainingLogicalHeight);
   7558         if (((lineBox == firstRootBox() && totalLogicalHeight < pageLogicalHeightAtNewOffset) || (!style()->hasAutoOrphans() && style()->orphans() >= lineCount(lineBox)))
   7559             && !isOutOfFlowPositioned() && !isTableCell())
   7560             setPaginationStrut(remainingLogicalHeight + max<LayoutUnit>(0, logicalOffset));
   7561         else {
   7562             delta += remainingLogicalHeight;
   7563             lineBox->setPaginationStrut(remainingLogicalHeight);
   7564             lineBox->setIsFirstAfterPageBreak(true);
   7565         }
   7566     } else if (remainingLogicalHeight == pageLogicalHeight && lineBox != firstRootBox())
   7567         lineBox->setIsFirstAfterPageBreak(true);
   7568 }
   7569 
   7570 LayoutUnit RenderBlock::adjustBlockChildForPagination(LayoutUnit logicalTopAfterClear, LayoutUnit estimateWithoutPagination, RenderBox* child, bool atBeforeSideOfBlock)
   7571 {
   7572     RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0;
   7573 
   7574     if (estimateWithoutPagination != logicalTopAfterClear) {
   7575         // Our guess prior to pagination movement was wrong. Before we attempt to paginate, let's try again at the new
   7576         // position.
   7577         setLogicalHeight(logicalTopAfterClear);
   7578         setLogicalTopForChild(child, logicalTopAfterClear, ApplyLayoutDelta);
   7579 
   7580         if (child->shrinkToAvoidFloats()) {
   7581             // The child's width depends on the line width.
   7582             // When the child shifts to clear an item, its width can
   7583             // change (because it has more available line width).
   7584             // So go ahead and mark the item as dirty.
   7585             child->setChildNeedsLayout(MarkOnlyThis);
   7586         }
   7587 
   7588         if (childRenderBlock) {
   7589             if (!child->avoidsFloats() && childRenderBlock->containsFloats())
   7590                 childRenderBlock->markAllDescendantsWithFloatsForLayout();
   7591             if (!child->needsLayout())
   7592                 child->markForPaginationRelayoutIfNeeded();
   7593         }
   7594 
   7595         // Our guess was wrong. Make the child lay itself out again.
   7596         child->layoutIfNeeded();
   7597     }
   7598 
   7599     LayoutUnit oldTop = logicalTopAfterClear;
   7600 
   7601     // If the object has a page or column break value of "before", then we should shift to the top of the next page.
   7602     LayoutUnit result = applyBeforeBreak(child, logicalTopAfterClear);
   7603 
   7604     if (pageLogicalHeightForOffset(result)) {
   7605         LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(result, ExcludePageBoundary);
   7606         LayoutUnit spaceShortage = child->logicalHeight() - remainingLogicalHeight;
   7607         if (spaceShortage > 0) {
   7608             // If the child crosses a column boundary, report a break, in case nothing inside it has already
   7609             // done so. The column balancer needs to know how much it has to stretch the columns to make more
   7610             // content fit. If no breaks are reported (but do occur), the balancer will have no clue. FIXME:
   7611             // This should be improved, though, because here we just pretend that the child is
   7612             // unsplittable. A splittable child, on the other hand, has break opportunities at every position
   7613             // where there's no child content, border or padding. In other words, we risk stretching more
   7614             // than necessary.
   7615             setPageBreak(result, spaceShortage);
   7616         }
   7617     }
   7618 
   7619     // For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one.
   7620     LayoutUnit logicalTopBeforeUnsplittableAdjustment = result;
   7621     LayoutUnit logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChild(child, result);
   7622 
   7623     LayoutUnit paginationStrut = 0;
   7624     LayoutUnit unsplittableAdjustmentDelta = logicalTopAfterUnsplittableAdjustment - logicalTopBeforeUnsplittableAdjustment;
   7625     if (unsplittableAdjustmentDelta)
   7626         paginationStrut = unsplittableAdjustmentDelta;
   7627     else if (childRenderBlock && childRenderBlock->paginationStrut())
   7628         paginationStrut = childRenderBlock->paginationStrut();
   7629 
   7630     if (paginationStrut) {
   7631         // We are willing to propagate out to our parent block as long as we were at the top of the block prior
   7632         // to collapsing our margins, and as long as we didn't clear or move as a result of other pagination.
   7633         if (atBeforeSideOfBlock && oldTop == result && !isOutOfFlowPositioned() && !isTableCell()) {
   7634             // FIXME: Should really check if we're exceeding the page height before propagating the strut, but we don't
   7635             // have all the information to do so (the strut only has the remaining amount to push). Gecko gets this wrong too
   7636             // and pushes to the next page anyway, so not too concerned about it.
   7637             setPaginationStrut(result + paginationStrut);
   7638             if (childRenderBlock)
   7639                 childRenderBlock->setPaginationStrut(0);
   7640         } else
   7641             result += paginationStrut;
   7642     }
   7643 
   7644     // Similar to how we apply clearance. Go ahead and boost height() to be the place where we're going to position the child.
   7645     setLogicalHeight(logicalHeight() + (result - oldTop));
   7646 
   7647     // Return the final adjusted logical top.
   7648     return result;
   7649 }
   7650 
   7651 bool RenderBlock::lineWidthForPaginatedLineChanged(RootInlineBox* rootBox, LayoutUnit lineDelta, RenderFlowThread* flowThread) const
   7652 {
   7653     if (!flowThread)
   7654         return false;
   7655 
   7656     RenderRegion* currentRegion = regionAtBlockOffset(rootBox->lineTopWithLeading() + lineDelta);
   7657     // Just bail if the region didn't change.
   7658     if (rootBox->containingRegion() == currentRegion)
   7659         return false;
   7660     return rootBox->paginatedLineWidth() != availableLogicalWidthForContent(currentRegion, offsetFromLogicalTopOfFirstPage());
   7661 }
   7662 
   7663 LayoutUnit RenderBlock::offsetFromLogicalTopOfFirstPage() const
   7664 {
   7665     LayoutState* layoutState = view()->layoutState();
   7666     if (layoutState && !layoutState->isPaginated())
   7667         return 0;
   7668     if (layoutState) {
   7669         // FIXME: Sanity check that the renderer in the layout state is ours, since otherwise the computation will be off.
   7670         // Right now this assert gets hit inside computeLogicalHeight for percentage margins, since they're computed using
   7671         // widths which can vary in each region. Until we patch that, we can't have this assert.
   7672         // ASSERT(layoutState->m_renderer == this);
   7673 
   7674         LayoutSize offsetDelta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
   7675         return isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.width();
   7676     }
   7677     // FIXME: Right now, this assert is hit outside layout, from logicalLeftSelectionOffset in selectionGapRectsForRepaint (called from FrameSelection::selectAll).
   7678     // ASSERT(inRenderFlowThread());
   7679 
   7680     // FIXME: This is a slower path that doesn't use layout state and relies on getting your logical top inside the enclosing flow thread. It doesn't
   7681     // work with columns or pages currently, but it should once they have been switched over to using flow threads.
   7682     RenderFlowThread* flowThread = flowThreadContainingBlock();
   7683     if (!flowThread)
   7684         return 0;
   7685 
   7686     const RenderBlock* currentBlock = this;
   7687     LayoutRect blockRect(0, 0, width(), height());
   7688 
   7689     while (currentBlock && !currentBlock->isRenderFlowThread()) {
   7690         RenderBlock* containerBlock = currentBlock->containingBlock();
   7691         ASSERT(containerBlock);
   7692         if (!containerBlock)
   7693             return 0;
   7694         LayoutPoint currentBlockLocation = currentBlock->location();
   7695 
   7696         if (containerBlock->style()->writingMode() != currentBlock->style()->writingMode()) {
   7697             // We have to put the block rect in container coordinates
   7698             // and we have to take into account both the container and current block flipping modes
   7699             if (containerBlock->style()->isFlippedBlocksWritingMode()) {
   7700                 if (containerBlock->isHorizontalWritingMode())
   7701                     blockRect.setY(currentBlock->height() - blockRect.maxY());
   7702                 else
   7703                     blockRect.setX(currentBlock->width() - blockRect.maxX());
   7704             }
   7705             currentBlock->flipForWritingMode(blockRect);
   7706         }
   7707         blockRect.moveBy(currentBlockLocation);
   7708         currentBlock = containerBlock;
   7709     };
   7710     return currentBlock->isHorizontalWritingMode() ? blockRect.y() : blockRect.x();
   7711 }
   7712 
   7713 RenderRegion* RenderBlock::regionAtBlockOffset(LayoutUnit blockOffset) const
   7714 {
   7715     RenderFlowThread* flowThread = flowThreadContainingBlock();
   7716     if (!flowThread || !flowThread->hasValidRegionInfo())
   7717         return 0;
   7718 
   7719     return flowThread->regionAtBlockOffset(offsetFromLogicalTopOfFirstPage() + blockOffset, true);
   7720 }
   7721 
   7722 void RenderBlock::updateStaticInlinePositionForChild(RenderBox* child, LayoutUnit logicalTop)
   7723 {
   7724     if (child->style()->isOriginalDisplayInlineType())
   7725         setStaticInlinePositionForChild(child, logicalTop, startAlignedOffsetForLine(logicalTop, false));
   7726     else
   7727         setStaticInlinePositionForChild(child, logicalTop, startOffsetForContent(logicalTop));
   7728 }
   7729 
   7730 void RenderBlock::setStaticInlinePositionForChild(RenderBox* child, LayoutUnit blockOffset, LayoutUnit inlinePosition)
   7731 {
   7732     if (flowThreadContainingBlock()) {
   7733         // Shift the inline position to exclude the region offset.
   7734         inlinePosition += startOffsetForContent() - startOffsetForContent(blockOffset);
   7735     }
   7736     child->layer()->setStaticInlinePosition(inlinePosition);
   7737 }
   7738 
   7739 bool RenderBlock::logicalWidthChangedInRegions(RenderFlowThread* flowThread) const
   7740 {
   7741     if (!flowThread || !flowThread->hasValidRegionInfo())
   7742         return false;
   7743 
   7744     return flowThread->logicalWidthChangedInRegions(this, offsetFromLogicalTopOfFirstPage());
   7745 }
   7746 
   7747 RenderRegion* RenderBlock::clampToStartAndEndRegions(RenderRegion* region) const
   7748 {
   7749     RenderFlowThread* flowThread = flowThreadContainingBlock();
   7750 
   7751     ASSERT(isRenderView() || (region && flowThread));
   7752     if (isRenderView())
   7753         return region;
   7754 
   7755     // We need to clamp to the block, since we want any lines or blocks that overflow out of the
   7756     // logical top or logical bottom of the block to size as though the border box in the first and
   7757     // last regions extended infinitely. Otherwise the lines are going to size according to the regions
   7758     // they overflow into, which makes no sense when this block doesn't exist in |region| at all.
   7759     RenderRegion* startRegion;
   7760     RenderRegion* endRegion;
   7761     flowThread->getRegionRangeForBox(this, startRegion, endRegion);
   7762 
   7763     if (startRegion && region->logicalTopForFlowThreadContent() < startRegion->logicalTopForFlowThreadContent())
   7764         return startRegion;
   7765     if (endRegion && region->logicalTopForFlowThreadContent() > endRegion->logicalTopForFlowThreadContent())
   7766         return endRegion;
   7767 
   7768     return region;
   7769 }
   7770 
   7771 LayoutUnit RenderBlock::collapsedMarginBeforeForChild(const RenderBox* child) const
   7772 {
   7773     // If the child has the same directionality as we do, then we can just return its
   7774     // collapsed margin.
   7775     if (!child->isWritingModeRoot())
   7776         return child->collapsedMarginBefore();
   7777 
   7778     // The child has a different directionality.  If the child is parallel, then it's just
   7779     // flipped relative to us.  We can use the collapsed margin for the opposite edge.
   7780     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
   7781         return child->collapsedMarginAfter();
   7782 
   7783     // The child is perpendicular to us, which means its margins don't collapse but are on the
   7784     // "logical left/right" sides of the child box.  We can just return the raw margin in this case.
   7785     return marginBeforeForChild(child);
   7786 }
   7787 
   7788 LayoutUnit RenderBlock::collapsedMarginAfterForChild(const  RenderBox* child) const
   7789 {
   7790     // If the child has the same directionality as we do, then we can just return its
   7791     // collapsed margin.
   7792     if (!child->isWritingModeRoot())
   7793         return child->collapsedMarginAfter();
   7794 
   7795     // The child has a different directionality.  If the child is parallel, then it's just
   7796     // flipped relative to us.  We can use the collapsed margin for the opposite edge.
   7797     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
   7798         return child->collapsedMarginBefore();
   7799 
   7800     // The child is perpendicular to us, which means its margins don't collapse but are on the
   7801     // "logical left/right" side of the child box.  We can just return the raw margin in this case.
   7802     return marginAfterForChild(child);
   7803 }
   7804 
   7805 bool RenderBlock::hasMarginBeforeQuirk(const RenderBox* child) const
   7806 {
   7807     // If the child has the same directionality as we do, then we can just return its
   7808     // margin quirk.
   7809     if (!child->isWritingModeRoot())
   7810         return child->isRenderBlock() ? toRenderBlock(child)->hasMarginBeforeQuirk() : child->style()->hasMarginBeforeQuirk();
   7811 
   7812     // The child has a different directionality. If the child is parallel, then it's just
   7813     // flipped relative to us. We can use the opposite edge.
   7814     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
   7815         return child->isRenderBlock() ? toRenderBlock(child)->hasMarginAfterQuirk() : child->style()->hasMarginAfterQuirk();
   7816 
   7817     // The child is perpendicular to us and box sides are never quirky in html.css, and we don't really care about
   7818     // whether or not authors specified quirky ems, since they're an implementation detail.
   7819     return false;
   7820 }
   7821 
   7822 bool RenderBlock::hasMarginAfterQuirk(const RenderBox* child) const
   7823 {
   7824     // If the child has the same directionality as we do, then we can just return its
   7825     // margin quirk.
   7826     if (!child->isWritingModeRoot())
   7827         return child->isRenderBlock() ? toRenderBlock(child)->hasMarginAfterQuirk() : child->style()->hasMarginAfterQuirk();
   7828 
   7829     // The child has a different directionality. If the child is parallel, then it's just
   7830     // flipped relative to us. We can use the opposite edge.
   7831     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
   7832         return child->isRenderBlock() ? toRenderBlock(child)->hasMarginBeforeQuirk() : child->style()->hasMarginBeforeQuirk();
   7833 
   7834     // The child is perpendicular to us and box sides are never quirky in html.css, and we don't really care about
   7835     // whether or not authors specified quirky ems, since they're an implementation detail.
   7836     return false;
   7837 }
   7838 
   7839 RenderBlock::MarginValues RenderBlock::marginValuesForChild(RenderBox* child) const
   7840 {
   7841     LayoutUnit childBeforePositive = 0;
   7842     LayoutUnit childBeforeNegative = 0;
   7843     LayoutUnit childAfterPositive = 0;
   7844     LayoutUnit childAfterNegative = 0;
   7845 
   7846     LayoutUnit beforeMargin = 0;
   7847     LayoutUnit afterMargin = 0;
   7848 
   7849     RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0;
   7850 
   7851     // If the child has the same directionality as we do, then we can just return its
   7852     // margins in the same direction.
   7853     if (!child->isWritingModeRoot()) {
   7854         if (childRenderBlock) {
   7855             childBeforePositive = childRenderBlock->maxPositiveMarginBefore();
   7856             childBeforeNegative = childRenderBlock->maxNegativeMarginBefore();
   7857             childAfterPositive = childRenderBlock->maxPositiveMarginAfter();
   7858             childAfterNegative = childRenderBlock->maxNegativeMarginAfter();
   7859         } else {
   7860             beforeMargin = child->marginBefore();
   7861             afterMargin = child->marginAfter();
   7862         }
   7863     } else if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) {
   7864         // The child has a different directionality.  If the child is parallel, then it's just
   7865         // flipped relative to us.  We can use the margins for the opposite edges.
   7866         if (childRenderBlock) {
   7867             childBeforePositive = childRenderBlock->maxPositiveMarginAfter();
   7868             childBeforeNegative = childRenderBlock->maxNegativeMarginAfter();
   7869             childAfterPositive = childRenderBlock->maxPositiveMarginBefore();
   7870             childAfterNegative = childRenderBlock->maxNegativeMarginBefore();
   7871         } else {
   7872             beforeMargin = child->marginAfter();
   7873             afterMargin = child->marginBefore();
   7874         }
   7875     } else {
   7876         // The child is perpendicular to us, which means its margins don't collapse but are on the
   7877         // "logical left/right" sides of the child box.  We can just return the raw margin in this case.
   7878         beforeMargin = marginBeforeForChild(child);
   7879         afterMargin = marginAfterForChild(child);
   7880     }
   7881 
   7882     // Resolve uncollapsing margins into their positive/negative buckets.
   7883     if (beforeMargin) {
   7884         if (beforeMargin > 0)
   7885             childBeforePositive = beforeMargin;
   7886         else
   7887             childBeforeNegative = -beforeMargin;
   7888     }
   7889     if (afterMargin) {
   7890         if (afterMargin > 0)
   7891             childAfterPositive = afterMargin;
   7892         else
   7893             childAfterNegative = -afterMargin;
   7894     }
   7895 
   7896     return MarginValues(childBeforePositive, childBeforeNegative, childAfterPositive, childAfterNegative);
   7897 }
   7898 
   7899 const char* RenderBlock::renderName() const
   7900 {
   7901     if (isBody())
   7902         return "RenderBody"; // FIXME: Temporary hack until we know that the regression tests pass.
   7903 
   7904     if (isFloating())
   7905         return "RenderBlock (floating)";
   7906     if (isOutOfFlowPositioned())
   7907         return "RenderBlock (positioned)";
   7908     if (isAnonymousColumnsBlock())
   7909         return "RenderBlock (anonymous multi-column)";
   7910     if (isAnonymousColumnSpanBlock())
   7911         return "RenderBlock (anonymous multi-column span)";
   7912     if (isAnonymousBlock())
   7913         return "RenderBlock (anonymous)";
   7914     // FIXME: Temporary hack while the new generated content system is being implemented.
   7915     if (isPseudoElement())
   7916         return "RenderBlock (generated)";
   7917     if (isAnonymous())
   7918         return "RenderBlock (generated)";
   7919     if (isRelPositioned())
   7920         return "RenderBlock (relative positioned)";
   7921     if (isStickyPositioned())
   7922         return "RenderBlock (sticky positioned)";
   7923     if (isRunIn())
   7924         return "RenderBlock (run-in)";
   7925     return "RenderBlock";
   7926 }
   7927 
   7928 inline RenderBlock::FloatingObjects::FloatingObjects(const RenderBlock* renderer, bool horizontalWritingMode)
   7929     : m_placedFloatsTree(UninitializedTree)
   7930     , m_leftObjectsCount(0)
   7931     , m_rightObjectsCount(0)
   7932     , m_horizontalWritingMode(horizontalWritingMode)
   7933     , m_renderer(renderer)
   7934 {
   7935 }
   7936 
   7937 void RenderBlock::createFloatingObjects()
   7938 {
   7939     m_floatingObjects = adoptPtr(new FloatingObjects(this, isHorizontalWritingMode()));
   7940 }
   7941 
   7942 inline void RenderBlock::FloatingObjects::clear()
   7943 {
   7944     m_set.clear();
   7945     m_placedFloatsTree.clear();
   7946     m_leftObjectsCount = 0;
   7947     m_rightObjectsCount = 0;
   7948 }
   7949 
   7950 inline void RenderBlock::FloatingObjects::increaseObjectsCount(FloatingObject::Type type)
   7951 {
   7952     if (type == FloatingObject::FloatLeft)
   7953         m_leftObjectsCount++;
   7954     else
   7955         m_rightObjectsCount++;
   7956 }
   7957 
   7958 inline void RenderBlock::FloatingObjects::decreaseObjectsCount(FloatingObject::Type type)
   7959 {
   7960     if (type == FloatingObject::FloatLeft)
   7961         m_leftObjectsCount--;
   7962     else
   7963         m_rightObjectsCount--;
   7964 }
   7965 
   7966 inline RenderBlock::FloatingObjectInterval RenderBlock::FloatingObjects::intervalForFloatingObject(FloatingObject* floatingObject)
   7967 {
   7968     if (m_horizontalWritingMode)
   7969         return RenderBlock::FloatingObjectInterval(floatingObject->frameRect().pixelSnappedY(), floatingObject->frameRect().pixelSnappedMaxY(), floatingObject);
   7970     return RenderBlock::FloatingObjectInterval(floatingObject->frameRect().pixelSnappedX(), floatingObject->frameRect().pixelSnappedMaxX(), floatingObject);
   7971 }
   7972 
   7973 void RenderBlock::FloatingObjects::addPlacedObject(FloatingObject* floatingObject)
   7974 {
   7975     ASSERT(!floatingObject->isInPlacedTree());
   7976 
   7977     floatingObject->setIsPlaced(true);
   7978     if (m_placedFloatsTree.isInitialized())
   7979         m_placedFloatsTree.add(intervalForFloatingObject(floatingObject));
   7980 
   7981 #ifndef NDEBUG
   7982     floatingObject->setIsInPlacedTree(true);
   7983 #endif
   7984 }
   7985 
   7986 void RenderBlock::FloatingObjects::removePlacedObject(FloatingObject* floatingObject)
   7987 {
   7988     ASSERT(floatingObject->isPlaced() && floatingObject->isInPlacedTree());
   7989 
   7990     if (m_placedFloatsTree.isInitialized()) {
   7991         bool removed = m_placedFloatsTree.remove(intervalForFloatingObject(floatingObject));
   7992         ASSERT_UNUSED(removed, removed);
   7993     }
   7994 
   7995     floatingObject->setIsPlaced(false);
   7996 #ifndef NDEBUG
   7997     floatingObject->setIsInPlacedTree(false);
   7998 #endif
   7999 }
   8000 
   8001 inline void RenderBlock::FloatingObjects::add(FloatingObject* floatingObject)
   8002 {
   8003     increaseObjectsCount(floatingObject->type());
   8004     m_set.add(floatingObject);
   8005     if (floatingObject->isPlaced())
   8006         addPlacedObject(floatingObject);
   8007 }
   8008 
   8009 inline void RenderBlock::FloatingObjects::remove(FloatingObject* floatingObject)
   8010 {
   8011     decreaseObjectsCount(floatingObject->type());
   8012     m_set.remove(floatingObject);
   8013     ASSERT(floatingObject->isPlaced() || !floatingObject->isInPlacedTree());
   8014     if (floatingObject->isPlaced())
   8015         removePlacedObject(floatingObject);
   8016 }
   8017 
   8018 void RenderBlock::FloatingObjects::computePlacedFloatsTree()
   8019 {
   8020     ASSERT(!m_placedFloatsTree.isInitialized());
   8021     if (m_set.isEmpty())
   8022         return;
   8023     m_placedFloatsTree.initIfNeeded(m_renderer->view()->intervalArena());
   8024     FloatingObjectSetIterator it = m_set.begin();
   8025     FloatingObjectSetIterator end = m_set.end();
   8026     for (; it != end; ++it) {
   8027         FloatingObject* floatingObject = *it;
   8028         if (floatingObject->isPlaced())
   8029             m_placedFloatsTree.add(intervalForFloatingObject(floatingObject));
   8030     }
   8031 }
   8032 
   8033 template <typename CharacterType>
   8034 static inline TextRun constructTextRunInternal(RenderObject* context, const Font& font, const CharacterType* characters, int length, RenderStyle* style, TextRun::ExpansionBehavior expansion)
   8035 {
   8036     ASSERT(style);
   8037 
   8038     TextDirection textDirection = LTR;
   8039     bool directionalOverride = style->rtlOrdering() == VisualOrder;
   8040 
   8041     TextRun run(characters, length, 0, 0, expansion, textDirection, directionalOverride);
   8042     if (textRunNeedsRenderingContext(font))
   8043         run.setRenderingContext(SVGTextRunRenderingContext::create(context));
   8044 
   8045     return run;
   8046 }
   8047 
   8048 template <typename CharacterType>
   8049 static inline TextRun constructTextRunInternal(RenderObject* context, const Font& font, const CharacterType* characters, int length, RenderStyle* style, TextRun::ExpansionBehavior expansion, TextRunFlags flags)
   8050 {
   8051     ASSERT(style);
   8052 
   8053     TextDirection textDirection = LTR;
   8054     bool directionalOverride = style->rtlOrdering() == VisualOrder;
   8055     if (flags != DefaultTextRunFlags) {
   8056         if (flags & RespectDirection)
   8057             textDirection = style->direction();
   8058         if (flags & RespectDirectionOverride)
   8059             directionalOverride |= isOverride(style->unicodeBidi());
   8060     }
   8061     TextRun run(characters, length, 0, 0, expansion, textDirection, directionalOverride);
   8062     if (textRunNeedsRenderingContext(font))
   8063         run.setRenderingContext(SVGTextRunRenderingContext::create(context));
   8064 
   8065     return run;
   8066 }
   8067 
   8068 TextRun RenderBlock::constructTextRun(RenderObject* context, const Font& font, const LChar* characters, int length, RenderStyle* style, TextRun::ExpansionBehavior expansion)
   8069 {
   8070     return constructTextRunInternal(context, font, characters, length, style, expansion);
   8071 }
   8072 
   8073 TextRun RenderBlock::constructTextRun(RenderObject* context, const Font& font, const UChar* characters, int length, RenderStyle* style, TextRun::ExpansionBehavior expansion)
   8074 {
   8075     return constructTextRunInternal(context, font, characters, length, style, expansion);
   8076 }
   8077 
   8078 TextRun RenderBlock::constructTextRun(RenderObject* context, const Font& font, const RenderText* text, RenderStyle* style, TextRun::ExpansionBehavior expansion)
   8079 {
   8080     if (text->is8Bit())
   8081         return constructTextRunInternal(context, font, text->characters8(), text->textLength(), style, expansion);
   8082     return constructTextRunInternal(context, font, text->characters16(), text->textLength(), style, expansion);
   8083 }
   8084 
   8085 TextRun RenderBlock::constructTextRun(RenderObject* context, const Font& font, const RenderText* text, unsigned offset, unsigned length, RenderStyle* style, TextRun::ExpansionBehavior expansion)
   8086 {
   8087     ASSERT(offset + length <= text->textLength());
   8088     if (text->is8Bit())
   8089         return constructTextRunInternal(context, font, text->characters8() + offset, length, style, expansion);
   8090     return constructTextRunInternal(context, font, text->characters16() + offset, length, style, expansion);
   8091 }
   8092 
   8093 TextRun RenderBlock::constructTextRun(RenderObject* context, const Font& font, const String& string, RenderStyle* style, TextRun::ExpansionBehavior expansion, TextRunFlags flags)
   8094 {
   8095     unsigned length = string.length();
   8096     if (!length)
   8097         return constructTextRunInternal(context, font, static_cast<const LChar*>(0), length, style, expansion, flags);
   8098     if (string.is8Bit())
   8099         return constructTextRunInternal(context, font, string.characters8(), length, style, expansion, flags);
   8100     return constructTextRunInternal(context, font, string.characters16(), length, style, expansion, flags);
   8101 }
   8102 
   8103 RenderBlock* RenderBlock::createAnonymousWithParentRendererAndDisplay(const RenderObject* parent, EDisplay display)
   8104 {
   8105     // FIXME: Do we need to convert all our inline displays to block-type in the anonymous logic ?
   8106     EDisplay newDisplay;
   8107     RenderBlock* newBox = 0;
   8108     if (display == BOX || display == INLINE_BOX) {
   8109         // FIXME: Remove this case once we have eliminated all internal users of old flexbox
   8110         newBox = RenderDeprecatedFlexibleBox::createAnonymous(parent->document());
   8111         newDisplay = BOX;
   8112     } else if (display == FLEX || display == INLINE_FLEX) {
   8113         newBox = RenderFlexibleBox::createAnonymous(parent->document());
   8114         newDisplay = FLEX;
   8115     } else {
   8116         newBox = RenderBlock::createAnonymous(parent->document());
   8117         newDisplay = BLOCK;
   8118     }
   8119 
   8120     RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(parent->style(), newDisplay);
   8121     newBox->setStyle(newStyle.release());
   8122     return newBox;
   8123 }
   8124 
   8125 RenderBlock* RenderBlock::createAnonymousColumnsWithParentRenderer(const RenderObject* parent)
   8126 {
   8127     RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(parent->style(), BLOCK);
   8128     newStyle->inheritColumnPropertiesFrom(parent->style());
   8129 
   8130     RenderBlock* newBox = RenderBlock::createAnonymous(parent->document());
   8131     newBox->setStyle(newStyle.release());
   8132     return newBox;
   8133 }
   8134 
   8135 RenderBlock* RenderBlock::createAnonymousColumnSpanWithParentRenderer(const RenderObject* parent)
   8136 {
   8137     RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(parent->style(), BLOCK);
   8138     newStyle->setColumnSpan(ColumnSpanAll);
   8139 
   8140     RenderBlock* newBox = RenderBlock::createAnonymous(parent->document());
   8141     newBox->setStyle(newStyle.release());
   8142     return newBox;
   8143 }
   8144 
   8145 #ifndef NDEBUG
   8146 void RenderBlock::checkPositionedObjectsNeedLayout()
   8147 {
   8148     if (!gPositionedDescendantsMap)
   8149         return;
   8150 
   8151     if (TrackedRendererListHashSet* positionedDescendantSet = positionedObjects()) {
   8152         TrackedRendererListHashSet::const_iterator end = positionedDescendantSet->end();
   8153         for (TrackedRendererListHashSet::const_iterator it = positionedDescendantSet->begin(); it != end; ++it) {
   8154             RenderBox* currBox = *it;
   8155             ASSERT(!currBox->needsLayout());
   8156         }
   8157     }
   8158 }
   8159 
   8160 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* markedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const RenderObject* obj) const
   8161 {
   8162     showRenderObject();
   8163     for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox())
   8164         root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLabel2, obj, 1);
   8165 }
   8166 
   8167 // These helpers are only used by the PODIntervalTree for debugging purposes.
   8168 String ValueToString<int>::string(const int value)
   8169 {
   8170     return String::number(value);
   8171 }
   8172 
   8173 String ValueToString<RenderBlock::FloatingObject*>::string(const RenderBlock::FloatingObject* floatingObject)
   8174 {
   8175     return String::format("%p (%dx%d %dx%d)", floatingObject, floatingObject->frameRect().pixelSnappedX(), floatingObject->frameRect().pixelSnappedY(), floatingObject->frameRect().pixelSnappedMaxX(), floatingObject->frameRect().pixelSnappedMaxY());
   8176 }
   8177 
   8178 
   8179 #endif
   8180 
   8181 } // namespace WebCore
   8182