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