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/events/OverflowEvent.h"
     32 #include "core/dom/shadow/ShadowRoot.h"
     33 #include "core/editing/Editor.h"
     34 #include "core/editing/FrameSelection.h"
     35 #include "core/fetch/ResourceLoadPriorityOptimizer.h"
     36 #include "core/frame/Frame.h"
     37 #include "core/frame/FrameView.h"
     38 #include "core/page/Page.h"
     39 #include "core/frame/Settings.h"
     40 #include "core/rendering/FastTextAutosizer.h"
     41 #include "core/rendering/GraphicsContextAnnotator.h"
     42 #include "core/rendering/HitTestLocation.h"
     43 #include "core/rendering/HitTestResult.h"
     44 #include "core/rendering/InlineIterator.h"
     45 #include "core/rendering/InlineTextBox.h"
     46 #include "core/rendering/LayoutRectRecorder.h"
     47 #include "core/rendering/LayoutRepainter.h"
     48 #include "core/rendering/PaintInfo.h"
     49 #include "core/rendering/RenderCombineText.h"
     50 #include "core/rendering/RenderDeprecatedFlexibleBox.h"
     51 #include "core/rendering/RenderFlexibleBox.h"
     52 #include "core/rendering/RenderInline.h"
     53 #include "core/rendering/RenderLayer.h"
     54 #include "core/rendering/RenderMarquee.h"
     55 #include "core/rendering/RenderNamedFlowThread.h"
     56 #include "core/rendering/RenderRegion.h"
     57 #include "core/rendering/RenderTableCell.h"
     58 #include "core/rendering/RenderTextFragment.h"
     59 #include "core/rendering/RenderTheme.h"
     60 #include "core/rendering/RenderView.h"
     61 #include "core/rendering/shapes/ShapeOutsideInfo.h"
     62 #include "core/rendering/style/ContentData.h"
     63 #include "core/rendering/style/RenderStyle.h"
     64 #include "platform/geometry/FloatQuad.h"
     65 #include "platform/geometry/TransformState.h"
     66 #include "platform/graphics/GraphicsContextStateSaver.h"
     67 #include "wtf/StdLibExtras.h"
     68 #include "wtf/TemporaryChange.h"
     69 
     70 using namespace std;
     71 using namespace WTF;
     72 using namespace Unicode;
     73 
     74 namespace WebCore {
     75 
     76 using namespace HTMLNames;
     77 
     78 struct SameSizeAsRenderBlock : public RenderBox {
     79     void* pointers[1];
     80     RenderObjectChildList children;
     81     RenderLineBoxList lineBoxes;
     82     uint32_t bitfields;
     83 };
     84 
     85 COMPILE_ASSERT(sizeof(RenderBlock) == sizeof(SameSizeAsRenderBlock), RenderBlock_should_stay_small);
     86 
     87 typedef WTF::HashMap<const RenderBox*, OwnPtr<ColumnInfo> > ColumnInfoMap;
     88 static ColumnInfoMap* gColumnInfoMap = 0;
     89 
     90 static TrackedDescendantsMap* gPositionedDescendantsMap = 0;
     91 static TrackedDescendantsMap* gPercentHeightDescendantsMap = 0;
     92 
     93 static TrackedContainerMap* gPositionedContainerMap = 0;
     94 static TrackedContainerMap* gPercentHeightContainerMap = 0;
     95 
     96 typedef WTF::HashMap<RenderBlock*, OwnPtr<ListHashSet<RenderInline*> > > ContinuationOutlineTableMap;
     97 
     98 typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet;
     99 static int gDelayUpdateScrollInfo = 0;
    100 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0;
    101 
    102 static bool gColumnFlowSplitEnabled = true;
    103 
    104 // This class helps dispatching the 'overflow' event on layout change. overflow can be set on RenderBoxes, yet the existing code
    105 // only works on RenderBlocks. If this changes, this class should be shared with other RenderBoxes.
    106 class OverflowEventDispatcher {
    107     WTF_MAKE_NONCOPYABLE(OverflowEventDispatcher);
    108 public:
    109     OverflowEventDispatcher(const RenderBlock* block)
    110         : m_block(block)
    111     {
    112         m_shouldDispatchEvent = !m_block->isAnonymous() && m_block->hasOverflowClip() && m_block->document().hasListenerType(Document::OVERFLOWCHANGED_LISTENER);
    113         if (m_shouldDispatchEvent) {
    114             m_hadHorizontalLayoutOverflow = m_block->hasHorizontalLayoutOverflow();
    115             m_hadVerticalLayoutOverflow = m_block->hasVerticalLayoutOverflow();
    116         }
    117     }
    118 
    119     ~OverflowEventDispatcher()
    120     {
    121         if (!m_shouldDispatchEvent)
    122             return;
    123 
    124         bool hasHorizontalLayoutOverflow = m_block->hasHorizontalLayoutOverflow();
    125         bool hasVerticalLayoutOverflow = m_block->hasVerticalLayoutOverflow();
    126 
    127         bool horizontalLayoutOverflowChanged = hasHorizontalLayoutOverflow != m_hadHorizontalLayoutOverflow;
    128         bool verticalLayoutOverflowChanged = hasVerticalLayoutOverflow != m_hadVerticalLayoutOverflow;
    129 
    130         if (!horizontalLayoutOverflowChanged && !verticalLayoutOverflowChanged)
    131             return;
    132 
    133         RefPtr<OverflowEvent> event = OverflowEvent::create(horizontalLayoutOverflowChanged, hasHorizontalLayoutOverflow, verticalLayoutOverflowChanged, hasVerticalLayoutOverflow);
    134         event->setTarget(m_block->node());
    135         m_block->document().enqueueAnimationFrameEvent(event.release());
    136     }
    137 
    138 private:
    139     const RenderBlock* m_block;
    140     bool m_shouldDispatchEvent;
    141     bool m_hadHorizontalLayoutOverflow;
    142     bool m_hadVerticalLayoutOverflow;
    143 };
    144 
    145 RenderBlock::RenderBlock(ContainerNode* node)
    146     : RenderBox(node)
    147     , m_lineHeight(-1)
    148     , m_hasMarginBeforeQuirk(false)
    149     , m_hasMarginAfterQuirk(false)
    150     , m_beingDestroyed(false)
    151     , m_hasMarkupTruncation(false)
    152     , m_hasBorderOrPaddingLogicalWidthChanged(false)
    153 {
    154     setChildrenInline(true);
    155 }
    156 
    157 static void removeBlockFromDescendantAndContainerMaps(RenderBlock* block, TrackedDescendantsMap*& descendantMap, TrackedContainerMap*& containerMap)
    158 {
    159     if (OwnPtr<TrackedRendererListHashSet> descendantSet = descendantMap->take(block)) {
    160         TrackedRendererListHashSet::iterator end = descendantSet->end();
    161         for (TrackedRendererListHashSet::iterator descendant = descendantSet->begin(); descendant != end; ++descendant) {
    162             TrackedContainerMap::iterator it = containerMap->find(*descendant);
    163             ASSERT(it != containerMap->end());
    164             if (it == containerMap->end())
    165                 continue;
    166             HashSet<RenderBlock*>* containerSet = it->value.get();
    167             ASSERT(containerSet->contains(block));
    168             containerSet->remove(block);
    169             if (containerSet->isEmpty())
    170                 containerMap->remove(it);
    171         }
    172     }
    173 }
    174 
    175 static void appendImageIfNotNull(Vector<ImageResource*>& imageResources, const StyleImage* styleImage)
    176 {
    177     if (styleImage && styleImage->cachedImage())
    178         imageResources.append(styleImage->cachedImage());
    179 }
    180 
    181 static void appendLayers(Vector<ImageResource*>& images, const FillLayer* styleLayer)
    182 {
    183     for (const FillLayer* layer = styleLayer; layer; layer = layer->next()) {
    184         appendImageIfNotNull(images, layer->image());
    185     }
    186 }
    187 
    188 RenderBlock::~RenderBlock()
    189 {
    190     if (hasColumns())
    191         gColumnInfoMap->take(this);
    192     if (gPercentHeightDescendantsMap)
    193         removeBlockFromDescendantAndContainerMaps(this, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
    194     if (gPositionedDescendantsMap)
    195         removeBlockFromDescendantAndContainerMaps(this, gPositionedDescendantsMap, gPositionedContainerMap);
    196 }
    197 
    198 void RenderBlock::willBeDestroyed()
    199 {
    200     // Mark as being destroyed to avoid trouble with merges in removeChild().
    201     m_beingDestroyed = true;
    202 
    203     // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
    204     // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
    205     children()->destroyLeftoverChildren();
    206 
    207     // Destroy our continuation before anything other than anonymous children.
    208     // The reason we don't destroy it before anonymous children is that they may
    209     // have continuations of their own that are anonymous children of our continuation.
    210     RenderBoxModelObject* continuation = this->continuation();
    211     if (continuation) {
    212         continuation->destroy();
    213         setContinuation(0);
    214     }
    215 
    216     if (!documentBeingDestroyed()) {
    217         if (firstLineBox()) {
    218             // We can't wait for RenderBox::destroy to clear the selection,
    219             // because by then we will have nuked the line boxes.
    220             // FIXME: The FrameSelection should be responsible for this when it
    221             // is notified of DOM mutations.
    222             if (isSelectionBorder())
    223                 view()->clearSelection();
    224 
    225             // If we are an anonymous block, then our line boxes might have children
    226             // that will outlast this block. In the non-anonymous block case those
    227             // children will be destroyed by the time we return from this function.
    228             if (isAnonymousBlock()) {
    229                 for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox()) {
    230                     while (InlineBox* childBox = box->firstChild())
    231                         childBox->remove();
    232                 }
    233             }
    234         } else if (parent())
    235             parent()->dirtyLinesFromChangedChild(this);
    236     }
    237 
    238     m_lineBoxes.deleteLineBoxes();
    239 
    240     if (UNLIKELY(gDelayedUpdateScrollInfoSet != 0))
    241         gDelayedUpdateScrollInfoSet->remove(this);
    242 
    243     FastTextAutosizer* textAutosizer = document().fastTextAutosizer();
    244     if (textAutosizer)
    245         textAutosizer->destroy(this);
    246 
    247     RenderBox::willBeDestroyed();
    248 }
    249 
    250 void RenderBlock::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
    251 {
    252     RenderStyle* oldStyle = style();
    253 
    254     setReplaced(newStyle->isDisplayInlineType());
    255 
    256     if (oldStyle && parent() && diff == StyleDifferenceLayout && oldStyle->position() != newStyle->position()) {
    257         if (newStyle->position() == StaticPosition)
    258             // Clear our positioned objects list. Our absolutely positioned descendants will be
    259             // inserted into our containing block's positioned objects list during layout.
    260             removePositionedObjects(0, NewContainingBlock);
    261         else if (oldStyle->position() == StaticPosition) {
    262             // Remove our absolutely positioned descendants from their current containing block.
    263             // They will be inserted into our positioned objects list during layout.
    264             RenderObject* cb = parent();
    265             while (cb && (cb->style()->position() == StaticPosition || (cb->isInline() && !cb->isReplaced())) && !cb->isRenderView()) {
    266                 if (cb->style()->position() == RelativePosition && cb->isInline() && !cb->isReplaced()) {
    267                     cb = cb->containingBlock();
    268                     break;
    269                 }
    270                 cb = cb->parent();
    271             }
    272 
    273             if (cb->isRenderBlock())
    274                 toRenderBlock(cb)->removePositionedObjects(this, NewContainingBlock);
    275         }
    276     }
    277 
    278     RenderBox::styleWillChange(diff, newStyle);
    279 }
    280 
    281 static bool borderOrPaddingLogicalWidthChanged(const RenderStyle* oldStyle, const RenderStyle* newStyle)
    282 {
    283     if (newStyle->isHorizontalWritingMode())
    284         return oldStyle->borderLeftWidth() != newStyle->borderLeftWidth()
    285             || oldStyle->borderRightWidth() != newStyle->borderRightWidth()
    286             || oldStyle->paddingLeft() != newStyle->paddingLeft()
    287             || oldStyle->paddingRight() != newStyle->paddingRight();
    288 
    289     return oldStyle->borderTopWidth() != newStyle->borderTopWidth()
    290         || oldStyle->borderBottomWidth() != newStyle->borderBottomWidth()
    291         || oldStyle->paddingTop() != newStyle->paddingTop()
    292         || oldStyle->paddingBottom() != newStyle->paddingBottom();
    293 }
    294 
    295 void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
    296 {
    297     RenderBox::styleDidChange(diff, oldStyle);
    298 
    299     RenderStyle* newStyle = style();
    300 
    301     updateShapeInsideInfoAfterStyleChange(newStyle->resolvedShapeInside(), oldStyle ? oldStyle->resolvedShapeInside() : RenderStyle::initialShapeInside());
    302 
    303     if (!isAnonymousBlock()) {
    304         // Ensure that all of our continuation blocks pick up the new style.
    305         for (RenderBlock* currCont = blockElementContinuation(); currCont; currCont = currCont->blockElementContinuation()) {
    306             RenderBoxModelObject* nextCont = currCont->continuation();
    307             currCont->setContinuation(0);
    308             currCont->setStyle(newStyle);
    309             currCont->setContinuation(nextCont);
    310         }
    311     }
    312 
    313     FastTextAutosizer* textAutosizer = document().fastTextAutosizer();
    314     if (textAutosizer)
    315         textAutosizer->record(this);
    316 
    317     propagateStyleToAnonymousChildren(true);
    318     m_lineHeight = -1;
    319 
    320     // It's possible for our border/padding to change, but for the overall logical width of the block to
    321     // end up being the same. We keep track of this change so in layoutBlock, we can know to set relayoutChildren=true.
    322     m_hasBorderOrPaddingLogicalWidthChanged = oldStyle && diff == StyleDifferenceLayout && needsLayout() && borderOrPaddingLogicalWidthChanged(oldStyle, newStyle);
    323 }
    324 
    325 RenderBlock* RenderBlock::continuationBefore(RenderObject* beforeChild)
    326 {
    327     if (beforeChild && beforeChild->parent() == this)
    328         return this;
    329 
    330     RenderBlock* curr = toRenderBlock(continuation());
    331     RenderBlock* nextToLast = this;
    332     RenderBlock* last = this;
    333     while (curr) {
    334         if (beforeChild && beforeChild->parent() == curr) {
    335             if (curr->firstChild() == beforeChild)
    336                 return last;
    337             return curr;
    338         }
    339 
    340         nextToLast = last;
    341         last = curr;
    342         curr = toRenderBlock(curr->continuation());
    343     }
    344 
    345     if (!beforeChild && !last->firstChild())
    346         return nextToLast;
    347     return last;
    348 }
    349 
    350 void RenderBlock::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild)
    351 {
    352     RenderBlock* flow = continuationBefore(beforeChild);
    353     ASSERT(!beforeChild || beforeChild->parent()->isAnonymousColumnSpanBlock() || beforeChild->parent()->isRenderBlock());
    354     RenderBoxModelObject* beforeChildParent = 0;
    355     if (beforeChild)
    356         beforeChildParent = toRenderBoxModelObject(beforeChild->parent());
    357     else {
    358         RenderBoxModelObject* cont = flow->continuation();
    359         if (cont)
    360             beforeChildParent = cont;
    361         else
    362             beforeChildParent = flow;
    363     }
    364 
    365     if (newChild->isFloatingOrOutOfFlowPositioned()) {
    366         beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
    367         return;
    368     }
    369 
    370     // A continuation always consists of two potential candidates: a block or an anonymous
    371     // column span box holding column span children.
    372     bool childIsNormal = newChild->isInline() || !newChild->style()->columnSpan();
    373     bool bcpIsNormal = beforeChildParent->isInline() || !beforeChildParent->style()->columnSpan();
    374     bool flowIsNormal = flow->isInline() || !flow->style()->columnSpan();
    375 
    376     if (flow == beforeChildParent) {
    377         flow->addChildIgnoringContinuation(newChild, beforeChild);
    378         return;
    379     }
    380 
    381     // The goal here is to match up if we can, so that we can coalesce and create the
    382     // minimal # of continuations needed for the inline.
    383     if (childIsNormal == bcpIsNormal) {
    384         beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
    385         return;
    386     }
    387     if (flowIsNormal == childIsNormal) {
    388         flow->addChildIgnoringContinuation(newChild, 0); // Just treat like an append.
    389         return;
    390     }
    391     beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
    392 }
    393 
    394 
    395 void RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
    396 {
    397     ASSERT(!continuation()); // We don't yet support column spans that aren't immediate children of the multi-column block.
    398 
    399     // The goal is to locate a suitable box in which to place our child.
    400     RenderBlock* beforeChildParent = 0;
    401     if (beforeChild) {
    402         RenderObject* curr = beforeChild;
    403         while (curr && curr->parent() != this)
    404             curr = curr->parent();
    405         beforeChildParent = toRenderBlock(curr);
    406         ASSERT(beforeChildParent);
    407         ASSERT(beforeChildParent->isAnonymousColumnsBlock() || beforeChildParent->isAnonymousColumnSpanBlock());
    408     } else
    409         beforeChildParent = toRenderBlock(lastChild());
    410 
    411     // If the new child is floating or positioned it can just go in that block.
    412     if (newChild->isFloatingOrOutOfFlowPositioned()) {
    413         beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
    414         return;
    415     }
    416 
    417     // See if the child can be placed in the box.
    418     bool newChildHasColumnSpan = newChild->style()->columnSpan() && !newChild->isInline();
    419     bool beforeChildParentHoldsColumnSpans = beforeChildParent->isAnonymousColumnSpanBlock();
    420 
    421     if (newChildHasColumnSpan == beforeChildParentHoldsColumnSpans) {
    422         beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
    423         return;
    424     }
    425 
    426     if (!beforeChild) {
    427         // Create a new block of the correct type.
    428         RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
    429         children()->appendChildNode(this, newBox);
    430         newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
    431         return;
    432     }
    433 
    434     RenderObject* immediateChild = beforeChild;
    435     bool isPreviousBlockViable = true;
    436     while (immediateChild->parent() != this) {
    437         if (isPreviousBlockViable)
    438             isPreviousBlockViable = !immediateChild->previousSibling();
    439         immediateChild = immediateChild->parent();
    440     }
    441     if (isPreviousBlockViable && immediateChild->previousSibling()) {
    442         toRenderBlock(immediateChild->previousSibling())->addChildIgnoringAnonymousColumnBlocks(newChild, 0); // Treat like an append.
    443         return;
    444     }
    445 
    446     // Split our anonymous blocks.
    447     RenderObject* newBeforeChild = splitAnonymousBoxesAroundChild(beforeChild);
    448 
    449 
    450     // Create a new anonymous box of the appropriate type.
    451     RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock() : createAnonymousColumnsBlock();
    452     children()->insertChildNode(this, newBox, newBeforeChild);
    453     newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
    454     return;
    455 }
    456 
    457 RenderBlockFlow* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBlock)
    458 {
    459     RenderBlock* firstChildIgnoringAnonymousWrappers = 0;
    460     for (RenderObject* curr = this; curr; curr = curr->parent()) {
    461         if (!curr->isRenderBlock() || curr->isFloatingOrOutOfFlowPositioned() || curr->isTableCell() || curr->isRoot() || curr->isRenderView() || curr->hasOverflowClip()
    462             || curr->isInlineBlockOrInlineTable())
    463             return 0;
    464 
    465         // FIXME: Renderers that do special management of their children (tables, buttons,
    466         // lists, flexboxes, etc.) breaks when the flow is split through them. Disabling
    467         // multi-column for them to avoid this problem.)
    468         if (!curr->isRenderBlockFlow() || curr->isListItem())
    469             return 0;
    470 
    471         RenderBlockFlow* currBlock = toRenderBlockFlow(curr);
    472         if (!currBlock->createsAnonymousWrapper())
    473             firstChildIgnoringAnonymousWrappers = currBlock;
    474 
    475         if (currBlock->style()->specifiesColumns() && (allowAnonymousColumnBlock || !currBlock->isAnonymousColumnsBlock()))
    476             return toRenderBlockFlow(firstChildIgnoringAnonymousWrappers);
    477 
    478         if (currBlock->isAnonymousColumnSpanBlock())
    479             return 0;
    480     }
    481     return 0;
    482 }
    483 
    484 RenderBlock* RenderBlock::clone() const
    485 {
    486     RenderBlock* cloneBlock;
    487     if (isAnonymousBlock()) {
    488         cloneBlock = createAnonymousBlock();
    489         cloneBlock->setChildrenInline(childrenInline());
    490     }
    491     else {
    492         RenderObject* cloneRenderer = toElement(node())->createRenderer(style());
    493         cloneBlock = toRenderBlock(cloneRenderer);
    494         cloneBlock->setStyle(style());
    495 
    496         // This takes care of setting the right value of childrenInline in case
    497         // generated content is added to cloneBlock and 'this' does not have
    498         // generated content added yet.
    499         cloneBlock->setChildrenInline(cloneBlock->firstChild() ? cloneBlock->firstChild()->isInline() : childrenInline());
    500     }
    501     cloneBlock->setFlowThreadState(flowThreadState());
    502     return cloneBlock;
    503 }
    504 
    505 void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
    506                               RenderBlock* middleBlock,
    507                               RenderObject* beforeChild, RenderBoxModelObject* oldCont)
    508 {
    509     // Create a clone of this inline.
    510     RenderBlock* cloneBlock = clone();
    511     if (!isAnonymousBlock())
    512         cloneBlock->setContinuation(oldCont);
    513 
    514     if (!beforeChild && isAfterContent(lastChild()))
    515         beforeChild = lastChild();
    516 
    517     // If we are moving inline children from |this| to cloneBlock, then we need
    518     // to clear our line box tree.
    519     if (beforeChild && childrenInline())
    520         deleteLineBoxTree();
    521 
    522     // Now take all of the children from beforeChild to the end and remove
    523     // them from |this| and place them in the clone.
    524     moveChildrenTo(cloneBlock, beforeChild, 0, true);
    525 
    526     // Hook |clone| up as the continuation of the middle block.
    527     if (!cloneBlock->isAnonymousBlock())
    528         middleBlock->setContinuation(cloneBlock);
    529 
    530     // We have been reparented and are now under the fromBlock.  We need
    531     // to walk up our block parent chain until we hit the containing anonymous columns block.
    532     // Once we hit the anonymous columns block we're done.
    533     RenderBoxModelObject* curr = toRenderBoxModelObject(parent());
    534     RenderBoxModelObject* currChild = this;
    535     RenderObject* currChildNextSibling = currChild->nextSibling();
    536 
    537     while (curr && curr->isDescendantOf(fromBlock) && curr != fromBlock) {
    538         ASSERT_WITH_SECURITY_IMPLICATION(curr->isRenderBlock());
    539 
    540         RenderBlock* blockCurr = toRenderBlock(curr);
    541 
    542         // Create a new clone.
    543         RenderBlock* cloneChild = cloneBlock;
    544         cloneBlock = blockCurr->clone();
    545 
    546         // Insert our child clone as the first child.
    547         cloneBlock->addChildIgnoringContinuation(cloneChild, 0);
    548 
    549         // Hook the clone up as a continuation of |curr|.  Note we do encounter
    550         // anonymous blocks possibly as we walk up the block chain.  When we split an
    551         // anonymous block, there's no need to do any continuation hookup, since we haven't
    552         // actually split a real element.
    553         if (!blockCurr->isAnonymousBlock()) {
    554             oldCont = blockCurr->continuation();
    555             blockCurr->setContinuation(cloneBlock);
    556             cloneBlock->setContinuation(oldCont);
    557         }
    558 
    559         // Now we need to take all of the children starting from the first child
    560         // *after* currChild and append them all to the clone.
    561         blockCurr->moveChildrenTo(cloneBlock, currChildNextSibling, 0, true);
    562 
    563         // Keep walking up the chain.
    564         currChild = curr;
    565         currChildNextSibling = currChild->nextSibling();
    566         curr = toRenderBoxModelObject(curr->parent());
    567     }
    568 
    569     // Now we are at the columns block level. We need to put the clone into the toBlock.
    570     toBlock->children()->appendChildNode(toBlock, cloneBlock);
    571 
    572     // Now take all the children after currChild and remove them from the fromBlock
    573     // and put them in the toBlock.
    574     fromBlock->moveChildrenTo(toBlock, currChildNextSibling, 0, true);
    575 }
    576 
    577 void RenderBlock::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
    578                             RenderObject* newChild, RenderBoxModelObject* oldCont)
    579 {
    580     RenderBlock* pre = 0;
    581     RenderBlock* block = containingColumnsBlock();
    582 
    583     // Delete our line boxes before we do the inline split into continuations.
    584     block->deleteLineBoxTree();
    585 
    586     bool madeNewBeforeBlock = false;
    587     if (block->isAnonymousColumnsBlock()) {
    588         // We can reuse this block and make it the preBlock of the next continuation.
    589         pre = block;
    590         pre->removePositionedObjects(0);
    591         if (block->isRenderBlockFlow())
    592             toRenderBlockFlow(pre)->removeFloatingObjects();
    593         block = toRenderBlock(block->parent());
    594     } else {
    595         // No anonymous block available for use.  Make one.
    596         pre = block->createAnonymousColumnsBlock();
    597         pre->setChildrenInline(false);
    598         madeNewBeforeBlock = true;
    599     }
    600 
    601     RenderBlock* post = block->createAnonymousColumnsBlock();
    602     post->setChildrenInline(false);
    603 
    604     RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
    605     if (madeNewBeforeBlock)
    606         block->children()->insertChildNode(block, pre, boxFirst);
    607     block->children()->insertChildNode(block, newBlockBox, boxFirst);
    608     block->children()->insertChildNode(block, post, boxFirst);
    609     block->setChildrenInline(false);
    610 
    611     if (madeNewBeforeBlock)
    612         block->moveChildrenTo(pre, boxFirst, 0, true);
    613 
    614     splitBlocks(pre, post, newBlockBox, beforeChild, oldCont);
    615 
    616     // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
    617     // time in makeChildrenNonInline by just setting this explicitly up front.
    618     newBlockBox->setChildrenInline(false);
    619 
    620     newBlockBox->addChild(newChild);
    621 
    622     // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
    623     // get deleted properly.  Because objects moves from the pre block into the post block, we want to
    624     // make new line boxes instead of leaving the old line boxes around.
    625     pre->setNeedsLayoutAndPrefWidthsRecalc();
    626     block->setNeedsLayoutAndPrefWidthsRecalc();
    627     post->setNeedsLayoutAndPrefWidthsRecalc();
    628 }
    629 
    630 void RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlockFlow* newBlockBox, RenderObject* newChild)
    631 {
    632     RenderBlockFlow* pre = 0;
    633     RenderBlockFlow* post = 0;
    634     RenderBlock* block = this; // Eventually block will not just be |this|, but will also be a block nested inside |this|.  Assign to a variable
    635                                // so that we don't have to patch all of the rest of the code later on.
    636 
    637     // Delete the block's line boxes before we do the split.
    638     block->deleteLineBoxTree();
    639 
    640     if (beforeChild && beforeChild->parent() != this)
    641         beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
    642 
    643     if (beforeChild != firstChild()) {
    644         pre = block->createAnonymousColumnsBlock();
    645         pre->setChildrenInline(block->childrenInline());
    646     }
    647 
    648     if (beforeChild) {
    649         post = block->createAnonymousColumnsBlock();
    650         post->setChildrenInline(block->childrenInline());
    651     }
    652 
    653     RenderObject* boxFirst = block->firstChild();
    654     if (pre)
    655         block->children()->insertChildNode(block, pre, boxFirst);
    656     block->children()->insertChildNode(block, newBlockBox, boxFirst);
    657     if (post)
    658         block->children()->insertChildNode(block, post, boxFirst);
    659     block->setChildrenInline(false);
    660 
    661     // 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).
    662     block->moveChildrenTo(pre, boxFirst, beforeChild, true);
    663     block->moveChildrenTo(post, beforeChild, 0, true);
    664 
    665     // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
    666     // time in makeChildrenNonInline by just setting this explicitly up front.
    667     newBlockBox->setChildrenInline(false);
    668 
    669     newBlockBox->addChild(newChild);
    670 
    671     // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
    672     // get deleted properly.  Because objects moved from the pre block into the post block, we want to
    673     // make new line boxes instead of leaving the old line boxes around.
    674     if (pre)
    675         pre->setNeedsLayoutAndPrefWidthsRecalc();
    676     block->setNeedsLayoutAndPrefWidthsRecalc();
    677     if (post)
    678         post->setNeedsLayoutAndPrefWidthsRecalc();
    679 }
    680 
    681 RenderBlockFlow* RenderBlock::columnsBlockForSpanningElement(RenderObject* newChild)
    682 {
    683     // FIXME: This function is the gateway for the addition of column-span support.  It will
    684     // be added to in three stages:
    685     // (1) Immediate children of a multi-column block can span.
    686     // (2) Nested block-level children with only block-level ancestors between them and the multi-column block can span.
    687     // (3) Nested children with block or inline ancestors between them and the multi-column block can span (this is when we
    688     // cross the streams and have to cope with both types of continuations mixed together).
    689     // This function currently supports (1) and (2).
    690     RenderBlockFlow* columnsBlockAncestor = 0;
    691     if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isBeforeOrAfterContent()
    692         && !newChild->isFloatingOrOutOfFlowPositioned() && !newChild->isInline() && !isAnonymousColumnSpanBlock()) {
    693         columnsBlockAncestor = containingColumnsBlock(false);
    694         if (columnsBlockAncestor) {
    695             // Make sure that none of the parent ancestors have a continuation.
    696             // If yes, we do not want split the block into continuations.
    697             RenderObject* curr = this;
    698             while (curr && curr != columnsBlockAncestor) {
    699                 if (curr->isRenderBlock() && toRenderBlock(curr)->continuation()) {
    700                     columnsBlockAncestor = 0;
    701                     break;
    702                 }
    703                 curr = curr->parent();
    704             }
    705         }
    706     }
    707     return columnsBlockAncestor;
    708 }
    709 
    710 void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
    711 {
    712     if (beforeChild && beforeChild->parent() != this) {
    713         RenderObject* beforeChildContainer = beforeChild->parent();
    714         while (beforeChildContainer->parent() != this)
    715             beforeChildContainer = beforeChildContainer->parent();
    716         ASSERT(beforeChildContainer);
    717 
    718         if (beforeChildContainer->isAnonymous()) {
    719             // If the requested beforeChild is not one of our children, then this is because
    720             // there is an anonymous container within this object that contains the beforeChild.
    721             RenderObject* beforeChildAnonymousContainer = beforeChildContainer;
    722             if (beforeChildAnonymousContainer->isAnonymousBlock()
    723                 // Full screen renderers and full screen placeholders act as anonymous blocks, not tables:
    724                 || beforeChildAnonymousContainer->isRenderFullScreen()
    725                 || beforeChildAnonymousContainer->isRenderFullScreenPlaceholder()
    726                 ) {
    727                 // Insert the child into the anonymous block box instead of here.
    728                 if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)
    729                     beforeChild->parent()->addChild(newChild, beforeChild);
    730                 else
    731                     addChild(newChild, beforeChild->parent());
    732                 return;
    733             }
    734 
    735             ASSERT(beforeChildAnonymousContainer->isTable());
    736             if (newChild->isTablePart()) {
    737                 // Insert into the anonymous table.
    738                 beforeChildAnonymousContainer->addChild(newChild, beforeChild);
    739                 return;
    740             }
    741 
    742             beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
    743 
    744             ASSERT(beforeChild->parent() == this);
    745             if (beforeChild->parent() != this) {
    746                 // We should never reach here. If we do, we need to use the
    747                 // safe fallback to use the topmost beforeChild container.
    748                 beforeChild = beforeChildContainer;
    749             }
    750         }
    751     }
    752 
    753     // Check for a spanning element in columns.
    754     if (gColumnFlowSplitEnabled) {
    755         RenderBlockFlow* columnsBlockAncestor = columnsBlockForSpanningElement(newChild);
    756         if (columnsBlockAncestor) {
    757             TemporaryChange<bool> columnFlowSplitEnabled(gColumnFlowSplitEnabled, false);
    758             // We are placing a column-span element inside a block.
    759             RenderBlockFlow* newBox = createAnonymousColumnSpanBlock();
    760 
    761             if (columnsBlockAncestor != this && !isRenderFlowThread()) {
    762                 // We are nested inside a multi-column element and are being split by the span. We have to break up
    763                 // our block into continuations.
    764                 RenderBoxModelObject* oldContinuation = continuation();
    765 
    766                 // When we split an anonymous block, there's no need to do any continuation hookup,
    767                 // since we haven't actually split a real element.
    768                 if (!isAnonymousBlock())
    769                     setContinuation(newBox);
    770 
    771                 splitFlow(beforeChild, newBox, newChild, oldContinuation);
    772                 return;
    773             }
    774 
    775             // We have to perform a split of this block's children. This involves creating an anonymous block box to hold
    776             // the column-spanning |newChild|. We take all of the children from before |newChild| and put them into
    777             // one anonymous columns block, and all of the children after |newChild| go into another anonymous block.
    778             makeChildrenAnonymousColumnBlocks(beforeChild, newBox, newChild);
    779             return;
    780         }
    781     }
    782 
    783     bool madeBoxesNonInline = false;
    784 
    785     // A block has to either have all of its children inline, or all of its children as blocks.
    786     // So, if our children are currently inline and a block child has to be inserted, we move all our
    787     // inline children into anonymous block boxes.
    788     if (childrenInline() && !newChild->isInline() && !newChild->isFloatingOrOutOfFlowPositioned()) {
    789         // This is a block with inline content. Wrap the inline content in anonymous blocks.
    790         makeChildrenNonInline(beforeChild);
    791         madeBoxesNonInline = true;
    792 
    793         if (beforeChild && beforeChild->parent() != this) {
    794             beforeChild = beforeChild->parent();
    795             ASSERT(beforeChild->isAnonymousBlock());
    796             ASSERT(beforeChild->parent() == this);
    797         }
    798     } else if (!childrenInline() && (newChild->isFloatingOrOutOfFlowPositioned() || newChild->isInline())) {
    799         // If we're inserting an inline child but all of our children are blocks, then we have to make sure
    800         // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise
    801         // a new one is created and inserted into our list of children in the appropriate position.
    802         RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();
    803 
    804         if (afterChild && afterChild->isAnonymousBlock()) {
    805             afterChild->addChild(newChild);
    806             return;
    807         }
    808 
    809         if (newChild->isInline()) {
    810             // No suitable existing anonymous box - create a new one.
    811             RenderBlock* newBox = createAnonymousBlock();
    812             RenderBox::addChild(newBox, beforeChild);
    813             newBox->addChild(newChild);
    814             return;
    815         }
    816     }
    817 
    818     RenderBox::addChild(newChild, beforeChild);
    819 
    820     if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRenderBlock())
    821         toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
    822     // this object may be dead here
    823 }
    824 
    825 void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
    826 {
    827     if (continuation() && !isAnonymousBlock())
    828         addChildToContinuation(newChild, beforeChild);
    829     else
    830         addChildIgnoringContinuation(newChild, beforeChild);
    831 }
    832 
    833 void RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild)
    834 {
    835     if (!isAnonymousBlock() && firstChild() && (firstChild()->isAnonymousColumnsBlock() || firstChild()->isAnonymousColumnSpanBlock()))
    836         addChildToAnonymousColumnBlocks(newChild, beforeChild);
    837     else
    838         addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
    839 }
    840 
    841 static void getInlineRun(RenderObject* start, RenderObject* boundary,
    842                          RenderObject*& inlineRunStart,
    843                          RenderObject*& inlineRunEnd)
    844 {
    845     // Beginning at |start| we find the largest contiguous run of inlines that
    846     // we can.  We denote the run with start and end points, |inlineRunStart|
    847     // and |inlineRunEnd|.  Note that these two values may be the same if
    848     // we encounter only one inline.
    849     //
    850     // We skip any non-inlines we encounter as long as we haven't found any
    851     // inlines yet.
    852     //
    853     // |boundary| indicates a non-inclusive boundary point.  Regardless of whether |boundary|
    854     // is inline or not, we will not include it in a run with inlines before it.  It's as though we encountered
    855     // a non-inline.
    856 
    857     // Start by skipping as many non-inlines as we can.
    858     RenderObject * curr = start;
    859     bool sawInline;
    860     do {
    861         while (curr && !(curr->isInline() || curr->isFloatingOrOutOfFlowPositioned()))
    862             curr = curr->nextSibling();
    863 
    864         inlineRunStart = inlineRunEnd = curr;
    865 
    866         if (!curr)
    867             return; // No more inline children to be found.
    868 
    869         sawInline = curr->isInline();
    870 
    871         curr = curr->nextSibling();
    872         while (curr && (curr->isInline() || curr->isFloatingOrOutOfFlowPositioned()) && (curr != boundary)) {
    873             inlineRunEnd = curr;
    874             if (curr->isInline())
    875                 sawInline = true;
    876             curr = curr->nextSibling();
    877         }
    878     } while (!sawInline);
    879 }
    880 
    881 void RenderBlock::deleteLineBoxTree()
    882 {
    883     m_lineBoxes.deleteLineBoxTree();
    884 
    885     if (AXObjectCache* cache = document().existingAXObjectCache())
    886         cache->recomputeIsIgnored(this);
    887 }
    888 
    889 RootInlineBox* RenderBlock::createAndAppendRootInlineBox()
    890 {
    891     RootInlineBox* rootBox = createRootInlineBox();
    892     m_lineBoxes.appendLineBox(rootBox);
    893 
    894     if (UNLIKELY(AXObjectCache::accessibilityEnabled()) && m_lineBoxes.firstLineBox() == rootBox) {
    895         if (AXObjectCache* cache = document().existingAXObjectCache())
    896             cache->recomputeIsIgnored(this);
    897     }
    898 
    899     return rootBox;
    900 }
    901 
    902 void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
    903 {
    904     // makeChildrenNonInline takes a block whose children are *all* inline and it
    905     // makes sure that inline children are coalesced under anonymous
    906     // blocks.  If |insertionPoint| is defined, then it represents the insertion point for
    907     // the new block child that is causing us to have to wrap all the inlines.  This
    908     // means that we cannot coalesce inlines before |insertionPoint| with inlines following
    909     // |insertionPoint|, because the new child is going to be inserted in between the inlines,
    910     // splitting them.
    911     ASSERT(isInlineBlockOrInlineTable() || !isInline());
    912     ASSERT(!insertionPoint || insertionPoint->parent() == this);
    913 
    914     setChildrenInline(false);
    915 
    916     RenderObject *child = firstChild();
    917     if (!child)
    918         return;
    919 
    920     deleteLineBoxTree();
    921 
    922     while (child) {
    923         RenderObject *inlineRunStart, *inlineRunEnd;
    924         getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);
    925 
    926         if (!inlineRunStart)
    927             break;
    928 
    929         child = inlineRunEnd->nextSibling();
    930 
    931         RenderBlock* block = createAnonymousBlock();
    932         children()->insertChildNode(this, block, inlineRunStart);
    933         moveChildrenTo(block, inlineRunStart, child);
    934     }
    935 
    936 #ifndef NDEBUG
    937     for (RenderObject *c = firstChild(); c; c = c->nextSibling())
    938         ASSERT(!c->isInline());
    939 #endif
    940 
    941     repaint();
    942 }
    943 
    944 void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
    945 {
    946     ASSERT(child->isAnonymousBlock());
    947     ASSERT(!child->childrenInline());
    948 
    949     if (child->continuation() || (child->firstChild() && (child->isAnonymousColumnSpanBlock() || child->isAnonymousColumnsBlock())))
    950         return;
    951 
    952     RenderObject* firstAnChild = child->m_children.firstChild();
    953     RenderObject* lastAnChild = child->m_children.lastChild();
    954     if (firstAnChild) {
    955         RenderObject* o = firstAnChild;
    956         while (o) {
    957             o->setParent(this);
    958             o = o->nextSibling();
    959         }
    960         firstAnChild->setPreviousSibling(child->previousSibling());
    961         lastAnChild->setNextSibling(child->nextSibling());
    962         if (child->previousSibling())
    963             child->previousSibling()->setNextSibling(firstAnChild);
    964         if (child->nextSibling())
    965             child->nextSibling()->setPreviousSibling(lastAnChild);
    966 
    967         if (child == m_children.firstChild())
    968             m_children.setFirstChild(firstAnChild);
    969         if (child == m_children.lastChild())
    970             m_children.setLastChild(lastAnChild);
    971     } else {
    972         if (child == m_children.firstChild())
    973             m_children.setFirstChild(child->nextSibling());
    974         if (child == m_children.lastChild())
    975             m_children.setLastChild(child->previousSibling());
    976 
    977         if (child->previousSibling())
    978             child->previousSibling()->setNextSibling(child->nextSibling());
    979         if (child->nextSibling())
    980             child->nextSibling()->setPreviousSibling(child->previousSibling());
    981     }
    982 
    983     child->children()->setFirstChild(0);
    984     child->m_next = 0;
    985 
    986     // Remove all the information in the flow thread associated with the leftover anonymous block.
    987     child->removeFromRenderFlowThread();
    988 
    989     child->setParent(0);
    990     child->setPreviousSibling(0);
    991     child->setNextSibling(0);
    992 
    993     child->destroy();
    994 }
    995 
    996 static bool canMergeContiguousAnonymousBlocks(RenderObject* oldChild, RenderObject* prev, RenderObject* next)
    997 {
    998     if (oldChild->documentBeingDestroyed() || oldChild->isInline() || oldChild->virtualContinuation())
    999         return false;
   1000 
   1001     if ((prev && (!prev->isAnonymousBlock() || toRenderBlock(prev)->continuation() || toRenderBlock(prev)->beingDestroyed()))
   1002         || (next && (!next->isAnonymousBlock() || toRenderBlock(next)->continuation() || toRenderBlock(next)->beingDestroyed())))
   1003         return false;
   1004 
   1005     if ((prev && (prev->isRubyRun() || prev->isRubyBase()))
   1006         || (next && (next->isRubyRun() || next->isRubyBase())))
   1007         return false;
   1008 
   1009     if (!prev || !next)
   1010         return true;
   1011 
   1012     // Make sure the types of the anonymous blocks match up.
   1013     return prev->isAnonymousColumnsBlock() == next->isAnonymousColumnsBlock()
   1014            && prev->isAnonymousColumnSpanBlock() == next->isAnonymousColumnSpanBlock();
   1015 }
   1016 
   1017 void RenderBlock::collapseAnonymousBlockChild(RenderBlock* parent, RenderBlock* child)
   1018 {
   1019     // It's possible that this block's destruction may have been triggered by the
   1020     // child's removal. Just bail if the anonymous child block is already being
   1021     // destroyed. See crbug.com/282088
   1022     if (child->beingDestroyed())
   1023         return;
   1024     parent->setNeedsLayoutAndPrefWidthsRecalc();
   1025     parent->setChildrenInline(child->childrenInline());
   1026     RenderObject* nextSibling = child->nextSibling();
   1027 
   1028     RenderFlowThread* childFlowThread = child->flowThreadContainingBlock();
   1029     CurrentRenderFlowThreadMaintainer flowThreadMaintainer(childFlowThread);
   1030 
   1031     parent->children()->removeChildNode(parent, child, child->hasLayer());
   1032     child->moveAllChildrenTo(parent, nextSibling, child->hasLayer());
   1033     // Explicitly delete the child's line box tree, or the special anonymous
   1034     // block handling in willBeDestroyed will cause problems.
   1035     child->deleteLineBoxTree();
   1036     if (childFlowThread && childFlowThread->isRenderNamedFlowThread())
   1037         toRenderNamedFlowThread(childFlowThread)->removeFlowChildInfo(child);
   1038     child->destroy();
   1039 }
   1040 
   1041 void RenderBlock::removeChild(RenderObject* oldChild)
   1042 {
   1043     // No need to waste time in merging or removing empty anonymous blocks.
   1044     // We can just bail out if our document is getting destroyed.
   1045     if (documentBeingDestroyed()) {
   1046         RenderBox::removeChild(oldChild);
   1047         return;
   1048     }
   1049 
   1050     // This protects against column split flows when anonymous blocks are getting merged.
   1051     TemporaryChange<bool> columnFlowSplitEnabled(gColumnFlowSplitEnabled, false);
   1052 
   1053     // If this child is a block, and if our previous and next siblings are
   1054     // both anonymous blocks with inline content, then we can go ahead and
   1055     // fold the inline content back together.
   1056     RenderObject* prev = oldChild->previousSibling();
   1057     RenderObject* next = oldChild->nextSibling();
   1058     bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, prev, next);
   1059     if (canMergeAnonymousBlocks && prev && next) {
   1060         prev->setNeedsLayoutAndPrefWidthsRecalc();
   1061         RenderBlock* nextBlock = toRenderBlock(next);
   1062         RenderBlock* prevBlock = toRenderBlock(prev);
   1063 
   1064         if (prev->childrenInline() != next->childrenInline()) {
   1065             RenderBlock* inlineChildrenBlock = prev->childrenInline() ? prevBlock : nextBlock;
   1066             RenderBlock* blockChildrenBlock = prev->childrenInline() ? nextBlock : prevBlock;
   1067 
   1068             // Place the inline children block inside of the block children block instead of deleting it.
   1069             // In order to reuse it, we have to reset it to just be a generic anonymous block.  Make sure
   1070             // to clear out inherited column properties by just making a new style, and to also clear the
   1071             // column span flag if it is set.
   1072             ASSERT(!inlineChildrenBlock->continuation());
   1073             RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK);
   1074             // Cache this value as it might get changed in setStyle() call.
   1075             bool inlineChildrenBlockHasLayer = inlineChildrenBlock->hasLayer();
   1076             inlineChildrenBlock->setStyle(newStyle);
   1077             children()->removeChildNode(this, inlineChildrenBlock, inlineChildrenBlockHasLayer);
   1078 
   1079             // Now just put the inlineChildrenBlock inside the blockChildrenBlock.
   1080             blockChildrenBlock->children()->insertChildNode(blockChildrenBlock, inlineChildrenBlock, prev == inlineChildrenBlock ? blockChildrenBlock->firstChild() : 0,
   1081                                                             inlineChildrenBlockHasLayer || blockChildrenBlock->hasLayer());
   1082             next->setNeedsLayoutAndPrefWidthsRecalc();
   1083 
   1084             // inlineChildrenBlock got reparented to blockChildrenBlock, so it is no longer a child
   1085             // of "this". we null out prev or next so that is not used later in the function.
   1086             if (inlineChildrenBlock == prevBlock)
   1087                 prev = 0;
   1088             else
   1089                 next = 0;
   1090         } else {
   1091             // Take all the children out of the |next| block and put them in
   1092             // the |prev| block.
   1093             nextBlock->moveAllChildrenIncludingFloatsTo(prevBlock, nextBlock->hasLayer() || prevBlock->hasLayer());
   1094 
   1095             // Delete the now-empty block's lines and nuke it.
   1096             nextBlock->deleteLineBoxTree();
   1097             nextBlock->destroy();
   1098             next = 0;
   1099         }
   1100     }
   1101 
   1102     RenderBox::removeChild(oldChild);
   1103 
   1104     RenderObject* child = prev ? prev : next;
   1105     if (canMergeAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && canCollapseAnonymousBlockChild()) {
   1106         // The removal has knocked us down to containing only a single anonymous
   1107         // box.  We can go ahead and pull the content right back up into our
   1108         // box.
   1109         collapseAnonymousBlockChild(this, toRenderBlock(child));
   1110     } else if (((prev && prev->isAnonymousBlock()) || (next && next->isAnonymousBlock())) && canCollapseAnonymousBlockChild()) {
   1111         // It's possible that the removal has knocked us down to a single anonymous
   1112         // block with pseudo-style element siblings (e.g. first-letter). If these
   1113         // are floating, then we need to pull the content up also.
   1114         RenderBlock* anonymousBlock = toRenderBlock((prev && prev->isAnonymousBlock()) ? prev : next);
   1115         if ((anonymousBlock->previousSibling() || anonymousBlock->nextSibling())
   1116             && (!anonymousBlock->previousSibling() || (anonymousBlock->previousSibling()->style()->styleType() != NOPSEUDO && anonymousBlock->previousSibling()->isFloating() && !anonymousBlock->previousSibling()->previousSibling()))
   1117             && (!anonymousBlock->nextSibling() || (anonymousBlock->nextSibling()->style()->styleType() != NOPSEUDO && anonymousBlock->nextSibling()->isFloating() && !anonymousBlock->nextSibling()->nextSibling()))) {
   1118             collapseAnonymousBlockChild(this, anonymousBlock);
   1119         }
   1120     }
   1121 
   1122     if (!firstChild()) {
   1123         // If this was our last child be sure to clear out our line boxes.
   1124         if (childrenInline())
   1125             deleteLineBoxTree();
   1126 
   1127         // If we are an empty anonymous block in the continuation chain,
   1128         // we need to remove ourself and fix the continuation chain.
   1129         if (!beingDestroyed() && isAnonymousBlockContinuation() && !oldChild->isListMarker()) {
   1130             RenderObject* containingBlockIgnoringAnonymous = containingBlock();
   1131             while (containingBlockIgnoringAnonymous && containingBlockIgnoringAnonymous->isAnonymousBlock())
   1132                 containingBlockIgnoringAnonymous = containingBlockIgnoringAnonymous->containingBlock();
   1133             for (RenderObject* curr = this; curr; curr = curr->previousInPreOrder(containingBlockIgnoringAnonymous)) {
   1134                 if (curr->virtualContinuation() != this)
   1135                     continue;
   1136 
   1137                 // Found our previous continuation. We just need to point it to
   1138                 // |this|'s next continuation.
   1139                 RenderBoxModelObject* nextContinuation = continuation();
   1140                 if (curr->isRenderInline())
   1141                     toRenderInline(curr)->setContinuation(nextContinuation);
   1142                 else if (curr->isRenderBlock())
   1143                     toRenderBlock(curr)->setContinuation(nextContinuation);
   1144                 else
   1145                     ASSERT_NOT_REACHED();
   1146 
   1147                 break;
   1148             }
   1149             setContinuation(0);
   1150             destroy();
   1151         }
   1152     }
   1153 }
   1154 
   1155 bool RenderBlock::isSelfCollapsingBlock() const
   1156 {
   1157     // We are not self-collapsing if we
   1158     // (a) have a non-zero height according to layout (an optimization to avoid wasting time)
   1159     // (b) are a table,
   1160     // (c) have border/padding,
   1161     // (d) have a min-height
   1162     // (e) have specified that one of our margins can't collapse using a CSS extension
   1163     if (logicalHeight() > 0
   1164         || isTable() || borderAndPaddingLogicalHeight()
   1165         || style()->logicalMinHeight().isPositive()
   1166         || style()->marginBeforeCollapse() == MSEPARATE || style()->marginAfterCollapse() == MSEPARATE)
   1167         return false;
   1168 
   1169     Length logicalHeightLength = style()->logicalHeight();
   1170     bool hasAutoHeight = logicalHeightLength.isAuto();
   1171     if (logicalHeightLength.isPercent() && !document().inQuirksMode()) {
   1172         hasAutoHeight = true;
   1173         for (RenderBlock* cb = containingBlock(); !cb->isRenderView(); cb = cb->containingBlock()) {
   1174             if (cb->style()->logicalHeight().isFixed() || cb->isTableCell())
   1175                 hasAutoHeight = false;
   1176         }
   1177     }
   1178 
   1179     // If the height is 0 or auto, then whether or not we are a self-collapsing block depends
   1180     // on whether we have content that is all self-collapsing or not.
   1181     if (hasAutoHeight || ((logicalHeightLength.isFixed() || logicalHeightLength.isPercent()) && logicalHeightLength.isZero())) {
   1182         // If the block has inline children, see if we generated any line boxes.  If we have any
   1183         // line boxes, then we can't be self-collapsing, since we have content.
   1184         if (childrenInline())
   1185             return !firstLineBox();
   1186 
   1187         // Whether or not we collapse is dependent on whether all our normal flow children
   1188         // are also self-collapsing.
   1189         for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
   1190             if (child->isFloatingOrOutOfFlowPositioned())
   1191                 continue;
   1192             if (!child->isSelfCollapsingBlock())
   1193                 return false;
   1194         }
   1195         return true;
   1196     }
   1197     return false;
   1198 }
   1199 
   1200 void RenderBlock::startDelayUpdateScrollInfo()
   1201 {
   1202     if (gDelayUpdateScrollInfo == 0) {
   1203         ASSERT(!gDelayedUpdateScrollInfoSet);
   1204         gDelayedUpdateScrollInfoSet = new DelayedUpdateScrollInfoSet;
   1205     }
   1206     ASSERT(gDelayedUpdateScrollInfoSet);
   1207     ++gDelayUpdateScrollInfo;
   1208 }
   1209 
   1210 void RenderBlock::finishDelayUpdateScrollInfo()
   1211 {
   1212     --gDelayUpdateScrollInfo;
   1213     ASSERT(gDelayUpdateScrollInfo >= 0);
   1214     if (gDelayUpdateScrollInfo == 0) {
   1215         ASSERT(gDelayedUpdateScrollInfoSet);
   1216 
   1217         OwnPtr<DelayedUpdateScrollInfoSet> infoSet(adoptPtr(gDelayedUpdateScrollInfoSet));
   1218         gDelayedUpdateScrollInfoSet = 0;
   1219 
   1220         for (DelayedUpdateScrollInfoSet::iterator it = infoSet->begin(); it != infoSet->end(); ++it) {
   1221             RenderBlock* block = *it;
   1222             if (block->hasOverflowClip()) {
   1223                 block->layer()->scrollableArea()->updateAfterLayout();
   1224             }
   1225         }
   1226     }
   1227 }
   1228 
   1229 void RenderBlock::updateScrollInfoAfterLayout()
   1230 {
   1231     if (hasOverflowClip()) {
   1232         if (style()->isFlippedBlocksWritingMode()) {
   1233             // FIXME: https://bugs.webkit.org/show_bug.cgi?id=97937
   1234             // Workaround for now. We cannot delay the scroll info for overflow
   1235             // for items with opposite writing directions, as the contents needs
   1236             // to overflow in that direction
   1237             layer()->scrollableArea()->updateAfterLayout();
   1238             return;
   1239         }
   1240 
   1241         if (gDelayUpdateScrollInfo)
   1242             gDelayedUpdateScrollInfoSet->add(this);
   1243         else
   1244             layer()->scrollableArea()->updateAfterLayout();
   1245     }
   1246 }
   1247 
   1248 void RenderBlock::layout()
   1249 {
   1250     OverflowEventDispatcher dispatcher(this);
   1251     LayoutRectRecorder recorder(*this);
   1252 
   1253     // Update our first letter info now.
   1254     updateFirstLetter();
   1255 
   1256     // Table cells call layoutBlock directly, so don't add any logic here.  Put code into
   1257     // layoutBlock().
   1258     layoutBlock(false);
   1259 
   1260     if (frameView()->partialLayout().isStopping())
   1261         return;
   1262 
   1263     // It's safe to check for control clip here, since controls can never be table cells.
   1264     // If we have a lightweight clip, there can never be any overflow from children.
   1265     if (hasControlClip() && m_overflow)
   1266         clearLayoutOverflow();
   1267 
   1268     invalidateBackgroundObscurationStatus();
   1269 }
   1270 
   1271 void RenderBlock::didLayout(ResourceLoadPriorityOptimizer& optimizer)
   1272 {
   1273     RenderBox::didLayout(optimizer);
   1274     updateStyleImageLoadingPriorities(optimizer);
   1275 }
   1276 
   1277 void RenderBlock::didScroll(ResourceLoadPriorityOptimizer& optimizer)
   1278 {
   1279     RenderBox::didScroll(optimizer);
   1280     updateStyleImageLoadingPriorities(optimizer);
   1281 }
   1282 
   1283 void RenderBlock::updateStyleImageLoadingPriorities(ResourceLoadPriorityOptimizer& optimizer)
   1284 {
   1285     RenderStyle* blockStyle = style();
   1286     if (!blockStyle)
   1287         return;
   1288 
   1289     Vector<ImageResource*> images;
   1290 
   1291     appendLayers(images, blockStyle->backgroundLayers());
   1292     appendLayers(images, blockStyle->maskLayers());
   1293 
   1294     const ContentData* contentData = blockStyle->contentData();
   1295     if (contentData && contentData->isImage()) {
   1296         const ImageContentData* imageContentData = static_cast<const ImageContentData*>(contentData);
   1297         appendImageIfNotNull(images, imageContentData->image());
   1298     }
   1299     if (blockStyle->boxReflect())
   1300         appendImageIfNotNull(images, blockStyle->boxReflect()->mask().image());
   1301     appendImageIfNotNull(images, blockStyle->listStyleImage());
   1302     appendImageIfNotNull(images, blockStyle->borderImageSource());
   1303     appendImageIfNotNull(images, blockStyle->maskBoxImageSource());
   1304 
   1305     if (images.isEmpty())
   1306         return;
   1307 
   1308     LayoutRect viewBounds = viewRect();
   1309     LayoutRect objectBounds = absoluteContentBox();
   1310     // The object bounds might be empty right now, so intersects will fail since it doesn't deal
   1311     // with empty rects. Use LayoutRect::contains in that case.
   1312     bool isVisible;
   1313     if (!objectBounds.isEmpty())
   1314         isVisible =  viewBounds.intersects(objectBounds);
   1315     else
   1316         isVisible = viewBounds.contains(objectBounds);
   1317 
   1318     ResourceLoadPriorityOptimizer::VisibilityStatus status = isVisible ?
   1319         ResourceLoadPriorityOptimizer::Visible : ResourceLoadPriorityOptimizer::NotVisible;
   1320 
   1321     for (Vector<ImageResource*>::iterator it = images.begin(), end = images.end(); it != end; ++it)
   1322         optimizer.notifyImageResourceVisibility(*it, status);
   1323 }
   1324 
   1325 void RenderBlock::relayoutShapeDescendantIfMoved(RenderBlock* child, LayoutSize offset)
   1326 {
   1327     LayoutUnit left = isHorizontalWritingMode() ? offset.width() : offset.height();
   1328     if (!left || !child || child->shapeInsideInfo() || !layoutShapeInsideInfo())
   1329         return;
   1330     // Propagate layout markers only up to the child, as we are still in the middle
   1331     // of a layout pass
   1332     child->setNormalChildNeedsLayout(true);
   1333     child->markShapeInsideDescendantsForLayout();
   1334     child->layoutIfNeeded();
   1335 }
   1336 
   1337 ShapeInsideInfo* RenderBlock::layoutShapeInsideInfo() const
   1338 {
   1339     if (ShapeInsideInfo* shapeInsideInfo = view()->layoutState()->shapeInsideInfo())
   1340         return shapeInsideInfo;
   1341 
   1342     RenderFlowThread* flowThread = flowThreadContainingBlock();
   1343     if (allowsShapeInsideInfoSharing(flowThread)) {
   1344         LayoutUnit lineHeight = this->lineHeight(false, isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
   1345         // regionAtBlockOffset returns regions like an array first={0,N-1}, second={N,M-1}, ...
   1346         LayoutUnit offset = logicalHeight() + lineHeight - LayoutUnit(1);
   1347         RenderRegion* region = regionAtBlockOffset(offset);
   1348         if (region && region->logicalHeight())
   1349             return region->shapeInsideInfo();
   1350     }
   1351 
   1352     return 0;
   1353 }
   1354 
   1355 LayoutSize RenderBlock::logicalOffsetFromShapeAncestorContainer(const RenderBlock* container) const
   1356 {
   1357     const RenderBlock* currentBlock = this;
   1358     LayoutRect blockRect(currentBlock->borderBoxRect());
   1359     while (currentBlock && !currentBlock->isRenderFlowThread() && currentBlock != container) {
   1360         RenderBlock* containerBlock = currentBlock->containingBlock();
   1361         ASSERT(containerBlock);
   1362         if (!containerBlock)
   1363             return LayoutSize();
   1364 
   1365         if (containerBlock->style()->writingMode() != currentBlock->style()->writingMode()) {
   1366             // We have to put the block rect in container coordinates
   1367             // and we have to take into account both the container and current block flipping modes
   1368             // Bug: Flipping inline and block directions at the same time will not work,
   1369             // as one of the flipped dimensions will not yet have been set to its final size
   1370             if (containerBlock->style()->isFlippedBlocksWritingMode()) {
   1371                 if (containerBlock->isHorizontalWritingMode())
   1372                     blockRect.setY(currentBlock->height() - blockRect.maxY());
   1373                 else
   1374                     blockRect.setX(currentBlock->width() - blockRect.maxX());
   1375             }
   1376             currentBlock->flipForWritingMode(blockRect);
   1377         }
   1378 
   1379         blockRect.moveBy(currentBlock->location());
   1380         currentBlock = containerBlock;
   1381     }
   1382 
   1383     LayoutSize result = isHorizontalWritingMode() ? LayoutSize(blockRect.x(), blockRect.y()) : LayoutSize(blockRect.y(), blockRect.x());
   1384     return result;
   1385 }
   1386 
   1387 void RenderBlock::imageChanged(WrappedImagePtr image, const IntRect*)
   1388 {
   1389     RenderBox::imageChanged(image);
   1390 
   1391     if (!parent() || !everHadLayout())
   1392         return;
   1393 
   1394     ShapeValue* shapeValue = style()->shapeInside();
   1395     if (shapeValue && shapeValue->image() && shapeValue->image()->data() == image) {
   1396         ShapeInsideInfo* shapeInsideInfo = ensureShapeInsideInfo();
   1397         shapeInsideInfo->dirtyShapeSize();
   1398         markShapeInsideDescendantsForLayout();
   1399     }
   1400 
   1401     ShapeValue* shapeOutsideValue = style()->shapeOutside();
   1402     if (isFloating() && shapeOutsideValue && shapeOutsideValue->image() && shapeOutsideValue->image()->data() == image)
   1403         parent()->setNeedsLayoutAndPrefWidthsRecalc();
   1404 }
   1405 
   1406 void RenderBlock::updateShapeInsideInfoAfterStyleChange(const ShapeValue* shapeInside, const ShapeValue* oldShapeInside)
   1407 {
   1408     // FIXME: A future optimization would do a deep comparison for equality.
   1409     if (shapeInside == oldShapeInside)
   1410         return;
   1411 
   1412     if (shapeInside) {
   1413         ShapeInsideInfo* shapeInsideInfo = ensureShapeInsideInfo();
   1414         shapeInsideInfo->dirtyShapeSize();
   1415     } else {
   1416         setShapeInsideInfo(nullptr);
   1417         markShapeInsideDescendantsForLayout();
   1418     }
   1419 }
   1420 
   1421 static inline bool shapeInfoRequiresRelayout(const RenderBlock* block)
   1422 {
   1423     ShapeInsideInfo* info = block->shapeInsideInfo();
   1424     if (info)
   1425         info->setNeedsLayout(info->shapeSizeDirty());
   1426     else
   1427         info = block->layoutShapeInsideInfo();
   1428     return info && info->needsLayout();
   1429 }
   1430 
   1431 bool RenderBlock::updateRegionsAndShapesLogicalSize(RenderFlowThread* flowThread)
   1432 {
   1433     if (!flowThread && !shapeInsideInfo())
   1434         return shapeInfoRequiresRelayout(this);
   1435 
   1436     LayoutUnit oldHeight = logicalHeight();
   1437     LayoutUnit oldTop = logicalTop();
   1438 
   1439     // Compute the maximum logical height content may cause this block to expand to
   1440     // FIXME: These should eventually use the const computeLogicalHeight rather than updateLogicalHeight
   1441     setLogicalHeight(RenderFlowThread::maxLogicalHeight());
   1442     updateLogicalHeight();
   1443 
   1444     computeShapeSize();
   1445 
   1446     // Set our start and end regions. No regions above or below us will be considered by our children. They are
   1447     // effectively clamped to our region range.
   1448     computeRegionRangeForBlock(flowThread);
   1449 
   1450     setLogicalHeight(oldHeight);
   1451     setLogicalTop(oldTop);
   1452 
   1453     return shapeInfoRequiresRelayout(this);
   1454 }
   1455 
   1456 void RenderBlock::computeShapeSize()
   1457 {
   1458     ShapeInsideInfo* shapeInsideInfo = this->shapeInsideInfo();
   1459     if (!shapeInsideInfo)
   1460         return;
   1461 
   1462     if (isRenderNamedFlowFragment()) {
   1463         ShapeInsideInfo* parentShapeInsideInfo = toRenderBlock(parent())->shapeInsideInfo();
   1464         ASSERT(parentShapeInsideInfo);
   1465         shapeInsideInfo->setShapeSize(parentShapeInsideInfo->shapeSize().width(), parentShapeInsideInfo->shapeSize().height());
   1466     } else {
   1467         bool percentageLogicalHeightResolvable = percentageLogicalHeightIsResolvableFromBlock(this, false);
   1468         shapeInsideInfo->setShapeSize(logicalWidth(), percentageLogicalHeightResolvable ? logicalHeight() : LayoutUnit());
   1469     }
   1470 }
   1471 
   1472 void RenderBlock::updateRegionsAndShapesAfterChildLayout(RenderFlowThread* flowThread, bool heightChanged)
   1473 {
   1474     // A previous sibling has changed dimension, so we need to relayout the shape with the content
   1475     ShapeInsideInfo* shapeInsideInfo = layoutShapeInsideInfo();
   1476     if (heightChanged && shapeInsideInfo)
   1477         shapeInsideInfo->dirtyShapeSize();
   1478 
   1479     computeRegionRangeForBlock(flowThread);
   1480 }
   1481 
   1482 void RenderBlock::computeRegionRangeForBlock(RenderFlowThread* flowThread)
   1483 {
   1484     if (flowThread)
   1485         flowThread->setRegionRangeForBox(this, offsetFromLogicalTopOfFirstPage());
   1486 }
   1487 
   1488 bool RenderBlock::updateLogicalWidthAndColumnWidth()
   1489 {
   1490     LayoutUnit oldWidth = logicalWidth();
   1491     LayoutUnit oldColumnWidth = desiredColumnWidth();
   1492 
   1493     updateLogicalWidth();
   1494     calcColumnWidth();
   1495 
   1496     bool hasBorderOrPaddingLogicalWidthChanged = m_hasBorderOrPaddingLogicalWidthChanged;
   1497     m_hasBorderOrPaddingLogicalWidthChanged = false;
   1498 
   1499     return oldWidth != logicalWidth() || oldColumnWidth != desiredColumnWidth() || hasBorderOrPaddingLogicalWidthChanged;
   1500 }
   1501 
   1502 void RenderBlock::checkForPaginationLogicalHeightChange(LayoutUnit& pageLogicalHeight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight)
   1503 {
   1504     ColumnInfo* colInfo = columnInfo();
   1505     if (hasColumns()) {
   1506         if (!pageLogicalHeight) {
   1507             // We need to go ahead and set our explicit page height if one exists, so that we can
   1508             // avoid doing two layout passes.
   1509             updateLogicalHeight();
   1510             LayoutUnit columnHeight = contentLogicalHeight();
   1511             if (columnHeight > 0) {
   1512                 pageLogicalHeight = columnHeight;
   1513                 hasSpecifiedPageLogicalHeight = true;
   1514             }
   1515             setLogicalHeight(0);
   1516         }
   1517         if (colInfo->columnHeight() != pageLogicalHeight && everHadLayout()) {
   1518             colInfo->setColumnHeight(pageLogicalHeight);
   1519             pageLogicalHeightChanged = true;
   1520         }
   1521 
   1522         if (!hasSpecifiedPageLogicalHeight && !pageLogicalHeight)
   1523             colInfo->clearForcedBreaks();
   1524 
   1525         colInfo->setPaginationUnit(paginationUnit());
   1526     } else if (isRenderFlowThread()) {
   1527         pageLogicalHeight = 1; // This is just a hack to always make sure we have a page logical height.
   1528         pageLogicalHeightChanged = toRenderFlowThread(this)->pageLogicalSizeChanged();
   1529     }
   1530 }
   1531 
   1532 void RenderBlock::layoutBlock(bool, LayoutUnit)
   1533 {
   1534     ASSERT_NOT_REACHED();
   1535     clearNeedsLayout();
   1536 }
   1537 
   1538 void RenderBlock::addOverflowFromChildren()
   1539 {
   1540     if (!hasColumns()) {
   1541         if (childrenInline())
   1542             toRenderBlockFlow(this)->addOverflowFromInlineChildren();
   1543         else
   1544             addOverflowFromBlockChildren();
   1545     } else {
   1546         ColumnInfo* colInfo = columnInfo();
   1547         if (columnCount(colInfo)) {
   1548             LayoutRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1);
   1549             addLayoutOverflow(lastRect);
   1550             addContentsVisualOverflow(lastRect);
   1551         }
   1552     }
   1553 }
   1554 
   1555 void RenderBlock::computeOverflow(LayoutUnit oldClientAfterEdge, bool)
   1556 {
   1557     m_overflow.clear();
   1558 
   1559     // Add overflow from children.
   1560     addOverflowFromChildren();
   1561 
   1562     // Add in the overflow from positioned objects.
   1563     addOverflowFromPositionedObjects();
   1564 
   1565     if (hasOverflowClip()) {
   1566         // When we have overflow clip, propagate the original spillout since it will include collapsed bottom margins
   1567         // and bottom padding.  Set the axis we don't care about to be 1, since we want this overflow to always
   1568         // be considered reachable.
   1569         LayoutRect clientRect(noOverflowRect());
   1570         LayoutRect rectToApply;
   1571         if (isHorizontalWritingMode())
   1572             rectToApply = LayoutRect(clientRect.x(), clientRect.y(), 1, max<LayoutUnit>(0, oldClientAfterEdge - clientRect.y()));
   1573         else
   1574             rectToApply = LayoutRect(clientRect.x(), clientRect.y(), max<LayoutUnit>(0, oldClientAfterEdge - clientRect.x()), 1);
   1575         addLayoutOverflow(rectToApply);
   1576         if (hasRenderOverflow())
   1577             m_overflow->setLayoutClientAfterEdge(oldClientAfterEdge);
   1578     }
   1579 
   1580     // Add visual overflow from box-shadow and border-image-outset.
   1581     addVisualEffectOverflow();
   1582 
   1583     // Add visual overflow from theme.
   1584     addVisualOverflowFromTheme();
   1585 
   1586     if (isRenderNamedFlowThread())
   1587         toRenderNamedFlowThread(this)->computeOversetStateForRegions(oldClientAfterEdge);
   1588 }
   1589 
   1590 void RenderBlock::addOverflowFromBlockChildren()
   1591 {
   1592     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
   1593         if (!child->isFloatingOrOutOfFlowPositioned())
   1594             addOverflowFromChild(child);
   1595     }
   1596 }
   1597 
   1598 void RenderBlock::addOverflowFromPositionedObjects()
   1599 {
   1600     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
   1601     if (!positionedDescendants)
   1602         return;
   1603 
   1604     RenderBox* positionedObject;
   1605     TrackedRendererListHashSet::iterator end = positionedDescendants->end();
   1606     for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
   1607         positionedObject = *it;
   1608 
   1609         // Fixed positioned elements don't contribute to layout overflow, since they don't scroll with the content.
   1610         if (positionedObject->style()->position() != FixedPosition)
   1611             addOverflowFromChild(positionedObject, LayoutSize(positionedObject->x(), positionedObject->y()));
   1612     }
   1613 }
   1614 
   1615 void RenderBlock::addVisualOverflowFromTheme()
   1616 {
   1617     if (!style()->hasAppearance())
   1618         return;
   1619 
   1620     IntRect inflatedRect = pixelSnappedBorderBoxRect();
   1621     RenderTheme::theme().adjustRepaintRect(this, inflatedRect);
   1622     addVisualOverflow(inflatedRect);
   1623 }
   1624 
   1625 bool RenderBlock::expandsToEncloseOverhangingFloats() const
   1626 {
   1627     return isInlineBlockOrInlineTable() || isFloatingOrOutOfFlowPositioned() || hasOverflowClip() || (parent() && parent()->isFlexibleBoxIncludingDeprecated())
   1628            || hasColumns() || isTableCell() || isTableCaption() || isFieldset() || isWritingModeRoot() || isRoot();
   1629 }
   1630 
   1631 LayoutUnit RenderBlock::computeStartPositionDeltaForChildAvoidingFloats(const RenderBox* child, LayoutUnit childMarginStart, RenderRegion* region)
   1632 {
   1633     LayoutUnit startPosition = startOffsetForContent(region);
   1634 
   1635     // Add in our start margin.
   1636     LayoutUnit oldPosition = startPosition + childMarginStart;
   1637     LayoutUnit newPosition = oldPosition;
   1638 
   1639     LayoutUnit blockOffset = logicalTopForChild(child);
   1640     if (region)
   1641         blockOffset = max(blockOffset, blockOffset + (region->logicalTopForFlowThreadContent() - offsetFromLogicalTopOfFirstPage()));
   1642 
   1643     LayoutUnit startOff = startOffsetForLineInRegion(blockOffset, false, region, logicalHeightForChild(child));
   1644 
   1645     if (style()->textAlign() != WEBKIT_CENTER && !child->style()->marginStartUsing(style()).isAuto()) {
   1646         if (childMarginStart < 0)
   1647             startOff += childMarginStart;
   1648         newPosition = max(newPosition, startOff); // Let the float sit in the child's margin if it can fit.
   1649     } else if (startOff != startPosition)
   1650         newPosition = startOff + childMarginStart;
   1651 
   1652     return newPosition - oldPosition;
   1653 }
   1654 
   1655 void RenderBlock::determineLogicalLeftPositionForChild(RenderBox* child, ApplyLayoutDeltaMode applyDelta)
   1656 {
   1657     LayoutUnit startPosition = borderStart() + paddingStart();
   1658     if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
   1659         startPosition -= verticalScrollbarWidth();
   1660     LayoutUnit totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + availableLogicalWidth();
   1661 
   1662     // Add in our start margin.
   1663     LayoutUnit childMarginStart = marginStartForChild(child);
   1664     LayoutUnit newPosition = startPosition + childMarginStart;
   1665 
   1666     // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats.  They need
   1667     // to shift over as necessary to dodge any floats that might get in the way.
   1668     if (child->avoidsFloats() && containsFloats() && !flowThreadContainingBlock())
   1669         newPosition += computeStartPositionDeltaForChildAvoidingFloats(child, marginStartForChild(child));
   1670 
   1671     setLogicalLeftForChild(child, style()->isLeftToRightDirection() ? newPosition : totalAvailableLogicalWidth - newPosition - logicalWidthForChild(child), applyDelta);
   1672 }
   1673 
   1674 void RenderBlock::setLogicalLeftForChild(RenderBox* child, LayoutUnit logicalLeft, ApplyLayoutDeltaMode applyDelta)
   1675 {
   1676     if (isHorizontalWritingMode()) {
   1677         if (applyDelta == ApplyLayoutDelta)
   1678             view()->addLayoutDelta(LayoutSize(child->x() - logicalLeft, 0));
   1679         child->setX(logicalLeft);
   1680     } else {
   1681         if (applyDelta == ApplyLayoutDelta)
   1682             view()->addLayoutDelta(LayoutSize(0, child->y() - logicalLeft));
   1683         child->setY(logicalLeft);
   1684     }
   1685 }
   1686 
   1687 void RenderBlock::setLogicalTopForChild(RenderBox* child, LayoutUnit logicalTop, ApplyLayoutDeltaMode applyDelta)
   1688 {
   1689     if (isHorizontalWritingMode()) {
   1690         if (applyDelta == ApplyLayoutDelta)
   1691             view()->addLayoutDelta(LayoutSize(0, child->y() - logicalTop));
   1692         child->setY(logicalTop);
   1693     } else {
   1694         if (applyDelta == ApplyLayoutDelta)
   1695             view()->addLayoutDelta(LayoutSize(child->x() - logicalTop, 0));
   1696         child->setX(logicalTop);
   1697     }
   1698 }
   1699 
   1700 void RenderBlock::updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, RenderBox* child)
   1701 {
   1702     // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into
   1703     // an auto value. Add a method to determine this, so that we can avoid the relayout.
   1704     if (relayoutChildren || (child->hasRelativeLogicalHeight() && !isRenderView()))
   1705         child->setChildNeedsLayout(MarkOnlyThis);
   1706 
   1707     // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.
   1708     if (relayoutChildren && child->needsPreferredWidthsRecalculation())
   1709         child->setPreferredLogicalWidthsDirty(MarkOnlyThis);
   1710 }
   1711 
   1712 void RenderBlock::simplifiedNormalFlowLayout()
   1713 {
   1714     if (childrenInline()) {
   1715         ListHashSet<RootInlineBox*> lineBoxes;
   1716         for (InlineWalker walker(this); !walker.atEnd(); walker.advance()) {
   1717             RenderObject* o = walker.current();
   1718             if (!o->isOutOfFlowPositioned() && (o->isReplaced() || o->isFloating())) {
   1719                 o->layoutIfNeeded();
   1720                 if (toRenderBox(o)->inlineBoxWrapper()) {
   1721                     RootInlineBox* box = toRenderBox(o)->inlineBoxWrapper()->root();
   1722                     lineBoxes.add(box);
   1723                 }
   1724             } else if (o->isText() || (o->isRenderInline() && !walker.atEndOfInline())) {
   1725                 o->clearNeedsLayout();
   1726             }
   1727         }
   1728 
   1729         // FIXME: Glyph overflow will get lost in this case, but not really a big deal.
   1730         GlyphOverflowAndFallbackFontsMap textBoxDataMap;
   1731         for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it != lineBoxes.end(); ++it) {
   1732             RootInlineBox* box = *it;
   1733             box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap);
   1734         }
   1735     } else {
   1736         for (RenderBox* box = firstChildBox(); box; box = box->nextSiblingBox()) {
   1737             if (!box->isOutOfFlowPositioned())
   1738                 box->layoutIfNeeded();
   1739         }
   1740     }
   1741 }
   1742 
   1743 bool RenderBlock::simplifiedLayout()
   1744 {
   1745     if ((!posChildNeedsLayout() && !needsSimplifiedNormalFlowLayout()) || normalChildNeedsLayout() || selfNeedsLayout())
   1746         return false;
   1747 
   1748     LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
   1749 
   1750     if (needsPositionedMovementLayout() && !tryLayoutDoingPositionedMovementOnly())
   1751         return false;
   1752 
   1753     // Lay out positioned descendants or objects that just need to recompute overflow.
   1754     if (needsSimplifiedNormalFlowLayout())
   1755         simplifiedNormalFlowLayout();
   1756 
   1757     // Make sure a forced break is applied after the content if we are a flow thread in a simplified layout.
   1758     // This ensures the size information is correctly computed for the last auto-height region receiving content.
   1759     if (isRenderFlowThread())
   1760         toRenderFlowThread(this)->applyBreakAfterContent(clientLogicalBottom());
   1761 
   1762     // Lay out our positioned objects if our positioned child bit is set.
   1763     // Also, if an absolute position element inside a relative positioned container moves, and the absolute element has a fixed position
   1764     // child, neither the fixed element nor its container learn of the movement since posChildNeedsLayout() is only marked as far as the
   1765     // relative positioned container. So if we can have fixed pos objects in our positioned objects list check if any of them
   1766     // are statically positioned and thus need to move with their absolute ancestors.
   1767     bool canContainFixedPosObjects = canContainFixedPositionObjects();
   1768     if (posChildNeedsLayout() || canContainFixedPosObjects)
   1769         layoutPositionedObjects(false, !posChildNeedsLayout() && canContainFixedPosObjects);
   1770 
   1771     // Recompute our overflow information.
   1772     // FIXME: We could do better here by computing a temporary overflow object from layoutPositionedObjects and only
   1773     // updating our overflow if we either used to have overflow or if the new temporary object has overflow.
   1774     // For now just always recompute overflow.  This is no worse performance-wise than the old code that called rightmostPosition and
   1775     // lowestPosition on every relayout so it's not a regression.
   1776     // computeOverflow expects the bottom edge before we clamp our height. Since this information isn't available during
   1777     // simplifiedLayout, we cache the value in m_overflow.
   1778     LayoutUnit oldClientAfterEdge = hasRenderOverflow() ? m_overflow->layoutClientAfterEdge() : clientLogicalBottom();
   1779     computeOverflow(oldClientAfterEdge, true);
   1780 
   1781     statePusher.pop();
   1782 
   1783     updateLayerTransform();
   1784 
   1785     updateScrollInfoAfterLayout();
   1786 
   1787     clearNeedsLayout();
   1788     return true;
   1789 }
   1790 
   1791 void RenderBlock::markFixedPositionObjectForLayoutIfNeeded(RenderObject* child, SubtreeLayoutScope& layoutScope)
   1792 {
   1793     if (child->style()->position() != FixedPosition)
   1794         return;
   1795 
   1796     bool hasStaticBlockPosition = child->style()->hasStaticBlockPosition(isHorizontalWritingMode());
   1797     bool hasStaticInlinePosition = child->style()->hasStaticInlinePosition(isHorizontalWritingMode());
   1798     if (!hasStaticBlockPosition && !hasStaticInlinePosition)
   1799         return;
   1800 
   1801     RenderObject* o = child->parent();
   1802     while (o && !o->isRenderView() && o->style()->position() != AbsolutePosition)
   1803         o = o->parent();
   1804     if (o->style()->position() != AbsolutePosition)
   1805         return;
   1806 
   1807     RenderBox* box = toRenderBox(child);
   1808     if (hasStaticInlinePosition) {
   1809         LayoutUnit oldLeft = box->logicalLeft();
   1810         box->updateLogicalWidth();
   1811         if (box->logicalLeft() != oldLeft)
   1812             layoutScope.setChildNeedsLayout(child);
   1813     } else if (hasStaticBlockPosition) {
   1814         LayoutUnit oldTop = box->logicalTop();
   1815         box->updateLogicalHeight();
   1816         if (box->logicalTop() != oldTop)
   1817             layoutScope.setChildNeedsLayout(child);
   1818     }
   1819 }
   1820 
   1821 LayoutUnit RenderBlock::marginIntrinsicLogicalWidthForChild(RenderBox* child) const
   1822 {
   1823     // A margin has three types: fixed, percentage, and auto (variable).
   1824     // Auto and percentage margins become 0 when computing min/max width.
   1825     // Fixed margins can be added in as is.
   1826     Length marginLeft = child->style()->marginStartUsing(style());
   1827     Length marginRight = child->style()->marginEndUsing(style());
   1828     LayoutUnit margin = 0;
   1829     if (marginLeft.isFixed())
   1830         margin += marginLeft.value();
   1831     if (marginRight.isFixed())
   1832         margin += marginRight.value();
   1833     return margin;
   1834 }
   1835 
   1836 void RenderBlock::layoutPositionedObjects(bool relayoutChildren, bool fixedPositionObjectsOnly)
   1837 {
   1838     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
   1839     if (!positionedDescendants)
   1840         return;
   1841 
   1842     if (hasColumns())
   1843         view()->layoutState()->clearPaginationInformation(); // Positioned objects are not part of the column flow, so they don't paginate with the columns.
   1844 
   1845     RenderBox* r;
   1846     TrackedRendererListHashSet::iterator end = positionedDescendants->end();
   1847     for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
   1848         r = *it;
   1849 
   1850         SubtreeLayoutScope layoutScope(r);
   1851         // A fixed position element with an absolute positioned ancestor has no way of knowing if the latter has changed position. So
   1852         // 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.
   1853         // it has static position.
   1854         markFixedPositionObjectForLayoutIfNeeded(r, layoutScope);
   1855         if (fixedPositionObjectsOnly) {
   1856             r->layoutIfNeeded();
   1857             continue;
   1858         }
   1859 
   1860         // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the
   1861         // non-positioned block.  Rather than trying to detect all of these movement cases, we just always lay out positioned
   1862         // objects that are positioned implicitly like this.  Such objects are rare, and so in typical DHTML menu usage (where everything is
   1863         // positioned explicitly) this should not incur a performance penalty.
   1864         if (relayoutChildren || (r->style()->hasStaticBlockPosition(isHorizontalWritingMode()) && r->parent() != this))
   1865             layoutScope.setChildNeedsLayout(r);
   1866 
   1867         // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.
   1868         if (relayoutChildren && r->needsPreferredWidthsRecalculation())
   1869             r->setPreferredLogicalWidthsDirty(MarkOnlyThis);
   1870 
   1871         if (!r->needsLayout())
   1872             r->markForPaginationRelayoutIfNeeded(layoutScope);
   1873 
   1874         // 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
   1875         // and we hit the available width constraint, the layoutIfNeeded() will catch it and do a full layout.
   1876         if (r->needsPositionedMovementLayoutOnly() && r->tryLayoutDoingPositionedMovementOnly())
   1877             r->clearNeedsLayout();
   1878 
   1879         // If we are paginated or in a line grid, go ahead and compute a vertical position for our object now.
   1880         // If it's wrong we'll lay out again.
   1881         LayoutUnit oldLogicalTop = 0;
   1882         bool needsBlockDirectionLocationSetBeforeLayout = r->needsLayout() && view()->layoutState()->needsBlockDirectionLocationSetBeforeLayout();
   1883         if (needsBlockDirectionLocationSetBeforeLayout) {
   1884             if (isHorizontalWritingMode() == r->isHorizontalWritingMode())
   1885                 r->updateLogicalHeight();
   1886             else
   1887                 r->updateLogicalWidth();
   1888             oldLogicalTop = logicalTopForChild(r);
   1889         }
   1890 
   1891         r->layoutIfNeeded();
   1892 
   1893         // Lay out again if our estimate was wrong.
   1894         if (needsBlockDirectionLocationSetBeforeLayout && logicalTopForChild(r) != oldLogicalTop)
   1895             r->forceChildLayout();
   1896     }
   1897 
   1898     if (hasColumns())
   1899         view()->layoutState()->m_columnInfo = columnInfo(); // FIXME: Kind of gross. We just put this back into the layout state so that pop() will work.
   1900 }
   1901 
   1902 void RenderBlock::markPositionedObjectsForLayout()
   1903 {
   1904     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
   1905     if (positionedDescendants) {
   1906         RenderBox* r;
   1907         TrackedRendererListHashSet::iterator end = positionedDescendants->end();
   1908         for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
   1909             r = *it;
   1910             r->setChildNeedsLayout();
   1911         }
   1912     }
   1913 }
   1914 
   1915 void RenderBlock::markForPaginationRelayoutIfNeeded(SubtreeLayoutScope& layoutScope)
   1916 {
   1917     ASSERT(!needsLayout());
   1918     if (needsLayout())
   1919         return;
   1920 
   1921     if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(this, logicalTop()) != pageLogicalOffset()))
   1922         layoutScope.setChildNeedsLayout(this);
   1923 }
   1924 
   1925 void RenderBlock::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
   1926 {
   1927     ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this);
   1928 
   1929     LayoutPoint adjustedPaintOffset = paintOffset + location();
   1930 
   1931     PaintPhase phase = paintInfo.phase;
   1932 
   1933     // Check if we need to do anything at all.
   1934     // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
   1935     // paints the root's background.
   1936     if (!isRoot()) {
   1937         LayoutRect overflowBox = overflowRectForPaintRejection();
   1938         flipForWritingMode(overflowBox);
   1939         overflowBox.inflate(maximalOutlineSize(paintInfo.phase));
   1940         overflowBox.moveBy(adjustedPaintOffset);
   1941         if (!overflowBox.intersects(paintInfo.rect))
   1942             return;
   1943     }
   1944 
   1945     // There are some cases where not all clipped visual overflow is accounted for.
   1946     // FIXME: reduce the number of such cases.
   1947     ContentsClipBehavior contentsClipBehavior = ForceContentsClip;
   1948     if (hasOverflowClip() && !hasControlClip() && !(shouldPaintSelectionGaps() && phase == PaintPhaseForeground) && !hasCaret())
   1949         contentsClipBehavior = SkipContentsClipIfPossible;
   1950 
   1951     bool pushedClip = pushContentsClip(paintInfo, adjustedPaintOffset, contentsClipBehavior);
   1952     paintObject(paintInfo, adjustedPaintOffset);
   1953     if (pushedClip)
   1954         popContentsClip(paintInfo, phase, adjustedPaintOffset);
   1955 
   1956     // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
   1957     // z-index.  We paint after we painted the background/border, so that the scrollbars will
   1958     // sit above the background/border.
   1959     if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && paintInfo.shouldPaintWithinRoot(this) && !paintInfo.paintRootBackgroundOnly())
   1960         layer()->scrollableArea()->paintOverflowControls(paintInfo.context, roundedIntPoint(adjustedPaintOffset), paintInfo.rect, false /* paintingOverlayControls */);
   1961 }
   1962 
   1963 void RenderBlock::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
   1964 {
   1965     if (paintInfo.context->paintingDisabled())
   1966         return;
   1967 
   1968     const Color& ruleColor = resolveColor(CSSPropertyWebkitColumnRuleColor);
   1969     bool ruleTransparent = style()->columnRuleIsTransparent();
   1970     EBorderStyle ruleStyle = style()->columnRuleStyle();
   1971     LayoutUnit ruleThickness = style()->columnRuleWidth();
   1972     LayoutUnit colGap = columnGap();
   1973     bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent;
   1974     if (!renderRule)
   1975         return;
   1976 
   1977     ColumnInfo* colInfo = columnInfo();
   1978     unsigned colCount = columnCount(colInfo);
   1979 
   1980     bool antialias = shouldAntialiasLines(paintInfo.context);
   1981 
   1982     if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
   1983         bool leftToRight = style()->isLeftToRightDirection() ^ colInfo->progressionIsReversed();
   1984         LayoutUnit currLogicalLeftOffset = leftToRight ? LayoutUnit() : contentLogicalWidth();
   1985         LayoutUnit ruleAdd = logicalLeftOffsetForContent();
   1986         LayoutUnit ruleLogicalLeft = leftToRight ? LayoutUnit() : contentLogicalWidth();
   1987         LayoutUnit inlineDirectionSize = colInfo->desiredColumnWidth();
   1988         BoxSide boxSide = isHorizontalWritingMode()
   1989             ? leftToRight ? BSLeft : BSRight
   1990             : leftToRight ? BSTop : BSBottom;
   1991 
   1992         for (unsigned i = 0; i < colCount; i++) {
   1993             // Move to the next position.
   1994             if (leftToRight) {
   1995                 ruleLogicalLeft += inlineDirectionSize + colGap / 2;
   1996                 currLogicalLeftOffset += inlineDirectionSize + colGap;
   1997             } else {
   1998                 ruleLogicalLeft -= (inlineDirectionSize + colGap / 2);
   1999                 currLogicalLeftOffset -= (inlineDirectionSize + colGap);
   2000             }
   2001 
   2002             // Now paint the column rule.
   2003             if (i < colCount - 1) {
   2004                 LayoutUnit ruleLeft = isHorizontalWritingMode() ? paintOffset.x() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd : paintOffset.x() + borderLeft() + paddingLeft();
   2005                 LayoutUnit ruleRight = isHorizontalWritingMode() ? ruleLeft + ruleThickness : ruleLeft + contentWidth();
   2006                 LayoutUnit ruleTop = isHorizontalWritingMode() ? paintOffset.y() + borderTop() + paddingTop() : paintOffset.y() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd;
   2007                 LayoutUnit ruleBottom = isHorizontalWritingMode() ? ruleTop + contentHeight() : ruleTop + ruleThickness;
   2008                 IntRect pixelSnappedRuleRect = pixelSnappedIntRectFromEdges(ruleLeft, ruleTop, ruleRight, ruleBottom);
   2009                 drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
   2010             }
   2011 
   2012             ruleLogicalLeft = currLogicalLeftOffset;
   2013         }
   2014     } else {
   2015         bool topToBottom = !style()->isFlippedBlocksWritingMode() ^ colInfo->progressionIsReversed();
   2016         LayoutUnit ruleLeft = isHorizontalWritingMode()
   2017             ? borderLeft() + paddingLeft()
   2018             : colGap / 2 - colGap - ruleThickness / 2 + (!colInfo->progressionIsReversed() ? borderBefore() + paddingBefore() : borderAfter() + paddingAfter());
   2019         LayoutUnit ruleWidth = isHorizontalWritingMode() ? contentWidth() : ruleThickness;
   2020         LayoutUnit ruleTop = isHorizontalWritingMode()
   2021             ? colGap / 2 - colGap - ruleThickness / 2 + (!colInfo->progressionIsReversed() ? borderBefore() + paddingBefore() : borderAfter() + paddingAfter())
   2022             : borderStart() + paddingStart();
   2023         LayoutUnit ruleHeight = isHorizontalWritingMode() ? ruleThickness : contentHeight();
   2024         LayoutRect ruleRect(ruleLeft, ruleTop, ruleWidth, ruleHeight);
   2025 
   2026         if (!topToBottom) {
   2027             if (isHorizontalWritingMode())
   2028                 ruleRect.setY(height() - ruleRect.maxY());
   2029             else
   2030                 ruleRect.setX(width() - ruleRect.maxX());
   2031         }
   2032 
   2033         ruleRect.moveBy(paintOffset);
   2034 
   2035         BoxSide boxSide = isHorizontalWritingMode()
   2036             ? topToBottom ? BSTop : BSBottom
   2037             : topToBottom ? BSLeft : BSRight;
   2038 
   2039         LayoutSize step(0, topToBottom ? colInfo->columnHeight() + colGap : -(colInfo->columnHeight() + colGap));
   2040         if (!isHorizontalWritingMode())
   2041             step = step.transposedSize();
   2042 
   2043         for (unsigned i = 1; i < colCount; i++) {
   2044             ruleRect.move(step);
   2045             IntRect pixelSnappedRuleRect = pixelSnappedIntRect(ruleRect);
   2046             drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
   2047         }
   2048     }
   2049 }
   2050 
   2051 void RenderBlock::paintColumnContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset, bool paintingFloats)
   2052 {
   2053     // We need to do multiple passes, breaking up our child painting into strips.
   2054     GraphicsContext* context = paintInfo.context;
   2055     ColumnInfo* colInfo = columnInfo();
   2056     unsigned colCount = columnCount(colInfo);
   2057     if (!colCount)
   2058         return;
   2059     LayoutUnit currLogicalTopOffset = 0;
   2060     LayoutUnit colGap = columnGap();
   2061     for (unsigned i = 0; i < colCount; i++) {
   2062         // For each rect, we clip to the rect, and then we adjust our coords.
   2063         LayoutRect colRect = columnRectAt(colInfo, i);
   2064         flipForWritingMode(colRect);
   2065         LayoutUnit logicalLeftOffset = (isHorizontalWritingMode() ? colRect.x() : colRect.y()) - logicalLeftOffsetForContent();
   2066         LayoutSize offset = isHorizontalWritingMode() ? LayoutSize(logicalLeftOffset, currLogicalTopOffset) : LayoutSize(currLogicalTopOffset, logicalLeftOffset);
   2067         if (colInfo->progressionAxis() == ColumnInfo::BlockAxis) {
   2068             if (isHorizontalWritingMode())
   2069                 offset.expand(0, colRect.y() - borderTop() - paddingTop());
   2070             else
   2071                 offset.expand(colRect.x() - borderLeft() - paddingLeft(), 0);
   2072         }
   2073         colRect.moveBy(paintOffset);
   2074         PaintInfo info(paintInfo);
   2075         info.rect.intersect(pixelSnappedIntRect(colRect));
   2076 
   2077         if (!info.rect.isEmpty()) {
   2078             GraphicsContextStateSaver stateSaver(*context);
   2079             LayoutRect clipRect(colRect);
   2080 
   2081             if (i < colCount - 1) {
   2082                 if (isHorizontalWritingMode())
   2083                     clipRect.expand(colGap / 2, 0);
   2084                 else
   2085                     clipRect.expand(0, colGap / 2);
   2086             }
   2087             // Each strip pushes a clip, since column boxes are specified as being
   2088             // like overflow:hidden.
   2089             // FIXME: Content and column rules that extend outside column boxes at the edges of the multi-column element
   2090             // are clipped according to the 'overflow' property.
   2091             context->clip(pixelSnappedIntRect(clipRect));
   2092 
   2093             // Adjust our x and y when painting.
   2094             LayoutPoint adjustedPaintOffset = paintOffset + offset;
   2095             if (paintingFloats)
   2096                 paintFloats(info, adjustedPaintOffset, paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip);
   2097             else
   2098                 paintContents(info, adjustedPaintOffset);
   2099         }
   2100 
   2101         LayoutUnit blockDelta = (isHorizontalWritingMode() ? colRect.height() : colRect.width());
   2102         if (style()->isFlippedBlocksWritingMode())
   2103             currLogicalTopOffset += blockDelta;
   2104         else
   2105             currLogicalTopOffset -= blockDelta;
   2106     }
   2107 }
   2108 
   2109 void RenderBlock::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
   2110 {
   2111     // Avoid painting descendants of the root element when stylesheets haven't loaded.  This eliminates FOUC.
   2112     // It's ok not to draw, because later on, when all the stylesheets do load, styleResolverChanged() on the Document
   2113     // will do a full repaint.
   2114     if (document().didLayoutWithPendingStylesheets() && !isRenderView())
   2115         return;
   2116 
   2117     if (childrenInline())
   2118         m_lineBoxes.paint(this, paintInfo, paintOffset);
   2119     else {
   2120         PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase;
   2121         newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase;
   2122 
   2123         // We don't paint our own background, but we do let the kids paint their backgrounds.
   2124         PaintInfo paintInfoForChild(paintInfo);
   2125         paintInfoForChild.phase = newPhase;
   2126         paintInfoForChild.updatePaintingRootForChildren(this);
   2127         paintChildren(paintInfoForChild, paintOffset);
   2128     }
   2129 }
   2130 
   2131 void RenderBlock::paintChildren(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
   2132 {
   2133     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox())
   2134         paintChild(child, paintInfo, paintOffset);
   2135 }
   2136 
   2137 void RenderBlock::paintChild(RenderBox* child, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
   2138 {
   2139     LayoutPoint childPoint = flipForWritingModeForChild(child, paintOffset);
   2140     if (!child->hasSelfPaintingLayer() && !child->isFloating())
   2141         child->paint(paintInfo, childPoint);
   2142 }
   2143 
   2144 void RenderBlock::paintChildAsInlineBlock(RenderBox* child, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
   2145 {
   2146     LayoutPoint childPoint = flipForWritingModeForChild(child, paintOffset);
   2147     if (!child->hasSelfPaintingLayer() && !child->isFloating())
   2148         paintAsInlineBlock(child, paintInfo, childPoint);
   2149 }
   2150 
   2151 void RenderBlock::paintAsInlineBlock(RenderObject* renderer, PaintInfo& paintInfo, const LayoutPoint& childPoint)
   2152 {
   2153     if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection)
   2154         return;
   2155 
   2156     // Paint all phases atomically, as though the element established its own
   2157     // stacking context.  (See Appendix E.2, section 7.2.1.4 on
   2158     // inline block/table/replaced elements in the CSS2.1 specification.)
   2159     // This is also used by other elements (e.g. flex items and grid items).
   2160     bool preservePhase = paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip;
   2161     PaintInfo info(paintInfo);
   2162     info.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
   2163     renderer->paint(info, childPoint);
   2164     if (!preservePhase) {
   2165         info.phase = PaintPhaseChildBlockBackgrounds;
   2166         renderer->paint(info, childPoint);
   2167         info.phase = PaintPhaseFloat;
   2168         renderer->paint(info, childPoint);
   2169         info.phase = PaintPhaseForeground;
   2170         renderer->paint(info, childPoint);
   2171         info.phase = PaintPhaseOutline;
   2172         renderer->paint(info, childPoint);
   2173     }
   2174 }
   2175 
   2176 bool RenderBlock::hasCaret(CaretType type) const
   2177 {
   2178     // Paint the caret if the FrameSelection says so or if caret browsing is enabled
   2179     bool caretBrowsing = frame()->settings() && frame()->settings()->caretBrowsingEnabled();
   2180     RenderObject* caretPainter;
   2181     bool isContentEditable;
   2182     if (type == CursorCaret) {
   2183         caretPainter = frame()->selection().caretRenderer();
   2184         isContentEditable = frame()->selection().rendererIsEditable();
   2185     } else {
   2186         caretPainter = frame()->page()->dragCaretController().caretRenderer();
   2187         isContentEditable = frame()->page()->dragCaretController().isContentEditable();
   2188     }
   2189     return caretPainter == this && (isContentEditable || caretBrowsing);
   2190 }
   2191 
   2192 void RenderBlock::paintCaret(PaintInfo& paintInfo, const LayoutPoint& paintOffset, CaretType type)
   2193 {
   2194     if (!hasCaret(type))
   2195         return;
   2196 
   2197     if (type == CursorCaret)
   2198         frame()->selection().paintCaret(paintInfo.context, paintOffset, paintInfo.rect);
   2199     else
   2200         frame()->page()->dragCaretController().paintDragCaret(frame(), paintInfo.context, paintOffset, paintInfo.rect);
   2201 }
   2202 
   2203 void RenderBlock::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
   2204 {
   2205     PaintPhase paintPhase = paintInfo.phase;
   2206 
   2207     // Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div).
   2208     LayoutPoint scrolledOffset = paintOffset;
   2209     if (hasOverflowClip())
   2210         scrolledOffset.move(-scrolledContentOffset());
   2211 
   2212     // 1. paint background, borders etc
   2213     if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && style()->visibility() == VISIBLE) {
   2214         if (hasBoxDecorations())
   2215             paintBoxDecorations(paintInfo, paintOffset);
   2216         if (hasColumns() && !paintInfo.paintRootBackgroundOnly())
   2217             paintColumnRules(paintInfo, scrolledOffset);
   2218     }
   2219 
   2220     if (paintPhase == PaintPhaseMask && style()->visibility() == VISIBLE) {
   2221         paintMask(paintInfo, paintOffset);
   2222         return;
   2223     }
   2224 
   2225     if (paintPhase == PaintPhaseClippingMask && style()->visibility() == VISIBLE) {
   2226         paintClippingMask(paintInfo, paintOffset);
   2227         return;
   2228     }
   2229 
   2230     // We're done.  We don't bother painting any children.
   2231     if (paintPhase == PaintPhaseBlockBackground || paintInfo.paintRootBackgroundOnly())
   2232         return;
   2233 
   2234     // 2. paint contents
   2235     if (paintPhase != PaintPhaseSelfOutline) {
   2236         if (hasColumns())
   2237             paintColumnContents(paintInfo, scrolledOffset);
   2238         else
   2239             paintContents(paintInfo, scrolledOffset);
   2240     }
   2241 
   2242     // 3. paint selection
   2243     // FIXME: Make this work with multi column layouts.  For now don't fill gaps.
   2244     bool isPrinting = document().printing();
   2245     if (!isPrinting && !hasColumns())
   2246         paintSelection(paintInfo, scrolledOffset); // Fill in gaps in selection on lines and between blocks.
   2247 
   2248     // 4. paint floats.
   2249     if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip) {
   2250         if (hasColumns())
   2251             paintColumnContents(paintInfo, scrolledOffset, true);
   2252         else
   2253             paintFloats(paintInfo, scrolledOffset, paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip);
   2254     }
   2255 
   2256     // 5. paint outline.
   2257     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
   2258         paintOutline(paintInfo, LayoutRect(paintOffset, size()));
   2259 
   2260     // 6. paint continuation outlines.
   2261     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) {
   2262         RenderInline* inlineCont = inlineElementContinuation();
   2263         if (inlineCont && inlineCont->hasOutline() && inlineCont->style()->visibility() == VISIBLE) {
   2264             RenderInline* inlineRenderer = toRenderInline(inlineCont->node()->renderer());
   2265             RenderBlock* cb = containingBlock();
   2266 
   2267             bool inlineEnclosedInSelfPaintingLayer = false;
   2268             for (RenderBoxModelObject* box = inlineRenderer; box != cb; box = box->parent()->enclosingBoxModelObject()) {
   2269                 if (box->hasSelfPaintingLayer()) {
   2270                     inlineEnclosedInSelfPaintingLayer = true;
   2271                     break;
   2272                 }
   2273             }
   2274 
   2275             // Do not add continuations for outline painting by our containing block if we are a relative positioned
   2276             // 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
   2277             // in the same layer.
   2278             if (!inlineEnclosedInSelfPaintingLayer && !hasLayer())
   2279                 cb->addContinuationWithOutline(inlineRenderer);
   2280             else if (!inlineRenderer->firstLineBox() || (!inlineEnclosedInSelfPaintingLayer && hasLayer()))
   2281                 inlineRenderer->paintOutline(paintInfo, paintOffset - locationOffset() + inlineRenderer->containingBlock()->location());
   2282         }
   2283         paintContinuationOutlines(paintInfo, paintOffset);
   2284     }
   2285 
   2286     // 7. paint caret.
   2287     // If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground,
   2288     // then paint the caret.
   2289     if (paintPhase == PaintPhaseForeground) {
   2290         paintCaret(paintInfo, paintOffset, CursorCaret);
   2291         paintCaret(paintInfo, paintOffset, DragCaret);
   2292     }
   2293 }
   2294 
   2295 RenderInline* RenderBlock::inlineElementContinuation() const
   2296 {
   2297     RenderBoxModelObject* continuation = this->continuation();
   2298     return continuation && continuation->isInline() ? toRenderInline(continuation) : 0;
   2299 }
   2300 
   2301 RenderBlock* RenderBlock::blockElementContinuation() const
   2302 {
   2303     RenderBoxModelObject* currentContinuation = continuation();
   2304     if (!currentContinuation || currentContinuation->isInline())
   2305         return 0;
   2306     RenderBlock* nextContinuation = toRenderBlock(currentContinuation);
   2307     if (nextContinuation->isAnonymousBlock())
   2308         return nextContinuation->blockElementContinuation();
   2309     return nextContinuation;
   2310 }
   2311 
   2312 static ContinuationOutlineTableMap* continuationOutlineTable()
   2313 {
   2314     DEFINE_STATIC_LOCAL(ContinuationOutlineTableMap, table, ());
   2315     return &table;
   2316 }
   2317 
   2318 void RenderBlock::addContinuationWithOutline(RenderInline* flow)
   2319 {
   2320     // We can't make this work if the inline is in a layer.  We'll just rely on the broken
   2321     // way of painting.
   2322     ASSERT(!flow->layer() && !flow->isInlineElementContinuation());
   2323 
   2324     ContinuationOutlineTableMap* table = continuationOutlineTable();
   2325     ListHashSet<RenderInline*>* continuations = table->get(this);
   2326     if (!continuations) {
   2327         continuations = new ListHashSet<RenderInline*>;
   2328         table->set(this, adoptPtr(continuations));
   2329     }
   2330 
   2331     continuations->add(flow);
   2332 }
   2333 
   2334 bool RenderBlock::paintsContinuationOutline(RenderInline* flow)
   2335 {
   2336     ContinuationOutlineTableMap* table = continuationOutlineTable();
   2337     if (table->isEmpty())
   2338         return false;
   2339 
   2340     ListHashSet<RenderInline*>* continuations = table->get(this);
   2341     if (!continuations)
   2342         return false;
   2343 
   2344     return continuations->contains(flow);
   2345 }
   2346 
   2347 void RenderBlock::paintContinuationOutlines(PaintInfo& info, const LayoutPoint& paintOffset)
   2348 {
   2349     ContinuationOutlineTableMap* table = continuationOutlineTable();
   2350     if (table->isEmpty())
   2351         return;
   2352 
   2353     OwnPtr<ListHashSet<RenderInline*> > continuations = table->take(this);
   2354     if (!continuations)
   2355         return;
   2356 
   2357     LayoutPoint accumulatedPaintOffset = paintOffset;
   2358     // Paint each continuation outline.
   2359     ListHashSet<RenderInline*>::iterator end = continuations->end();
   2360     for (ListHashSet<RenderInline*>::iterator it = continuations->begin(); it != end; ++it) {
   2361         // Need to add in the coordinates of the intervening blocks.
   2362         RenderInline* flow = *it;
   2363         RenderBlock* block = flow->containingBlock();
   2364         for ( ; block && block != this; block = block->containingBlock())
   2365             accumulatedPaintOffset.moveBy(block->location());
   2366         ASSERT(block);
   2367         flow->paintOutline(info, accumulatedPaintOffset);
   2368     }
   2369 }
   2370 
   2371 bool RenderBlock::shouldPaintSelectionGaps() const
   2372 {
   2373     return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot();
   2374 }
   2375 
   2376 bool RenderBlock::isSelectionRoot() const
   2377 {
   2378     if (isPseudoElement())
   2379         return false;
   2380     ASSERT(node() || isAnonymous());
   2381 
   2382     // FIXME: Eventually tables should have to learn how to fill gaps between cells, at least in simple non-spanning cases.
   2383     if (isTable())
   2384         return false;
   2385 
   2386     if (isBody() || isRoot() || hasOverflowClip()
   2387         || isPositioned() || isFloating()
   2388         || isTableCell() || isInlineBlockOrInlineTable()
   2389         || hasTransform() || hasReflection() || hasMask() || isWritingModeRoot()
   2390         || isRenderFlowThread())
   2391         return true;
   2392 
   2393     if (view() && view()->selectionStart()) {
   2394         Node* startElement = view()->selectionStart()->node();
   2395         if (startElement && startElement->rootEditableElement() == node())
   2396             return true;
   2397     }
   2398 
   2399     return false;
   2400 }
   2401 
   2402 GapRects RenderBlock::selectionGapRectsForRepaint(const RenderLayerModelObject* repaintContainer)
   2403 {
   2404     ASSERT(!needsLayout());
   2405 
   2406     if (!shouldPaintSelectionGaps())
   2407         return GapRects();
   2408 
   2409     TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
   2410     mapLocalToContainer(repaintContainer, transformState, ApplyContainerFlip | UseTransforms);
   2411     LayoutPoint offsetFromRepaintContainer = roundedLayoutPoint(transformState.mappedPoint());
   2412 
   2413     if (hasOverflowClip())
   2414         offsetFromRepaintContainer -= scrolledContentOffset();
   2415 
   2416     LayoutUnit lastTop = 0;
   2417     LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop);
   2418     LayoutUnit lastRight = logicalRightSelectionOffset(this, lastTop);
   2419 
   2420     return selectionGaps(this, offsetFromRepaintContainer, IntSize(), lastTop, lastLeft, lastRight);
   2421 }
   2422 
   2423 void RenderBlock::paintSelection(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
   2424 {
   2425     if (shouldPaintSelectionGaps() && paintInfo.phase == PaintPhaseForeground) {
   2426         LayoutUnit lastTop = 0;
   2427         LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop);
   2428         LayoutUnit lastRight = logicalRightSelectionOffset(this, lastTop);
   2429         GraphicsContextStateSaver stateSaver(*paintInfo.context);
   2430 
   2431         LayoutRect gapRectsBounds = selectionGaps(this, paintOffset, LayoutSize(), lastTop, lastLeft, lastRight, &paintInfo);
   2432         if (!gapRectsBounds.isEmpty()) {
   2433             if (RenderLayer* layer = enclosingLayer()) {
   2434                 gapRectsBounds.moveBy(-paintOffset);
   2435                 if (!hasLayer()) {
   2436                     LayoutRect localBounds(gapRectsBounds);
   2437                     flipForWritingMode(localBounds);
   2438                     gapRectsBounds = localToContainerQuad(FloatRect(localBounds), layer->renderer()).enclosingBoundingBox();
   2439                     if (layer->renderer()->hasOverflowClip())
   2440                         gapRectsBounds.move(layer->renderBox()->scrolledContentOffset());
   2441                 }
   2442                 layer->addBlockSelectionGapsBounds(gapRectsBounds);
   2443             }
   2444         }
   2445     }
   2446 }
   2447 
   2448 static void clipOutPositionedObjects(const PaintInfo* paintInfo, const LayoutPoint& offset, TrackedRendererListHashSet* positionedObjects)
   2449 {
   2450     if (!positionedObjects)
   2451         return;
   2452 
   2453     TrackedRendererListHashSet::const_iterator end = positionedObjects->end();
   2454     for (TrackedRendererListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
   2455         RenderBox* r = *it;
   2456         paintInfo->context->clipOut(IntRect(offset.x() + r->x(), offset.y() + r->y(), r->width(), r->height()));
   2457     }
   2458 }
   2459 
   2460 LayoutUnit RenderBlock::blockDirectionOffset(const LayoutSize& offsetFromBlock) const
   2461 {
   2462     return isHorizontalWritingMode() ? offsetFromBlock.height() : offsetFromBlock.width();
   2463 }
   2464 
   2465 LayoutUnit RenderBlock::inlineDirectionOffset(const LayoutSize& offsetFromBlock) const
   2466 {
   2467     return isHorizontalWritingMode() ? offsetFromBlock.width() : offsetFromBlock.height();
   2468 }
   2469 
   2470 LayoutRect RenderBlock::logicalRectToPhysicalRect(const LayoutPoint& rootBlockPhysicalPosition, const LayoutRect& logicalRect)
   2471 {
   2472     LayoutRect result;
   2473     if (isHorizontalWritingMode())
   2474         result = logicalRect;
   2475     else
   2476         result = LayoutRect(logicalRect.y(), logicalRect.x(), logicalRect.height(), logicalRect.width());
   2477     flipForWritingMode(result);
   2478     result.moveBy(rootBlockPhysicalPosition);
   2479     return result;
   2480 }
   2481 
   2482 GapRects RenderBlock::selectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
   2483                                     LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* paintInfo)
   2484 {
   2485     // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore.
   2486     // Clip out floating and positioned objects when painting selection gaps.
   2487     if (paintInfo) {
   2488         // Note that we don't clip out overflow for positioned objects.  We just stick to the border box.
   2489         LayoutRect flippedBlockRect(offsetFromRootBlock.width(), offsetFromRootBlock.height(), width(), height());
   2490         rootBlock->flipForWritingMode(flippedBlockRect);
   2491         flippedBlockRect.moveBy(rootBlockPhysicalPosition);
   2492         clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), positionedObjects());
   2493         if (isBody() || isRoot()) // The <body> must make sure to examine its containingBlock's positioned objects.
   2494             for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock())
   2495                 clipOutPositionedObjects(paintInfo, LayoutPoint(cb->x(), cb->y()), cb->positionedObjects()); // FIXME: Not right for flipped writing modes.
   2496         clipOutFloatingObjects(rootBlock, paintInfo, rootBlockPhysicalPosition, offsetFromRootBlock);
   2497     }
   2498 
   2499     // 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
   2500     // fixed).
   2501     GapRects result;
   2502     if (!isRenderBlockFlow() && !isFlexibleBoxIncludingDeprecated()) // FIXME: Make multi-column selection gap filling work someday.
   2503         return result;
   2504 
   2505     if (hasColumns() || hasTransform() || style()->columnSpan()) {
   2506         // FIXME: We should learn how to gap fill multiple columns and transforms eventually.
   2507         lastLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) + logicalHeight();
   2508         lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight());
   2509         lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight());
   2510         return result;
   2511     }
   2512 
   2513     if (childrenInline())
   2514         result = toRenderBlockFlow(this)->inlineSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
   2515     else
   2516         result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo);
   2517 
   2518     // Go ahead and fill the vertical gap all the way to the bottom of our block if the selection extends past our block.
   2519     if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd))
   2520         result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
   2521                                              logicalHeight(), paintInfo));
   2522     return result;
   2523 }
   2524 
   2525 GapRects RenderBlock::blockSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
   2526                                          LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* paintInfo)
   2527 {
   2528     GapRects result;
   2529 
   2530     // Go ahead and jump right to the first block child that contains some selected objects.
   2531     RenderBox* curr;
   2532     for (curr = firstChildBox(); curr && curr->selectionState() == SelectionNone; curr = curr->nextSiblingBox()) { }
   2533 
   2534     for (bool sawSelectionEnd = false; curr && !sawSelectionEnd; curr = curr->nextSiblingBox()) {
   2535         SelectionState childState = curr->selectionState();
   2536         if (childState == SelectionBoth || childState == SelectionEnd)
   2537             sawSelectionEnd = true;
   2538 
   2539         if (curr->isFloatingOrOutOfFlowPositioned())
   2540             continue; // We must be a normal flow object in order to even be considered.
   2541 
   2542         if (curr->isInFlowPositioned() && curr->hasLayer()) {
   2543             // If the relposition offset is anything other than 0, then treat this just like an absolute positioned element.
   2544             // Just disregard it completely.
   2545             LayoutSize relOffset = curr->layer()->offsetForInFlowPosition();
   2546             if (relOffset.width() || relOffset.height())
   2547                 continue;
   2548         }
   2549 
   2550         bool paintsOwnSelection = curr->shouldPaintSelectionGaps() || curr->isTable(); // FIXME: Eventually we won't special-case table like this.
   2551         bool fillBlockGaps = paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone);
   2552         if (fillBlockGaps) {
   2553             // We need to fill the vertical gap above this object.
   2554             if (childState == SelectionEnd || childState == SelectionInside)
   2555                 // Fill the gap above the object.
   2556                 result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight,
   2557                                                      curr->logicalTop(), paintInfo));
   2558 
   2559             // 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*
   2560             // our object.  We know this if the selection did not end inside our object.
   2561             if (paintsOwnSelection && (childState == SelectionStart || sawSelectionEnd))
   2562                 childState = SelectionNone;
   2563 
   2564             // Fill side gaps on this object based off its state.
   2565             bool leftGap, rightGap;
   2566             getSelectionGapInfo(childState, leftGap, rightGap);
   2567 
   2568             if (leftGap)
   2569                 result.uniteLeft(logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalLeft(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
   2570             if (rightGap)
   2571                 result.uniteRight(logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, this, curr->logicalRight(), curr->logicalTop(), curr->logicalHeight(), paintInfo));
   2572 
   2573             // Update lastLogicalTop to be just underneath the object.  lastLogicalLeft and lastLogicalRight extend as far as
   2574             // they can without bumping into floating or positioned objects.  Ideally they will go right up
   2575             // to the border of the root selection block.
   2576             lastLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) + curr->logicalBottom();
   2577             lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, curr->logicalBottom());
   2578             lastLogicalRight = logicalRightSelectionOffset(rootBlock, curr->logicalBottom());
   2579         } else if (childState != SelectionNone)
   2580             // We must be a block that has some selected object inside it.  Go ahead and recur.
   2581             result.unite(toRenderBlock(curr)->selectionGaps(rootBlock, rootBlockPhysicalPosition, LayoutSize(offsetFromRootBlock.width() + curr->x(), offsetFromRootBlock.height() + curr->y()),
   2582                                                             lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo));
   2583     }
   2584     return result;
   2585 }
   2586 
   2587 LayoutRect RenderBlock::blockSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
   2588                                           LayoutUnit lastLogicalTop, LayoutUnit lastLogicalLeft, LayoutUnit lastLogicalRight, LayoutUnit logicalBottom, const PaintInfo* paintInfo)
   2589 {
   2590     LayoutUnit logicalTop = lastLogicalTop;
   2591     LayoutUnit logicalHeight = rootBlock->blockDirectionOffset(offsetFromRootBlock) + logicalBottom - logicalTop;
   2592     if (logicalHeight <= 0)
   2593         return LayoutRect();
   2594 
   2595     // Get the selection offsets for the bottom of the gap
   2596     LayoutUnit logicalLeft = max(lastLogicalLeft, logicalLeftSelectionOffset(rootBlock, logicalBottom));
   2597     LayoutUnit logicalRight = min(lastLogicalRight, logicalRightSelectionOffset(rootBlock, logicalBottom));
   2598     LayoutUnit logicalWidth = logicalRight - logicalLeft;
   2599     if (logicalWidth <= 0)
   2600         return LayoutRect();
   2601 
   2602     LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(logicalLeft, logicalTop, logicalWidth, logicalHeight));
   2603     if (paintInfo)
   2604         paintInfo->context->fillRect(pixelSnappedIntRect(gapRect), selectionBackgroundColor());
   2605     return gapRect;
   2606 }
   2607 
   2608 LayoutRect RenderBlock::logicalLeftSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
   2609                                                 RenderObject* selObj, LayoutUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo* paintInfo)
   2610 {
   2611     LayoutUnit rootBlockLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) + logicalTop;
   2612     LayoutUnit rootBlockLogicalLeft = max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight));
   2613     LayoutUnit rootBlockLogicalRight = min(rootBlock->inlineDirectionOffset(offsetFromRootBlock) + floorToInt(logicalLeft), min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight)));
   2614     LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
   2615     if (rootBlockLogicalWidth <= 0)
   2616         return LayoutRect();
   2617 
   2618     LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
   2619     if (paintInfo)
   2620         paintInfo->context->fillRect(pixelSnappedIntRect(gapRect), selObj->selectionBackgroundColor());
   2621     return gapRect;
   2622 }
   2623 
   2624 LayoutRect RenderBlock::logicalRightSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
   2625                                                  RenderObject* selObj, LayoutUnit logicalRight, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo* paintInfo)
   2626 {
   2627     LayoutUnit rootBlockLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) + logicalTop;
   2628     LayoutUnit rootBlockLogicalLeft = max(rootBlock->inlineDirectionOffset(offsetFromRootBlock) + floorToInt(logicalRight), max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight)));
   2629     LayoutUnit rootBlockLogicalRight = min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight));
   2630     LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft;
   2631     if (rootBlockLogicalWidth <= 0)
   2632         return LayoutRect();
   2633 
   2634     LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight));
   2635     if (paintInfo)
   2636         paintInfo->context->fillRect(pixelSnappedIntRect(gapRect), selObj->selectionBackgroundColor());
   2637     return gapRect;
   2638 }
   2639 
   2640 void RenderBlock::getSelectionGapInfo(SelectionState state, bool& leftGap, bool& rightGap)
   2641 {
   2642     bool ltr = style()->isLeftToRightDirection();
   2643     leftGap = (state == RenderObject::SelectionInside) ||
   2644               (state == RenderObject::SelectionEnd && ltr) ||
   2645               (state == RenderObject::SelectionStart && !ltr);
   2646     rightGap = (state == RenderObject::SelectionInside) ||
   2647                (state == RenderObject::SelectionStart && ltr) ||
   2648                (state == RenderObject::SelectionEnd && !ltr);
   2649 }
   2650 
   2651 LayoutUnit RenderBlock::logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position)
   2652 {
   2653     LayoutUnit logicalLeft = logicalLeftOffsetForLine(position, false);
   2654     if (logicalLeft == logicalLeftOffsetForContent()) {
   2655         if (rootBlock != this)
   2656             // The border can potentially be further extended by our containingBlock().
   2657             return containingBlock()->logicalLeftSelectionOffset(rootBlock, position + logicalTop());
   2658         return logicalLeft;
   2659     } else {
   2660         RenderBlock* cb = this;
   2661         while (cb != rootBlock) {
   2662             logicalLeft += cb->logicalLeft();
   2663             cb = cb->containingBlock();
   2664         }
   2665     }
   2666     return logicalLeft;
   2667 }
   2668 
   2669 LayoutUnit RenderBlock::logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position)
   2670 {
   2671     LayoutUnit logicalRight = logicalRightOffsetForLine(position, false);
   2672     if (logicalRight == logicalRightOffsetForContent()) {
   2673         if (rootBlock != this)
   2674             // The border can potentially be further extended by our containingBlock().
   2675             return containingBlock()->logicalRightSelectionOffset(rootBlock, position + logicalTop());
   2676         return logicalRight;
   2677     } else {
   2678         RenderBlock* cb = this;
   2679         while (cb != rootBlock) {
   2680             logicalRight += cb->logicalLeft();
   2681             cb = cb->containingBlock();
   2682         }
   2683     }
   2684     return logicalRight;
   2685 }
   2686 
   2687 RenderBlock* RenderBlock::blockBeforeWithinSelectionRoot(LayoutSize& offset) const
   2688 {
   2689     if (isSelectionRoot())
   2690         return 0;
   2691 
   2692     const RenderObject* object = this;
   2693     RenderObject* sibling;
   2694     do {
   2695         sibling = object->previousSibling();
   2696         while (sibling && (!sibling->isRenderBlock() || toRenderBlock(sibling)->isSelectionRoot()))
   2697             sibling = sibling->previousSibling();
   2698 
   2699         offset -= LayoutSize(toRenderBlock(object)->logicalLeft(), toRenderBlock(object)->logicalTop());
   2700         object = object->parent();
   2701     } while (!sibling && object && object->isRenderBlock() && !toRenderBlock(object)->isSelectionRoot());
   2702 
   2703     if (!sibling)
   2704         return 0;
   2705 
   2706     RenderBlock* beforeBlock = toRenderBlock(sibling);
   2707 
   2708     offset += LayoutSize(beforeBlock->logicalLeft(), beforeBlock->logicalTop());
   2709 
   2710     RenderObject* child = beforeBlock->lastChild();
   2711     while (child && child->isRenderBlock()) {
   2712         beforeBlock = toRenderBlock(child);
   2713         offset += LayoutSize(beforeBlock->logicalLeft(), beforeBlock->logicalTop());
   2714         child = beforeBlock->lastChild();
   2715     }
   2716     return beforeBlock;
   2717 }
   2718 
   2719 void RenderBlock::insertIntoTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*& descendantsMap, TrackedContainerMap*& containerMap)
   2720 {
   2721     if (!descendantsMap) {
   2722         descendantsMap = new TrackedDescendantsMap;
   2723         containerMap = new TrackedContainerMap;
   2724     }
   2725 
   2726     TrackedRendererListHashSet* descendantSet = descendantsMap->get(this);
   2727     if (!descendantSet) {
   2728         descendantSet = new TrackedRendererListHashSet;
   2729         descendantsMap->set(this, adoptPtr(descendantSet));
   2730     }
   2731     bool added = descendantSet->add(descendant).isNewEntry;
   2732     if (!added) {
   2733         ASSERT(containerMap->get(descendant));
   2734         ASSERT(containerMap->get(descendant)->contains(this));
   2735         return;
   2736     }
   2737 
   2738     HashSet<RenderBlock*>* containerSet = containerMap->get(descendant);
   2739     if (!containerSet) {
   2740         containerSet = new HashSet<RenderBlock*>;
   2741         containerMap->set(descendant, adoptPtr(containerSet));
   2742     }
   2743     ASSERT(!containerSet->contains(this));
   2744     containerSet->add(this);
   2745 }
   2746 
   2747 void RenderBlock::removeFromTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*& descendantsMap, TrackedContainerMap*& containerMap)
   2748 {
   2749     if (!descendantsMap)
   2750         return;
   2751 
   2752     OwnPtr<HashSet<RenderBlock*> > containerSet = containerMap->take(descendant);
   2753     if (!containerSet)
   2754         return;
   2755 
   2756     HashSet<RenderBlock*>::iterator end = containerSet->end();
   2757     for (HashSet<RenderBlock*>::iterator it = containerSet->begin(); it != end; ++it) {
   2758         RenderBlock* container = *it;
   2759 
   2760         // FIXME: Disabling this assert temporarily until we fix the layout
   2761         // bugs associated with positioned objects not properly cleared from
   2762         // their ancestor chain before being moved. See webkit bug 93766.
   2763         // ASSERT(descendant->isDescendantOf(container));
   2764 
   2765         TrackedDescendantsMap::iterator descendantsMapIterator = descendantsMap->find(container);
   2766         ASSERT(descendantsMapIterator != descendantsMap->end());
   2767         if (descendantsMapIterator == descendantsMap->end())
   2768             continue;
   2769         TrackedRendererListHashSet* descendantSet = descendantsMapIterator->value.get();
   2770         ASSERT(descendantSet->contains(descendant));
   2771         descendantSet->remove(descendant);
   2772         if (descendantSet->isEmpty())
   2773             descendantsMap->remove(descendantsMapIterator);
   2774     }
   2775 }
   2776 
   2777 TrackedRendererListHashSet* RenderBlock::positionedObjects() const
   2778 {
   2779     if (gPositionedDescendantsMap)
   2780         return gPositionedDescendantsMap->get(this);
   2781     return 0;
   2782 }
   2783 
   2784 void RenderBlock::insertPositionedObject(RenderBox* o)
   2785 {
   2786     ASSERT(!isAnonymousBlock());
   2787 
   2788     if (o->isRenderFlowThread())
   2789         return;
   2790 
   2791     insertIntoTrackedRendererMaps(o, gPositionedDescendantsMap, gPositionedContainerMap);
   2792 }
   2793 
   2794 void RenderBlock::removePositionedObject(RenderBox* o)
   2795 {
   2796     removeFromTrackedRendererMaps(o, gPositionedDescendantsMap, gPositionedContainerMap);
   2797 }
   2798 
   2799 void RenderBlock::removePositionedObjects(RenderBlock* o, ContainingBlockState containingBlockState)
   2800 {
   2801     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
   2802     if (!positionedDescendants)
   2803         return;
   2804 
   2805     RenderBox* r;
   2806 
   2807     TrackedRendererListHashSet::iterator end = positionedDescendants->end();
   2808 
   2809     Vector<RenderBox*, 16> deadObjects;
   2810 
   2811     for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
   2812         r = *it;
   2813         if (!o || r->isDescendantOf(o)) {
   2814             if (containingBlockState == NewContainingBlock)
   2815                 r->setChildNeedsLayout(MarkOnlyThis);
   2816 
   2817             // It is parent blocks job to add positioned child to positioned objects list of its containing block
   2818             // Parent layout needs to be invalidated to ensure this happens.
   2819             RenderObject* p = r->parent();
   2820             while (p && !p->isRenderBlock())
   2821                 p = p->parent();
   2822             if (p)
   2823                 p->setChildNeedsLayout();
   2824 
   2825             deadObjects.append(r);
   2826         }
   2827     }
   2828 
   2829     for (unsigned i = 0; i < deadObjects.size(); i++)
   2830         removePositionedObject(deadObjects.at(i));
   2831 }
   2832 
   2833 void RenderBlock::addPercentHeightDescendant(RenderBox* descendant)
   2834 {
   2835     insertIntoTrackedRendererMaps(descendant, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
   2836 }
   2837 
   2838 void RenderBlock::removePercentHeightDescendant(RenderBox* descendant)
   2839 {
   2840     removeFromTrackedRendererMaps(descendant, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
   2841 }
   2842 
   2843 TrackedRendererListHashSet* RenderBlock::percentHeightDescendants() const
   2844 {
   2845     return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0;
   2846 }
   2847 
   2848 bool RenderBlock::hasPercentHeightContainerMap()
   2849 {
   2850     return gPercentHeightContainerMap;
   2851 }
   2852 
   2853 bool RenderBlock::hasPercentHeightDescendant(RenderBox* descendant)
   2854 {
   2855     // We don't null check gPercentHeightContainerMap since the caller
   2856     // already ensures this and we need to call this function on every
   2857     // descendant in clearPercentHeightDescendantsFrom().
   2858     ASSERT(gPercentHeightContainerMap);
   2859     return gPercentHeightContainerMap->contains(descendant);
   2860 }
   2861 
   2862 void RenderBlock::dirtyForLayoutFromPercentageHeightDescendants(SubtreeLayoutScope& layoutScope)
   2863 {
   2864     if (!gPercentHeightDescendantsMap)
   2865         return;
   2866 
   2867     TrackedRendererListHashSet* descendants = gPercentHeightDescendantsMap->get(this);
   2868     if (!descendants)
   2869         return;
   2870 
   2871     TrackedRendererListHashSet::iterator end = descendants->end();
   2872     for (TrackedRendererListHashSet::iterator it = descendants->begin(); it != end; ++it) {
   2873         RenderBox* box = *it;
   2874         while (box != this) {
   2875             if (box->normalChildNeedsLayout())
   2876                 break;
   2877             layoutScope.setChildNeedsLayout(box);
   2878             box = box->containingBlock();
   2879             ASSERT(box);
   2880             if (!box)
   2881                 break;
   2882         }
   2883     }
   2884 }
   2885 
   2886 void RenderBlock::removePercentHeightDescendantIfNeeded(RenderBox* descendant)
   2887 {
   2888     // We query the map directly, rather than looking at style's
   2889     // logicalHeight()/logicalMinHeight()/logicalMaxHeight() since those
   2890     // can change with writing mode/directional changes.
   2891     if (!hasPercentHeightContainerMap())
   2892         return;
   2893 
   2894     if (!hasPercentHeightDescendant(descendant))
   2895         return;
   2896 
   2897     removePercentHeightDescendant(descendant);
   2898 }
   2899 
   2900 void RenderBlock::clearPercentHeightDescendantsFrom(RenderBox* parent)
   2901 {
   2902     ASSERT(gPercentHeightContainerMap);
   2903     for (RenderObject* curr = parent->firstChild(); curr; curr = curr->nextInPreOrder(parent)) {
   2904         if (!curr->isBox())
   2905             continue;
   2906 
   2907         RenderBox* box = toRenderBox(curr);
   2908         if (!hasPercentHeightDescendant(box))
   2909             continue;
   2910 
   2911         removePercentHeightDescendant(box);
   2912     }
   2913 }
   2914 
   2915 LayoutUnit RenderBlock::textIndentOffset() const
   2916 {
   2917     LayoutUnit cw = 0;
   2918     RenderView* renderView = 0;
   2919     if (style()->textIndent().isPercent())
   2920         cw = containingBlock()->availableLogicalWidth();
   2921     else if (style()->textIndent().isViewportPercentage())
   2922         renderView = view();
   2923     return minimumValueForLength(style()->textIndent(), cw, renderView);
   2924 }
   2925 
   2926 LayoutUnit RenderBlock::logicalLeftOffsetForContent(RenderRegion* region) const
   2927 {
   2928     LayoutUnit logicalLeftOffset = style()->isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop();
   2929     if (!region)
   2930         return logicalLeftOffset;
   2931     LayoutRect boxRect = borderBoxRectInRegion(region);
   2932     return logicalLeftOffset + (isHorizontalWritingMode() ? boxRect.x() : boxRect.y());
   2933 }
   2934 
   2935 LayoutUnit RenderBlock::logicalRightOffsetForContent(RenderRegion* region) const
   2936 {
   2937     LayoutUnit logicalRightOffset = style()->isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop();
   2938     logicalRightOffset += availableLogicalWidth();
   2939     if (!region)
   2940         return logicalRightOffset;
   2941     LayoutRect boxRect = borderBoxRectInRegion(region);
   2942     return logicalRightOffset - (logicalWidth() - (isHorizontalWritingMode() ? boxRect.maxX() : boxRect.maxY()));
   2943 }
   2944 
   2945 LayoutUnit RenderBlock::adjustLogicalLeftOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const
   2946 {
   2947     LayoutUnit left = offsetFromFloats;
   2948 
   2949     if (applyTextIndent && style()->isLeftToRightDirection())
   2950         left += textIndentOffset();
   2951 
   2952     if (style()->lineAlign() == LineAlignNone)
   2953         return left;
   2954 
   2955     // Push in our left offset so that it is aligned with the character grid.
   2956     LayoutState* layoutState = view()->layoutState();
   2957     if (!layoutState)
   2958         return left;
   2959 
   2960     RenderBlock* lineGrid = layoutState->lineGrid();
   2961     if (!lineGrid || lineGrid->style()->writingMode() != style()->writingMode())
   2962         return left;
   2963 
   2964     // FIXME: Should letter-spacing apply? This is complicated since it doesn't apply at the edge?
   2965     float maxCharWidth = lineGrid->style()->font().primaryFont()->maxCharWidth();
   2966     if (!maxCharWidth)
   2967         return left;
   2968 
   2969     LayoutUnit lineGridOffset = lineGrid->isHorizontalWritingMode() ? layoutState->lineGridOffset().width(): layoutState->lineGridOffset().height();
   2970     LayoutUnit layoutOffset = lineGrid->isHorizontalWritingMode() ? layoutState->layoutOffset().width() : layoutState->layoutOffset().height();
   2971 
   2972     // Push in to the nearest character width.
   2973     // FIXME: This is wrong for RTL (https://bugs.webkit.org/show_bug.cgi?id=79945).
   2974     // FIXME: This doesn't work with columns or regions (https://bugs.webkit.org/show_bug.cgi?id=79942).
   2975     // FIXME: This doesn't work when the inline position of the object isn't set ahead of time.
   2976     // FIXME: Dynamic changes to the font or to the inline position need to result in a deep relayout.
   2977     // (https://bugs.webkit.org/show_bug.cgi?id=79944)
   2978     float remainder = fmodf(maxCharWidth - fmodf(left + layoutOffset - lineGridOffset, maxCharWidth), maxCharWidth);
   2979     left += remainder;
   2980     return left;
   2981 }
   2982 
   2983 LayoutUnit RenderBlock::adjustLogicalRightOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const
   2984 {
   2985     LayoutUnit right = offsetFromFloats;
   2986 
   2987     if (applyTextIndent && !style()->isLeftToRightDirection())
   2988         right -= textIndentOffset();
   2989 
   2990     if (style()->lineAlign() == LineAlignNone)
   2991         return right;
   2992 
   2993     // Push in our right offset so that it is aligned with the character grid.
   2994     LayoutState* layoutState = view()->layoutState();
   2995     if (!layoutState)
   2996         return right;
   2997 
   2998     RenderBlock* lineGrid = layoutState->lineGrid();
   2999     if (!lineGrid || lineGrid->style()->writingMode() != style()->writingMode())
   3000         return right;
   3001 
   3002     // FIXME: Should letter-spacing apply? This is complicated since it doesn't apply at the edge?
   3003     float maxCharWidth = lineGrid->style()->font().primaryFont()->maxCharWidth();
   3004     if (!maxCharWidth)
   3005         return right;
   3006 
   3007     LayoutUnit lineGridOffset = lineGrid->isHorizontalWritingMode() ? layoutState->lineGridOffset().width(): layoutState->lineGridOffset().height();
   3008     LayoutUnit layoutOffset = lineGrid->isHorizontalWritingMode() ? layoutState->layoutOffset().width() : layoutState->layoutOffset().height();
   3009 
   3010     // Push in to the nearest character width.
   3011     // FIXME: This is wrong for RTL (https://bugs.webkit.org/show_bug.cgi?id=79945).
   3012     // FIXME: This doesn't work with columns or regions (https://bugs.webkit.org/show_bug.cgi?id=79942).
   3013     // FIXME: This doesn't work when the inline position of the object isn't set ahead of time.
   3014     // FIXME: Dynamic changes to the font or to the inline position need to result in a deep relayout.
   3015     // (https://bugs.webkit.org/show_bug.cgi?id=79944)
   3016     float remainder = fmodf(fmodf(right + layoutOffset - lineGridOffset, maxCharWidth), maxCharWidth);
   3017     right -= LayoutUnit::fromFloatCeil(remainder);
   3018     return right;
   3019 }
   3020 
   3021 void RenderBlock::markLinesDirtyInBlockRange(LayoutUnit logicalTop, LayoutUnit logicalBottom, RootInlineBox* highest)
   3022 {
   3023     if (logicalTop >= logicalBottom)
   3024         return;
   3025 
   3026     RootInlineBox* lowestDirtyLine = lastRootBox();
   3027     RootInlineBox* afterLowest = lowestDirtyLine;
   3028     while (lowestDirtyLine && lowestDirtyLine->lineBottomWithLeading() >= logicalBottom && logicalBottom < LayoutUnit::max()) {
   3029         afterLowest = lowestDirtyLine;
   3030         lowestDirtyLine = lowestDirtyLine->prevRootBox();
   3031     }
   3032 
   3033     while (afterLowest && afterLowest != highest && (afterLowest->lineBottomWithLeading() >= logicalTop || afterLowest->lineBottomWithLeading() < 0)) {
   3034         afterLowest->markDirty();
   3035         afterLowest = afterLowest->prevRootBox();
   3036     }
   3037 }
   3038 
   3039 bool RenderBlock::avoidsFloats() const
   3040 {
   3041     // Floats can't intrude into our box if we have a non-auto column count or width.
   3042     return RenderBox::avoidsFloats() || !style()->hasAutoColumnCount() || !style()->hasAutoColumnWidth();
   3043 }
   3044 
   3045 void RenderBlock::markShapeInsideDescendantsForLayout()
   3046 {
   3047     if (!everHadLayout())
   3048         return;
   3049     if (childrenInline()) {
   3050         setNeedsLayout();
   3051         return;
   3052     }
   3053     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
   3054         if (!child->isRenderBlock())
   3055             continue;
   3056         RenderBlock* childBlock = toRenderBlock(child);
   3057         childBlock->markShapeInsideDescendantsForLayout();
   3058     }
   3059 }
   3060 
   3061 bool RenderBlock::isPointInOverflowControl(HitTestResult& result, const LayoutPoint& locationInContainer, const LayoutPoint& accumulatedOffset)
   3062 {
   3063     if (!scrollsOverflow())
   3064         return false;
   3065 
   3066     return layer()->scrollableArea()->hitTestOverflowControls(result, roundedIntPoint(locationInContainer - toLayoutSize(accumulatedOffset)));
   3067 }
   3068 
   3069 Node* RenderBlock::nodeForHitTest() const
   3070 {
   3071     // If we are in the margins of block elements that are part of a
   3072     // continuation we're actually still inside the enclosing element
   3073     // that was split. Use the appropriate inner node.
   3074     return isAnonymousBlockContinuation() ? continuation()->node() : node();
   3075 }
   3076 
   3077 bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
   3078 {
   3079     LayoutPoint adjustedLocation(accumulatedOffset + location());
   3080     LayoutSize localOffset = toLayoutSize(adjustedLocation);
   3081 
   3082     if (!isRenderView()) {
   3083         // Check if we need to do anything at all.
   3084         LayoutRect overflowBox = visualOverflowRect();
   3085         flipForWritingMode(overflowBox);
   3086         overflowBox.moveBy(adjustedLocation);
   3087         if (!locationInContainer.intersects(overflowBox))
   3088             return false;
   3089     }
   3090 
   3091     if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) && isPointInOverflowControl(result, locationInContainer.point(), adjustedLocation)) {
   3092         updateHitTestResult(result, locationInContainer.point() - localOffset);
   3093         // FIXME: isPointInOverflowControl() doesn't handle rect-based tests yet.
   3094         if (!result.addNodeToRectBasedTestResult(nodeForHitTest(), request, locationInContainer))
   3095            return true;
   3096     }
   3097 
   3098     // If we have clipping, then we can't have any spillout.
   3099     bool useOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer();
   3100     bool useClip = (hasControlClip() || useOverflowClip);
   3101     bool checkChildren = !useClip || (hasControlClip() ? locationInContainer.intersects(controlClipRect(adjustedLocation)) : locationInContainer.intersects(overflowClipRect(adjustedLocation, locationInContainer.region(), IncludeOverlayScrollbarSize)));
   3102     if (checkChildren) {
   3103         // Hit test descendants first.
   3104         LayoutSize scrolledOffset(localOffset);
   3105         if (hasOverflowClip())
   3106             scrolledOffset -= scrolledContentOffset();
   3107 
   3108         // Hit test contents if we don't have columns.
   3109         if (!hasColumns()) {
   3110             if (hitTestContents(request, result, locationInContainer, toLayoutPoint(scrolledOffset), hitTestAction)) {
   3111                 updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - localOffset));
   3112                 return true;
   3113             }
   3114             if (hitTestAction == HitTestFloat && hitTestFloats(request, result, locationInContainer, toLayoutPoint(scrolledOffset)))
   3115                 return true;
   3116         } else if (hitTestColumns(request, result, locationInContainer, toLayoutPoint(scrolledOffset), hitTestAction)) {
   3117             updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - localOffset));
   3118             return true;
   3119         }
   3120     }
   3121 
   3122     // Check if the point is outside radii.
   3123     if (!isRenderView() && style()->hasBorderRadius()) {
   3124         LayoutRect borderRect = borderBoxRect();
   3125         borderRect.moveBy(adjustedLocation);
   3126         RoundedRect border = style()->getRoundedBorderFor(borderRect, view());
   3127         if (!locationInContainer.intersects(border))
   3128             return false;
   3129     }
   3130 
   3131     // Now hit test our background
   3132     if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) {
   3133         LayoutRect boundsRect(adjustedLocation, size());
   3134         if (visibleToHitTestRequest(request) && locationInContainer.intersects(boundsRect)) {
   3135             updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - localOffset));
   3136             if (!result.addNodeToRectBasedTestResult(nodeForHitTest(), request, locationInContainer, boundsRect))
   3137                 return true;
   3138         }
   3139     }
   3140 
   3141     return false;
   3142 }
   3143 
   3144 class ColumnRectIterator {
   3145     WTF_MAKE_NONCOPYABLE(ColumnRectIterator);
   3146 public:
   3147     ColumnRectIterator(const RenderBlock& block)
   3148         : m_block(block)
   3149         , m_colInfo(block.columnInfo())
   3150         , m_direction(m_block.style()->isFlippedBlocksWritingMode() ? 1 : -1)
   3151         , m_isHorizontal(block.isHorizontalWritingMode())
   3152         , m_logicalLeft(block.logicalLeftOffsetForContent())
   3153     {
   3154         int colCount = m_colInfo->columnCount();
   3155         m_colIndex = colCount - 1;
   3156         m_currLogicalTopOffset = colCount * m_colInfo->columnHeight() * m_direction;
   3157         update();
   3158     }
   3159 
   3160     void advance()
   3161     {
   3162         ASSERT(hasMore());
   3163         m_colIndex--;
   3164         update();
   3165     }
   3166 
   3167     LayoutRect columnRect() const { return m_colRect; }
   3168     bool hasMore() const { return m_colIndex >= 0; }
   3169 
   3170     void adjust(LayoutSize& offset) const
   3171     {
   3172         LayoutUnit currLogicalLeftOffset = (m_isHorizontal ? m_colRect.x() : m_colRect.y()) - m_logicalLeft;
   3173         offset += m_isHorizontal ? LayoutSize(currLogicalLeftOffset, m_currLogicalTopOffset) : LayoutSize(m_currLogicalTopOffset, currLogicalLeftOffset);
   3174         if (m_colInfo->progressionAxis() == ColumnInfo::BlockAxis) {
   3175             if (m_isHorizontal)
   3176                 offset.expand(0, m_colRect.y() - m_block.borderTop() - m_block.paddingTop());
   3177             else
   3178                 offset.expand(m_colRect.x() - m_block.borderLeft() - m_block.paddingLeft(), 0);
   3179         }
   3180     }
   3181 
   3182 private:
   3183     void update()
   3184     {
   3185         if (m_colIndex < 0)
   3186             return;
   3187 
   3188         m_colRect = m_block.columnRectAt(const_cast<ColumnInfo*>(m_colInfo), m_colIndex);
   3189         m_block.flipForWritingMode(m_colRect);
   3190         m_currLogicalTopOffset -= (m_isHorizontal ? m_colRect.height() : m_colRect.width()) * m_direction;
   3191     }
   3192 
   3193     const RenderBlock& m_block;
   3194     const ColumnInfo* const m_colInfo;
   3195     const int m_direction;
   3196     const bool m_isHorizontal;
   3197     const LayoutUnit m_logicalLeft;
   3198     int m_colIndex;
   3199     LayoutUnit m_currLogicalTopOffset;
   3200     LayoutRect m_colRect;
   3201 };
   3202 
   3203 bool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
   3204 {
   3205     // We need to do multiple passes, breaking up our hit testing into strips.
   3206     if (!hasColumns())
   3207         return false;
   3208 
   3209     for (ColumnRectIterator it(*this); it.hasMore(); it.advance()) {
   3210         LayoutRect hitRect = locationInContainer.boundingBox();
   3211         LayoutRect colRect = it.columnRect();
   3212         colRect.moveBy(accumulatedOffset);
   3213         if (locationInContainer.intersects(colRect)) {
   3214             // The point is inside this column.
   3215             // Adjust accumulatedOffset to change where we hit test.
   3216             LayoutSize offset;
   3217             it.adjust(offset);
   3218             LayoutPoint finalLocation = accumulatedOffset + offset;
   3219             if (!result.isRectBasedTest() || colRect.contains(hitRect))
   3220                 return hitTestContents(request, result, locationInContainer, finalLocation, hitTestAction) || (hitTestAction == HitTestFloat && hitTestFloats(request, result, locationInContainer, finalLocation));
   3221 
   3222             hitTestContents(request, result, locationInContainer, finalLocation, hitTestAction);
   3223         }
   3224     }
   3225 
   3226     return false;
   3227 }
   3228 
   3229 void RenderBlock::adjustForColumnRect(LayoutSize& offset, const LayoutPoint& locationInContainer) const
   3230 {
   3231     for (ColumnRectIterator it(*this); it.hasMore(); it.advance()) {
   3232         LayoutRect colRect = it.columnRect();
   3233         if (colRect.contains(locationInContainer)) {
   3234             it.adjust(offset);
   3235             return;
   3236         }
   3237     }
   3238 }
   3239 
   3240 bool RenderBlock::hitTestContents(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
   3241 {
   3242     if (isRenderRegion())
   3243         return toRenderRegion(this)->hitTestFlowThreadContents(request, result, locationInContainer, accumulatedOffset, hitTestAction);
   3244 
   3245     if (childrenInline() && !isTable()) {
   3246         // We have to hit-test our line boxes.
   3247         if (m_lineBoxes.hitTest(this, request, result, locationInContainer, accumulatedOffset, hitTestAction))
   3248             return true;
   3249     } else {
   3250         // Hit test our children.
   3251         HitTestAction childHitTest = hitTestAction;
   3252         if (hitTestAction == HitTestChildBlockBackgrounds)
   3253             childHitTest = HitTestChildBlockBackground;
   3254         for (RenderBox* child = lastChildBox(); child; child = child->previousSiblingBox()) {
   3255             LayoutPoint childPoint = flipForWritingModeForChild(child, accumulatedOffset);
   3256             if (!child->hasSelfPaintingLayer() && !child->isFloating() && child->nodeAtPoint(request, result, locationInContainer, childPoint, childHitTest))
   3257                 return true;
   3258         }
   3259     }
   3260 
   3261     return false;
   3262 }
   3263 
   3264 Position RenderBlock::positionForBox(InlineBox *box, bool start) const
   3265 {
   3266     if (!box)
   3267         return Position();
   3268 
   3269     if (!box->renderer()->nonPseudoNode())
   3270         return createLegacyEditingPosition(nonPseudoNode(), start ? caretMinOffset() : caretMaxOffset());
   3271 
   3272     if (!box->isInlineTextBox())
   3273         return createLegacyEditingPosition(box->renderer()->nonPseudoNode(), start ? box->renderer()->caretMinOffset() : box->renderer()->caretMaxOffset());
   3274 
   3275     InlineTextBox* textBox = toInlineTextBox(box);
   3276     return createLegacyEditingPosition(box->renderer()->nonPseudoNode(), start ? textBox->start() : textBox->start() + textBox->len());
   3277 }
   3278 
   3279 static inline bool isEditingBoundary(RenderObject* ancestor, RenderObject* child)
   3280 {
   3281     ASSERT(!ancestor || ancestor->nonPseudoNode());
   3282     ASSERT(child && child->nonPseudoNode());
   3283     return !ancestor || !ancestor->parent() || (ancestor->hasLayer() && ancestor->parent()->isRenderView())
   3284         || ancestor->nonPseudoNode()->rendererIsEditable() == child->nonPseudoNode()->rendererIsEditable();
   3285 }
   3286 
   3287 // FIXME: This function should go on RenderObject as an instance method. Then
   3288 // all cases in which positionForPoint recurs could call this instead to
   3289 // prevent crossing editable boundaries. This would require many tests.
   3290 static PositionWithAffinity positionForPointRespectingEditingBoundaries(RenderBlock* parent, RenderBox* child, const LayoutPoint& pointInParentCoordinates)
   3291 {
   3292     LayoutPoint childLocation = child->location();
   3293     if (child->isInFlowPositioned())
   3294         childLocation += child->offsetForInFlowPosition();
   3295 
   3296     // FIXME: This is wrong if the child's writing-mode is different from the parent's.
   3297     LayoutPoint pointInChildCoordinates(toLayoutPoint(pointInParentCoordinates - childLocation));
   3298 
   3299     // If this is an anonymous renderer, we just recur normally
   3300     Node* childNode = child->nonPseudoNode();
   3301     if (!childNode)
   3302         return child->positionForPoint(pointInChildCoordinates);
   3303 
   3304     // Otherwise, first make sure that the editability of the parent and child agree.
   3305     // If they don't agree, then we return a visible position just before or after the child
   3306     RenderObject* ancestor = parent;
   3307     while (ancestor && !ancestor->nonPseudoNode())
   3308         ancestor = ancestor->parent();
   3309 
   3310     // If we can't find an ancestor to check editability on, or editability is unchanged, we recur like normal
   3311     if (isEditingBoundary(ancestor, child))
   3312         return child->positionForPoint(pointInChildCoordinates);
   3313 
   3314     // Otherwise return before or after the child, depending on if the click was to the logical left or logical right of the child
   3315     LayoutUnit childMiddle = parent->logicalWidthForChild(child) / 2;
   3316     LayoutUnit logicalLeft = parent->isHorizontalWritingMode() ? pointInChildCoordinates.x() : pointInChildCoordinates.y();
   3317     if (logicalLeft < childMiddle)
   3318         return ancestor->createPositionWithAffinity(childNode->nodeIndex(), DOWNSTREAM);
   3319     return ancestor->createPositionWithAffinity(childNode->nodeIndex() + 1, UPSTREAM);
   3320 }
   3321 
   3322 PositionWithAffinity RenderBlock::positionForPointWithInlineChildren(const LayoutPoint& pointInLogicalContents)
   3323 {
   3324     ASSERT(childrenInline());
   3325 
   3326     if (!firstRootBox())
   3327         return createPositionWithAffinity(0, DOWNSTREAM);
   3328 
   3329     bool linesAreFlipped = style()->isFlippedLinesWritingMode();
   3330     bool blocksAreFlipped = style()->isFlippedBlocksWritingMode();
   3331 
   3332     // look for the closest line box in the root box which is at the passed-in y coordinate
   3333     InlineBox* closestBox = 0;
   3334     RootInlineBox* firstRootBoxWithChildren = 0;
   3335     RootInlineBox* lastRootBoxWithChildren = 0;
   3336     for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
   3337         if (!root->firstLeafChild())
   3338             continue;
   3339         if (!firstRootBoxWithChildren)
   3340             firstRootBoxWithChildren = root;
   3341 
   3342         if (!linesAreFlipped && root->isFirstAfterPageBreak() && (pointInLogicalContents.y() < root->lineTopWithLeading()
   3343             || (blocksAreFlipped && pointInLogicalContents.y() == root->lineTopWithLeading())))
   3344             break;
   3345 
   3346         lastRootBoxWithChildren = root;
   3347 
   3348         // check if this root line box is located at this y coordinate
   3349         if (pointInLogicalContents.y() < root->selectionBottom() || (blocksAreFlipped && pointInLogicalContents.y() == root->selectionBottom())) {
   3350             if (linesAreFlipped) {
   3351                 RootInlineBox* nextRootBoxWithChildren = root->nextRootBox();
   3352                 while (nextRootBoxWithChildren && !nextRootBoxWithChildren->firstLeafChild())
   3353                     nextRootBoxWithChildren = nextRootBoxWithChildren->nextRootBox();
   3354 
   3355                 if (nextRootBoxWithChildren && nextRootBoxWithChildren->isFirstAfterPageBreak() && (pointInLogicalContents.y() > nextRootBoxWithChildren->lineTopWithLeading()
   3356                     || (!blocksAreFlipped && pointInLogicalContents.y() == nextRootBoxWithChildren->lineTopWithLeading())))
   3357                     continue;
   3358             }
   3359             closestBox = root->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
   3360             if (closestBox)
   3361                 break;
   3362         }
   3363     }
   3364 
   3365     bool moveCaretToBoundary = document().frame()->editor().behavior().shouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom();
   3366 
   3367     if (!moveCaretToBoundary && !closestBox && lastRootBoxWithChildren) {
   3368         // y coordinate is below last root line box, pretend we hit it
   3369         closestBox = lastRootBoxWithChildren->closestLeafChildForLogicalLeftPosition(pointInLogicalContents.x());
   3370     }
   3371 
   3372     if (closestBox) {
   3373         if (moveCaretToBoundary) {
   3374             LayoutUnit firstRootBoxWithChildrenTop = min<LayoutUnit>(firstRootBoxWithChildren->selectionTop(), firstRootBoxWithChildren->logicalTop());
   3375             if (pointInLogicalContents.y() < firstRootBoxWithChildrenTop
   3376                 || (blocksAreFlipped && pointInLogicalContents.y() == firstRootBoxWithChildrenTop)) {
   3377                 InlineBox* box = firstRootBoxWithChildren->firstLeafChild();
   3378                 if (box->isLineBreak()) {
   3379                     if (InlineBox* newBox = box->nextLeafChildIgnoringLineBreak())
   3380                         box = newBox;
   3381                 }
   3382                 // y coordinate is above first root line box, so return the start of the first
   3383                 return PositionWithAffinity(positionForBox(box, true), DOWNSTREAM);
   3384             }
   3385         }
   3386 
   3387         // pass the box a top position that is inside it
   3388         LayoutPoint point(pointInLogicalContents.x(), closestBox->root()->blockDirectionPointInLine());
   3389         if (!isHorizontalWritingMode())
   3390             point = point.transposedPoint();
   3391         if (closestBox->renderer()->isReplaced())
   3392             return positionForPointRespectingEditingBoundaries(this, toRenderBox(closestBox->renderer()), point);
   3393         return closestBox->renderer()->positionForPoint(point);
   3394     }
   3395 
   3396     if (lastRootBoxWithChildren) {
   3397         // We hit this case for Mac behavior when the Y coordinate is below the last box.
   3398         ASSERT(moveCaretToBoundary);
   3399         InlineBox* logicallyLastBox;
   3400         if (lastRootBoxWithChildren->getLogicalEndBoxWithNode(logicallyLastBox))
   3401             return PositionWithAffinity(positionForBox(logicallyLastBox, false), DOWNSTREAM);
   3402     }
   3403 
   3404     // Can't reach this. We have a root line box, but it has no kids.
   3405     // FIXME: This should ASSERT_NOT_REACHED(), but clicking on placeholder text
   3406     // seems to hit this code path.
   3407     return createPositionWithAffinity(0, DOWNSTREAM);
   3408 }
   3409 
   3410 static inline bool isChildHitTestCandidate(RenderBox* box)
   3411 {
   3412     return box->height() && box->style()->visibility() == VISIBLE && !box->isFloatingOrOutOfFlowPositioned();
   3413 }
   3414 
   3415 PositionWithAffinity RenderBlock::positionForPoint(const LayoutPoint& point)
   3416 {
   3417     if (isTable())
   3418         return RenderBox::positionForPoint(point);
   3419 
   3420     if (isReplaced()) {
   3421         // FIXME: This seems wrong when the object's writing-mode doesn't match the line's writing-mode.
   3422         LayoutUnit pointLogicalLeft = isHorizontalWritingMode() ? point.x() : point.y();
   3423         LayoutUnit pointLogicalTop = isHorizontalWritingMode() ? point.y() : point.x();
   3424 
   3425         if (pointLogicalLeft < 0)
   3426             return createPositionWithAffinity(caretMinOffset(), DOWNSTREAM);
   3427         if (pointLogicalLeft >= logicalWidth())
   3428             return createPositionWithAffinity(caretMaxOffset(), DOWNSTREAM);
   3429         if (pointLogicalTop < 0)
   3430             return createPositionWithAffinity(caretMinOffset(), DOWNSTREAM);
   3431         if (pointLogicalTop >= logicalHeight())
   3432             return createPositionWithAffinity(caretMaxOffset(), DOWNSTREAM);
   3433     }
   3434 
   3435     LayoutPoint pointInContents = point;
   3436     offsetForContents(pointInContents);
   3437     LayoutPoint pointInLogicalContents(pointInContents);
   3438     if (!isHorizontalWritingMode())
   3439         pointInLogicalContents = pointInLogicalContents.transposedPoint();
   3440 
   3441     if (childrenInline())
   3442         return positionForPointWithInlineChildren(pointInLogicalContents);
   3443 
   3444     RenderBox* lastCandidateBox = lastChildBox();
   3445     while (lastCandidateBox && !isChildHitTestCandidate(lastCandidateBox))
   3446         lastCandidateBox = lastCandidateBox->previousSiblingBox();
   3447 
   3448     bool blocksAreFlipped = style()->isFlippedBlocksWritingMode();
   3449     if (lastCandidateBox) {
   3450         if (pointInLogicalContents.y() > logicalTopForChild(lastCandidateBox)
   3451             || (!blocksAreFlipped && pointInLogicalContents.y() == logicalTopForChild(lastCandidateBox)))
   3452             return positionForPointRespectingEditingBoundaries(this, lastCandidateBox, pointInContents);
   3453 
   3454         for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
   3455             if (!isChildHitTestCandidate(childBox))
   3456                 continue;
   3457             LayoutUnit childLogicalBottom = logicalTopForChild(childBox) + logicalHeightForChild(childBox);
   3458             // We hit child if our click is above the bottom of its padding box (like IE6/7 and FF3).
   3459             if (isChildHitTestCandidate(childBox) && (pointInLogicalContents.y() < childLogicalBottom
   3460                 || (blocksAreFlipped && pointInLogicalContents.y() == childLogicalBottom)))
   3461                 return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents);
   3462         }
   3463     }
   3464 
   3465     // We only get here if there are no hit test candidate children below the click.
   3466     return RenderBox::positionForPoint(point);
   3467 }
   3468 
   3469 void RenderBlock::offsetForContents(LayoutPoint& offset) const
   3470 {
   3471     offset = flipForWritingMode(offset);
   3472 
   3473     if (hasOverflowClip())
   3474         offset += scrolledContentOffset();
   3475 
   3476     if (hasColumns())
   3477         adjustPointToColumnContents(offset);
   3478 
   3479     offset = flipForWritingMode(offset);
   3480 }
   3481 
   3482 LayoutUnit RenderBlock::availableLogicalWidth() const
   3483 {
   3484     // If we have multiple columns, then the available logical width is reduced to our column width.
   3485     if (hasColumns())
   3486         return desiredColumnWidth();
   3487     return RenderBox::availableLogicalWidth();
   3488 }
   3489 
   3490 int RenderBlock::columnGap() const
   3491 {
   3492     if (style()->hasNormalColumnGap())
   3493         return style()->fontDescription().computedPixelSize(); // "1em" is recommended as the normal gap setting. Matches <p> margins.
   3494     return static_cast<int>(style()->columnGap());
   3495 }
   3496 
   3497 void RenderBlock::calcColumnWidth()
   3498 {
   3499     if (document().regionBasedColumnsEnabled())
   3500         return;
   3501 
   3502     // Calculate our column width and column count.
   3503     // FIXME: Can overflow on fast/block/float/float-not-removed-from-next-sibling4.html, see https://bugs.webkit.org/show_bug.cgi?id=68744
   3504     unsigned desiredColumnCount = 1;
   3505     LayoutUnit desiredColumnWidth = contentLogicalWidth();
   3506 
   3507     // For now, we don't support multi-column layouts when printing, since we have to do a lot of work for proper pagination.
   3508     if (document().paginated() || (style()->hasAutoColumnCount() && style()->hasAutoColumnWidth()) || !style()->hasInlineColumnAxis()) {
   3509         setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
   3510         return;
   3511     }
   3512 
   3513     LayoutUnit availWidth = desiredColumnWidth;
   3514     LayoutUnit colGap = columnGap();
   3515     LayoutUnit colWidth = max<LayoutUnit>(1, LayoutUnit(style()->columnWidth()));
   3516     int colCount = max<int>(1, style()->columnCount());
   3517 
   3518     if (style()->hasAutoColumnWidth() && !style()->hasAutoColumnCount()) {
   3519         desiredColumnCount = colCount;
   3520         desiredColumnWidth = max<LayoutUnit>(0, (availWidth - ((desiredColumnCount - 1) * colGap)) / desiredColumnCount);
   3521     } else if (!style()->hasAutoColumnWidth() && style()->hasAutoColumnCount()) {
   3522         desiredColumnCount = max<LayoutUnit>(1, (availWidth + colGap) / (colWidth + colGap));
   3523         desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colGap;
   3524     } else {
   3525         desiredColumnCount = max<LayoutUnit>(min<LayoutUnit>(colCount, (availWidth + colGap) / (colWidth + colGap)), 1);
   3526         desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colGap;
   3527     }
   3528     setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
   3529 }
   3530 
   3531 bool RenderBlock::requiresColumns(int desiredColumnCount) const
   3532 {
   3533     // If overflow-y is set to paged-x or paged-y on the body or html element, we'll handle the paginating
   3534     // in the RenderView instead.
   3535     bool isPaginated = (style()->overflowY() == OPAGEDX || style()->overflowY() == OPAGEDY) && !(isRoot() || isBody());
   3536 
   3537     return firstChild()
   3538         && (desiredColumnCount != 1 || !style()->hasAutoColumnWidth() || !style()->hasInlineColumnAxis() || isPaginated)
   3539         && !firstChild()->isAnonymousColumnsBlock()
   3540         && !firstChild()->isAnonymousColumnSpanBlock();
   3541 }
   3542 
   3543 void RenderBlock::setDesiredColumnCountAndWidth(int count, LayoutUnit width)
   3544 {
   3545     bool destroyColumns = !requiresColumns(count);
   3546     if (destroyColumns) {
   3547         if (hasColumns()) {
   3548             gColumnInfoMap->take(this);
   3549             setHasColumns(false);
   3550         }
   3551     } else {
   3552         ColumnInfo* info;
   3553         if (hasColumns())
   3554             info = gColumnInfoMap->get(this);
   3555         else {
   3556             if (!gColumnInfoMap)
   3557                 gColumnInfoMap = new ColumnInfoMap;
   3558             info = new ColumnInfo;
   3559             gColumnInfoMap->add(this, adoptPtr(info));
   3560             setHasColumns(true);
   3561         }
   3562         info->setDesiredColumnCount(count);
   3563         info->setDesiredColumnWidth(width);
   3564         info->setProgressionAxis(style()->hasInlineColumnAxis() ? ColumnInfo::InlineAxis : ColumnInfo::BlockAxis);
   3565         info->setProgressionIsReversed(style()->columnProgression() == ReverseColumnProgression);
   3566     }
   3567 }
   3568 
   3569 void RenderBlock::updateColumnInfoFromStyle(RenderStyle* style)
   3570 {
   3571     if (!hasColumns())
   3572         return;
   3573 
   3574     ColumnInfo* info = gColumnInfoMap->get(this);
   3575 
   3576     bool needsLayout = false;
   3577     ColumnInfo::Axis oldAxis = info->progressionAxis();
   3578     ColumnInfo::Axis newAxis = style->hasInlineColumnAxis() ? ColumnInfo::InlineAxis : ColumnInfo::BlockAxis;
   3579     if (oldAxis != newAxis) {
   3580         info->setProgressionAxis(newAxis);
   3581         needsLayout = true;
   3582     }
   3583 
   3584     bool oldProgressionIsReversed = info->progressionIsReversed();
   3585     bool newProgressionIsReversed = style->columnProgression() == ReverseColumnProgression;
   3586     if (oldProgressionIsReversed != newProgressionIsReversed) {
   3587         info->setProgressionIsReversed(newProgressionIsReversed);
   3588         needsLayout = true;
   3589     }
   3590 
   3591     if (needsLayout)
   3592         setNeedsLayoutAndPrefWidthsRecalc();
   3593 }
   3594 
   3595 LayoutUnit RenderBlock::desiredColumnWidth() const
   3596 {
   3597     if (!hasColumns())
   3598         return contentLogicalWidth();
   3599     return gColumnInfoMap->get(this)->desiredColumnWidth();
   3600 }
   3601 
   3602 ColumnInfo* RenderBlock::columnInfo() const
   3603 {
   3604     if (!hasColumns())
   3605         return 0;
   3606     return gColumnInfoMap->get(this);
   3607 }
   3608 
   3609 unsigned RenderBlock::columnCount(ColumnInfo* colInfo) const
   3610 {
   3611     ASSERT(hasColumns());
   3612     ASSERT(gColumnInfoMap->get(this) == colInfo);
   3613     return colInfo->columnCount();
   3614 }
   3615 
   3616 LayoutRect RenderBlock::columnRectAt(ColumnInfo* colInfo, unsigned index) const
   3617 {
   3618     ASSERT(hasColumns() && gColumnInfoMap->get(this) == colInfo);
   3619 
   3620     // Compute the appropriate rect based off our information.
   3621     LayoutUnit colLogicalWidth = colInfo->desiredColumnWidth();
   3622     LayoutUnit colLogicalHeight = colInfo->columnHeight();
   3623     LayoutUnit colLogicalTop = borderBefore() + paddingBefore();
   3624     LayoutUnit colLogicalLeft = logicalLeftOffsetForContent();
   3625     LayoutUnit colGap = columnGap();
   3626     if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
   3627         if (style()->isLeftToRightDirection() ^ colInfo->progressionIsReversed())
   3628             colLogicalLeft += index * (colLogicalWidth + colGap);
   3629         else
   3630             colLogicalLeft += contentLogicalWidth() - colLogicalWidth - index * (colLogicalWidth + colGap);
   3631     } else {
   3632         if (!colInfo->progressionIsReversed())
   3633             colLogicalTop += index * (colLogicalHeight + colGap);
   3634         else
   3635             colLogicalTop += contentLogicalHeight() - colLogicalHeight - index * (colLogicalHeight + colGap);
   3636     }
   3637 
   3638     if (isHorizontalWritingMode())
   3639         return LayoutRect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLogicalHeight);
   3640     return LayoutRect(colLogicalTop, colLogicalLeft, colLogicalHeight, colLogicalWidth);
   3641 }
   3642 
   3643 bool RenderBlock::relayoutToAvoidWidows(LayoutStateMaintainer& statePusher)
   3644 {
   3645     if (!shouldBreakAtLineToAvoidWidow())
   3646         return false;
   3647 
   3648     statePusher.pop();
   3649     setEverHadLayout(true);
   3650     layoutBlock(false);
   3651     return true;
   3652 }
   3653 
   3654 void RenderBlock::adjustPointToColumnContents(LayoutPoint& point) const
   3655 {
   3656     // Just bail if we have no columns.
   3657     if (!hasColumns())
   3658         return;
   3659 
   3660     ColumnInfo* colInfo = columnInfo();
   3661     if (!columnCount(colInfo))
   3662         return;
   3663 
   3664     // Determine which columns we intersect.
   3665     LayoutUnit colGap = columnGap();
   3666     LayoutUnit halfColGap = colGap / 2;
   3667     LayoutPoint columnPoint(columnRectAt(colInfo, 0).location());
   3668     LayoutUnit logicalOffset = 0;
   3669     for (unsigned i = 0; i < colInfo->columnCount(); i++) {
   3670         // Add in half the column gap to the left and right of the rect.
   3671         LayoutRect colRect = columnRectAt(colInfo, i);
   3672         flipForWritingMode(colRect);
   3673         if (isHorizontalWritingMode() == (colInfo->progressionAxis() == ColumnInfo::InlineAxis)) {
   3674             LayoutRect gapAndColumnRect(colRect.x() - halfColGap, colRect.y(), colRect.width() + colGap, colRect.height());
   3675             if (point.x() >= gapAndColumnRect.x() && point.x() < gapAndColumnRect.maxX()) {
   3676                 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
   3677                     // FIXME: The clamping that follows is not completely right for right-to-left
   3678                     // content.
   3679                     // Clamp everything above the column to its top left.
   3680                     if (point.y() < gapAndColumnRect.y())
   3681                         point = gapAndColumnRect.location();
   3682                     // Clamp everything below the column to the next column's top left. If there is
   3683                     // no next column, this still maps to just after this column.
   3684                     else if (point.y() >= gapAndColumnRect.maxY()) {
   3685                         point = gapAndColumnRect.location();
   3686                         point.move(0, gapAndColumnRect.height());
   3687                     }
   3688                 } else {
   3689                     if (point.x() < colRect.x())
   3690                         point.setX(colRect.x());
   3691                     else if (point.x() >= colRect.maxX())
   3692                         point.setX(colRect.maxX() - 1);
   3693                 }
   3694 
   3695                 // We're inside the column.  Translate the x and y into our column coordinate space.
   3696                 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
   3697                     point.move(columnPoint.x() - colRect.x(), (!style()->isFlippedBlocksWritingMode() ? logicalOffset : -logicalOffset));
   3698                 else
   3699                     point.move((!style()->isFlippedBlocksWritingMode() ? logicalOffset : -logicalOffset) - colRect.x() + borderLeft() + paddingLeft(), 0);
   3700                 return;
   3701             }
   3702 
   3703             // Move to the next position.
   3704             logicalOffset += colInfo->progressionAxis() == ColumnInfo::InlineAxis ? colRect.height() : colRect.width();
   3705         } else {
   3706             LayoutRect gapAndColumnRect(colRect.x(), colRect.y() - halfColGap, colRect.width(), colRect.height() + colGap);
   3707             if (point.y() >= gapAndColumnRect.y() && point.y() < gapAndColumnRect.maxY()) {
   3708                 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
   3709                     // FIXME: The clamping that follows is not completely right for right-to-left
   3710                     // content.
   3711                     // Clamp everything above the column to its top left.
   3712                     if (point.x() < gapAndColumnRect.x())
   3713                         point = gapAndColumnRect.location();
   3714                     // Clamp everything below the column to the next column's top left. If there is
   3715                     // no next column, this still maps to just after this column.
   3716                     else if (point.x() >= gapAndColumnRect.maxX()) {
   3717                         point = gapAndColumnRect.location();
   3718                         point.move(gapAndColumnRect.width(), 0);
   3719                     }
   3720                 } else {
   3721                     if (point.y() < colRect.y())
   3722                         point.setY(colRect.y());
   3723                     else if (point.y() >= colRect.maxY())
   3724                         point.setY(colRect.maxY() - 1);
   3725                 }
   3726 
   3727                 // We're inside the column.  Translate the x and y into our column coordinate space.
   3728                 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
   3729                     point.move((!style()->isFlippedBlocksWritingMode() ? logicalOffset : -logicalOffset), columnPoint.y() - colRect.y());
   3730                 else
   3731                     point.move(0, (!style()->isFlippedBlocksWritingMode() ? logicalOffset : -logicalOffset) - colRect.y() + borderTop() + paddingTop());
   3732                 return;
   3733             }
   3734 
   3735             // Move to the next position.
   3736             logicalOffset += colInfo->progressionAxis() == ColumnInfo::InlineAxis ? colRect.width() : colRect.height();
   3737         }
   3738     }
   3739 }
   3740 
   3741 void RenderBlock::adjustRectForColumns(LayoutRect& r) const
   3742 {
   3743     // Just bail if we have no columns.
   3744     if (!hasColumns())
   3745         return;
   3746 
   3747     ColumnInfo* colInfo = columnInfo();
   3748 
   3749     // Determine which columns we intersect.
   3750     unsigned colCount = columnCount(colInfo);
   3751     if (!colCount)
   3752         return;
   3753 
   3754     // Begin with a result rect that is empty.
   3755     LayoutRect result;
   3756 
   3757     bool isHorizontal = isHorizontalWritingMode();
   3758     LayoutUnit beforeBorderPadding = borderBefore() + paddingBefore();
   3759     LayoutUnit colHeight = colInfo->columnHeight();
   3760     if (!colHeight)
   3761         return;
   3762 
   3763     LayoutUnit startOffset = max(isHorizontal ? r.y() : r.x(), beforeBorderPadding);
   3764     LayoutUnit endOffset = max(min<LayoutUnit>(isHorizontal ? r.maxY() : r.maxX(), beforeBorderPadding + colCount * colHeight), beforeBorderPadding);
   3765 
   3766     // FIXME: Can overflow on fast/block/float/float-not-removed-from-next-sibling4.html, see https://bugs.webkit.org/show_bug.cgi?id=68744
   3767     unsigned startColumn = (startOffset - beforeBorderPadding) / colHeight;
   3768     unsigned endColumn = (endOffset - beforeBorderPadding) / colHeight;
   3769 
   3770     if (startColumn == endColumn) {
   3771         // The rect is fully contained within one column. Adjust for our offsets
   3772         // and repaint only that portion.
   3773         LayoutUnit logicalLeftOffset = logicalLeftOffsetForContent();
   3774         LayoutRect colRect = columnRectAt(colInfo, startColumn);
   3775         LayoutRect repaintRect = r;
   3776 
   3777         if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
   3778             if (isHorizontal)
   3779                 repaintRect.move(colRect.x() - logicalLeftOffset, - static_cast<int>(startColumn) * colHeight);
   3780             else
   3781                 repaintRect.move(- static_cast<int>(startColumn) * colHeight, colRect.y() - logicalLeftOffset);
   3782         } else {
   3783             if (isHorizontal)
   3784                 repaintRect.move(0, colRect.y() - startColumn * colHeight - beforeBorderPadding);
   3785             else
   3786                 repaintRect.move(colRect.x() - startColumn * colHeight - beforeBorderPadding, 0);
   3787         }
   3788         repaintRect.intersect(colRect);
   3789         result.unite(repaintRect);
   3790     } else {
   3791         // We span multiple columns. We can just unite the start and end column to get the final
   3792         // repaint rect.
   3793         result.unite(columnRectAt(colInfo, startColumn));
   3794         result.unite(columnRectAt(colInfo, endColumn));
   3795     }
   3796 
   3797     r = result;
   3798 }
   3799 
   3800 LayoutPoint RenderBlock::flipForWritingModeIncludingColumns(const LayoutPoint& point) const
   3801 {
   3802     ASSERT(hasColumns());
   3803     if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
   3804         return point;
   3805     ColumnInfo* colInfo = columnInfo();
   3806     LayoutUnit columnLogicalHeight = colInfo->columnHeight();
   3807     LayoutUnit expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
   3808     if (isHorizontalWritingMode())
   3809         return LayoutPoint(point.x(), expandedLogicalHeight - point.y());
   3810     return LayoutPoint(expandedLogicalHeight - point.x(), point.y());
   3811 }
   3812 
   3813 void RenderBlock::adjustStartEdgeForWritingModeIncludingColumns(LayoutRect& rect) const
   3814 {
   3815     ASSERT(hasColumns());
   3816     if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
   3817         return;
   3818 
   3819     ColumnInfo* colInfo = columnInfo();
   3820     LayoutUnit columnLogicalHeight = colInfo->columnHeight();
   3821     LayoutUnit expandedLogicalHeight = borderBefore() + paddingBefore() + columnCount(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollbarLogicalHeight();
   3822 
   3823     if (isHorizontalWritingMode())
   3824         rect.setY(expandedLogicalHeight - rect.maxY());
   3825     else
   3826         rect.setX(expandedLogicalHeight - rect.maxX());
   3827 }
   3828 
   3829 void RenderBlock::adjustForColumns(LayoutSize& offset, const LayoutPoint& point) const
   3830 {
   3831     if (!hasColumns())
   3832         return;
   3833 
   3834     ColumnInfo* colInfo = columnInfo();
   3835 
   3836     LayoutUnit logicalLeft = logicalLeftOffsetForContent();
   3837     unsigned colCount = columnCount(colInfo);
   3838     LayoutUnit colLogicalWidth = colInfo->desiredColumnWidth();
   3839     LayoutUnit colLogicalHeight = colInfo->columnHeight();
   3840 
   3841     for (unsigned i = 0; i < colCount; ++i) {
   3842         // Compute the edges for a given column in the block progression direction.
   3843         LayoutRect sliceRect = LayoutRect(logicalLeft, borderBefore() + paddingBefore() + i * colLogicalHeight, colLogicalWidth, colLogicalHeight);
   3844         if (!isHorizontalWritingMode())
   3845             sliceRect = sliceRect.transposedRect();
   3846 
   3847         LayoutUnit logicalOffset = i * colLogicalHeight;
   3848 
   3849         // Now we're in the same coordinate space as the point.  See if it is inside the rectangle.
   3850         if (isHorizontalWritingMode()) {
   3851             if (point.y() >= sliceRect.y() && point.y() < sliceRect.maxY()) {
   3852                 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
   3853                     offset.expand(columnRectAt(colInfo, i).x() - logicalLeft, -logicalOffset);
   3854                 else
   3855                     offset.expand(0, columnRectAt(colInfo, i).y() - logicalOffset - borderBefore() - paddingBefore());
   3856                 return;
   3857             }
   3858         } else {
   3859             if (point.x() >= sliceRect.x() && point.x() < sliceRect.maxX()) {
   3860                 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
   3861                     offset.expand(-logicalOffset, columnRectAt(colInfo, i).y() - logicalLeft);
   3862                 else
   3863                     offset.expand(columnRectAt(colInfo, i).x() - logicalOffset - borderBefore() - paddingBefore(), 0);
   3864                 return;
   3865             }
   3866         }
   3867     }
   3868 }
   3869 
   3870 void RenderBlock::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
   3871 {
   3872     if (childrenInline()) {
   3873         // FIXME: Remove this const_cast.
   3874         const_cast<RenderBlock*>(this)->computeInlinePreferredLogicalWidths(minLogicalWidth, maxLogicalWidth);
   3875     } else
   3876         computeBlockPreferredLogicalWidths(minLogicalWidth, maxLogicalWidth);
   3877 
   3878     maxLogicalWidth = max(minLogicalWidth, maxLogicalWidth);
   3879 
   3880     adjustIntrinsicLogicalWidthsForColumns(minLogicalWidth, maxLogicalWidth);
   3881 
   3882     // A horizontal marquee with inline children has no minimum width.
   3883     if (childrenInline() && isMarquee() && toRenderMarquee(this)->isHorizontal())
   3884         minLogicalWidth = 0;
   3885 
   3886     if (isTableCell()) {
   3887         Length tableCellWidth = toRenderTableCell(this)->styleOrColLogicalWidth();
   3888         if (tableCellWidth.isFixed() && tableCellWidth.value() > 0)
   3889             maxLogicalWidth = max(minLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(tableCellWidth.value()));
   3890     }
   3891 
   3892     int scrollbarWidth = instrinsicScrollbarLogicalWidth();
   3893     maxLogicalWidth += scrollbarWidth;
   3894     minLogicalWidth += scrollbarWidth;
   3895 }
   3896 
   3897 void RenderBlock::computePreferredLogicalWidths()
   3898 {
   3899     ASSERT(preferredLogicalWidthsDirty());
   3900 
   3901     updateFirstLetter();
   3902 
   3903     m_minPreferredLogicalWidth = 0;
   3904     m_maxPreferredLogicalWidth = 0;
   3905 
   3906     // FIXME: The isFixed() calls here should probably be checking for isSpecified since you
   3907     // should be able to use percentage, calc or viewport relative values for width.
   3908     RenderStyle* styleToUse = style();
   3909     if (!isTableCell() && styleToUse->logicalWidth().isFixed() && styleToUse->logicalWidth().value() >= 0
   3910         && !(isDeprecatedFlexItem() && !styleToUse->logicalWidth().intValue()))
   3911         m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalWidth().value());
   3912     else
   3913         computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
   3914 
   3915     if (styleToUse->logicalMinWidth().isFixed() && styleToUse->logicalMinWidth().value() > 0) {
   3916         m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMinWidth().value()));
   3917         m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMinWidth().value()));
   3918     }
   3919 
   3920     if (styleToUse->logicalMaxWidth().isFixed()) {
   3921         m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMaxWidth().value()));
   3922         m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMaxWidth().value()));
   3923     }
   3924 
   3925     // Table layout uses integers, ceil the preferred widths to ensure that they can contain the contents.
   3926     if (isTableCell()) {
   3927         m_minPreferredLogicalWidth = m_minPreferredLogicalWidth.ceil();
   3928         m_maxPreferredLogicalWidth = m_maxPreferredLogicalWidth.ceil();
   3929     }
   3930 
   3931     LayoutUnit borderAndPadding = borderAndPaddingLogicalWidth();
   3932     m_minPreferredLogicalWidth += borderAndPadding;
   3933     m_maxPreferredLogicalWidth += borderAndPadding;
   3934 
   3935     clearPreferredLogicalWidthsDirty();
   3936 }
   3937 
   3938 void RenderBlock::adjustIntrinsicLogicalWidthsForColumns(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
   3939 {
   3940     // FIXME: make this method virtual and move the code to RenderMultiColumnBlock once the old
   3941     // multicol code is gone.
   3942 
   3943     if (!style()->hasAutoColumnCount() || !style()->hasAutoColumnWidth()) {
   3944         // The min/max intrinsic widths calculated really tell how much space elements need when
   3945         // laid out inside the columns. In order to eventually end up with the desired column width,
   3946         // we need to convert them to values pertaining to the multicol container.
   3947         int columnCount = style()->hasAutoColumnCount() ? 1 : style()->columnCount();
   3948         LayoutUnit columnWidth;
   3949         LayoutUnit gapExtra = (columnCount - 1) * columnGap();
   3950         if (style()->hasAutoColumnWidth()) {
   3951             minLogicalWidth = minLogicalWidth * columnCount + gapExtra;
   3952         } else {
   3953             columnWidth = style()->columnWidth();
   3954             minLogicalWidth = min(minLogicalWidth, columnWidth);
   3955         }
   3956         // FIXME: If column-count is auto here, we should resolve it to calculate the maximum
   3957         // intrinsic width, instead of pretending that it's 1. The only way to do that is by
   3958         // performing a layout pass, but this is not an appropriate time or place for layout. The
   3959         // good news is that if height is unconstrained and there are no explicit breaks, the
   3960         // resolved column-count really should be 1.
   3961         maxLogicalWidth = max(maxLogicalWidth, columnWidth) * columnCount + gapExtra;
   3962     }
   3963 }
   3964 
   3965 struct InlineMinMaxIterator {
   3966 /* InlineMinMaxIterator is a class that will iterate over all render objects that contribute to
   3967    inline min/max width calculations.  Note the following about the way it walks:
   3968    (1) Positioned content is skipped (since it does not contribute to min/max width of a block)
   3969    (2) We do not drill into the children of floats or replaced elements, since you can't break
   3970        in the middle of such an element.
   3971    (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side can have
   3972        distinct borders/margin/padding that contribute to the min/max width.
   3973 */
   3974     RenderObject* parent;
   3975     RenderObject* current;
   3976     bool endOfInline;
   3977 
   3978     InlineMinMaxIterator(RenderObject* p, bool end = false)
   3979         :parent(p), current(p), endOfInline(end) {}
   3980 
   3981     RenderObject* next();
   3982 };
   3983 
   3984 RenderObject* InlineMinMaxIterator::next()
   3985 {
   3986     RenderObject* result = 0;
   3987     bool oldEndOfInline = endOfInline;
   3988     endOfInline = false;
   3989     while (current || current == parent) {
   3990         if (!oldEndOfInline &&
   3991             (current == parent ||
   3992              (!current->isFloating() && !current->isReplaced() && !current->isOutOfFlowPositioned())))
   3993             result = current->firstChild();
   3994         if (!result) {
   3995             // We hit the end of our inline. (It was empty, e.g., <span></span>.)
   3996             if (!oldEndOfInline && current->isRenderInline()) {
   3997                 result = current;
   3998                 endOfInline = true;
   3999                 break;
   4000             }
   4001 
   4002             while (current && current != parent) {
   4003                 result = current->nextSibling();
   4004                 if (result) break;
   4005                 current = current->parent();
   4006                 if (current && current != parent && current->isRenderInline()) {
   4007                     result = current;
   4008                     endOfInline = true;
   4009                     break;
   4010                 }
   4011             }
   4012         }
   4013 
   4014         if (!result)
   4015             break;
   4016 
   4017         if (!result->isOutOfFlowPositioned() && (result->isText() || result->isFloating() || result->isReplaced() || result->isRenderInline()))
   4018              break;
   4019 
   4020         current = result;
   4021         result = 0;
   4022     }
   4023 
   4024     // Update our position.
   4025     current = result;
   4026     return current;
   4027 }
   4028 
   4029 static LayoutUnit getBPMWidth(LayoutUnit childValue, Length cssUnit)
   4030 {
   4031     if (cssUnit.type() != Auto)
   4032         return (cssUnit.isFixed() ? static_cast<LayoutUnit>(cssUnit.value()) : childValue);
   4033     return 0;
   4034 }
   4035 
   4036 static LayoutUnit getBorderPaddingMargin(const RenderBoxModelObject* child, bool endOfInline)
   4037 {
   4038     RenderStyle* childStyle = child->style();
   4039     if (endOfInline)
   4040         return getBPMWidth(child->marginEnd(), childStyle->marginEnd()) +
   4041                getBPMWidth(child->paddingEnd(), childStyle->paddingEnd()) +
   4042                child->borderEnd();
   4043     return getBPMWidth(child->marginStart(), childStyle->marginStart()) +
   4044                getBPMWidth(child->paddingStart(), childStyle->paddingStart()) +
   4045                child->borderStart();
   4046 }
   4047 
   4048 static inline void stripTrailingSpace(float& inlineMax, float& inlineMin,
   4049                                       RenderObject* trailingSpaceChild)
   4050 {
   4051     if (trailingSpaceChild && trailingSpaceChild->isText()) {
   4052         // Collapse away the trailing space at the end of a block.
   4053         RenderText* t = toRenderText(trailingSpaceChild);
   4054         const UChar space = ' ';
   4055         const Font& font = t->style()->font(); // FIXME: This ignores first-line.
   4056         float spaceWidth = font.width(RenderBlockFlow::constructTextRun(t, font, &space, 1, t->style()));
   4057         inlineMax -= spaceWidth + font.wordSpacing();
   4058         if (inlineMin > inlineMax)
   4059             inlineMin = inlineMax;
   4060     }
   4061 }
   4062 
   4063 static inline void updatePreferredWidth(LayoutUnit& preferredWidth, float& result)
   4064 {
   4065     LayoutUnit snappedResult = LayoutUnit::fromFloatCeil(result);
   4066     preferredWidth = max(snappedResult, preferredWidth);
   4067 }
   4068 
   4069 // When converting between floating point and LayoutUnits we risk losing precision
   4070 // with each conversion. When this occurs while accumulating our preferred widths,
   4071 // we can wind up with a line width that's larger than our maxPreferredWidth due to
   4072 // pure float accumulation.
   4073 static inline LayoutUnit adjustFloatForSubPixelLayout(float value)
   4074 {
   4075     return LayoutUnit::fromFloatCeil(value);
   4076 }
   4077 
   4078 
   4079 void RenderBlock::computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth)
   4080 {
   4081     float inlineMax = 0;
   4082     float inlineMin = 0;
   4083 
   4084     RenderStyle* styleToUse = style();
   4085     RenderBlock* containingBlock = this->containingBlock();
   4086     LayoutUnit cw = containingBlock ? containingBlock->contentLogicalWidth() : LayoutUnit();
   4087 
   4088     // If we are at the start of a line, we want to ignore all white-space.
   4089     // Also strip spaces if we previously had text that ended in a trailing space.
   4090     bool stripFrontSpaces = true;
   4091     RenderObject* trailingSpaceChild = 0;
   4092 
   4093     // Firefox and Opera will allow a table cell to grow to fit an image inside it under
   4094     // very specific cirucumstances (in order to match common WinIE renderings).
   4095     // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
   4096     bool allowImagesToBreak = !document().inQuirksMode() || !isTableCell() || !styleToUse->logicalWidth().isIntrinsicOrAuto();
   4097 
   4098     bool autoWrap, oldAutoWrap;
   4099     autoWrap = oldAutoWrap = styleToUse->autoWrap();
   4100 
   4101     InlineMinMaxIterator childIterator(this);
   4102 
   4103     // Only gets added to the max preffered width once.
   4104     bool addedTextIndent = false;
   4105     // Signals the text indent was more negative than the min preferred width
   4106     bool hasRemainingNegativeTextIndent = false;
   4107 
   4108     LayoutUnit textIndent = minimumValueForLength(styleToUse->textIndent(), cw, view());
   4109     RenderObject* prevFloat = 0;
   4110     bool isPrevChildInlineFlow = false;
   4111     bool shouldBreakLineAfterText = false;
   4112     while (RenderObject* child = childIterator.next()) {
   4113         autoWrap = child->isReplaced() ? child->parent()->style()->autoWrap() :
   4114             child->style()->autoWrap();
   4115 
   4116         if (!child->isBR()) {
   4117             // Step One: determine whether or not we need to go ahead and
   4118             // terminate our current line.  Each discrete chunk can become
   4119             // the new min-width, if it is the widest chunk seen so far, and
   4120             // it can also become the max-width.
   4121 
   4122             // Children fall into three categories:
   4123             // (1) An inline flow object.  These objects always have a min/max of 0,
   4124             // and are included in the iteration solely so that their margins can
   4125             // be added in.
   4126             //
   4127             // (2) An inline non-text non-flow object, e.g., an inline replaced element.
   4128             // These objects can always be on a line by themselves, so in this situation
   4129             // we need to go ahead and break the current line, and then add in our own
   4130             // margins and min/max width on its own line, and then terminate the line.
   4131             //
   4132             // (3) A text object.  Text runs can have breakable characters at the start,
   4133             // the middle or the end.  They may also lose whitespace off the front if
   4134             // we're already ignoring whitespace.  In order to compute accurate min-width
   4135             // information, we need three pieces of information.
   4136             // (a) the min-width of the first non-breakable run.  Should be 0 if the text string
   4137             // starts with whitespace.
   4138             // (b) the min-width of the last non-breakable run. Should be 0 if the text string
   4139             // ends with whitespace.
   4140             // (c) the min/max width of the string (trimmed for whitespace).
   4141             //
   4142             // If the text string starts with whitespace, then we need to go ahead and
   4143             // terminate our current line (unless we're already in a whitespace stripping
   4144             // mode.
   4145             //
   4146             // If the text string has a breakable character in the middle, but didn't start
   4147             // with whitespace, then we add the width of the first non-breakable run and
   4148             // then end the current line.  We then need to use the intermediate min/max width
   4149             // values (if any of them are larger than our current min/max).  We then look at
   4150             // the width of the last non-breakable run and use that to start a new line
   4151             // (unless we end in whitespace).
   4152             RenderStyle* childStyle = child->style();
   4153             float childMin = 0;
   4154             float childMax = 0;
   4155 
   4156             if (!child->isText()) {
   4157                 // Case (1) and (2).  Inline replaced and inline flow elements.
   4158                 if (child->isRenderInline()) {
   4159                     // Add in padding/border/margin from the appropriate side of
   4160                     // the element.
   4161                     float bpm = getBorderPaddingMargin(toRenderInline(child), childIterator.endOfInline);
   4162                     childMin += bpm;
   4163                     childMax += bpm;
   4164 
   4165                     inlineMin += childMin;
   4166                     inlineMax += childMax;
   4167 
   4168                     child->clearPreferredLogicalWidthsDirty();
   4169                 } else {
   4170                     // Inline replaced elts add in their margins to their min/max values.
   4171                     LayoutUnit margins = 0;
   4172                     Length startMargin = childStyle->marginStart();
   4173                     Length endMargin = childStyle->marginEnd();
   4174                     if (startMargin.isFixed())
   4175                         margins += adjustFloatForSubPixelLayout(startMargin.value());
   4176                     if (endMargin.isFixed())
   4177                         margins += adjustFloatForSubPixelLayout(endMargin.value());
   4178                     childMin += margins.ceilToFloat();
   4179                     childMax += margins.ceilToFloat();
   4180                 }
   4181             }
   4182 
   4183             if (!child->isRenderInline() && !child->isText()) {
   4184                 // Case (2). Inline replaced elements and floats.
   4185                 // Go ahead and terminate the current line as far as
   4186                 // minwidth is concerned.
   4187                 LayoutUnit childMinPreferredLogicalWidth, childMaxPreferredLogicalWidth;
   4188                 if (child->isBox() && child->isHorizontalWritingMode() != isHorizontalWritingMode()) {
   4189                     RenderBox* childBox = toRenderBox(child);
   4190                     LogicalExtentComputedValues computedValues;
   4191                     childBox->computeLogicalHeight(childBox->borderAndPaddingLogicalHeight(), 0, computedValues);
   4192                     childMinPreferredLogicalWidth = childMaxPreferredLogicalWidth = computedValues.m_extent;
   4193                 } else {
   4194                     childMinPreferredLogicalWidth = child->minPreferredLogicalWidth();
   4195                     childMaxPreferredLogicalWidth = child->maxPreferredLogicalWidth();
   4196                 }
   4197                 childMin += childMinPreferredLogicalWidth.ceilToFloat();
   4198                 childMax += childMaxPreferredLogicalWidth.ceilToFloat();
   4199 
   4200                 bool clearPreviousFloat;
   4201                 if (child->isFloating()) {
   4202                     clearPreviousFloat = (prevFloat
   4203                         && ((prevFloat->style()->floating() == LeftFloat && (childStyle->clear() & CLEFT))
   4204                             || (prevFloat->style()->floating() == RightFloat && (childStyle->clear() & CRIGHT))));
   4205                     prevFloat = child;
   4206                 } else
   4207                     clearPreviousFloat = false;
   4208 
   4209                 bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak;
   4210                 if ((canBreakReplacedElement && (autoWrap || oldAutoWrap) && (!isPrevChildInlineFlow || shouldBreakLineAfterText)) || clearPreviousFloat) {
   4211                     updatePreferredWidth(minLogicalWidth, inlineMin);
   4212                     inlineMin = 0;
   4213                 }
   4214 
   4215                 // If we're supposed to clear the previous float, then terminate maxwidth as well.
   4216                 if (clearPreviousFloat) {
   4217                     updatePreferredWidth(maxLogicalWidth, inlineMax);
   4218                     inlineMax = 0;
   4219                 }
   4220 
   4221                 // Add in text-indent.  This is added in only once.
   4222                 if (!addedTextIndent && !child->isFloating()) {
   4223                     float ceiledTextIndent = textIndent.ceilToFloat();
   4224                     childMin += ceiledTextIndent;
   4225                     childMax += ceiledTextIndent;
   4226 
   4227                     if (childMin < 0)
   4228                         textIndent = adjustFloatForSubPixelLayout(childMin);
   4229                     else
   4230                         addedTextIndent = true;
   4231                 }
   4232 
   4233                 // Add our width to the max.
   4234                 inlineMax += max<float>(0, childMax);
   4235 
   4236                 if (!autoWrap || !canBreakReplacedElement || (isPrevChildInlineFlow && !shouldBreakLineAfterText)) {
   4237                     if (child->isFloating())
   4238                         updatePreferredWidth(minLogicalWidth, childMin);
   4239                     else
   4240                         inlineMin += childMin;
   4241                 } else {
   4242                     // Now check our line.
   4243                     updatePreferredWidth(minLogicalWidth, childMin);
   4244 
   4245                     // Now start a new line.
   4246                     inlineMin = 0;
   4247                 }
   4248 
   4249                 if (autoWrap && canBreakReplacedElement && isPrevChildInlineFlow) {
   4250                     updatePreferredWidth(minLogicalWidth, inlineMin);
   4251                     inlineMin = 0;
   4252                 }
   4253 
   4254                 // We are no longer stripping whitespace at the start of
   4255                 // a line.
   4256                 if (!child->isFloating()) {
   4257                     stripFrontSpaces = false;
   4258                     trailingSpaceChild = 0;
   4259                 }
   4260             } else if (child->isText()) {
   4261                 // Case (3). Text.
   4262                 RenderText* t = toRenderText(child);
   4263 
   4264                 if (t->isWordBreak()) {
   4265                     updatePreferredWidth(minLogicalWidth, inlineMin);
   4266                     inlineMin = 0;
   4267                     continue;
   4268                 }
   4269 
   4270                 if (t->style()->hasTextCombine() && t->isCombineText())
   4271                     toRenderCombineText(t)->combineText();
   4272 
   4273                 // Determine if we have a breakable character.  Pass in
   4274                 // whether or not we should ignore any spaces at the front
   4275                 // of the string.  If those are going to be stripped out,
   4276                 // then they shouldn't be considered in the breakable char
   4277                 // check.
   4278                 bool hasBreakableChar, hasBreak;
   4279                 float firstLineMinWidth, lastLineMinWidth;
   4280                 bool hasBreakableStart, hasBreakableEnd;
   4281                 float firstLineMaxWidth, lastLineMaxWidth;
   4282                 t->trimmedPrefWidths(inlineMax,
   4283                     firstLineMinWidth, hasBreakableStart, lastLineMinWidth, hasBreakableEnd,
   4284                     hasBreakableChar, hasBreak, firstLineMaxWidth, lastLineMaxWidth,
   4285                     childMin, childMax, stripFrontSpaces);
   4286 
   4287                 // This text object will not be rendered, but it may still provide a breaking opportunity.
   4288                 if (!hasBreak && childMax == 0) {
   4289                     if (autoWrap && (hasBreakableStart || hasBreakableEnd)) {
   4290                         updatePreferredWidth(minLogicalWidth, inlineMin);
   4291                         inlineMin = 0;
   4292                     }
   4293                     continue;
   4294                 }
   4295 
   4296                 if (stripFrontSpaces)
   4297                     trailingSpaceChild = child;
   4298                 else
   4299                     trailingSpaceChild = 0;
   4300 
   4301                 // Add in text-indent.  This is added in only once.
   4302                 float ti = 0;
   4303                 if (!addedTextIndent || hasRemainingNegativeTextIndent) {
   4304                     ti = textIndent.ceilToFloat();
   4305                     childMin += ti;
   4306                     firstLineMinWidth += ti;
   4307 
   4308                     // It the text indent negative and larger than the child minimum, we re-use the remainder
   4309                     // in future minimum calculations, but using the negative value again on the maximum
   4310                     // will lead to under-counting the max pref width.
   4311                     if (!addedTextIndent) {
   4312                         childMax += ti;
   4313                         firstLineMaxWidth += ti;
   4314                         addedTextIndent = true;
   4315                     }
   4316 
   4317                     if (childMin < 0) {
   4318                         textIndent = childMin;
   4319                         hasRemainingNegativeTextIndent = true;
   4320                     }
   4321                 }
   4322 
   4323                 // If we have no breakable characters at all,
   4324                 // then this is the easy case. We add ourselves to the current
   4325                 // min and max and continue.
   4326                 if (!hasBreakableChar) {
   4327                     inlineMin += childMin;
   4328                 } else {
   4329                     if (hasBreakableStart) {
   4330                         updatePreferredWidth(minLogicalWidth, inlineMin);
   4331                     } else {
   4332                         inlineMin += firstLineMinWidth;
   4333                         updatePreferredWidth(minLogicalWidth, inlineMin);
   4334                         childMin -= ti;
   4335                     }
   4336 
   4337                     inlineMin = childMin;
   4338 
   4339                     if (hasBreakableEnd) {
   4340                         updatePreferredWidth(minLogicalWidth, inlineMin);
   4341                         inlineMin = 0;
   4342                         shouldBreakLineAfterText = false;
   4343                     } else {
   4344                         updatePreferredWidth(minLogicalWidth, inlineMin);
   4345                         inlineMin = lastLineMinWidth;
   4346                         shouldBreakLineAfterText = true;
   4347                     }
   4348                 }
   4349 
   4350                 if (hasBreak) {
   4351                     inlineMax += firstLineMaxWidth;
   4352                     updatePreferredWidth(maxLogicalWidth, inlineMax);
   4353                     updatePreferredWidth(maxLogicalWidth, childMax);
   4354                     inlineMax = lastLineMaxWidth;
   4355                     addedTextIndent = true;
   4356                 } else {
   4357                     inlineMax += max<float>(0, childMax);
   4358                 }
   4359             }
   4360 
   4361             // Ignore spaces after a list marker.
   4362             if (child->isListMarker())
   4363                 stripFrontSpaces = true;
   4364         } else {
   4365             updatePreferredWidth(minLogicalWidth, inlineMin);
   4366             updatePreferredWidth(maxLogicalWidth, inlineMax);
   4367             inlineMin = inlineMax = 0;
   4368             stripFrontSpaces = true;
   4369             trailingSpaceChild = 0;
   4370             addedTextIndent = true;
   4371         }
   4372 
   4373         if (!child->isText() && child->isRenderInline())
   4374             isPrevChildInlineFlow = true;
   4375         else
   4376             isPrevChildInlineFlow = false;
   4377 
   4378         oldAutoWrap = autoWrap;
   4379     }
   4380 
   4381     if (styleToUse->collapseWhiteSpace())
   4382         stripTrailingSpace(inlineMax, inlineMin, trailingSpaceChild);
   4383 
   4384     updatePreferredWidth(minLogicalWidth, inlineMin);
   4385     updatePreferredWidth(maxLogicalWidth, inlineMax);
   4386 }
   4387 
   4388 void RenderBlock::computeBlockPreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
   4389 {
   4390     RenderStyle* styleToUse = style();
   4391     bool nowrap = styleToUse->whiteSpace() == NOWRAP;
   4392 
   4393     RenderObject* child = firstChild();
   4394     RenderBlock* containingBlock = this->containingBlock();
   4395     LayoutUnit floatLeftWidth = 0, floatRightWidth = 0;
   4396     while (child) {
   4397         // Positioned children don't affect the min/max width
   4398         if (child->isOutOfFlowPositioned()) {
   4399             child = child->nextSibling();
   4400             continue;
   4401         }
   4402 
   4403         RenderStyle* childStyle = child->style();
   4404         if (child->isFloating() || (child->isBox() && toRenderBox(child)->avoidsFloats())) {
   4405             LayoutUnit floatTotalWidth = floatLeftWidth + floatRightWidth;
   4406             if (childStyle->clear() & CLEFT) {
   4407                 maxLogicalWidth = max(floatTotalWidth, maxLogicalWidth);
   4408                 floatLeftWidth = 0;
   4409             }
   4410             if (childStyle->clear() & CRIGHT) {
   4411                 maxLogicalWidth = max(floatTotalWidth, maxLogicalWidth);
   4412                 floatRightWidth = 0;
   4413             }
   4414         }
   4415 
   4416         // A margin basically has three types: fixed, percentage, and auto (variable).
   4417         // Auto and percentage margins simply become 0 when computing min/max width.
   4418         // Fixed margins can be added in as is.
   4419         Length startMarginLength = childStyle->marginStartUsing(styleToUse);
   4420         Length endMarginLength = childStyle->marginEndUsing(styleToUse);
   4421         LayoutUnit margin = 0;
   4422         LayoutUnit marginStart = 0;
   4423         LayoutUnit marginEnd = 0;
   4424         if (startMarginLength.isFixed())
   4425             marginStart += startMarginLength.value();
   4426         if (endMarginLength.isFixed())
   4427             marginEnd += endMarginLength.value();
   4428         margin = marginStart + marginEnd;
   4429 
   4430         LayoutUnit childMinPreferredLogicalWidth, childMaxPreferredLogicalWidth;
   4431         if (child->isBox() && child->isHorizontalWritingMode() != isHorizontalWritingMode()) {
   4432             RenderBox* childBox = toRenderBox(child);
   4433             LogicalExtentComputedValues computedValues;
   4434             childBox->computeLogicalHeight(childBox->borderAndPaddingLogicalHeight(), 0, computedValues);
   4435             childMinPreferredLogicalWidth = childMaxPreferredLogicalWidth = computedValues.m_extent;
   4436         } else {
   4437             childMinPreferredLogicalWidth = child->minPreferredLogicalWidth();
   4438             childMaxPreferredLogicalWidth = child->maxPreferredLogicalWidth();
   4439         }
   4440 
   4441         LayoutUnit w = childMinPreferredLogicalWidth + margin;
   4442         minLogicalWidth = max(w, minLogicalWidth);
   4443 
   4444         // IE ignores tables for calculation of nowrap. Makes some sense.
   4445         if (nowrap && !child->isTable())
   4446             maxLogicalWidth = max(w, maxLogicalWidth);
   4447 
   4448         w = childMaxPreferredLogicalWidth + margin;
   4449 
   4450         if (!child->isFloating()) {
   4451             if (child->isBox() && toRenderBox(child)->avoidsFloats()) {
   4452                 // Determine a left and right max value based off whether or not the floats can fit in the
   4453                 // margins of the object.  For negative margins, we will attempt to overlap the float if the negative margin
   4454                 // is smaller than the float width.
   4455                 bool ltr = containingBlock ? containingBlock->style()->isLeftToRightDirection() : styleToUse->isLeftToRightDirection();
   4456                 LayoutUnit marginLogicalLeft = ltr ? marginStart : marginEnd;
   4457                 LayoutUnit marginLogicalRight = ltr ? marginEnd : marginStart;
   4458                 LayoutUnit maxLeft = marginLogicalLeft > 0 ? max(floatLeftWidth, marginLogicalLeft) : floatLeftWidth + marginLogicalLeft;
   4459                 LayoutUnit maxRight = marginLogicalRight > 0 ? max(floatRightWidth, marginLogicalRight) : floatRightWidth + marginLogicalRight;
   4460                 w = childMaxPreferredLogicalWidth + maxLeft + maxRight;
   4461                 w = max(w, floatLeftWidth + floatRightWidth);
   4462             }
   4463             else
   4464                 maxLogicalWidth = max(floatLeftWidth + floatRightWidth, maxLogicalWidth);
   4465             floatLeftWidth = floatRightWidth = 0;
   4466         }
   4467 
   4468         if (child->isFloating()) {
   4469             if (childStyle->floating() == LeftFloat)
   4470                 floatLeftWidth += w;
   4471             else
   4472                 floatRightWidth += w;
   4473         } else
   4474             maxLogicalWidth = max(w, maxLogicalWidth);
   4475 
   4476         child = child->nextSibling();
   4477     }
   4478 
   4479     // Always make sure these values are non-negative.
   4480     minLogicalWidth = max<LayoutUnit>(0, minLogicalWidth);
   4481     maxLogicalWidth = max<LayoutUnit>(0, maxLogicalWidth);
   4482 
   4483     maxLogicalWidth = max(floatLeftWidth + floatRightWidth, maxLogicalWidth);
   4484 }
   4485 
   4486 bool RenderBlock::hasLineIfEmpty() const
   4487 {
   4488     if (!node())
   4489         return false;
   4490 
   4491     if (node()->isRootEditableElement())
   4492         return true;
   4493 
   4494     if (node()->isShadowRoot() && toShadowRoot(node())->host()->hasTagName(inputTag))
   4495         return true;
   4496 
   4497     return false;
   4498 }
   4499 
   4500 LayoutUnit RenderBlock::lineHeight(bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
   4501 {
   4502     // Inline blocks are replaced elements. Otherwise, just pass off to
   4503     // the base class.  If we're being queried as though we're the root line
   4504     // box, then the fact that we're an inline-block is irrelevant, and we behave
   4505     // just like a block.
   4506     if (isReplaced() && linePositionMode == PositionOnContainingLine)
   4507         return RenderBox::lineHeight(firstLine, direction, linePositionMode);
   4508 
   4509     if (firstLine && document().styleEngine()->usesFirstLineRules()) {
   4510         RenderStyle* s = style(firstLine);
   4511         if (s != style())
   4512             return s->computedLineHeight(view());
   4513     }
   4514 
   4515     if (m_lineHeight == -1)
   4516         m_lineHeight = style()->computedLineHeight(view());
   4517 
   4518     return m_lineHeight;
   4519 }
   4520 
   4521 int RenderBlock::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
   4522 {
   4523     // Inline blocks are replaced elements. Otherwise, just pass off to
   4524     // the base class.  If we're being queried as though we're the root line
   4525     // box, then the fact that we're an inline-block is irrelevant, and we behave
   4526     // just like a block.
   4527     if (isReplaced() && linePositionMode == PositionOnContainingLine) {
   4528         // For "leaf" theme objects, let the theme decide what the baseline position is.
   4529         // FIXME: Might be better to have a custom CSS property instead, so that if the theme
   4530         // is turned off, checkboxes/radios will still have decent baselines.
   4531         // FIXME: Need to patch form controls to deal with vertical lines.
   4532         if (style()->hasAppearance() && !RenderTheme::theme().isControlContainer(style()->appearance()))
   4533             return RenderTheme::theme().baselinePosition(this);
   4534 
   4535         // CSS2.1 states that the baseline of an inline block is the baseline of the last line box in
   4536         // the normal flow.  We make an exception for marquees, since their baselines are meaningless
   4537         // (the content inside them moves).  This matches WinIE as well, which just bottom-aligns them.
   4538         // We also give up on finding a baseline if we have a vertical scrollbar, or if we are scrolled
   4539         // vertically (e.g., an overflow:hidden block that has had scrollTop moved).
   4540         bool ignoreBaseline = (layer() && layer()->scrollableArea() && (isMarquee() || (direction == HorizontalLine ? (layer()->scrollableArea()->verticalScrollbar() || layer()->scrollableArea()->scrollYOffset())
   4541             : (layer()->scrollableArea()->horizontalScrollbar() || layer()->scrollableArea()->scrollXOffset())))) || (isWritingModeRoot() && !isRubyRun());
   4542 
   4543         int baselinePos = ignoreBaseline ? -1 : inlineBlockBaseline(direction);
   4544 
   4545         if (isDeprecatedFlexibleBox()) {
   4546             // Historically, we did this check for all baselines. But we can't
   4547             // remove this code from deprecated flexbox, because it effectively
   4548             // breaks -webkit-line-clamp, which is used in the wild -- we would
   4549             // calculate the baseline as if -webkit-line-clamp wasn't used.
   4550             // For simplicity, we use this for all uses of deprecated flexbox.
   4551             LayoutUnit bottomOfContent = direction == HorizontalLine ? borderTop() + paddingTop() + contentHeight() : borderRight() + paddingRight() + contentWidth();
   4552             if (baselinePos > bottomOfContent)
   4553                 baselinePos = -1;
   4554         }
   4555         if (baselinePos != -1)
   4556             return direction == HorizontalLine ? marginTop() + baselinePos : marginRight() + baselinePos;
   4557 
   4558         return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
   4559     }
   4560 
   4561     // If we're not replaced, we'll only get called with PositionOfInteriorLineBoxes.
   4562     // Note that inline-block counts as replaced here.
   4563     ASSERT(linePositionMode == PositionOfInteriorLineBoxes);
   4564 
   4565     const FontMetrics& fontMetrics = style(firstLine)->fontMetrics();
   4566     return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2;
   4567 }
   4568 
   4569 LayoutUnit RenderBlock::minLineHeightForReplacedRenderer(bool isFirstLine, LayoutUnit replacedHeight) const
   4570 {
   4571     if (!document().inNoQuirksMode() && replacedHeight)
   4572         return replacedHeight;
   4573 
   4574     if (!(style(isFirstLine)->lineBoxContain() & LineBoxContainBlock))
   4575         return 0;
   4576 
   4577     return std::max<LayoutUnit>(replacedHeight, lineHeight(isFirstLine, isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes));
   4578 }
   4579 
   4580 int RenderBlock::firstLineBoxBaseline() const
   4581 {
   4582     if (isWritingModeRoot() && !isRubyRun())
   4583         return -1;
   4584 
   4585     if (childrenInline()) {
   4586         if (firstLineBox())
   4587             return firstLineBox()->logicalTop() + style(true)->fontMetrics().ascent(firstRootBox()->baselineType());
   4588         else
   4589             return -1;
   4590     }
   4591     else {
   4592         for (RenderBox* curr = firstChildBox(); curr; curr = curr->nextSiblingBox()) {
   4593             if (!curr->isFloatingOrOutOfFlowPositioned()) {
   4594                 int result = curr->firstLineBoxBaseline();
   4595                 if (result != -1)
   4596                     return curr->logicalTop() + result; // Translate to our coordinate space.
   4597             }
   4598         }
   4599     }
   4600 
   4601     return -1;
   4602 }
   4603 
   4604 int RenderBlock::inlineBlockBaseline(LineDirectionMode direction) const
   4605 {
   4606     if (style()->overflowY() != OVISIBLE) {
   4607         // We are not calling RenderBox::baselinePosition here because the caller should add the margin-top/margin-right, not us.
   4608         return direction == HorizontalLine ? height() + m_marginBox.bottom() : width() + m_marginBox.left();
   4609     }
   4610 
   4611     return lastLineBoxBaseline(direction);
   4612 }
   4613 
   4614 int RenderBlock::lastLineBoxBaseline(LineDirectionMode lineDirection) const
   4615 {
   4616     if (isWritingModeRoot() && !isRubyRun())
   4617         return -1;
   4618 
   4619     if (childrenInline()) {
   4620         if (!firstLineBox() && hasLineIfEmpty()) {
   4621             const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
   4622             return fontMetrics.ascent()
   4623                  + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
   4624                  + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
   4625         }
   4626         if (lastLineBox())
   4627             return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->fontMetrics().ascent(lastRootBox()->baselineType());
   4628         return -1;
   4629     } else {
   4630         bool haveNormalFlowChild = false;
   4631         for (RenderBox* curr = lastChildBox(); curr; curr = curr->previousSiblingBox()) {
   4632             if (!curr->isFloatingOrOutOfFlowPositioned()) {
   4633                 haveNormalFlowChild = true;
   4634                 int result = curr->inlineBlockBaseline(lineDirection);
   4635                 if (result != -1)
   4636                     return curr->logicalTop() + result; // Translate to our coordinate space.
   4637             }
   4638         }
   4639         if (!haveNormalFlowChild && hasLineIfEmpty()) {
   4640             const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
   4641             return fontMetrics.ascent()
   4642                  + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
   4643                  + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
   4644         }
   4645     }
   4646 
   4647     return -1;
   4648 }
   4649 
   4650 RenderBlock* RenderBlock::firstLineBlock() const
   4651 {
   4652     RenderBlock* firstLineBlock = const_cast<RenderBlock*>(this);
   4653     bool hasPseudo = false;
   4654     while (true) {
   4655         hasPseudo = firstLineBlock->style()->hasPseudoStyle(FIRST_LINE);
   4656         if (hasPseudo)
   4657             break;
   4658         RenderObject* parentBlock = firstLineBlock->parent();
   4659         // We include isRenderButton in this check because buttons are
   4660         // implemented using flex box but should still support first-line. The
   4661         // flex box spec requires that flex box does not support first-line,
   4662         // though.
   4663         // FIXME: Remove when buttons are implemented with align-items instead
   4664         // of flexbox.
   4665         if (firstLineBlock->isReplaced() || firstLineBlock->isFloating()
   4666             || !parentBlock || parentBlock->firstChild() != firstLineBlock
   4667             || (!parentBlock->isRenderBlockFlow() && !parentBlock->isRenderButton()))
   4668             break;
   4669         ASSERT_WITH_SECURITY_IMPLICATION(parentBlock->isRenderBlock());
   4670         firstLineBlock = toRenderBlock(parentBlock);
   4671     }
   4672 
   4673     if (!hasPseudo)
   4674         return 0;
   4675 
   4676     return firstLineBlock;
   4677 }
   4678 
   4679 static RenderStyle* styleForFirstLetter(RenderObject* firstLetterBlock, RenderObject* firstLetterContainer)
   4680 {
   4681     RenderStyle* pseudoStyle = firstLetterBlock->getCachedPseudoStyle(FIRST_LETTER, firstLetterContainer->firstLineStyle());
   4682     // Force inline display (except for floating first-letters).
   4683     pseudoStyle->setDisplay(pseudoStyle->isFloating() ? BLOCK : INLINE);
   4684     // CSS2 says first-letter can't be positioned.
   4685     pseudoStyle->setPosition(StaticPosition);
   4686     return pseudoStyle;
   4687 }
   4688 
   4689 // CSS 2.1 http://www.w3.org/TR/CSS21/selector.html#first-letter
   4690 // "Punctuation (i.e, characters defined in Unicode [UNICODE] in the "open" (Ps), "close" (Pe),
   4691 // "initial" (Pi). "final" (Pf) and "other" (Po) punctuation classes), that precedes or follows the first letter should be included"
   4692 static inline bool isPunctuationForFirstLetter(UChar c)
   4693 {
   4694     CharCategory charCategory = category(c);
   4695     return charCategory == Punctuation_Open
   4696         || charCategory == Punctuation_Close
   4697         || charCategory == Punctuation_InitialQuote
   4698         || charCategory == Punctuation_FinalQuote
   4699         || charCategory == Punctuation_Other;
   4700 }
   4701 
   4702 static inline bool shouldSkipForFirstLetter(UChar c)
   4703 {
   4704     return isSpaceOrNewline(c) || c == noBreakSpace || isPunctuationForFirstLetter(c);
   4705 }
   4706 
   4707 static inline RenderObject* findFirstLetterBlock(RenderBlock* start)
   4708 {
   4709     RenderObject* firstLetterBlock = start;
   4710     while (true) {
   4711         // We include isRenderButton in these two checks because buttons are
   4712         // implemented using flex box but should still support first-letter.
   4713         // The flex box spec requires that flex box does not support
   4714         // first-letter, though.
   4715         // FIXME: Remove when buttons are implemented with align-items instead
   4716         // of flexbox.
   4717         bool canHaveFirstLetterRenderer = firstLetterBlock->style()->hasPseudoStyle(FIRST_LETTER)
   4718             && firstLetterBlock->canHaveGeneratedChildren()
   4719             && (!firstLetterBlock->isFlexibleBox() || firstLetterBlock->isRenderButton());
   4720         if (canHaveFirstLetterRenderer)
   4721             return firstLetterBlock;
   4722 
   4723         RenderObject* parentBlock = firstLetterBlock->parent();
   4724         if (firstLetterBlock->isReplaced() || !parentBlock || parentBlock->firstChild() != firstLetterBlock ||
   4725             (!parentBlock->isRenderBlockFlow() && !parentBlock->isRenderButton()))
   4726             return 0;
   4727         firstLetterBlock = parentBlock;
   4728     }
   4729 
   4730     return 0;
   4731 }
   4732 
   4733 void RenderBlock::updateFirstLetterStyle(RenderObject* firstLetterBlock, RenderObject* currentChild)
   4734 {
   4735     RenderObject* firstLetter = currentChild->parent();
   4736     RenderObject* firstLetterContainer = firstLetter->parent();
   4737     RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
   4738     ASSERT(firstLetter->isFloating() || firstLetter->isInline());
   4739 
   4740     if (RenderStyle::compare(firstLetter->style(), pseudoStyle) == Reattach) {
   4741         // The first-letter renderer needs to be replaced. Create a new renderer of the right type.
   4742         RenderBoxModelObject* newFirstLetter;
   4743         if (pseudoStyle->display() == INLINE)
   4744             newFirstLetter = RenderInline::createAnonymous(&document());
   4745         else
   4746             newFirstLetter = RenderBlockFlow::createAnonymous(&document());
   4747         newFirstLetter->setStyle(pseudoStyle);
   4748 
   4749         // Move the first letter into the new renderer.
   4750         LayoutStateDisabler layoutStateDisabler(view());
   4751         while (RenderObject* child = firstLetter->firstChild()) {
   4752             if (child->isText())
   4753                 toRenderText(child)->removeAndDestroyTextBoxes();
   4754             firstLetter->removeChild(child);
   4755             newFirstLetter->addChild(child, 0);
   4756         }
   4757 
   4758         RenderObject* nextSibling = firstLetter->nextSibling();
   4759         if (RenderTextFragment* remainingText = toRenderBoxModelObject(firstLetter)->firstLetterRemainingText()) {
   4760             ASSERT(remainingText->isAnonymous() || remainingText->node()->renderer() == remainingText);
   4761             // Replace the old renderer with the new one.
   4762             remainingText->setFirstLetter(newFirstLetter);
   4763             newFirstLetter->setFirstLetterRemainingText(remainingText);
   4764         }
   4765         // To prevent removal of single anonymous block in RenderBlock::removeChild and causing
   4766         // |nextSibling| to go stale, we remove the old first letter using removeChildNode first.
   4767         firstLetterContainer->virtualChildren()->removeChildNode(firstLetterContainer, firstLetter);
   4768         firstLetter->destroy();
   4769         firstLetter = newFirstLetter;
   4770         firstLetterContainer->addChild(firstLetter, nextSibling);
   4771     } else
   4772         firstLetter->setStyle(pseudoStyle);
   4773 
   4774     for (RenderObject* genChild = firstLetter->firstChild(); genChild; genChild = genChild->nextSibling()) {
   4775         if (genChild->isText())
   4776             genChild->setStyle(pseudoStyle);
   4777     }
   4778 }
   4779 
   4780 static inline unsigned firstLetterLength(const String& text)
   4781 {
   4782     unsigned length = 0;
   4783     bool punctuationOpen = false;
   4784 
   4785     // Account for leading spaces and punctuation.
   4786     while (length < text.length() && shouldSkipForFirstLetter((text)[length])) {
   4787         if (isPunctuationForFirstLetter((text)[length]))
   4788             punctuationOpen = true;
   4789 
   4790         length++;
   4791     }
   4792 
   4793     // Bail if we didn't find a letter
   4794     if (text.length() && length == text.length())
   4795         return 0;
   4796 
   4797     // Account for first letter.
   4798     length++;
   4799 
   4800     if (!punctuationOpen)
   4801         return length;
   4802 
   4803     // Keep looking for whitespace and allowed punctuation, but avoid
   4804     // accumulating just whitespace into the :first-letter.
   4805     for (unsigned scanLength = length; scanLength < text.length(); ++scanLength) {
   4806         UChar c = (text)[scanLength];
   4807 
   4808         if (!shouldSkipForFirstLetter(c))
   4809             break;
   4810 
   4811         if (isPunctuationForFirstLetter(c))
   4812             length = scanLength + 1;
   4813     }
   4814 
   4815     return length;
   4816 }
   4817 
   4818 void RenderBlock::createFirstLetterRenderer(RenderObject* firstLetterBlock, RenderObject* currentChild, unsigned length)
   4819 {
   4820     ASSERT(length && currentChild->isText());
   4821 
   4822     RenderObject* firstLetterContainer = currentChild->parent();
   4823     RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
   4824     RenderObject* firstLetter = 0;
   4825     if (pseudoStyle->display() == INLINE)
   4826         firstLetter = RenderInline::createAnonymous(&document());
   4827     else
   4828         firstLetter = RenderBlockFlow::createAnonymous(&document());
   4829     firstLetter->setStyle(pseudoStyle);
   4830     firstLetterContainer->addChild(firstLetter, currentChild);
   4831 
   4832     RenderText* textObj = toRenderText(currentChild);
   4833 
   4834     // The original string is going to be either a generated content string or a DOM node's
   4835     // string.  We want the original string before it got transformed in case first-letter has
   4836     // no text-transform or a different text-transform applied to it.
   4837     String oldText = textObj->originalText();
   4838     ASSERT(oldText.impl());
   4839 
   4840     // Construct a text fragment for the text after the first letter.
   4841     // This text fragment might be empty.
   4842     RenderTextFragment* remainingText =
   4843         new RenderTextFragment(textObj->node() ? textObj->node() : &textObj->document(), oldText.impl(), length, oldText.length() - length);
   4844     remainingText->setStyle(textObj->style());
   4845     if (remainingText->node())
   4846         remainingText->node()->setRenderer(remainingText);
   4847 
   4848     firstLetterContainer->addChild(remainingText, textObj);
   4849     firstLetterContainer->removeChild(textObj);
   4850     remainingText->setFirstLetter(firstLetter);
   4851     toRenderBoxModelObject(firstLetter)->setFirstLetterRemainingText(remainingText);
   4852 
   4853     // construct text fragment for the first letter
   4854     RenderTextFragment* letter =
   4855         new RenderTextFragment(remainingText->node() ? remainingText->node() : &remainingText->document(), oldText.impl(), 0, length);
   4856     letter->setStyle(pseudoStyle);
   4857     firstLetter->addChild(letter);
   4858 
   4859     textObj->destroy();
   4860 }
   4861 
   4862 void RenderBlock::updateFirstLetter()
   4863 {
   4864     if (!document().styleEngine()->usesFirstLetterRules())
   4865         return;
   4866     // Don't recur
   4867     if (style()->styleType() == FIRST_LETTER)
   4868         return;
   4869 
   4870     // FIXME: We need to destroy the first-letter object if it is no longer the first child. Need to find
   4871     // an efficient way to check for that situation though before implementing anything.
   4872     RenderObject* firstLetterBlock = findFirstLetterBlock(this);
   4873     if (!firstLetterBlock)
   4874         return;
   4875 
   4876     // Drill into inlines looking for our first text child.
   4877     RenderObject* currChild = firstLetterBlock->firstChild();
   4878     unsigned length = 0;
   4879     while (currChild) {
   4880         if (currChild->isText()) {
   4881             // FIXME: If there is leading punctuation in a different RenderText than
   4882             // the first letter, we'll not apply the correct style to it.
   4883             length = firstLetterLength(toRenderText(currChild)->originalText());
   4884             if (length)
   4885                 break;
   4886             currChild = currChild->nextSibling();
   4887         } else if (currChild->isListMarker()) {
   4888             currChild = currChild->nextSibling();
   4889         } else if (currChild->isFloatingOrOutOfFlowPositioned()) {
   4890             if (currChild->style()->styleType() == FIRST_LETTER) {
   4891                 currChild = currChild->firstChild();
   4892                 break;
   4893             }
   4894             currChild = currChild->nextSibling();
   4895         } else if (currChild->isReplaced() || currChild->isRenderButton() || currChild->isMenuList())
   4896             break;
   4897         else if (currChild->style()->hasPseudoStyle(FIRST_LETTER) && currChild->canHaveGeneratedChildren())  {
   4898             // We found a lower-level node with first-letter, which supersedes the higher-level style
   4899             firstLetterBlock = currChild;
   4900             currChild = currChild->firstChild();
   4901         } else
   4902             currChild = currChild->firstChild();
   4903     }
   4904 
   4905     if (!currChild)
   4906         return;
   4907 
   4908     // If the child already has style, then it has already been created, so we just want
   4909     // to update it.
   4910     if (currChild->parent()->style()->styleType() == FIRST_LETTER) {
   4911         updateFirstLetterStyle(firstLetterBlock, currChild);
   4912         return;
   4913     }
   4914 
   4915     if (!currChild->isText() || currChild->isBR())
   4916         return;
   4917 
   4918     // Our layout state is not valid for the repaints we are going to trigger by
   4919     // adding and removing children of firstLetterContainer.
   4920     LayoutStateDisabler layoutStateDisabler(view());
   4921 
   4922     createFirstLetterRenderer(firstLetterBlock, currChild, length);
   4923 }
   4924 
   4925 // Helper methods for obtaining the last line, computing line counts and heights for line counts
   4926 // (crawling into blocks).
   4927 static bool shouldCheckLines(RenderObject* obj)
   4928 {
   4929     return !obj->isFloatingOrOutOfFlowPositioned()
   4930         && obj->isRenderBlock() && obj->style()->height().isAuto()
   4931         && (!obj->isDeprecatedFlexibleBox() || obj->style()->boxOrient() == VERTICAL);
   4932 }
   4933 
   4934 static int getHeightForLineCount(RenderBlock* block, int l, bool includeBottom, int& count)
   4935 {
   4936     if (block->style()->visibility() == VISIBLE) {
   4937         if (block->childrenInline()) {
   4938             for (RootInlineBox* box = block->firstRootBox(); box; box = box->nextRootBox()) {
   4939                 if (++count == l)
   4940                     return box->lineBottom() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : LayoutUnit());
   4941             }
   4942         }
   4943         else {
   4944             RenderBox* normalFlowChildWithoutLines = 0;
   4945             for (RenderBox* obj = block->firstChildBox(); obj; obj = obj->nextSiblingBox()) {
   4946                 if (shouldCheckLines(obj)) {
   4947                     int result = getHeightForLineCount(toRenderBlock(obj), l, false, count);
   4948                     if (result != -1)
   4949                         return result + obj->y() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : LayoutUnit());
   4950                 } else if (!obj->isFloatingOrOutOfFlowPositioned())
   4951                     normalFlowChildWithoutLines = obj;
   4952             }
   4953             if (normalFlowChildWithoutLines && l == 0)
   4954                 return normalFlowChildWithoutLines->y() + normalFlowChildWithoutLines->height();
   4955         }
   4956     }
   4957 
   4958     return -1;
   4959 }
   4960 
   4961 RootInlineBox* RenderBlock::lineAtIndex(int i) const
   4962 {
   4963     ASSERT(i >= 0);
   4964 
   4965     if (style()->visibility() != VISIBLE)
   4966         return 0;
   4967 
   4968     if (childrenInline()) {
   4969         for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
   4970             if (!i--)
   4971                 return box;
   4972     } else {
   4973         for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
   4974             if (!shouldCheckLines(child))
   4975                 continue;
   4976             if (RootInlineBox* box = toRenderBlock(child)->lineAtIndex(i))
   4977                 return box;
   4978         }
   4979     }
   4980 
   4981     return 0;
   4982 }
   4983 
   4984 int RenderBlock::lineCount(const RootInlineBox* stopRootInlineBox, bool* found) const
   4985 {
   4986     int count = 0;
   4987 
   4988     if (style()->visibility() == VISIBLE) {
   4989         if (childrenInline())
   4990             for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) {
   4991                 count++;
   4992                 if (box == stopRootInlineBox) {
   4993                     if (found)
   4994                         *found = true;
   4995                     break;
   4996                 }
   4997             }
   4998         else
   4999             for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling())
   5000                 if (shouldCheckLines(obj)) {
   5001                     bool recursiveFound = false;
   5002                     count += toRenderBlock(obj)->lineCount(stopRootInlineBox, &recursiveFound);
   5003                     if (recursiveFound) {
   5004                         if (found)
   5005                             *found = true;
   5006                         break;
   5007                     }
   5008                 }
   5009     }
   5010     return count;
   5011 }
   5012 
   5013 int RenderBlock::heightForLineCount(int l)
   5014 {
   5015     int count = 0;
   5016     return getHeightForLineCount(this, l, true, count);
   5017 }
   5018 
   5019 void RenderBlock::adjustForBorderFit(LayoutUnit x, LayoutUnit& left, LayoutUnit& right) const
   5020 {
   5021     // We don't deal with relative positioning.  Our assumption is that you shrink to fit the lines without accounting
   5022     // for either overflow or translations via relative positioning.
   5023     if (style()->visibility() == VISIBLE) {
   5024         if (childrenInline()) {
   5025             for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) {
   5026                 if (box->firstChild())
   5027                     left = min(left, x + static_cast<LayoutUnit>(box->firstChild()->x()));
   5028                 if (box->lastChild())
   5029                     right = max(right, x + static_cast<LayoutUnit>(ceilf(box->lastChild()->logicalRight())));
   5030             }
   5031         } else {
   5032             for (RenderBox* obj = firstChildBox(); obj; obj = obj->nextSiblingBox()) {
   5033                 if (!obj->isFloatingOrOutOfFlowPositioned()) {
   5034                     if (obj->isRenderBlockFlow() && !obj->hasOverflowClip())
   5035                         toRenderBlock(obj)->adjustForBorderFit(x + obj->x(), left, right);
   5036                     else if (obj->style()->visibility() == VISIBLE) {
   5037                         // We are a replaced element or some kind of non-block-flow object.
   5038                         left = min(left, x + obj->x());
   5039                         right = max(right, x + obj->x() + obj->width());
   5040                     }
   5041                 }
   5042             }
   5043         }
   5044     }
   5045 }
   5046 
   5047 void RenderBlock::fitBorderToLinesIfNeeded()
   5048 {
   5049     if (style()->borderFit() == BorderFitBorder || hasOverrideWidth())
   5050         return;
   5051 
   5052     // Walk any normal flow lines to snugly fit.
   5053     LayoutUnit left = LayoutUnit::max();
   5054     LayoutUnit right = LayoutUnit::min();
   5055     LayoutUnit oldWidth = contentWidth();
   5056     adjustForBorderFit(0, left, right);
   5057 
   5058     // Clamp to our existing edges. We can never grow. We only shrink.
   5059     LayoutUnit leftEdge = borderLeft() + paddingLeft();
   5060     LayoutUnit rightEdge = leftEdge + oldWidth;
   5061     left = min(rightEdge, max(leftEdge, left));
   5062     right = max(leftEdge, min(rightEdge, right));
   5063 
   5064     LayoutUnit newContentWidth = right - left;
   5065     if (newContentWidth == oldWidth)
   5066         return;
   5067 
   5068     setOverrideLogicalContentWidth(newContentWidth);
   5069     layoutBlock(false);
   5070     clearOverrideLogicalContentWidth();
   5071 }
   5072 
   5073 void RenderBlock::clearTruncation()
   5074 {
   5075     if (style()->visibility() == VISIBLE) {
   5076         if (childrenInline() && hasMarkupTruncation()) {
   5077             setHasMarkupTruncation(false);
   5078             for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
   5079                 box->clearTruncation();
   5080         } else {
   5081             for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling()) {
   5082                 if (shouldCheckLines(obj))
   5083                     toRenderBlock(obj)->clearTruncation();
   5084             }
   5085         }
   5086     }
   5087 }
   5088 
   5089 void RenderBlock::setPaginationStrut(LayoutUnit strut)
   5090 {
   5091     if (!m_rareData) {
   5092         if (!strut)
   5093             return;
   5094         m_rareData = adoptPtr(new RenderBlockRareData());
   5095     }
   5096     m_rareData->m_paginationStrut = strut;
   5097 }
   5098 
   5099 void RenderBlock::setPageLogicalOffset(LayoutUnit logicalOffset)
   5100 {
   5101     if (!m_rareData) {
   5102         if (!logicalOffset)
   5103             return;
   5104         m_rareData = adoptPtr(new RenderBlockRareData());
   5105     }
   5106     m_rareData->m_pageLogicalOffset = logicalOffset;
   5107 }
   5108 
   5109 void RenderBlock::setBreakAtLineToAvoidWidow(int lineToBreak)
   5110 {
   5111     ASSERT(lineToBreak >= 0);
   5112     if (!m_rareData)
   5113         m_rareData = adoptPtr(new RenderBlockRareData());
   5114 
   5115     ASSERT(!m_rareData->m_didBreakAtLineToAvoidWidow);
   5116     m_rareData->m_lineBreakToAvoidWidow = lineToBreak;
   5117 }
   5118 
   5119 void RenderBlock::setDidBreakAtLineToAvoidWidow()
   5120 {
   5121     ASSERT(!shouldBreakAtLineToAvoidWidow());
   5122 
   5123     // This function should be called only after a break was applied to avoid widows
   5124     // so assert |m_rareData| exists.
   5125     ASSERT(m_rareData);
   5126 
   5127     m_rareData->m_didBreakAtLineToAvoidWidow = true;
   5128 }
   5129 
   5130 void RenderBlock::clearDidBreakAtLineToAvoidWidow()
   5131 {
   5132     if (!m_rareData)
   5133         return;
   5134 
   5135     m_rareData->m_didBreakAtLineToAvoidWidow = false;
   5136 }
   5137 
   5138 void RenderBlock::clearShouldBreakAtLineToAvoidWidow() const
   5139 {
   5140     ASSERT(shouldBreakAtLineToAvoidWidow());
   5141     if (!m_rareData)
   5142         return;
   5143 
   5144     m_rareData->m_lineBreakToAvoidWidow = -1;
   5145 }
   5146 
   5147 void RenderBlock::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const
   5148 {
   5149     // For blocks inside inlines, we go ahead and include margins so that we run right up to the
   5150     // inline boxes above and below us (thus getting merged with them to form a single irregular
   5151     // shape).
   5152     if (isAnonymousBlockContinuation()) {
   5153         // FIXME: This is wrong for block-flows that are horizontal.
   5154         // https://bugs.webkit.org/show_bug.cgi?id=46781
   5155         rects.append(pixelSnappedIntRect(accumulatedOffset.x(), accumulatedOffset.y() - collapsedMarginBefore(),
   5156                                 width(), height() + collapsedMarginBefore() + collapsedMarginAfter()));
   5157         continuation()->absoluteRects(rects, accumulatedOffset - toLayoutSize(location() +
   5158                 inlineElementContinuation()->containingBlock()->location()));
   5159     } else
   5160         rects.append(pixelSnappedIntRect(accumulatedOffset, size()));
   5161 }
   5162 
   5163 void RenderBlock::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
   5164 {
   5165     // For blocks inside inlines, we go ahead and include margins so that we run right up to the
   5166     // inline boxes above and below us (thus getting merged with them to form a single irregular
   5167     // shape).
   5168     if (isAnonymousBlockContinuation()) {
   5169         // FIXME: This is wrong for block-flows that are horizontal.
   5170         // https://bugs.webkit.org/show_bug.cgi?id=46781
   5171         FloatRect localRect(0, -collapsedMarginBefore(),
   5172                             width(), height() + collapsedMarginBefore() + collapsedMarginAfter());
   5173         quads.append(localToAbsoluteQuad(localRect, 0 /* mode */, wasFixed));
   5174         continuation()->absoluteQuads(quads, wasFixed);
   5175     } else
   5176         quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width(), height()), 0 /* mode */, wasFixed));
   5177 }
   5178 
   5179 LayoutRect RenderBlock::rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const
   5180 {
   5181     LayoutRect r(RenderBox::rectWithOutlineForRepaint(repaintContainer, outlineWidth));
   5182     if (isAnonymousBlockContinuation())
   5183         r.inflateY(collapsedMarginBefore()); // FIXME: This is wrong for block-flows that are horizontal.
   5184     return r;
   5185 }
   5186 
   5187 RenderObject* RenderBlock::hoverAncestor() const
   5188 {
   5189     return isAnonymousBlockContinuation() ? continuation() : RenderBox::hoverAncestor();
   5190 }
   5191 
   5192 void RenderBlock::updateDragState(bool dragOn)
   5193 {
   5194     RenderBox::updateDragState(dragOn);
   5195     if (continuation())
   5196         continuation()->updateDragState(dragOn);
   5197 }
   5198 
   5199 RenderStyle* RenderBlock::outlineStyleForRepaint() const
   5200 {
   5201     return isAnonymousBlockContinuation() ? continuation()->style() : style();
   5202 }
   5203 
   5204 void RenderBlock::childBecameNonInline(RenderObject*)
   5205 {
   5206     makeChildrenNonInline();
   5207     if (isAnonymousBlock() && parent() && parent()->isRenderBlock())
   5208         toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
   5209     // |this| may be dead here
   5210 }
   5211 
   5212 void RenderBlock::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
   5213 {
   5214     if (result.innerNode())
   5215         return;
   5216 
   5217     if (Node* n = nodeForHitTest()) {
   5218         result.setInnerNode(n);
   5219         if (!result.innerNonSharedNode())
   5220             result.setInnerNonSharedNode(n);
   5221         result.setLocalPoint(point);
   5222     }
   5223 }
   5224 
   5225 LayoutRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, LayoutUnit* extraWidthToEndOfLine)
   5226 {
   5227     // Do the normal calculation in most cases.
   5228     if (firstChild())
   5229         return RenderBox::localCaretRect(inlineBox, caretOffset, extraWidthToEndOfLine);
   5230 
   5231     LayoutRect caretRect = localCaretRectForEmptyElement(width(), textIndentOffset());
   5232 
   5233     if (extraWidthToEndOfLine) {
   5234         if (isRenderBlock()) {
   5235             *extraWidthToEndOfLine = width() - caretRect.maxX();
   5236         } else {
   5237             // FIXME: This code looks wrong.
   5238             // myRight and containerRight are set up, but then clobbered.
   5239             // So *extraWidthToEndOfLine will always be 0 here.
   5240 
   5241             LayoutUnit myRight = caretRect.maxX();
   5242             // FIXME: why call localToAbsoluteForContent() twice here, too?
   5243             FloatPoint absRightPoint = localToAbsolute(FloatPoint(myRight, 0));
   5244 
   5245             LayoutUnit containerRight = containingBlock()->x() + containingBlockLogicalWidthForContent();
   5246             FloatPoint absContainerPoint = localToAbsolute(FloatPoint(containerRight, 0));
   5247 
   5248             *extraWidthToEndOfLine = absContainerPoint.x() - absRightPoint.x();
   5249         }
   5250     }
   5251 
   5252     return caretRect;
   5253 }
   5254 
   5255 void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer)
   5256 {
   5257     // For blocks inside inlines, we go ahead and include margins so that we run right up to the
   5258     // inline boxes above and below us (thus getting merged with them to form a single irregular
   5259     // shape).
   5260     if (inlineElementContinuation()) {
   5261         // FIXME: This check really isn't accurate.
   5262         bool nextInlineHasLineBox = inlineElementContinuation()->firstLineBox();
   5263         // FIXME: This is wrong. The principal renderer may not be the continuation preceding this block.
   5264         // FIXME: This is wrong for block-flows that are horizontal.
   5265         // https://bugs.webkit.org/show_bug.cgi?id=46781
   5266         bool prevInlineHasLineBox = toRenderInline(inlineElementContinuation()->node()->renderer())->firstLineBox();
   5267         float topMargin = prevInlineHasLineBox ? collapsedMarginBefore() : LayoutUnit();
   5268         float bottomMargin = nextInlineHasLineBox ? collapsedMarginAfter() : LayoutUnit();
   5269         LayoutRect rect(additionalOffset.x(), additionalOffset.y() - topMargin, width(), height() + topMargin + bottomMargin);
   5270         if (!rect.isEmpty())
   5271             rects.append(pixelSnappedIntRect(rect));
   5272     } else if (width() && height())
   5273         rects.append(pixelSnappedIntRect(additionalOffset, size()));
   5274 
   5275     if (!hasOverflowClip() && !hasControlClip()) {
   5276         for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
   5277             LayoutUnit top = max<LayoutUnit>(curr->lineTop(), curr->top());
   5278             LayoutUnit bottom = min<LayoutUnit>(curr->lineBottom(), curr->top() + curr->height());
   5279             LayoutRect rect(additionalOffset.x() + curr->x(), additionalOffset.y() + top, curr->width(), bottom - top);
   5280             if (!rect.isEmpty())
   5281                 rects.append(pixelSnappedIntRect(rect));
   5282         }
   5283 
   5284         for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
   5285             if (!curr->isText() && !curr->isListMarker() && curr->isBox()) {
   5286                 RenderBox* box = toRenderBox(curr);
   5287                 FloatPoint pos;
   5288                 // FIXME: This doesn't work correctly with transforms.
   5289                 if (box->layer())
   5290                     pos = curr->localToContainerPoint(FloatPoint(), paintContainer);
   5291                 else
   5292                     pos = FloatPoint(additionalOffset.x() + box->x(), additionalOffset.y() + box->y());
   5293                 box->addFocusRingRects(rects, flooredLayoutPoint(pos), paintContainer);
   5294             }
   5295         }
   5296     }
   5297 
   5298     if (inlineElementContinuation())
   5299         inlineElementContinuation()->addFocusRingRects(rects, flooredLayoutPoint(additionalOffset + inlineElementContinuation()->containingBlock()->location() - location()), paintContainer);
   5300 }
   5301 
   5302 void RenderBlock::computeSelfHitTestRects(Vector<LayoutRect>& rects, const LayoutPoint& layerOffset) const
   5303 {
   5304     RenderBox::computeSelfHitTestRects(rects, layerOffset);
   5305 
   5306     if (hasHorizontalLayoutOverflow() || hasVerticalLayoutOverflow()) {
   5307         for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
   5308             LayoutUnit top = max<LayoutUnit>(curr->lineTop(), curr->top());
   5309             LayoutUnit bottom = min<LayoutUnit>(curr->lineBottom(), curr->top() + curr->height());
   5310             LayoutRect rect(layerOffset.x() + curr->x(), layerOffset.y() + top, curr->width(), bottom - top);
   5311             // It's common for this rect to be entirely contained in our box, so exclude that simple case.
   5312             if (!rect.isEmpty() && (rects.isEmpty() || !rects[0].contains(rect)))
   5313                 rects.append(rect);
   5314         }
   5315     }
   5316 }
   5317 
   5318 RenderBox* RenderBlock::createAnonymousBoxWithSameTypeAs(const RenderObject* parent) const
   5319 {
   5320     if (isAnonymousColumnsBlock())
   5321         return createAnonymousColumnsWithParentRenderer(parent);
   5322     if (isAnonymousColumnSpanBlock())
   5323         return createAnonymousColumnSpanWithParentRenderer(parent);
   5324     return createAnonymousWithParentRendererAndDisplay(parent, style()->display());
   5325 }
   5326 
   5327 bool RenderBlock::hasNextPage(LayoutUnit logicalOffset, PageBoundaryRule pageBoundaryRule) const
   5328 {
   5329     ASSERT(view()->layoutState() && view()->layoutState()->isPaginated());
   5330 
   5331     RenderFlowThread* flowThread = flowThreadContainingBlock();
   5332     if (!flowThread)
   5333         return true; // Printing and multi-column both make new pages to accommodate content.
   5334 
   5335     // See if we're in the last region.
   5336     LayoutUnit pageOffset = offsetFromLogicalTopOfFirstPage() + logicalOffset;
   5337     RenderRegion* region = flowThread->regionAtBlockOffset(pageOffset, this);
   5338     if (!region)
   5339         return false;
   5340     if (region->isLastRegion())
   5341         return region->isRenderRegionSet() || region->style()->regionFragment() == BreakRegionFragment
   5342             || (pageBoundaryRule == IncludePageBoundary && pageOffset == region->logicalTopForFlowThreadContent());
   5343     return true;
   5344 }
   5345 
   5346 LayoutUnit RenderBlock::nextPageLogicalTop(LayoutUnit logicalOffset, PageBoundaryRule pageBoundaryRule) const
   5347 {
   5348     LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
   5349     if (!pageLogicalHeight)
   5350         return logicalOffset;
   5351 
   5352     // The logicalOffset is in our coordinate space.  We can add in our pushed offset.
   5353     LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset);
   5354     if (pageBoundaryRule == ExcludePageBoundary)
   5355         return logicalOffset + (remainingLogicalHeight ? remainingLogicalHeight : pageLogicalHeight);
   5356     return logicalOffset + remainingLogicalHeight;
   5357 }
   5358 
   5359 ColumnInfo::PaginationUnit RenderBlock::paginationUnit() const
   5360 {
   5361     return ColumnInfo::Column;
   5362 }
   5363 
   5364 LayoutUnit RenderBlock::pageLogicalTopForOffset(LayoutUnit offset) const
   5365 {
   5366     RenderView* renderView = view();
   5367     LayoutUnit firstPageLogicalTop = isHorizontalWritingMode() ? renderView->layoutState()->m_pageOffset.height() : renderView->layoutState()->m_pageOffset.width();
   5368     LayoutUnit blockLogicalTop = isHorizontalWritingMode() ? renderView->layoutState()->m_layoutOffset.height() : renderView->layoutState()->m_layoutOffset.width();
   5369 
   5370     LayoutUnit cumulativeOffset = offset + blockLogicalTop;
   5371     RenderFlowThread* flowThread = flowThreadContainingBlock();
   5372     if (!flowThread) {
   5373         LayoutUnit pageLogicalHeight = renderView->layoutState()->pageLogicalHeight();
   5374         if (!pageLogicalHeight)
   5375             return 0;
   5376         return cumulativeOffset - roundToInt(cumulativeOffset - firstPageLogicalTop) % roundToInt(pageLogicalHeight);
   5377     }
   5378     return flowThread->pageLogicalTopForOffset(cumulativeOffset);
   5379 }
   5380 
   5381 LayoutUnit RenderBlock::pageLogicalHeightForOffset(LayoutUnit offset) const
   5382 {
   5383     RenderView* renderView = view();
   5384     RenderFlowThread* flowThread = flowThreadContainingBlock();
   5385     if (!flowThread)
   5386         return renderView->layoutState()->m_pageLogicalHeight;
   5387     return flowThread->pageLogicalHeightForOffset(offset + offsetFromLogicalTopOfFirstPage());
   5388 }
   5389 
   5390 LayoutUnit RenderBlock::pageRemainingLogicalHeightForOffset(LayoutUnit offset, PageBoundaryRule pageBoundaryRule) const
   5391 {
   5392     RenderView* renderView = view();
   5393     offset += offsetFromLogicalTopOfFirstPage();
   5394 
   5395     RenderFlowThread* flowThread = flowThreadContainingBlock();
   5396     if (!flowThread) {
   5397         LayoutUnit pageLogicalHeight = renderView->layoutState()->m_pageLogicalHeight;
   5398         LayoutUnit remainingHeight = pageLogicalHeight - intMod(offset, pageLogicalHeight);
   5399         if (pageBoundaryRule == IncludePageBoundary) {
   5400             // If includeBoundaryPoint is true the line exactly on the top edge of a
   5401             // column will act as being part of the previous column.
   5402             remainingHeight = intMod(remainingHeight, pageLogicalHeight);
   5403         }
   5404         return remainingHeight;
   5405     }
   5406 
   5407     return flowThread->pageRemainingLogicalHeightForOffset(offset, pageBoundaryRule);
   5408 }
   5409 
   5410 LayoutUnit RenderBlock::adjustForUnsplittableChild(RenderBox* child, LayoutUnit logicalOffset, bool includeMargins)
   5411 {
   5412     bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
   5413     bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight;
   5414     RenderFlowThread* flowThread = flowThreadContainingBlock();
   5415     bool checkRegionBreaks = flowThread && flowThread->isRenderNamedFlowThread();
   5416     bool isUnsplittable = child->isUnsplittableForPagination() || (checkColumnBreaks && child->style()->columnBreakInside() == PBAVOID)
   5417         || (checkPageBreaks && child->style()->pageBreakInside() == PBAVOID)
   5418         || (checkRegionBreaks && child->style()->regionBreakInside() == PBAVOID);
   5419     if (!isUnsplittable)
   5420         return logicalOffset;
   5421     LayoutUnit childLogicalHeight = logicalHeightForChild(child) + (includeMargins ? marginBeforeForChild(child) + marginAfterForChild(child) : LayoutUnit());
   5422     LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
   5423     bool hasUniformPageLogicalHeight = !flowThread || flowThread->regionsHaveUniformLogicalHeight();
   5424     updateMinimumPageHeight(logicalOffset, childLogicalHeight);
   5425     if (!pageLogicalHeight || (hasUniformPageLogicalHeight && childLogicalHeight > pageLogicalHeight)
   5426         || !hasNextPage(logicalOffset))
   5427         return logicalOffset;
   5428     LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset, ExcludePageBoundary);
   5429     if (remainingLogicalHeight < childLogicalHeight) {
   5430         if (!hasUniformPageLogicalHeight && !pushToNextPageWithMinimumLogicalHeight(remainingLogicalHeight, logicalOffset, childLogicalHeight))
   5431             return logicalOffset;
   5432         return logicalOffset + remainingLogicalHeight;
   5433     }
   5434     return logicalOffset;
   5435 }
   5436 
   5437 bool RenderBlock::pushToNextPageWithMinimumLogicalHeight(LayoutUnit& adjustment, LayoutUnit logicalOffset, LayoutUnit minimumLogicalHeight) const
   5438 {
   5439     bool checkRegion = false;
   5440     for (LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset + adjustment); pageLogicalHeight;
   5441         pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset + adjustment)) {
   5442         if (minimumLogicalHeight <= pageLogicalHeight)
   5443             return true;
   5444         if (!hasNextPage(logicalOffset + adjustment))
   5445             return false;
   5446         adjustment += pageLogicalHeight;
   5447         checkRegion = true;
   5448     }
   5449     return !checkRegion;
   5450 }
   5451 
   5452 void RenderBlock::setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage)
   5453 {
   5454     if (RenderFlowThread* flowThread = flowThreadContainingBlock())
   5455         flowThread->setPageBreak(offsetFromLogicalTopOfFirstPage() + offset, spaceShortage);
   5456 }
   5457 
   5458 void RenderBlock::updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight)
   5459 {
   5460     if (RenderFlowThread* flowThread = flowThreadContainingBlock())
   5461         flowThread->updateMinimumPageHeight(offsetFromLogicalTopOfFirstPage() + offset, minHeight);
   5462     else if (ColumnInfo* colInfo = view()->layoutState()->m_columnInfo)
   5463         colInfo->updateMinimumColumnHeight(minHeight);
   5464 }
   5465 
   5466 static inline LayoutUnit calculateMinimumPageHeight(RenderStyle* renderStyle, RootInlineBox* lastLine, LayoutUnit lineTop, LayoutUnit lineBottom)
   5467 {
   5468     // We may require a certain minimum number of lines per page in order to satisfy
   5469     // orphans and widows, and that may affect the minimum page height.
   5470     unsigned lineCount = max<unsigned>(renderStyle->hasAutoOrphans() ? 1 : renderStyle->orphans(), renderStyle->hasAutoWidows() ? 1 : renderStyle->widows());
   5471     if (lineCount > 1) {
   5472         RootInlineBox* line = lastLine;
   5473         for (unsigned i = 1; i < lineCount && line->prevRootBox(); i++)
   5474             line = line->prevRootBox();
   5475 
   5476         // FIXME: Paginating using line overflow isn't all fine. See FIXME in
   5477         // adjustLinePositionForPagination() for more details.
   5478         LayoutRect overflow = line->logicalVisualOverflowRect(line->lineTop(), line->lineBottom());
   5479         lineTop = min(line->lineTopWithLeading(), overflow.y());
   5480     }
   5481     return lineBottom - lineTop;
   5482 }
   5483 
   5484 void RenderBlock::adjustLinePositionForPagination(RootInlineBox* lineBox, LayoutUnit& delta, RenderFlowThread* flowThread)
   5485 {
   5486     // FIXME: For now we paginate using line overflow.  This ensures that lines don't overlap at all when we
   5487     // put a strut between them for pagination purposes.  However, this really isn't the desired rendering, since
   5488     // the line on the top of the next page will appear too far down relative to the same kind of line at the top
   5489     // of the first column.
   5490     //
   5491     // The rendering we would like to see is one where the lineTopWithLeading is at the top of the column, and any line overflow
   5492     // simply spills out above the top of the column.  This effect would match what happens at the top of the first column.
   5493     // We can't achieve this rendering, however, until we stop columns from clipping to the column bounds (thus allowing
   5494     // for overflow to occur), and then cache visible overflow for each column rect.
   5495     //
   5496     // Furthermore, the paint we have to do when a column has overflow has to be special.  We need to exclude
   5497     // content that paints in a previous column (and content that paints in the following column).
   5498     //
   5499     // For now we'll at least honor the lineTopWithLeading when paginating if it is above the logical top overflow. This will
   5500     // at least make positive leading work in typical cases.
   5501     //
   5502     // FIXME: Another problem with simply moving lines is that the available line width may change (because of floats).
   5503     // Technically if the location we move the line to has a different line width than our old position, then we need to dirty the
   5504     // line and all following lines.
   5505     LayoutRect logicalVisualOverflow = lineBox->logicalVisualOverflowRect(lineBox->lineTop(), lineBox->lineBottom());
   5506     LayoutUnit logicalOffset = min(lineBox->lineTopWithLeading(), logicalVisualOverflow.y());
   5507     LayoutUnit logicalBottom = max(lineBox->lineBottomWithLeading(), logicalVisualOverflow.maxY());
   5508     LayoutUnit lineHeight = logicalBottom - logicalOffset;
   5509     updateMinimumPageHeight(logicalOffset, calculateMinimumPageHeight(style(), lineBox, logicalOffset, logicalBottom));
   5510     logicalOffset += delta;
   5511     lineBox->setPaginationStrut(0);
   5512     lineBox->setIsFirstAfterPageBreak(false);
   5513     LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
   5514     bool hasUniformPageLogicalHeight = !flowThread || flowThread->regionsHaveUniformLogicalHeight();
   5515     // If lineHeight is greater than pageLogicalHeight, but logicalVisualOverflow.height() still fits, we are
   5516     // still going to add a strut, so that the visible overflow fits on a single page.
   5517     if (!pageLogicalHeight || (hasUniformPageLogicalHeight && logicalVisualOverflow.height() > pageLogicalHeight)
   5518         || !hasNextPage(logicalOffset))
   5519         // FIXME: In case the line aligns with the top of the page (or it's slightly shifted downwards) it will not be marked as the first line in the page.
   5520         // From here, the fix is not straightforward because it's not easy to always determine when the current line is the first in the page.
   5521         return;
   5522     LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset, ExcludePageBoundary);
   5523 
   5524     int lineIndex = lineCount(lineBox);
   5525     if (remainingLogicalHeight < lineHeight || (shouldBreakAtLineToAvoidWidow() && lineBreakToAvoidWidow() == lineIndex)) {
   5526         if (shouldBreakAtLineToAvoidWidow() && lineBreakToAvoidWidow() == lineIndex) {
   5527             clearShouldBreakAtLineToAvoidWidow();
   5528             setDidBreakAtLineToAvoidWidow();
   5529         }
   5530         // If we have a non-uniform page height, then we have to shift further possibly.
   5531         if (!hasUniformPageLogicalHeight && !pushToNextPageWithMinimumLogicalHeight(remainingLogicalHeight, logicalOffset, lineHeight))
   5532             return;
   5533         if (lineHeight > pageLogicalHeight) {
   5534             // Split the top margin in order to avoid splitting the visible part of the line.
   5535             remainingLogicalHeight -= min(lineHeight - pageLogicalHeight, max<LayoutUnit>(0, logicalVisualOverflow.y() - lineBox->lineTopWithLeading()));
   5536         }
   5537         LayoutUnit totalLogicalHeight = lineHeight + max<LayoutUnit>(0, logicalOffset);
   5538         LayoutUnit pageLogicalHeightAtNewOffset = hasUniformPageLogicalHeight ? pageLogicalHeight : pageLogicalHeightForOffset(logicalOffset + remainingLogicalHeight);
   5539         setPageBreak(logicalOffset, lineHeight - remainingLogicalHeight);
   5540         if (((lineBox == firstRootBox() && totalLogicalHeight < pageLogicalHeightAtNewOffset) || (!style()->hasAutoOrphans() && style()->orphans() >= lineIndex))
   5541             && !isOutOfFlowPositioned() && !isTableCell())
   5542             setPaginationStrut(remainingLogicalHeight + max<LayoutUnit>(0, logicalOffset));
   5543         else {
   5544             delta += remainingLogicalHeight;
   5545             lineBox->setPaginationStrut(remainingLogicalHeight);
   5546             lineBox->setIsFirstAfterPageBreak(true);
   5547         }
   5548     } else if (remainingLogicalHeight == pageLogicalHeight) {
   5549         // We're at the very top of a page or column.
   5550         if (lineBox != firstRootBox())
   5551             lineBox->setIsFirstAfterPageBreak(true);
   5552         if (lineBox != firstRootBox() || offsetFromLogicalTopOfFirstPage())
   5553             setPageBreak(logicalOffset, lineHeight);
   5554     }
   5555 }
   5556 
   5557 void RenderBlock::updateRegionForLine(RootInlineBox* lineBox) const
   5558 {
   5559     ASSERT(lineBox);
   5560     lineBox->setContainingRegion(regionAtBlockOffset(lineBox->lineTopWithLeading()));
   5561 
   5562     RootInlineBox* prevLineBox = lineBox->prevRootBox();
   5563     if (!prevLineBox)
   5564         return;
   5565 
   5566     // This check is more accurate than the one in |adjustLinePositionForPagination| because it takes into
   5567     // account just the container changes between lines. The before mentioned function doesn't set the flag
   5568     // correctly if the line is positioned at the top of the last fragment container.
   5569     if (lineBox->containingRegion() != prevLineBox->containingRegion())
   5570         lineBox->setIsFirstAfterPageBreak(true);
   5571 }
   5572 
   5573 bool RenderBlock::lineWidthForPaginatedLineChanged(RootInlineBox* rootBox, LayoutUnit lineDelta, RenderFlowThread* flowThread) const
   5574 {
   5575     if (!flowThread)
   5576         return false;
   5577 
   5578     RenderRegion* currentRegion = regionAtBlockOffset(rootBox->lineTopWithLeading() + lineDelta);
   5579     // Just bail if the region didn't change.
   5580     if (rootBox->containingRegion() == currentRegion)
   5581         return false;
   5582     return rootBox->paginatedLineWidth() != availableLogicalWidthForContent(currentRegion);
   5583 }
   5584 
   5585 LayoutUnit RenderBlock::offsetFromLogicalTopOfFirstPage() const
   5586 {
   5587     LayoutState* layoutState = view()->layoutState();
   5588     if (layoutState && !layoutState->isPaginated())
   5589         return 0;
   5590 
   5591     RenderFlowThread* flowThread = flowThreadContainingBlock();
   5592     if (flowThread)
   5593         return flowThread->offsetFromLogicalTopOfFirstRegion(this);
   5594 
   5595     if (layoutState) {
   5596         ASSERT(layoutState->renderer() == this);
   5597 
   5598         LayoutSize offsetDelta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
   5599         return isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.width();
   5600     }
   5601 
   5602     ASSERT_NOT_REACHED();
   5603     return 0;
   5604 }
   5605 
   5606 RenderRegion* RenderBlock::regionAtBlockOffset(LayoutUnit blockOffset) const
   5607 {
   5608     RenderFlowThread* flowThread = flowThreadContainingBlock();
   5609     if (!flowThread || !flowThread->hasValidRegionInfo())
   5610         return 0;
   5611 
   5612     return flowThread->regionAtBlockOffset(offsetFromLogicalTopOfFirstPage() + blockOffset, true);
   5613 }
   5614 
   5615 bool RenderBlock::logicalWidthChangedInRegions(RenderFlowThread* flowThread) const
   5616 {
   5617     if (!flowThread || !flowThread->hasValidRegionInfo())
   5618         return false;
   5619 
   5620     return flowThread->logicalWidthChangedInRegionsForBlock(this);
   5621 }
   5622 
   5623 RenderRegion* RenderBlock::clampToStartAndEndRegions(RenderRegion* region) const
   5624 {
   5625     RenderFlowThread* flowThread = flowThreadContainingBlock();
   5626 
   5627     ASSERT(isRenderView() || (region && flowThread));
   5628     if (isRenderView())
   5629         return region;
   5630 
   5631     // We need to clamp to the block, since we want any lines or blocks that overflow out of the
   5632     // logical top or logical bottom of the block to size as though the border box in the first and
   5633     // last regions extended infinitely. Otherwise the lines are going to size according to the regions
   5634     // they overflow into, which makes no sense when this block doesn't exist in |region| at all.
   5635     RenderRegion* startRegion;
   5636     RenderRegion* endRegion;
   5637     flowThread->getRegionRangeForBox(this, startRegion, endRegion);
   5638 
   5639     if (startRegion && region->logicalTopForFlowThreadContent() < startRegion->logicalTopForFlowThreadContent())
   5640         return startRegion;
   5641     if (endRegion && region->logicalTopForFlowThreadContent() > endRegion->logicalTopForFlowThreadContent())
   5642         return endRegion;
   5643 
   5644     return region;
   5645 }
   5646 
   5647 LayoutUnit RenderBlock::collapsedMarginBeforeForChild(const RenderBox* child) const
   5648 {
   5649     // If the child has the same directionality as we do, then we can just return its
   5650     // collapsed margin.
   5651     if (!child->isWritingModeRoot())
   5652         return child->collapsedMarginBefore();
   5653 
   5654     // The child has a different directionality.  If the child is parallel, then it's just
   5655     // flipped relative to us.  We can use the collapsed margin for the opposite edge.
   5656     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
   5657         return child->collapsedMarginAfter();
   5658 
   5659     // The child is perpendicular to us, which means its margins don't collapse but are on the
   5660     // "logical left/right" sides of the child box.  We can just return the raw margin in this case.
   5661     return marginBeforeForChild(child);
   5662 }
   5663 
   5664 LayoutUnit RenderBlock::collapsedMarginAfterForChild(const  RenderBox* child) const
   5665 {
   5666     // If the child has the same directionality as we do, then we can just return its
   5667     // collapsed margin.
   5668     if (!child->isWritingModeRoot())
   5669         return child->collapsedMarginAfter();
   5670 
   5671     // The child has a different directionality.  If the child is parallel, then it's just
   5672     // flipped relative to us.  We can use the collapsed margin for the opposite edge.
   5673     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
   5674         return child->collapsedMarginBefore();
   5675 
   5676     // The child is perpendicular to us, which means its margins don't collapse but are on the
   5677     // "logical left/right" side of the child box.  We can just return the raw margin in this case.
   5678     return marginAfterForChild(child);
   5679 }
   5680 
   5681 bool RenderBlock::hasMarginBeforeQuirk(const RenderBox* child) const
   5682 {
   5683     // If the child has the same directionality as we do, then we can just return its
   5684     // margin quirk.
   5685     if (!child->isWritingModeRoot())
   5686         return child->isRenderBlock() ? toRenderBlock(child)->hasMarginBeforeQuirk() : child->style()->hasMarginBeforeQuirk();
   5687 
   5688     // The child has a different directionality. If the child is parallel, then it's just
   5689     // flipped relative to us. We can use the opposite edge.
   5690     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
   5691         return child->isRenderBlock() ? toRenderBlock(child)->hasMarginAfterQuirk() : child->style()->hasMarginAfterQuirk();
   5692 
   5693     // The child is perpendicular to us and box sides are never quirky in html.css, and we don't really care about
   5694     // whether or not authors specified quirky ems, since they're an implementation detail.
   5695     return false;
   5696 }
   5697 
   5698 bool RenderBlock::hasMarginAfterQuirk(const RenderBox* child) const
   5699 {
   5700     // If the child has the same directionality as we do, then we can just return its
   5701     // margin quirk.
   5702     if (!child->isWritingModeRoot())
   5703         return child->isRenderBlock() ? toRenderBlock(child)->hasMarginAfterQuirk() : child->style()->hasMarginAfterQuirk();
   5704 
   5705     // The child has a different directionality. If the child is parallel, then it's just
   5706     // flipped relative to us. We can use the opposite edge.
   5707     if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
   5708         return child->isRenderBlock() ? toRenderBlock(child)->hasMarginBeforeQuirk() : child->style()->hasMarginBeforeQuirk();
   5709 
   5710     // The child is perpendicular to us and box sides are never quirky in html.css, and we don't really care about
   5711     // whether or not authors specified quirky ems, since they're an implementation detail.
   5712     return false;
   5713 }
   5714 
   5715 const char* RenderBlock::renderName() const
   5716 {
   5717     if (isBody())
   5718         return "RenderBody"; // FIXME: Temporary hack until we know that the regression tests pass.
   5719 
   5720     if (isFloating())
   5721         return "RenderBlock (floating)";
   5722     if (isOutOfFlowPositioned())
   5723         return "RenderBlock (positioned)";
   5724     if (isAnonymousColumnsBlock())
   5725         return "RenderBlock (anonymous multi-column)";
   5726     if (isAnonymousColumnSpanBlock())
   5727         return "RenderBlock (anonymous multi-column span)";
   5728     if (isAnonymousBlock())
   5729         return "RenderBlock (anonymous)";
   5730     // FIXME: Temporary hack while the new generated content system is being implemented.
   5731     if (isPseudoElement())
   5732         return "RenderBlock (generated)";
   5733     if (isAnonymous())
   5734         return "RenderBlock (generated)";
   5735     if (isRelPositioned())
   5736         return "RenderBlock (relative positioned)";
   5737     if (isStickyPositioned())
   5738         return "RenderBlock (sticky positioned)";
   5739     return "RenderBlock";
   5740 }
   5741 
   5742 RenderBlock* RenderBlock::createAnonymousWithParentRendererAndDisplay(const RenderObject* parent, EDisplay display)
   5743 {
   5744     // FIXME: Do we need to convert all our inline displays to block-type in the anonymous logic ?
   5745     EDisplay newDisplay;
   5746     RenderBlock* newBox = 0;
   5747     if (display == BOX || display == INLINE_BOX) {
   5748         // FIXME: Remove this case once we have eliminated all internal users of old flexbox
   5749         newBox = RenderDeprecatedFlexibleBox::createAnonymous(&parent->document());
   5750         newDisplay = BOX;
   5751     } else if (display == FLEX || display == INLINE_FLEX) {
   5752         newBox = RenderFlexibleBox::createAnonymous(&parent->document());
   5753         newDisplay = FLEX;
   5754     } else {
   5755         newBox = RenderBlockFlow::createAnonymous(&parent->document());
   5756         newDisplay = BLOCK;
   5757     }
   5758 
   5759     RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(parent->style(), newDisplay);
   5760     newBox->setStyle(newStyle.release());
   5761     return newBox;
   5762 }
   5763 
   5764 RenderBlockFlow* RenderBlock::createAnonymousColumnsWithParentRenderer(const RenderObject* parent)
   5765 {
   5766     RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(parent->style(), BLOCK);
   5767     newStyle->inheritColumnPropertiesFrom(parent->style());
   5768 
   5769     RenderBlockFlow* newBox = RenderBlockFlow::createAnonymous(&parent->document());
   5770     newBox->setStyle(newStyle.release());
   5771     return newBox;
   5772 }
   5773 
   5774 RenderBlockFlow* RenderBlock::createAnonymousColumnSpanWithParentRenderer(const RenderObject* parent)
   5775 {
   5776     RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(parent->style(), BLOCK);
   5777     newStyle->setColumnSpan(ColumnSpanAll);
   5778 
   5779     RenderBlockFlow* newBox = RenderBlockFlow::createAnonymous(&parent->document());
   5780     newBox->setStyle(newStyle.release());
   5781     return newBox;
   5782 }
   5783 
   5784 #ifndef NDEBUG
   5785 void RenderBlock::checkPositionedObjectsNeedLayout()
   5786 {
   5787     if (!gPositionedDescendantsMap)
   5788         return;
   5789 
   5790     if (TrackedRendererListHashSet* positionedDescendantSet = positionedObjects()) {
   5791         TrackedRendererListHashSet::const_iterator end = positionedDescendantSet->end();
   5792         for (TrackedRendererListHashSet::const_iterator it = positionedDescendantSet->begin(); it != end; ++it) {
   5793             RenderBox* currBox = *it;
   5794             ASSERT(!currBox->needsLayout());
   5795         }
   5796     }
   5797 }
   5798 
   5799 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* markedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const RenderObject* obj) const
   5800 {
   5801     showRenderObject();
   5802     for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox())
   5803         root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLabel2, obj, 1);
   5804 }
   5805 
   5806 #endif
   5807 
   5808 } // namespace WebCore
   5809