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